Вы знаете, что можете авторизовать любое действие в контроллере через метод 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 и предполагает название действия, которое вы хотите авторизовать.
Получите бесплатную консультацию на разработку Вашего проекта.