lliure / permission
Role-based permission system with scope and level support
v1.1.0
2026-03-18 20:41 UTC
Requires
- php: >= 8.1
This package is auto-updated.
Last update: 2026-03-18 20:44:54 UTC
README
Role-based permission system with scope and level support for PHP 8.1+.
Install
composer require lliure/permission
Scope-based permissions (boolean)
Traditional scope model where each permission is an independent boolean flag.
1. Create a permission class
class CampaignPermission
{
use \LlPermission\Permission;
}
2. Build the permission set
$permissions = (new \LlPermission\PermissionSet())
->setRole('staff');
$permissions->setClass(CampaignPermission::class)
->setScope('read')
->setScopes(['create', 'update']);
3. Check permissions
$campaign = new CampaignPermission($permissions);
$campaign->read(); // true
$campaign->create(); // true
$campaign->update(); // true
$campaign->delete(); // false (not granted)
The __call magic method enables checking any scope by calling it as a method.
Role hierarchy
The Permission trait includes built-in role checks:
$campaign->isDev(); // true if role === 'dev'
$campaign->isAdmin(); // true if role === 'dev' or 'admin'
$campaign->isUser(); // true if role === 'dev', 'admin', or 'user'
Users with role dev bypass all scope checks automatically.
Level-based permissions (hierarchical)
For systems where access levels are cumulative (e.g., view < edit < full).
1. Define the hierarchy
$permissions = (new \LlPermission\PermissionSet())
->setRole('operator')
->setLevelHierarchy(['none', 'view', 'edit', 'full']);
2. Assign levels per resource
$permissions->setClass('customer.360')->setLevel('edit');
$permissions->setClass('orders')->setLevel('view');
$permissions->setClass('audit')->setLevel('full');
setLevel('edit') automatically grants all lower levels (view and edit).
3. Check levels
$permissions->hasLevel('customer.360', 'view'); // true (edit >= view)
$permissions->hasLevel('customer.360', 'edit'); // true
$permissions->hasLevel('customer.360', 'full'); // false (edit < full)
$permissions->hasLevel('orders', 'view'); // true
$permissions->hasLevel('orders', 'edit'); // false
$permissions->hasLevel('audit', 'full'); // true
Mixing scopes and levels
You can combine both approaches in the same PermissionSet:
$permissions = (new \LlPermission\PermissionSet())
->setRole('manager')
->setLevelHierarchy(['none', 'view', 'edit', 'full']);
// Level-based resource
$permissions->setClass('customer.360')->setLevel('edit');
// Scope-based class
$permissions->setClass(CampaignPermission::class)
->setScopes(['read', 'create', 'update']);
API
PermissionSet
| Method | Description |
|---|---|
setRole(string $role): self | Set the user's role |
getRole(): string | Get the current role |
setLevelHierarchy(array $levels): self | Define ordered levels for setLevel() |
setClass(string $class): object | Start building permissions for a class/resource |
getPermissions(string $class, string $scope): bool | Check if a scope is granted |
hasLevel(string $class, string $level): bool | Check if a level is granted (alias for getPermissions) |
getClassPermissions(string $class): array | Get all scopes for a class |
getClasses(): array | List all registered classes/resources |
Class builder (returned by setClass())
| Method | Description |
|---|---|
setScope(string $scope): self | Grant a single scope |
setScopes(array $scopes): self | Grant multiple scopes |
setLevel(string $level): self | Grant a level and all lower levels |
Permission trait
| Method | Description |
|---|---|
isDev(): bool | Check if role is dev |
isAdmin(): bool | Check if role is dev or admin |
isUser(): bool | Check if role is dev, admin, or user |
__call($name): bool | Check scope via dynamic method call |