Вы знаете, что можете авторизовать любое действие в контроллере через метод authorize
, в котором вы должны передать действие как первый аргумент и модель как второй.
Но если вы не передадите действие в этот метод, Laravel предположит название этого действия из навзвания метода контроллера. Таким образом в этом примере:
public function update(Post $post)
{
$this->authorize('update', $post);
}
вы можете опустить название метода Policy, т.к. оно совпадает с названием метода контроллера, из которого вы вызываете authorize
:
public function update(Post $post)
{
$this->authorize($post);
}
Круто, правда? Но...
Становится намного яснее если взглянуть на трейт AuthorizesRequests
, который подключается в App\Http\Controllers\Controller
, что означает в любом контроллере, который наследует этот класс. Так выглядит метод authorize
:
public function authorize($ability, $arguments = [])
{
[$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
Переменные $ability
и $arguments
идут из метода parseAbilityAndArguments
:
protected function parseAbilityAndArguments($ability, $arguments)
{
if (is_string($ability) && strpos($ability, '\\') === false) {
return [$ability, $arguments];
}
$method = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
return [$this->normalizeGuessedAbilityName($method), $ability];
}
Переменные $ability
и $arguments
возвращаются сразу если мы непосредственно передаем действие, которое хотим авторизовать: $ability
является строчкой и не содержит \\
, что говорит о том, что это не путь к классу. Здесь начинается самое интересное:
Вы можете видеть использование функции debug_backtrace
, где вся магия и происходит. Это обычная функция PHP, которая показывает что на данный момент было вызвано в виде массива. Второй аргумент говорит сколько таких вызовов нам нужно знать. Нам нужно знать всего 3. Первый - это текущий метод, второй - метод authorize
и третий сам метод контроллера, из которого мы вызываем authorize
. Все что нам нужно, это взять название последнего. Вот и все! Таким образом Laravel и предполагает название действия, которое вы хотите авторизовать.
Получите бесплатную консультацию на разработку Вашего проекта.