lliure/permission

Role-based permission system with scope and level support

Maintainers

Package info

bitbucket.org/vinteenove/permission

pkg:composer/lliure/permission

Statistics

Installs: 78

Dependents: 0

Suggesters: 0

v1.1.0 2026-03-18 20:41 UTC

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

MethodDescription
setRole(string $role): selfSet the user's role
getRole(): stringGet the current role
setLevelHierarchy(array $levels): selfDefine ordered levels for setLevel()
setClass(string $class): objectStart building permissions for a class/resource
getPermissions(string $class, string $scope): boolCheck if a scope is granted
hasLevel(string $class, string $level): boolCheck if a level is granted (alias for getPermissions)
getClassPermissions(string $class): arrayGet all scopes for a class
getClasses(): arrayList all registered classes/resources

Class builder (returned by setClass())

MethodDescription
setScope(string $scope): selfGrant a single scope
setScopes(array $scopes): selfGrant multiple scopes
setLevel(string $level): selfGrant a level and all lower levels

Permission trait

MethodDescription
isDev(): boolCheck if role is dev
isAdmin(): boolCheck if role is dev or admin
isUser(): boolCheck if role is dev, admin, or user
__call($name): boolCheck scope via dynamic method call