Объявление App\Http\Requests\UserUpdateRequest::user() должно быть совместимо с Illuminate\Http\Request::user($guard = NULL)

Я пытаюсь поддержать и реализовать объекты FormRequest для проверки. Я успешно настроил запросы формы для всех моих моделей, кроме модели User. Я получаю следующую ошибкуDeclaration of App\Http\Requests\UserUpdateRequest::user() should be compatible with Illuminate\Http\Request::user($guard = NULL). Изучая эту ошибку, кажется, что это может быть проблема с тем, как я обрабатываю авторизацию с помощью политик. Обратите внимание, что UserStoreRequest работает, но UserUpdateRequest возвращает ошибку.

UserStoreRequest

<?php

namespace App\Http\Requests;

use App\User;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;

class UserStoreRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // Authorize action - create-user
        return Gate::allows('create', User::class);
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'      => 'required|string',
            'email'     => 'required|email|unique:users',
            'password'  => 'required|string|min:8|confirmed',
            'markets'   => 'required|array',
            'roles'     => 'required|array',
        ];
    }

    /**
     * Save the user.
     *
     * @return \App\User
     */
    public function save()
    {
        // Create the user
        $user = new User($this->validated());

        // Set the password
        $user->password = Hash::make($this->validated()['password']);
        $user->setRememberToken(Str::random(60));

        // Save the user
        $user->save();

        // Set users markets
        $user->markets()->sync($this->validated()['markets']);

        // Update the users role if included in the request
        if ($this->validated()['roles']) {
            foreach ($this->validated()['roles'] as $role) {
                $user->roles()->sync($role);

                if ($user->hasRole('admin')) {
                    $user->markets()->sync(Market::all());
                }
            }
        }

        return $user;
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'name.required'      => 'The name is required.',
            'email.required'     => 'The email is required.',
            'email.unique'       => 'The email must be unique.',
            'password.required'  => 'The password is required.',
            'password.confirmed' => 'The passwords do not match.',
            'password.min'       => 'The password must be at least 8 characters.',
            'markets.required'   => 'A market is required.',
            'roles.required'     => 'A role is required.',
        ];
    }
}

UserUpdateRequest

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;

class UserUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // Authorize action - update-user
        return Gate::allows('update', $this->user);
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'     => 'required|string',
        ];
    }

    /**
     * Get the user from the route.
     *
     * @return \App\User
     */
    public function user()
    {
        return $this->route('user');
    }

    /**
     * Save the email role.
     *
     * @return \App\Role
     */
    public function save()
    {
        // Update the user
        $this->user->update($this->validated());

        // // Check to see if password is being updated
        // if ($this->validated()['password']) {
        //     $this->user->password = Hash::make($this->validated()['password']);

        //     $this->user->setRememberToken(Str::random(60));
        // }

        // // Set users markets
        // $this->user->markets()->sync($this->validated()['markets']);

        // // Set users roles
        // // // Update the users role if included in the request
        // if ($this->validated()['roles']) {
        //     foreach ($this->validated()['roles'] as $role) {
        //         $this->user->roles()->sync($role);

        //         if ($this->user->hasRole('admin')) {
        //             $this->user->markets()->sync(Market::all());
        //         }
        //     }
        // }

        // // Save the user
        // $this->user->save();

        return $this->user;
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'name.required'      => 'The name is required.',
            'email.required'     => 'The email is required.',
            'email.unique'       => 'The email must be unique.',
            'markets.required'   => 'A market is required.',
            'roles.required'     => 'A role is required.',
        ];
    }
}

Как видите, я закомментировал большую часть кода UpdateRequest для устранения неполадок. Похоже, проблема вauthorize()метод. Ниже приведен код из UserPolicy

UserPolicy

/**
 * Determine whether the user can create models.
 *
 * @param \App\User $user
 *
 * @return mixed
 */
public function create(User $user)
{
    return $user->hasPermission('create-user');
}

/**
 * Determine whether the user can update the model.
 *
 * @param \App\User $user
 * @param \App\User $model
 *
 * @return mixed
 */
public function update(User $user, User $model)
{
    return $user->hasPermission('update-user');
}

UserController

/**
 * Store a newly created resource in storage.
 *
 * @param \Illuminate\Http\UserStoreRequest $request
 *
 * @return \Illuminate\Http\Response
 */
public function store(UserStoreRequest $request)
{
    return redirect($request->save()->path());
}

/**
 * Update the specified resource in storage.
 *
 * @param \Illuminate\Http\UserUpdateRequest $request
 * @param \App\User                          $user
 *
 * @return \Illuminate\Http\Response
 */
public function update(UserUpdateRequest $request, User $user)
{
    return redirect($request->save()->path());
}

Я использую авторизацию на основе разрешений для этой системы. У пользователя естьhasPermission()на нем, чтобы проверить, есть ли у пользователя необходимое разрешение для выполнения действия. Боюсь, что я запутался в этой настройке и неправильно проверяю. Все работало, пока не попыталась реализовать это на модели User.

hasPermission ()

/**
 * Check to see if the model has a permission assigned.
 *
 * @param string $permission
 *
 * @return bool
 */
public function hasPermission($permission)
{
    if (is_string($permission)) {
        if (is_null(Permission::whereName($permission)->first())) {
            return false;
        } else {
            return $this->hasRole(Permission::where('name', $permission)->first()->roles);
        }
    }

    return $this->hasRole($permission->roles);
}

hasRole()

/**
 * Check to see if model has a role assigned.
 *
 * @param string $role
 *
 * @return bool
 */
public function hasRole($role)
{
    if (is_string($role)) {
        return $this->roles->contains('name', $role);
    }

    return (bool) $role->intersect($this->roles)->count();
}

Обновить

Я попытался переименовать user()метод в UserUpdateRequest дляfrank()для решения любых проблем с переопределением пользователя Request. Это устраняет ошибку, указанную выше, но тогда ответ возвращается неавторизованным. У вошедшего в систему пользователя есть разрешения, позволяющие обновлять пользователей. Это называется вauthorize() метод с использованием Gate::allows. Я просто не уверен, проверяет ли он зарегистрированного пользователя или пользователя модели.

Я исследовал дальше и обнаружил, что после изменения метода на frank(). я получаюCall to a member function update() on null. Я должен возвращать пользователя, вытащенного из маршрута, из метода frank, но он, похоже, возвращает null.

Обновленный UserUpdateRequest

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Gate;

class UserUpdateRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        // Authorize action - update-user
        return Gate::allows('update', $this->frank);
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'name'     => 'required|string',
        ];
    }

    /**
     * Get the user from the route.
     *
     * @return \App\User
     */
    public function frank()
    {
        return $this->route('user');
    }

    /**
     * Save the email role.
     *
     * @return \App\Role
     */
    public function save()
    {
        // Update the user
        $this->frank->update($this->validated());

        // // Check to see if password is being updated
        // if ($this->validated()['password']) {
        //     $this->user->password = Hash::make($this->validated()['password']);

        //     $this->user->setRememberToken(Str::random(60));
        // }

        // // Set users markets
        // $this->user->markets()->sync($this->validated()['markets']);

        // // Set users roles
        // // // Update the users role if included in the request
        // if ($this->validated()['roles']) {
        //     foreach ($this->validated()['roles'] as $role) {
        //         $this->user->roles()->sync($role);

        //         if ($this->user->hasRole('admin')) {
        //             $this->user->markets()->sync(Market::all());
        //         }
        //     }
        // }

        // // Save the user
        // $this->user->save();

        return $this->frank;
    }

    /**
     * Get the error messages for the defined validation rules.
     *
     * @return array
     */
    public function messages()
    {
        return [
            'name.required'      => 'The name is required.',
            'email.required'     => 'The email is required.',
            'email.unique'       => 'The email must be unique.',
            'markets.required'   => 'A market is required.',
            'roles.required'     => 'A role is required.',
        ];
    }
}

1 ответ

Проблема в том user() метод, который вы определили в своем UserUpdateRequest класс.

UserUpdateRequest расширяет Illuminate\Foundation\Http\FormRequest, что, в свою очередь, расширяет Illuminate\Http\Request. Illuminate\Http\Request уже есть user() определен метод, поэтому user() метод в вашем UserUpdateRequest класс пытается переопределить это определение.

Поскольку ваш UserUpdateRequest::user() метод не соответствует Illuminate\Http\Request::user($guard = null) подпись, вы получаете эту ошибку.

Вы также можете:

  1. Удалить user() метод из вашего UserUpdateRequest класс, или
  2. Переименуйте ваш user() метод на вашем UserUpdateRequest класс, или
  3. Добавить $guard = null параметр к вашему user() метод на вашем UserUpdateRequest класс, чтобы он соответствовал сигнатуре базы user() метод.
Другие вопросы по тегам