Skip to content

Added backed enum as possible role and permission name when finding or creating them #2826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/Contracts/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function roles(): BelongsToMany;
*
* @throws \Spatie\Permission\Exceptions\PermissionDoesNotExist
*/
public static function findByName(string $name, ?string $guardName): self;
public static function findByName(string|\BackedEnum $name, ?string $guardName): self;

/**
* Find a permission by its id.
Expand All @@ -39,5 +39,5 @@ public static function findById(int|string $id, ?string $guardName): self;
/**
* Find or Create a permission by its name and guard name.
*/
public static function findOrCreate(string $name, ?string $guardName): self;
public static function findOrCreate(string|\BackedEnum $name, ?string $guardName): self;
}
4 changes: 2 additions & 2 deletions src/Contracts/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public function permissions(): BelongsToMany;
*
* @throws \Spatie\Permission\Exceptions\RoleDoesNotExist
*/
public static function findByName(string $name, ?string $guardName): self;
public static function findByName(string|\BackedEnum $name, ?string $guardName): self;

/**
* Find a role by its id and guard name.
Expand All @@ -39,7 +39,7 @@ public static function findById(int|string $id, ?string $guardName): self;
/**
* Find or create a role by its name and guard name.
*/
public static function findOrCreate(string $name, ?string $guardName): self;
public static function findOrCreate(string|\BackedEnum $name, ?string $guardName): self;

/**
* Determine if the user may perform the given permission.
Expand Down
16 changes: 14 additions & 2 deletions src/Models/Permission.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public static function create(array $attributes = [])
{
$attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);

$attributes['name'] = $attributes['name'] instanceof \BackedEnum
? $attributes['name']->value
: $attributes['name'];

$permission = static::getPermission(['name' => $attributes['name'], 'guard_name' => $attributes['guard_name']]);

if ($permission) {
Expand Down Expand Up @@ -86,8 +90,12 @@ public function users(): BelongsToMany
*
* @throws PermissionDoesNotExist
*/
public static function findByName(string $name, ?string $guardName = null): PermissionContract
public static function findByName(string|\BackedEnum $name, ?string $guardName = null): PermissionContract
{
if ($name instanceof \BackedEnum) {
$name = $name->value;
}

$guardName = $guardName ?? Guard::getDefaultName(static::class);
$permission = static::getPermission(['name' => $name, 'guard_name' => $guardName]);
if (! $permission) {
Expand Down Expand Up @@ -121,8 +129,12 @@ public static function findById(int|string $id, ?string $guardName = null): Perm
*
* @return PermissionContract|Permission
*/
public static function findOrCreate(string $name, ?string $guardName = null): PermissionContract
public static function findOrCreate(string|\BackedEnum $name, ?string $guardName = null): PermissionContract
{
if ($name instanceof \BackedEnum) {
$name = $name->value;
}

$guardName = $guardName ?? Guard::getDefaultName(static::class);
$permission = static::getPermission(['name' => $name, 'guard_name' => $guardName]);

Expand Down
29 changes: 24 additions & 5 deletions src/Models/Role.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public static function create(array $attributes = [])
{
$attributes['guard_name'] = $attributes['guard_name'] ?? Guard::getDefaultName(static::class);

$attributes['name'] = $attributes['name'] instanceof \BackedEnum
? $attributes['name']->value
: $attributes['name'];

$params = ['name' => $attributes['name'], 'guard_name' => $attributes['guard_name']];
if (app(PermissionRegistrar::class)->teams) {
$teamsKey = app(PermissionRegistrar::class)->teamsKey;
Expand Down Expand Up @@ -95,8 +99,12 @@ public function users(): BelongsToMany
*
* @throws RoleDoesNotExist
*/
public static function findByName(string $name, ?string $guardName = null): RoleContract
public static function findByName(string|\BackedEnum $name, ?string $guardName = null): RoleContract
{
if ($name instanceof \BackedEnum) {
$name = $name->value;
}

$guardName = $guardName ?? Guard::getDefaultName(static::class);

$role = static::findByParam(['name' => $name, 'guard_name' => $guardName]);
Expand Down Expand Up @@ -131,14 +139,22 @@ public static function findById(int|string $id, ?string $guardName = null): Role
*
* @return RoleContract|Role
*/
public static function findOrCreate(string $name, ?string $guardName = null): RoleContract
public static function findOrCreate(string|\BackedEnum $name, ?string $guardName = null): RoleContract
{
if ($name instanceof \BackedEnum) {
$name = $name->value;
}

$guardName = $guardName ?? Guard::getDefaultName(static::class);

$role = static::findByParam(['name' => $name, 'guard_name' => $guardName]);

if (! $role) {
return static::query()->create(['name' => $name, 'guard_name' => $guardName] + (app(PermissionRegistrar::class)->teams ? [app(PermissionRegistrar::class)->teamsKey => getPermissionsTeamId()] : []));
return static::query()->create(
['name' => $name, 'guard_name' => $guardName] + (app(PermissionRegistrar::class)->teams ? [
app(PermissionRegistrar::class)->teamsKey => getPermissionsTeamId(),
] : [])
);
}

return $role;
Expand Down Expand Up @@ -172,7 +188,7 @@ protected static function findByParam(array $params = []): ?RoleContract
/**
* Determine if the role may perform the given permission.
*
* @param string|int|\Spatie\Permission\Contracts\Permission|\BackedEnum $permission
* @param string|int|\Spatie\Permission\Contracts\Permission|\BackedEnum $permission
*
* @throws PermissionDoesNotExist|GuardDoesNotMatch
*/
Expand All @@ -185,7 +201,10 @@ public function hasPermissionTo($permission, ?string $guardName = null): bool
$permission = $this->filterPermission($permission, $guardName);

if (! $this->getGuardNames()->contains($permission->guard_name)) {
throw GuardDoesNotMatch::create($permission->guard_name, $guardName ? collect([$guardName]) : $this->getGuardNames());
throw GuardDoesNotMatch::create(
$permission->guard_name,
$guardName ? collect([$guardName]) : $this->getGuardNames()
);
}

return $this->loadMissing('permissions')->permissions
Expand Down
4 changes: 4 additions & 0 deletions src/PermissionRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,10 @@ public function getPermissions(array $params = [], bool $onlyOne = false): Colle

$permissions = $this->permissions->$method(static function ($permission) use ($params) {
foreach ($params as $attr => $value) {
if ($value instanceof \BackedEnum) {
$value = $value->value;
}

if ($permission->getAttribute($attr) != $value) {
return false;
}
Expand Down
22 changes: 22 additions & 0 deletions tests/PermissionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use PHPUnit\Framework\Attributes\Test;
use Spatie\Permission\Contracts\Permission;
use Spatie\Permission\Exceptions\PermissionAlreadyExists;
use Spatie\Permission\Tests\TestModels\TestRolePermissionsEnum;
use Spatie\Permission\Tests\TestModels\User;

class PermissionTest extends TestCase
Expand Down Expand Up @@ -86,4 +87,25 @@ public function it_can_delete_hydrated_permissions()

$this->assertCount(0, app(Permission::class)->where($this->testUserPermission->getKeyName(), $this->testUserPermission->getKey())->get());
}

/** @test */
#[Test]
public function it_can_find_or_create_permission_by_enum()
{
$permission = app(Permission::class)::findOrCreate(TestRolePermissionsEnum::VIEWARTICLES);

$this->assertEquals(TestRolePermissionsEnum::VIEWARTICLES->value, $permission->name);
}

/** @test */
#[Test]
public function it_can_find_permission_by_enum_name()
{
$permission = app(Permission::class)::create(['name' => TestRolePermissionsEnum::VIEWARTICLES]);
$foundPermission = app(Permission::class)::findByName(TestRolePermissionsEnum::VIEWARTICLES);

$this->assertEquals($permission->getKey(), $foundPermission->getKey());
$this->assertEquals(TestRolePermissionsEnum::VIEWARTICLES->value, $foundPermission->name);
$this->assertEquals($permission->name, $foundPermission->name);
}
}
22 changes: 22 additions & 0 deletions tests/RoleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Spatie\Permission\PermissionRegistrar;
use Spatie\Permission\Tests\TestModels\Admin;
use Spatie\Permission\Tests\TestModels\RuntimeRole;
use Spatie\Permission\Tests\TestModels\TestRolePermissionsEnum;
use Spatie\Permission\Tests\TestModels\User;

class RoleTest extends TestCase
Expand Down Expand Up @@ -318,4 +319,25 @@ public function it_can_change_role_class_on_runtime()
$this->assertInstanceOf(RuntimeRole::class, $this->testUser->roles[0]);
$this->assertSame('test-role', $this->testUser->roles[0]->name);
}

/** @test */
#[Test]
public function it_can_find_or_create_role_by_enum()
{
$permission = app(Role::class)::findOrCreate(TestRolePermissionsEnum::ADMIN);

$this->assertEquals(TestRolePermissionsEnum::ADMIN->value, $permission->name);
}

/** @test */
#[Test]
public function it_can_find_role_by_enum_name()
{
$role = app(Role::class)::create(['name' => TestRolePermissionsEnum::ADMIN]);
$foundRole = app(Role::class)::findByName(TestRolePermissionsEnum::ADMIN);

$this->assertEquals($role->getKey(), $foundRole->getKey());
$this->assertEquals(TestRolePermissionsEnum::ADMIN->value, $foundRole->name);
$this->assertEquals($role->name, $foundRole->name);
}
}
Loading