Skip to content

Commit

Permalink
Reuse code on withoutRole and withoutPermission (#2500)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikn69 authored Sep 13, 2023
1 parent 8f15d18 commit 5659d6a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 51 deletions.
29 changes: 6 additions & 23 deletions src/Traits/HasPermissions.php
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ public function permissions(): BelongsToMany
* Scope the model query to certain permissions only.
*
* @param string|int|array|Permission|Collection|\BackedEnum $permissions
* @param bool $without
*/
public function scopePermission(Builder $query, $permissions): Builder
public function scopePermission(Builder $query, $permissions, $without = false): Builder
{
$permissions = $this->convertToPermissionModels($permissions);

Expand All @@ -109,11 +110,11 @@ public function scopePermission(Builder $query, $permissions): Builder
);

return $query->where(fn (Builder $query) => $query
->whereHas('permissions', fn (Builder $subQuery) => $subQuery
->{! $without ? 'whereHas' : 'whereDoesntHave'}('permissions', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.permissions').".$permissionKey", \array_column($permissions, $permissionKey))
)
->when(count($rolesWithPermissions), fn ($whenQuery) => $whenQuery
->orWhereHas('roles', fn (Builder $subQuery) => $subQuery
->{! $without ? 'orWhereHas' : 'whereDoesntHave'}('roles', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.roles').".$roleKey", \array_column($rolesWithPermissions, $roleKey))
)
)
Expand All @@ -126,27 +127,9 @@ public function scopePermission(Builder $query, $permissions): Builder
*
* @param string|int|array|Permission|Collection|\BackedEnum $permissions
*/
public function scopeWithoutPermission(Builder $query, $permissions, $debug = false): Builder
public function scopeWithoutPermission(Builder $query, $permissions): Builder
{
$permissions = $this->convertToPermissionModels($permissions);

$permissionKey = (new ($this->getPermissionClass())())->getKeyName();
$roleKey = (new (is_a($this, Role::class) ? static::class : $this->getRoleClass())())->getKeyName();

$rolesWithPermissions = is_a($this, Role::class) ? [] : array_unique(
array_reduce($permissions, fn ($result, $permission) => array_merge($result, $permission->roles->all()), [])
);

return $query->where(fn (Builder $query) => $query
->whereDoesntHave('permissions', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.permissions').".$permissionKey", \array_column($permissions, $permissionKey))
)
->when(count($rolesWithPermissions), fn ($whenQuery) => $whenQuery
->whereDoesntHave('roles', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.roles').".$roleKey", \array_column($rolesWithPermissions, $roleKey))
)
)
);
return $this->scopePermission($query, $permissions, true);
}

/**
Expand Down
33 changes: 5 additions & 28 deletions src/Traits/HasRoles.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ public function roles(): BelongsToMany
*
* @param string|int|array|Role|Collection|\BackedEnum $roles
* @param string $guard
* @param bool $without
*/
public function scopeRole(Builder $query, $roles, $guard = null): Builder
public function scopeRole(Builder $query, $roles, $guard = null, $without = false): Builder
{
if ($roles instanceof Collection) {
$roles = $roles->all();
Expand All @@ -91,10 +92,9 @@ public function scopeRole(Builder $query, $roles, $guard = null): Builder
return $this->getRoleClass()::{$method}($role, $guard ?: $this->getDefaultGuardName());
}, Arr::wrap($roles));

$roleClass = $this->getRoleClass();
$key = (new $roleClass())->getKeyName();
$key = (new ($this->getRoleClass())())->getKeyName();

return $query->whereHas('roles', fn (Builder $subQuery) => $subQuery
return $query->{! $without ? 'whereHas' : 'whereDoesntHave'}('roles', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.roles').".$key", \array_column($roles, $key))
);
}
Expand All @@ -107,30 +107,7 @@ public function scopeRole(Builder $query, $roles, $guard = null): Builder
*/
public function scopeWithoutRole(Builder $query, $roles, $guard = null): Builder
{
if ($roles instanceof Collection) {
$roles = $roles->all();
}

$roles = array_map(function ($role) use ($guard) {
if ($role instanceof Role) {
return $role;
}

if ($role instanceof \BackedEnum) {
$role = $role->value;
}

$method = is_int($role) || PermissionRegistrar::isUid($role) ? 'findById' : 'findByName';

return $this->getRoleClass()::{$method}($role, $guard ?: $this->getDefaultGuardName());
}, Arr::wrap($roles));

$roleClass = $this->getRoleClass();
$key = (new $roleClass())->getKeyName();

return $query->whereDoesntHave('roles', fn (Builder $subQuery) => $subQuery
->whereIn(config('permission.table_names.roles').".$key", \array_column($roles, $key))
);
return $this->scopeRole($query, $roles, $guard, true);
}

/**
Expand Down

0 comments on commit 5659d6a

Please sign in to comment.