diff --git a/src/Contracts/Permission.php b/src/Contracts/Permission.php index 5446e501a..2b0fcd77d 100644 --- a/src/Contracts/Permission.php +++ b/src/Contracts/Permission.php @@ -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. @@ -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; } diff --git a/src/Contracts/Role.php b/src/Contracts/Role.php index 31a67a082..2cb9eda88 100644 --- a/src/Contracts/Role.php +++ b/src/Contracts/Role.php @@ -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. @@ -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. diff --git a/src/Models/Permission.php b/src/Models/Permission.php index 490a6c23c..3752107c9 100644 --- a/src/Models/Permission.php +++ b/src/Models/Permission.php @@ -43,6 +43,10 @@ public static function create(array $attributes = []) { $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) { @@ -86,10 +90,16 @@ 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 ??= Guard::getDefaultName(static::class); + $permission = static::getPermission(['name' => $name, 'guard_name' => $guardName]); + if (! $permission) { throw PermissionDoesNotExist::create($name, $guardName); } @@ -121,9 +131,14 @@ 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 ??= Guard::getDefaultName(static::class); + $permission = static::getPermission(['name' => $name, 'guard_name' => $guardName]); if (! $permission) { diff --git a/src/Models/Role.php b/src/Models/Role.php index 7aa729dc1..9352fb61c 100644 --- a/src/Models/Role.php +++ b/src/Models/Role.php @@ -44,6 +44,10 @@ public static function create(array $attributes = []) { $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; @@ -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 ??= Guard::getDefaultName(static::class); $role = static::findByParam(['name' => $name, 'guard_name' => $guardName]); @@ -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 ??= 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; @@ -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 */ @@ -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 diff --git a/src/PermissionRegistrar.php b/src/PermissionRegistrar.php index 92e6edc4e..b1e75fd73 100644 --- a/src/PermissionRegistrar.php +++ b/src/PermissionRegistrar.php @@ -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; } diff --git a/tests/PermissionTest.php b/tests/PermissionTest.php index 553b3650a..be0be35dc 100644 --- a/tests/PermissionTest.php +++ b/tests/PermissionTest.php @@ -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 @@ -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); + } } diff --git a/tests/RoleTest.php b/tests/RoleTest.php index af88b0af6..0ea40b6dc 100644 --- a/tests/RoleTest.php +++ b/tests/RoleTest.php @@ -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 @@ -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); + } }