PHPackages                             pkc/role-permission - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. pkc/role-permission

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

pkc/role-permission
===================

A dynamic role and permission management package for Laravel.

1.1.0(3mo ago)06MITPHPPHP ^8.2

Since Jan 12Pushed 3mo agoCompare

[ Source](https://github.com/laradevsumon/role-permission)[ Packagist](https://packagist.org/packages/pkc/role-permission)[ RSS](/packages/pkc-role-permission/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (3)Versions (4)Used By (0)

PKC Role Permission
===================

[](#pkc-role-permission)

A lightweight, dynamic role and permission management package for Laravel. This package allows you to manage roles and permissions dynamically via the database, with support for hierarchical permissions and granular access control.

✨ Features
----------

[](#-features)

- **🔐 Dynamic Roles &amp; Permissions**: Store and manage roles and permissions in the database
- **🌳 Hierarchical Permissions**: Supports parent-child relationships for permissions (e.g., a "Module" permission containing multiple "Action" permissions)
- **⚡ Performance Optimized**: Built-in caching support for faster permission checks
- **🚀 Easy Integration**: Simple traits for `User` and `Role` models
- **🎯 Route Access Control**: Helpers to check access based on route names
- **🔒 Production Ready**: Validation, error handling, and security features

📋 Requirements
--------------

[](#-requirements)

- PHP &gt;= 8.2
- Laravel &gt;= 11.0
- Composer

📦 Installation
--------------

[](#-installation)

You can install the package via composer:

```
composer require pkc/role-permission
```

🔧 Setup
-------

[](#-setup)

### 1. Publish Configuration (Optional)

[](#1-publish-configuration-optional)

```
php artisan vendor:publish --tag=role-permission-config
```

This will create `config/role-permission.php` where you can customize settings.

### 2. Run Migrations

[](#2-run-migrations)

The package comes with migrations for `roles`, `permissions`, and the pivot `role_permissions` table. Run them using:

```
php artisan migrate
```

### 3. Prepare your Models

[](#3-prepare-your-models)

#### User Model

[](#user-model)

Add the `HasRoles` trait to your `User` model:

```
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Pkc\RolePermission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // Your existing code...
}
```

Make sure your `users` table has a `role_id` foreign key column.

#### Role Model (Optional)

[](#role-model-optional)

If you want to extend or customize the `Role` model:

```
namespace App\Models;

use Pkc\RolePermission\Models\Role as BaseRole;

class Role extends BaseRole
{
    // Your custom logic here
}
```

💡 Complete Example Flow
-----------------------

[](#-complete-example-flow)

Here's a complete step-by-step example of setting up and using the package in a blog application:

### Step 1: Setup and Migration

[](#step-1-setup-and-migration)

```
# Install the package
composer require pkc/role-permission

# Run migrations
php artisan migrate
```

### Step 2: Configure User Model

[](#step-2-configure-user-model)

```
// app/Models/User.php
namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Pkc\RolePermission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;

    // Your existing code...
}
```

### Step 3: Create Roles

[](#step-3-create-roles)

```
use Pkc\RolePermission\Models\Role;

// Create roles
$admin = Role::create([
    'name' => 'Administrator',
    'slug' => 'admin',
    'description' => 'Full system access',
    'status' => true,
]);

$editor = Role::create([
    'name' => 'Editor',
    'slug' => 'editor',
    'description' => 'Can create and edit posts',
    'status' => true,
]);

$author = Role::create([
    'name' => 'Author',
    'slug' => 'author',
    'description' => 'Can create posts',
    'status' => true,
]);
```

### Step 4: Create Permissions (Hierarchical Structure)

[](#step-4-create-permissions-hierarchical-structure)

```
use Pkc\RolePermission\Models\Permission;

// Create Posts Module (parent permission)
$postsModule = Permission::create([
    'name' => 'Posts',
    'slug' => 'posts',
    'type' => 'module',
    'route_name' => 'posts.index',
    'order' => 1,
    'status' => true,
]);

// Create action permissions (children)
$viewPosts = Permission::create([
    'name' => 'View Posts',
    'slug' => 'posts.view',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.show',
    'order' => 1,
    'status' => true,
]);

$createPosts = Permission::create([
    'name' => 'Create Posts',
    'slug' => 'posts.create',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.create',
    'order' => 2,
    'status' => true,
]);

$editPosts = Permission::create([
    'name' => 'Edit Posts',
    'slug' => 'posts.edit',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.edit',
    'order' => 3,
    'status' => true,
]);

$deletePosts = Permission::create([
    'name' => 'Delete Posts',
    'slug' => 'posts.delete',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.destroy',
    'order' => 4,
    'status' => true,
]);
```

### Step 5: Assign Permissions to Roles

[](#step-5-assign-permissions-to-roles)

```
// Admin gets all permissions
$admin->syncPermissions([
    $postsModule->id,
    $viewPosts->id,
    $createPosts->id,
    $editPosts->id,
    $deletePosts->id,
]);

// Editor can view, create, and edit (but not delete)
$editor->syncPermissions([
    $viewPosts->id,
    $createPosts->id,
    $editPosts->id,
]);

// Author can only view and create
$author->syncPermissions([
    $viewPosts->id,
    $createPosts->id,
]);
```

### Step 6: Assign Roles to Users

[](#step-6-assign-roles-to-users)

```
use App\Models\User;

// Assign admin role to a user
$user1 = User::find(1);
$user1->update(['role_id' => $admin->id]);

// Assign editor role
$user2 = User::find(2);
$user2->update(['role_id' => $editor->id]);

// Assign author role
$user3 = User::find(3);
$user3->update(['role_id' => $author->id]);
```

### Step 7: Use in Controller

[](#step-7-use-in-controller)

```
// app/Http/Controllers/PostController.php
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        // Check permission
        if (!auth()->user()->hasPermission('posts.view')) {
            abort(403, 'You do not have permission to view posts.');
        }

        $posts = Post::all();
        return view('posts.index', compact('posts'));
    }

    public function create()
    {
        if (!auth()->user()->hasPermission('posts.create')) {
            abort(403);
        }

        return view('posts.create');
    }

    public function store(Request $request)
    {
        if (!auth()->user()->canAccessRoute('posts.create')) {
            abort(403);
        }

        // Create post logic...
    }

    public function edit($id)
    {
        if (!auth()->user()->hasPermission('posts.edit')) {
            abort(403);
        }

        $post = Post::findOrFail($id);
        return view('posts.edit', compact('post'));
    }

    public function destroy($id)
    {
        if (!auth()->user()->hasPermission('posts.delete')) {
            abort(403);
        }

        // Delete post logic...
    }
}
```

### Step 8: Use in Blade Templates

[](#step-8-use-in-blade-templates)

```
{{-- resources/views/posts/index.blade.php --}}

{{-- Show posts menu if user has posts permission --}}
@if(auth()->user()->hasPermission('posts'))
    Posts
@endif

{{-- Show create button if user has create permission --}}
@if(auth()->user()->hasPermission('posts.create'))
    Create Post
@endif

    @foreach($posts as $post)

            {{ $post->title }}

                {{-- Show edit button if user has edit permission --}}
                @if(auth()->user()->hasPermission('posts.edit'))
                    Edit
                @endif

                {{-- Show delete button if user has delete permission --}}
                @if(auth()->user()->hasPermission('posts.delete'))

                        @csrf
                        @method('DELETE')
                        Delete

                @endif

    @endforeach

```

### Step 9: Testing the Flow

[](#step-9-testing-the-flow)

```
// Example: Testing permissions
$user = User::find(2); // Editor user

// These will return true
$user->hasPermission('posts.view');     // true
$user->hasPermission('posts.create');   // true
$user->hasPermission('posts.edit');     // true
$user->hasPermission('posts');          // true (parent module)

// This will return false
$user->hasPermission('posts.delete');   // false

// Check role
$user->hasRole('editor');               // true
$user->hasAnyRole(['admin', 'editor']); // true

// Check multiple permissions
$user->hasAnyPermission(['posts.edit', 'posts.delete']); // true (has edit)
$user->hasAllPermissions(['posts.edit', 'posts.delete']); // false (missing delete)
```

### Step 10: Dynamic Permission Management (Optional)

[](#step-10-dynamic-permission-management-optional)

You can also manage permissions dynamically through your admin panel:

```
// In your admin controller
public function updateRolePermissions(Request $request, Role $role)
{
    $permissionIds = $request->input('permissions', []);

    // Validate permission IDs exist
    $validIds = Permission::whereIn('id', $permissionIds)->pluck('id')->toArray();

    // Sync permissions
    $role->syncPermissions($validIds);

    // Clear cache
    $role->clearPermissionCache();

    return redirect()->back()->with('success', 'Permissions updated successfully');
}
```

This complete flow demonstrates:

- ✅ Setting up the package
- ✅ Creating roles and permissions
- ✅ Building hierarchical permission structure
- ✅ Assigning permissions to roles
- ✅ Assigning roles to users
- ✅ Using permissions in controllers
- ✅ Using permissions in Blade templates
- ✅ Testing and verification

💡 Usage Examples
----------------

[](#-usage-examples)

### Creating Roles

[](#creating-roles)

```
use Pkc\RolePermission\Models\Role;

// Create a new role
$adminRole = Role::create([
    'name' => 'Administrator',
    'slug' => 'admin',
    'description' => 'Full system access',
    'status' => true,
]);

$editorRole = Role::create([
    'name' => 'Editor',
    'slug' => 'editor',
    'description' => 'Can edit content',
    'status' => true,
]);
```

### Creating Permissions

[](#creating-permissions)

```
use Pkc\RolePermission\Models\Permission;

// Create a parent permission (module)
$postsModule = Permission::create([
    'name' => 'Posts Management',
    'slug' => 'posts',
    'type' => 'module',
    'route_name' => 'posts.index',
    'order' => 1,
    'status' => true,
]);

// Create child permissions (actions)
$viewPosts = Permission::create([
    'name' => 'View Posts',
    'slug' => 'posts.view',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.show',
    'order' => 1,
    'status' => true,
]);

$editPosts = Permission::create([
    'name' => 'Edit Posts',
    'slug' => 'posts.edit',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.edit',
    'order' => 2,
    'status' => true,
]);

$deletePosts = Permission::create([
    'name' => 'Delete Posts',
    'slug' => 'posts.delete',
    'type' => 'action',
    'parent_id' => $postsModule->id,
    'route_name' => 'posts.destroy',
    'order' => 3,
    'status' => true,
]);
```

### Assigning Roles to Users

[](#assigning-roles-to-users)

```
$user = User::find(1);
$user->role_id = $adminRole->id;
$user->save();

// Or using update
$user->update(['role_id' => $editorRole->id]);
```

### Assigning Permissions to Roles

[](#assigning-permissions-to-roles)

```
$editorRole = Role::find(2);

// Sync permissions (replaces all existing permissions)
$editorRole->permissions()->sync([$viewPosts->id, $editPosts->id]);

// Or use the helper method
$editorRole->syncPermissions([$viewPosts->id, $editPosts->id]);
```

### Checking Permissions in Code

[](#checking-permissions-in-code)

```
// Check if user has a specific permission
if ($user->hasPermission('posts.edit')) {
    // User can edit posts
}

// Check if user can access a route
if ($user->canAccessRoute('posts.edit')) {
    // User can access this route
}

// Check if user has any of the given permissions
if ($user->hasAnyPermission(['posts.edit', 'posts.view'])) {
    // User has at least one permission
}

// Check if user has all of the given permissions
if ($user->hasAllPermissions(['posts.edit', 'posts.delete'])) {
    // User has all permissions
}

// Check if user has a specific role
if ($user->hasRole('admin')) {
    // User is an admin
}

// Check if user has any of the given roles
if ($user->hasAnyRole(['admin', 'editor'])) {
    // User has at least one role
}
```

### Using in Blade Templates

[](#using-in-blade-templates)

```
{{-- Check permission --}}
@if(auth()->user()->hasPermission('posts.edit'))
    Edit
@endif

{{-- Check route access --}}
@if(auth()->user()->canAccessRoute('posts.index'))
    All Posts
@endif

{{-- Check multiple permissions --}}
@if(auth()->user()->hasAnyPermission(['posts.edit', 'posts.delete']))

        Edit
        Delete

@endif

{{-- Show sidebar menu based on permission --}}
@if(auth()->user()->hasPermission('posts'))
    Posts
@endif
```

### Using in Controllers

[](#using-in-controllers)

```
namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;

class PostController extends Controller
{
    public function index()
    {
        // Check permission
        if (!auth()->user()->hasPermission('posts.view')) {
            abort(403, 'You do not have permission to view posts.');
        }

        // Your code...
    }

    public function edit($id)
    {
        if (!auth()->user()->canAccessRoute('posts.edit')) {
            abort(403);
        }

        // Your code...
    }
}
```

### Using in Middleware

[](#using-in-middleware)

```
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

class CheckPermission
{
    public function handle(Request $request, Closure $next, $permission)
    {
        if (!auth()->user()->hasPermission($permission)) {
            abort(403, 'Access denied');
        }

        return $next($request);
    }
}
```

Register in `bootstrap/app.php`:

```
$middleware->alias([
    'permission' => \App\Http\Middleware\CheckPermission::class,
]);
```

Use in routes:

```
Route::get('/posts', [PostController::class, 'index'])->middleware('permission:posts.view');
```

### Hierarchical Permissions

[](#hierarchical-permissions)

The package supports hierarchical permissions. If a permission is a "module" type and has children, checking the parent permission will return `true` if any of its children are assigned to the role.

```
// If 'posts' is a module and 'posts.edit' is assigned to the role
$user->hasPermission('posts'); // returns true (because descendant 'posts.edit' is assigned)
$user->hasPermission('posts.edit'); // returns true (directly assigned)

// This is useful for sidebar visibility
// If user has access to any action within a module, the module appears in the sidebar
```

### Querying Roles and Permissions

[](#querying-roles-and-permissions)

```
use Pkc\RolePermission\Models\Role;
use Pkc\RolePermission\Models\Permission;

// Get only active roles (excludes master-admin by default)
$roles = Role::visible()->active()->get();

// Get root permissions (no parent)
$rootPermissions = Permission::root()->get();

// Get only active permissions
$activePermissions = Permission::active()->get();

// Get permissions with their children
$permissions = Permission::root()->with('children')->get();
```

### Cache Management

[](#cache-management)

Permission checks are cached by default for better performance. To clear cache:

```
// Clear cache for a specific role
$role->clearPermissionCache();

// Or clear all cache
php artisan cache:clear
```

You can configure caching in `config/role-permission.php`:

```
'cache_enabled' => true,
'cache_ttl' => 3600, // Cache for 1 hour
```

🔒 Security Features
-------------------

[](#-security-features)

- **Validation**: Permission assignments are validated before saving
- **Circular Reference Prevention**: Automatic detection and prevention of circular permission hierarchies
- **Error Handling**: Proper exceptions for better error handling

📝 Configuration
---------------

[](#-configuration)

You can customize the package behavior by publishing the config file:

```
php artisan vendor:publish --tag=role-permission-config
```

Available configuration options:

- `user_model`: Your User model class
- `master_admin_slug`: Slug for master admin role (default: 'master-admin')
- `cache_enabled`: Enable/disable caching (default: true)
- `cache_ttl`: Cache time-to-live in seconds (default: 3600)
- `table_names`: Custom table names (optional)

🐛 Error Handling
----------------

[](#-error-handling)

The package provides specific exceptions:

```
use Pkc\RolePermission\Exceptions\CircularReferenceException;
use Pkc\RolePermission\Exceptions\InvalidPermissionAssignmentException;
use Pkc\RolePermission\Exceptions\PermissionNotFoundException;

try {
    $role->syncPermissions([1, 2, 3]);
} catch (InvalidPermissionAssignmentException $e) {
    // Handle invalid permission IDs
}
```

📚 API Reference
---------------

[](#-api-reference)

### User Model Methods (HasRoles trait)

[](#user-model-methods-hasroles-trait)

- `hasPermission(string $slug): bool` - Check if user has a permission
- `canAccessRoute(string $routeName): bool` - Check if user can access a route
- `hasAnyPermission(array $slugs): bool` - Check if user has any of the given permissions
- `hasAllPermissions(array $slugs): bool` - Check if user has all of the given permissions
- `hasRole(string $slug): bool` - Check if user has a specific role
- `hasAnyRole(array $slugs): bool` - Check if user has any of the given roles
- `role(): BelongsTo` - Get the user's role relationship

### Role Model Methods

[](#role-model-methods)

- `hasPermission(string $slug): bool` - Check if role has a permission
- `permissions(): BelongsToMany` - Get permissions relationship
- `syncPermissions(array $permissionIds, bool $recursive = false): void` - Sync permissions
- `clearPermissionCache(): void` - Clear permission cache for this role
- `isMasterAdmin(): bool` - Check if role is master admin
- `scopeVisible($query)` - Exclude master admin from queries
- `scopeActive($query)` - Get only active roles

### Permission Model Methods

[](#permission-model-methods)

- `parent(): BelongsTo` - Get parent permission
- `children(): HasMany` - Get child permissions
- `getAllDescendantIds(): array` - Get all descendant permission IDs
- `getAncestors(): Collection` - Get all ancestor permissions
- `toTreeArray(): array` - Get permission as tree structure
- `scopeRoot($query)` - Get only root permissions
- `scopeActive($query)` - Get only active permissions

🤝 Contributing
--------------

[](#-contributing)

Contributions are welcome! Please feel free to submit a Pull Request.

📄 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE) for more information.

👤 Author
--------

[](#-author)

**PKC**

- Email:

📊 Hierarchical Permission Structure Example
-------------------------------------------

[](#-hierarchical-permission-structure-example)

Here's an example of a real-world hierarchical permission structure:

```
FMDF
├── Stock Management
│   ├── Lot Entry
│   │   ├── Add
│   │   ├── Edit
│   │   ├── Delete
│   │   └── View
├── Order Management
    ├── Add
    ├── Edit
    ├── Delete
    └── View

```

**Flow Example:**

```
FMDF -> Stock Management -> Tree Stock -> Add

FMDF -> Order Management -> Add

```

This means:

- **FMDF** is the root module
- **Stock Management** is a child module of FMDF
- **Tree Stock** is a child module of Stock Management
- **Add** is an action permission under Tree Stock

When a user has the "Tree Stock -&gt; Add" permission, they automatically get access to:

- Tree Stock (parent module)
- Stock Management (grandparent module)
- FMDF (root module)

This hierarchical structure allows for:

- ✅ Flexible permission management
- ✅ Easy sidebar menu visibility control
- ✅ Granular access control at each level
- ✅ Automatic parent permission inheritance

🔗 Links
-------

[](#-links)

- [GitHub Repository](https://github.com/laradevsumon/role-permission)
- [Packagist](https://packagist.org/packages/pkc/role-permission)

###  Health Score

37

—

LowBetter than 82% of packages

Maintenance83

Actively maintained with recent releases

Popularity4

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity48

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

117d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/c94a67e75385ed3f69d5c9dcf6f3814915af9184cda0cfd491e5d23aaeed3775?d=identicon)[pkc](/maintainers/pkc)

---

Top Contributors

[![laradevsumon](https://avatars.githubusercontent.com/u/174681081?v=4)](https://github.com/laradevsumon "laradevsumon (4 commits)")

---

Tags

laravelauthorizationaclrolespermissions

### Embed Badge

![Health badge](/badges/pkc-role-permission/health.svg)

```
[![Health](https://phpackages.com/badges/pkc-role-permission/health.svg)](https://phpackages.com/packages/pkc-role-permission)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k89.8M1.0k](/packages/spatie-laravel-permission)[hasinhayder/tyro

Tyro - The ultimate Authentication, Authorization, and Role &amp; Privilege Management solution for Laravel 12 &amp; 13

6712.1k2](/packages/hasinhayder-tyro)[directorytree/authorization

Native Laravel Authorization.

1809.5k](/packages/directorytree-authorization)[shanmuga/laravel-entrust

This package provides a flexible solution to add ACL to Laravel

68312.9k2](/packages/shanmuga-laravel-entrust)[beatswitch/lock-laravel

A Laravel Driver for Lock.

15529.1k1](/packages/beatswitch-lock-laravel)[larapacks/authorization

Native Laravel Authorization.

5410.7k2](/packages/larapacks-authorization)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
