Laravel посредники

286
13 августа 2021, 12:00

Задача:

  • Есть сообщение, которые могут оставлять пользователи.
  • Нужно дать возможность пользователям редактировать/удалять свои сообщения.

Я реализовал это так:

if ( $message->user->id == Auth::id() )

Цель:

  • Хочу перенести эту логику в посредник (из контроллера), но не знаю, как передать в посредник $message
  • Из документации я узнал о параметрах в посредниках:

    Route::get('messages/{id}/edit', 'MessageController@edit')->middleware('redactor:id');

Но у меня получается передать лишь строку, с статическим значением.

Answer 1

Как указано в документации, посредник (Middleware) имеет метод handle(), который и выполняет всю работу. Примеры в документации тоже даны весьма показательные. Думаю, ее (документацию) стоит почитать...

Вот, например, как выглядит проверка в Middleware корректности возраста в запросе:

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->age <= 200) {
            return redirect('home');
        }
        return $next($request);
    }

Т.е. Middleware получает экземпляр классического класса \Illuminate\Http\Request.

Ваш вызов

Route::get('messages/{id}/edit','MessageController@edit')
       ->middleware('redactor:id');

для указанного маршрута передает во все Middleware дополнительный параметр $redactor с значением 'id'. Для того, чтобы Middleware его принял, сигнатура у метода handle() должна быть

public function handle($request, Closure $next, $redactor)

Это, кстати, также описано в документации и сопровождено примером.

А вот значение переменной $id, приведенное в строке маршрута 'messages/{id}/edit', передается в метод edit() контроллера MessageController. И, как учит нас документация по контроллерам Laravel, в методе edit() должен для нее быть параметр соответствующий:

public function edit($id)

Потенциально можно попробовать получить значение id для message в Midlleware, используя Route::input('id'). Но я лично этот метод не проверял и не уверен, что правильно понимаю его назначение и работу.

Для Вашего случая проще всего не использовать Middleware, поскольку для него нужно как-то получить id. А его можно получить уже в контроллере. И ограничивать нужно не все операции, а только edit и delete. Это проще организовать именно в контроллере.

Лично я бы в модель Message добавил локальный фильтр scope и в контроллере получал бы Message по id через этот scope:

Модель:

    /**
     * Scope a query to only editable for current users.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $query
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeEditable($query)
    {
        return $query->where('user_id', Auth::id());
    }

Контроллер:

    public function edit(Request $request, $id)
    {
        if (! ($message = App\Message::editable()->find($id)) ) {
            // для текущего пользователя запрещено редактирование
            // этого сообщения
        }
        // обработка редактирования
    }
READ ALSO
buddypress: ещё один способ нотификации

buddypress: ещё один способ нотификации

У buddypress есть два способа нотификации - системные сообщения и почтаМне нужно добавить ещё один способ: смс

278
Похожие записи по меткам в Wordpress

Похожие записи по меткам в Wordpress

Я вывожу похожие посты по меткам, мне нужно чтобы первыми отображались те которые больше всего связаны с этим постом, тоесть к примеру:

157
Выводить среднее значение столбца с MS SQL

Выводить среднее значение столбца с MS SQL

Есть готовый код по графикам ,и теперь мне просто нужно по этому запросу

152
Проблема при настройке NTLM-авторизации (mod_authnz_sspi) Apache 2.4 Windows

Проблема при настройке NTLM-авторизации (mod_authnz_sspi) Apache 2.4 Windows

Использую mod_authnz_sspi для авторизации через Active Directory для сайта в интрасетиУсловно сервер называется stat123prod

218