Sep 4, 2024
0
Level 23
Bind all model on one policy, but can't get model name inside policy.
I build a BasePolicy for all models, and get user permissions from database. Here is what i did:
1.bind all model to BasePolicy
public static function bindForNamespace(string $namespace): void
{
$classes = self::getClassesInNamespace($namespace);
foreach($classes as $class){
if(! is_subclass_of($class, 'Illuminate\Database\Eloquent\Model')){
continue;
}
if(Gate::getPolicyFor($class)){
continue;
}
Gate::policy($class, BasePolicy::class);
}
}
- use BasePolicy to get user's permission
class BasePolicy
{
public ?Collection $permissions;
public function __construct()
{
$user = Filament::auth()->user()->load('roles.permissions.menu');
$this->permissions = $user->roles->pluck('permissions');
}
public function viewAny($user, $model)
{
return false;
}
public function create(): bool
{
return $this->hasPermission('create');
}
public function update(): bool
{
return $this->hasPermission('update');
}
public function delete(): bool
{
return $this->hasPermission('delete');
}
protected function hasPermission(string $permissionName): bool
{
if($this->permissions->isEmpty()){
return false;
}
return $this->permissions
->where('status', Permission::STATUS_ENABLED)
->contains(fn($permission) =>
$permission->name === $permissionName
);
}
}
The problem is that I can not get model name inside policy, because laravel's Gate class removed it from $arguments,
protected function callPolicyMethod($policy, $method, $user, array $arguments)
{
// If this first argument is a string, that means they are passing a class name
// to the policy. We will remove the first argument from this argument array
// because this policy already knows what type of models it can authorize.
if (isset($arguments[0]) && is_string($arguments[0])) {
array_shift($arguments);
}
if (! is_callable([$policy, $method])) {
return;
}
if ($this->canBeCalledWithUser($user, $policy, $method)) {
return $policy->{$method}($user, ...$arguments);
}
}
Is there any solution for this, I need to get model name inside Basepolicy class
Please or to participate in this conversation.