Объявление 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)
подпись, вы получаете эту ошибку.
Вы также можете:
- Удалить
user()
метод из вашегоUserUpdateRequest
класс, или - Переименуйте ваш
user()
метод на вашемUserUpdateRequest
класс, или - Добавить
$guard = null
параметр к вашемуuser()
метод на вашемUserUpdateRequest
класс, чтобы он соответствовал сигнатуре базыuser()
метод.