VOOZH about

URL: https://deepwiki.com/hypervel/permission/2.1-haspermission-trait

⇱ HasPermission Trait | hypervel/permission | DeepWiki


Loading...
Menu

HasPermission Trait

Purpose and Scope

The HasPermission trait is the core authorization component of the Hypervel Permission package. It provides permission checking and assignment capabilities to any model that uses it (referred to as "owner" models). The trait implements a sophisticated permission system with support for direct permissions, role-inherited permissions, and forbidden (negative) permissions.

This trait handles permission checking logic, assignment operations, and integrates with the caching layer. For information about role management, see HasRole Trait. For details on the caching mechanism, see Caching System. For middleware integration, see HTTP Middleware Integration.

Sources: src/Traits/HasPermission.php1-534


Core Concepts

Owner Models

Any Eloquent model can use the HasPermission trait to become permission-aware. The trait refers to these models as "owners" of permissions. Common examples include User models, Team models, or any entity requiring authorization.

The trait property $permissions provides access to the owner's directly-assigned permissions through an Eloquent relationship.

Permission Types

The trait distinguishes between three types of permission associations:

Permission TypeDescriptionPriority
Direct PermissionsPermissions explicitly assigned to the ownerMedium
Role-Inherited PermissionsPermissions the owner has through assigned rolesLow
Forbidden PermissionsExplicit denial permissions that override othersHighest

Forbidden Permissions

Forbidden permissions (is_forbidden = true in pivot tables) represent explicit denials that take precedence over all other permission grants. If an owner has a forbidden permission either directly or through a role, hasPermission() returns false regardless of other permission assignments.

Sources: src/Traits/HasPermission.php17-26 src/Traits/HasPermission.php166-179 src/Traits/HasPermission.php456-504


Permission Checking Logic

Permission Resolution Flow


The hasPermission() method follows a strict evaluation order:

  1. Check for direct forbidden permissions
  2. Check for role-inherited forbidden permissions
  3. Check for direct allowed permissions
  4. Check for role-inherited allowed permissions

Sources: src/Traits/HasPermission.php166-179

Cache-Aware Permission Retrieval


The getCachedPermissions() method retrieves permissions with caching support. For Role models, it uses the global roles cache. For other owners, it maintains owner-specific caches.

Sources: src/Traits/HasPermission.php56-89 src/PermissionManager.php196-202


Permission Checking Methods

Basic Checking Methods

MethodParametersReturn TypeDescription
hasPermission()BackedEnum|int|string|UnitEnumboolChecks if owner has permission (direct or via roles), respecting forbidden permissions
hasDirectPermission()BackedEnum|int|string|UnitEnumboolChecks only directly-assigned permissions
hasPermissionViaRoles()BackedEnum|int|string|UnitEnumboolChecks only role-inherited permissions
hasForbiddenPermission()BackedEnum|int|string|UnitEnumboolChecks if owner has direct forbidden permission
hasForbiddenPermissionViaRoles()BackedEnum|int|string|UnitEnumboolChecks if owner has forbidden permission via roles

Sources: src/Traits/HasPermission.php166-179 src/Traits/HasPermission.php184-194 src/Traits/HasPermission.php199-231 src/Traits/HasPermission.php457-467 src/Traits/HasPermission.php472-504

Bulk Checking Methods

MethodParametersReturn TypeDescription
hasAnyPermissions()...$permissions (variadic array)boolReturns true if owner has any of the specified permissions
hasAllPermissions()...$permissions (variadic array)boolReturns true if owner has all specified permissions
hasAnyDirectPermissions()...$permissions (variadic array)boolReturns true if owner has any directly-assigned permission
hasAllDirectPermissions()...$permissions (variadic array)boolReturns true if owner has all directly-assigned permissions

These methods accept variadic parameters and automatically flatten nested arrays.

Sources: src/Traits/HasPermission.php236-271

Permission Retrieval Methods

MethodReturn TypeDescription
getAllPermissions()BaseCollectionReturns all permissions (direct and via roles), excluding forbidden direct permissions
getPermissionsViaRoles()BaseCollectionReturns only permissions inherited through roles

Sources: src/Traits/HasPermission.php109-122 src/Traits/HasPermission.php129-161


Permission Assignment

Assignment Method Overview


Sources: src/Traits/HasPermission.php274-363

givePermissionTo()

Assigns one or more permissions to the owner with is_forbidden = false.


The method:

  1. Calls collectPermissions() to resolve permission identifiers to IDs
  2. Calls attachPermission() to attach to the pivot table
  3. Clears the owner's cache (or global roles cache if owner is a Role)

Sources: src/Traits/HasPermission.php276-289

giveForbiddenTo()

Assigns forbidden permissions with is_forbidden = true. These permissions will cause hasPermission() to return false regardless of other grants.

Sources: src/Traits/HasPermission.php294-307

revokePermissionTo()

Removes permission assignments (both allowed and forbidden) by detaching from the pivot table.

Sources: src/Traits/HasPermission.php312-328

syncPermissions()

Replaces all permission assignments with the specified sets of allowed and forbidden permissions. This is the most efficient way to update multiple permissions at once.


If a permission appears in both arrays, the forbidden flag takes precedence.

Sources: src/Traits/HasPermission.php336-363


Type Support and Normalization

Supported Permission Identifiers

The trait accepts multiple types for permission identification:

TypeExampleResolution Method
int42Treated as permission ID
string'edit-posts'Treated as permission name
BackedEnum (int)Permission::EDIT->value = 1Treated as permission ID
BackedEnum (string)Permission::EDIT->value = 'edit'Treated as permission name
UnitEnumPermission::EDIT->name = 'EDIT'Treated as permission name

Normalization Process


The normalizePermissionValue() method converts any supported type to a [field, value] pair used for database queries.

Sources: src/Traits/HasPermission.php368-401

Permission Collection Process

The collectPermissions() method resolves mixed permission identifiers to database IDs:

  1. Flatten variadic input arrays
  2. Separate permissions by type using separatePermissionsByType()
  3. Build query with whereIn(id) and/or orWhereIn(name) clauses
  4. Return array of permission IDs

Sources: src/Traits/HasPermission.php509-533


Database Relationships

permissions() Relationship

The trait defines a polymorphic many-to-many relationship through the owner_has_permissions pivot table:


Configuration keys control the relationship:

  • permission.table_names.owner_name: Morph name (default: 'owner')
  • permission.table_names.owner_has_permissions: Pivot table name
  • permission.column_names.owner_morph_key: Owner ID column
  • permission.column_names.permission_pivot_key: Permission ID column

The relationship includes the is_forbidden pivot column via withPivot().

Sources: src/Traits/HasPermission.php94-104


Caching Behavior

Cache Invalidation Strategy

The trait invalidates caches whenever permissions change:

OperationCache ClearedCondition
givePermissionTo()Owner-specific cacheWhen owner is not a Role
givePermissionTo()Global roles cacheWhen owner is a Role
giveForbiddenTo()Owner-specific cacheWhen owner is not a Role
giveForbiddenTo()Global roles cacheWhen owner is a Role
revokePermissionTo()Owner-specific cacheWhen owner is not a Role
revokePermissionTo()Global roles cacheWhen owner is a Role
syncPermissions()Owner-specific cacheWhen owner is not a Role
syncPermissions()Global roles cacheWhen owner is a Role

Cache invalidation is performed through PermissionManager:

  • clearOwnerCache(ownerType, ownerId) for individual owners
  • clearAllRolesPermissionsCache() for Role models

Sources: src/Traits/HasPermission.php276-363 src/PermissionManager.php207-223

Role Model Special Handling

When the owner model implements the Role contract, the trait uses a different caching strategy:

  1. Reads from global getAllRolesWithPermissions() cache
  2. Writes invalidate the entire roles cache, not owner-specific cache
  3. This ensures role permission changes immediately affect all owners with that role

Sources: src/Traits/HasPermission.php64-68 src/Traits/HasPermission.php279-283


Integration with PermissionManager

Manager Access

The trait obtains the PermissionManager singleton through:


Sources: src/Traits/HasPermission.php42-45

Manager-Provided Services

The PermissionManager provides the following services to the trait:

ServiceMethodPurpose
Model ResolutiongetPermissionClass()Returns configured Permission model class
Cache RetrievalgetOwnerCachedPermissions()Retrieves cached permission data for owner
Cache RetrievalgetAllRolesWithPermissions()Retrieves global roles+permissions cache
Cache StoragecacheOwnerPermissions()Stores owner permissions in cache
Cache InvalidationclearOwnerCache()Clears specific owner's cache
Cache InvalidationclearAllRolesPermissionsCache()Clears global roles cache

Sources: src/Traits/HasPermission.php30-37 src/Traits/HasPermission.php60-89 src/PermissionManager.php69-77 src/PermissionManager.php140-156 src/PermissionManager.php174-180 src/PermissionManager.php196-202 src/PermissionManager.php207-223


HasRole Integration

Conditional Role Checking

The trait conditionally uses role-related functionality if the HasRole trait is present:


This design allows the trait to work independently or in combination with HasRole.

Sources: src/Traits/HasPermission.php140-147 src/Traits/HasPermission.php210-216 src/Traits/HasPermission.php484-490

Role Permission Inheritance

When checking permissions via roles:

  1. Retrieve owner's roles (cached or fresh)
  2. For each role, look up permissions in getAllRolesWithPermissions() cache
  3. Filter for is_forbidden = false when checking allowed permissions
  4. Filter for is_forbidden = true when checking forbidden permissions
  5. Merge results across all roles

Sources: src/Traits/HasPermission.php199-231 src/Traits/HasPermission.php472-504


Owner Type Identification

getOwnerType() Method

Returns the fully-qualified class name of the owner model using static::class. This is used for:

  • Generating cache keys
  • Distinguishing between different model types in polymorphic relationships
  • Special handling for Role models

Sources: src/Traits/HasPermission.php50-53

Role Model Detection

The trait detects if the owner is a Role model using:


This determines caching strategy and relationship loading behavior.

Sources: src/Traits/HasPermission.php64-68 src/Traits/HasPermission.php131-133 src/Traits/HasPermission.php201-203

Refresh this wiki

On this page