You know you can authorize any action in the controller via authorize
method where you need to pass the ability as the first argument and the model as the second one.
But when you don't pass the ability to that method, Laravel will assume the ability from the controller method name. So in this example:
public function update(Post $post)
{
$this->authorize('update', $post);
}
you can omit the Policy method name as it's the same as the controller method name where you call the authorize
from:
public function update(Post $post)
{
$this->authorize($post);
}
How cool is that? But...
Things get more clear when you take a look at the AuthorizesRequests
trait which is imported in the App\Http\Controllers\Controller
which means in every controller that extends this class. Here is the authorize
method:
public function authorize($ability, $arguments = [])
{
[$ability, $arguments] = $this->parseAbilityAndArguments($ability, $arguments);
return app(Gate::class)->authorize($ability, $arguments);
}
$ability
and $arguments
variables are going from the parseAbilityAndArguments
method:
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];
}
It immediately returns $ability
and $arguments
variables if we explicitly pass an ability: $ability
is actually a string and doesn't contain \\
so it's not a classpath. Here is the fun part:
You can see the usage of debug_backtrace
function where all the magic happens. It is a usual PHP function that can show us what has been called so far as an array. The second argument tells how many calls we need to know. It's 3. First is the current function, second is the authorize
method and the third one is the controller method itself. So we need to grab the function name of the last one. There we go! That's how Laravel assumes the ability name.
You will get free consultation on your project development.