Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Permission Manager Laravel Package

hosseinhezami/laravel-permission-manager

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation: Run the one-liner to install, migrate, and configure:

    php artisan permission-manager:install --migrate
    

    This auto-publishes config, migrations, and adds the PermissionTrait to your User model.

  2. First Permission: Create a wildcard permission for all admin routes:

    php artisan permission:create "admin.*"
    
  3. First Role: Create an admin role and assign the permission:

    php artisan role:create admin "Administrator" "Full system access"
    php artisan role:assign-permission admin "admin.*"
    
  4. Assign to User: Attach the role to a user (replace 1 with a user ID):

    php artisan user:assign-role 1 admin
    
  5. Protect a Route: Add middleware to a route in routes/web.php:

    Route::get('/admin/dashboard', [AdminController::class, 'dashboard'])
        ->middleware('pm:role:admin');
    
  6. Check in Blade: Use directives in your views:

    @hasRole('admin')
        <a href="/admin/dashboard">Admin Dashboard</a>
    @endhasRole
    

Where to Look First

  • Artisan Commands: The CLI is the primary interface for setup. Run php artisan to see all available commands.
  • Middleware: Check app/Http/Kernel.php for the pm middleware group.
  • User Model: Verify the PermissionTrait is added to your User model.
  • Config: Review config/permission-manager.php for cache duration and wildcard settings.

Implementation Patterns

Core Workflows

1. Role-Permission Assignment Workflow

  • Create Roles: Use php artisan role:create for initial setup.
  • Bulk Assign Permissions: Sync permissions to roles via:
    php artisan role:assign-permission admin "users.*,posts.*"
    
  • User Assignment: Attach roles to users in bulk:
    $user->assignRole(['admin', 'editor']);
    

2. Route Protection Pattern

  • Middleware: Use pm:role: or pm:permission: for route-level checks:
    Route::group(['middleware' => ['auth', 'pm:role:admin|manager']], function () {
        // Admin-only routes
    });
    
  • Wildcard Permissions: Define broad permissions (e.g., admin.*) and assign them to roles to avoid per-route middleware clutter.

3. Blade Integration

  • Conditional UI: Hide/show elements based on roles/permissions:
    @hasPermission('posts.create')
        <button class="btn btn-primary">Create Post</button>
    @endhasPermission
    
  • Dynamic Navigation: Build adaptive menus:
    @foreach(PermissionManager::permissions()->list() as $permission)
        @hasPermission($permission->route)
            <li><a href="{{ route($permission->route) }}">{{ $permission->route }}</a></li>
        @endhasPermission
    @endforeach
    

4. Permission Sync

  • Route-Based Permissions: Sync Laravel routes to permissions:
    php artisan permission:sync-routes
    
  • Automate Sync: Add a console command to your app/Console/Kernel.php:
    protected function commands()
    {
        $this->call('permission:sync-routes');
    }
    

5. User Management

  • Trait Methods: Leverage the PermissionTrait for user-specific checks:
    if ($user->hasPermission('users.edit')) {
        // Grant edit access
    }
    
  • Facade Methods: Use PermissionManager for programmatic control:
    $permissions = PermissionManager::user($userId)->permissions();
    

Integration Tips

  • Multi-Guard Support: Works with Laravel’s guards (e.g., api guard). Specify the guard in middleware:
    Route::middleware(['auth:api', 'pm:permission:api.orders.*'])->group(...);
    
  • Caching: Enable caching in config/permission-manager.php (cache_duration) for production. Clear cache after permission changes:
    php artisan cache:clear
    
  • Testing: Use the PermissionManager facade in tests:
    public function test_admin_can_access_dashboard()
    {
        $user = User::factory()->create();
        $user->assignRole('admin');
    
        $this->actingAs($user)
             ->get('/admin/dashboard')
             ->assertOk();
    }
    
  • Export/Import: Backup permissions for staging/production:
    php artisan role:export roles_backup.json
    php artisan permission:export permissions_backup.json
    

Gotchas and Tips

Pitfalls

  1. Wildcard Overuse:

    • Issue: Wildcards like *.* can lead to unintended permission overlaps.
    • Fix: Use specific wildcards (e.g., admin.* instead of *.*) and test thoroughly.
  2. Permission Sync Conflicts:

    • Issue: Running permission:sync-routes may overwrite existing permissions.
    • Fix: Backup permissions first or use --dry-run (if available) to preview changes.
  3. Cache Invalidation:

    • Issue: Forgetting to clear the cache after permission changes causes stale checks.
    • Fix: Automate cache clearing post-updates or use PermissionManager::clearCache().
  4. Middleware Misconfiguration:

    • Issue: Incorrect middleware syntax (e.g., pm:role instead of pm:role:admin).
    • Fix: Always specify the role/permission in the middleware:
      ->middleware('pm:role:admin|editor')
      
  5. Trait Conflicts:

    • Issue: Adding PermissionTrait to a model that already extends another trait with conflicting methods.
    • Fix: Check for method conflicts (e.g., roles()) and resolve via trait composition or aliasing.

Debugging

  • Permission Checks:

    • Log permission checks for debugging:
      if (PermissionManager::user($userId)->hasPermission('users.edit')) {
          logger()->debug('User has permission: users.edit');
      }
      
    • Enable log_denials in config to log failed checks.
  • Artisan Errors:

    • Use --verbose for detailed command output:
      php artisan role:create admin --verbose
      
    • Check for PermissionDoesNotExist or RoleDoesNotExist exceptions when assigning permissions/roles.
  • Route Sync Issues:

    • Verify route names match permission routes exactly (case-sensitive). Use:
      php artisan route:list
      
    • Ensure permission:sync-routes is run after adding new routes.

Extension Points

  1. Custom Models:

    • Extend the default models (e.g., Role, Permission) by publishing and modifying the migrations:
      php artisan vendor:publish --provider="HosseinHezami\PermissionManager\PermissionManagerServiceProvider" --tag="migrations"
      
  2. Additional Fields:

    • Add columns to the roles or permissions table (e.g., is_active):
      Schema::table('roles', function (Blueprint $table) {
          $table->boolean('is_active')->default(true);
      });
      
    • Update the PermissionManager facade to support the new field:
      PermissionManager::roles()->where('is_active', true)->list();
      
  3. Custom Guards:

    • Extend the PermissionGuard class to support custom logic (e.g., tenant-aware permissions):
      use HosseinHezami\PermissionManager\Contracts\Guard;
      
      class TenantGuard implements Guard
      {
          public function checkPermission($user, $permission)
          {
              // Add tenant logic here
              return $user->tenant->hasPermission($permission);
          }
      }
      
  4. Event Listeners:

    • Listen for permission changes to trigger side effects (e.g., notifications):
      PermissionManager::roles()->created(function ($role) {
          event(new RoleCreated($role));
      });
      
  5. Blade Extensions:

    • Create custom Blade directives for complex checks:
      Blade::directive('hasAnyPermission', function ($permissions) {
          return "<?php if (auth()->check() && auth()->user()->hasAnyPermission({$permissions})): ?>";
      });
      
      Usage:
      @hasAnyPermission(['users.edit', 'posts.delete'])
          <!-- Content -->
      @endhasAnyPermission
      

Configuration Quirks

  • Wildcard Performance:
    • Wildcards improve flexibility but may slow down permission checks if overused. Monitor query performance in user_roles and `role
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor