【发布时间】:2016-08-10 16:34:00
【问题描述】:
我在策略中有一个方法可以检查用户是否可以访问页面。页面名称和当前用户是策略方法的参数:
public function pageAllowed(User $user, string $page)
{
return $this->allGranted($user) || $user->hasPermission(self::PREFIX_PAGE . '.' . $page);
}
问题是如果我这样做了,我通常无法从刀片中检查策略
@can('page-allowed', [Auth::user(),'page.name'])
<li ng-class="{ active: properties.isActive('/feedback')}"><a href="#/feedback">Feedback</a></li>
@endcan
然后 Laravel 在调用策略的方法时会复制用户参数,因为它调用方法的方式,请参阅\Illuminate\Auth\Access\Gate::resolvePolicyCallback,第 388 行:
return call_user_func_array(
[$instance, $ability], array_merge([$user], $arguments)
);
如您所见,它将解析的用户(它自己另外解析)与传递的参数合并。第一个传递的参数是当前用户。第二个是页面的名称。它最终将以下参数传递给策略的方法:User, User, 'page.name'。前两个参数是相同的,我想去掉这个重复。
我很乐意不从刀片传递用户,但在这种情况下,Laravel 无法解析策略,因为它通过第一个传递的参数查找策略!请参阅\Illuminate\Auth\Access\Gate::firstArgumentCorrespondsToPolicy,第 346 行:
return is_string($arguments[0]) && isset($this->policies[$arguments[0]]);
因此,如果我不将用户作为第一个参数传递,它会尝试通过页面名称解析策略。我完全糊涂了,请帮忙。
更新
我找到了一个笨拙的解决方案,将刀片 @if 语句与 policy() 帮助器一起使用
@if(policy(Auth::user())->pageAllowed(Auth::user(),'feedback'))
<li ng-class="{ active: properties.isActive('/feedback')}"><a href="#/feedback">Feedback</a></li>
@endif
而不是@can 语句。但我想知道我做错了什么。
【问题讨论】:
标签: php laravel laravel-5 laravel-5.2