islamrumon/laravel-acl
Laravel ACL provides database-backed roles, groups, and permissions for Laravel 5.8+. Note: unmaintained since Jan 2024; consider spatie/laravel-permission instead.
Installation:
composer require mateusjunges/laravel-acl
Publish the migration and config:
php artisan vendor:publish --provider="MateusJunges\LaravelAcl\LaravelAclServiceProvider"
php artisan migrate
Define Roles/Groups:
Use the Role and Group models to create roles/groups via Tinker or migrations:
use MateusJunges\LaravelAcl\Models\Role;
use MateusJunges\LaravelAcl\Models\Group;
Role::create(['name' => 'Admin']);
Group::create(['name' => 'Editors']);
Assign Permissions: Attach permissions to roles/groups:
$role = Role::find(1);
$role->attachPermission('create-post'); // Define 'create-post' in config/acl.php
First Use Case: Check if a user (or model) has permission:
if (auth()->user()->can('create-post')) {
// Allow action
}
Role-Based Access Control (RBAC):
$user->attachRole($role);
if ($user->can('edit-post')) { ... }
Group-Based Permissions:
$user->attachGroup($group);
Dynamic Permission Checks:
can() with optional subject (e.g., model):
$post->author->can('delete', $post); // Custom logic via `can()` method
Middleware Integration:
Route::get('/admin', function () {
// ...
})->middleware('can:manage-admin');
Policy Integration:
use MateusJunges\LaravelAcl\Traits\HasPermissions;
class PostPolicy extends Policy {
use HasPermissions;
// Custom logic
}
Seeding Permissions: Use database seeds to predefine roles/groups/permissions:
public function run()
{
$adminRole = Role::create(['name' => 'Admin']);
$adminRole->attachPermissions(['create-post', 'delete-post']);
}
API Gate Integration:
Leverage Laravel’s Gate for fine-grained control:
Gate::define('edit-post', function ($user, $post) {
return $user->can('edit-post') && $post->user_id === $user->id;
});
Caching:
Enable caching in config/acl.php for performance:
'cache' => [
'enabled' => true,
'driver' => 'file',
],
Permission Caching:
php artisan cache:clear
\MateusJunges\LaravelAcl\Cache::clear();
Model Binding:
HasPermissions trait:
use MateusJunges\LaravelAcl\Traits\HasPermissions;
class User extends Authenticatable {
use HasPermissions;
}
Permission Names:
config/acl.php under permissions:
'permissions' => [
'create-post' => 'Create Post',
'delete-post' => 'Delete Post',
],
Middleware Conflicts:
can middleware, ensure the permission key matches exactly (e.g., can:create-post).Mass Assignment:
attachRole, attachPermission).Check Permissions: Log permissions for debugging:
dd(auth()->user()->permissions->pluck('name'));
SQL Queries: Enable Laravel’s query logging:
\DB::enableQueryLog();
auth()->user()->can('create-post'); // Check last query
dd(\DB::getQueryLog());
Cache Issues:
Verify cache driver in config/acl.php and clear it if permissions aren’t updating.
Custom Permission Logic:
Override the can() method in your model:
public function can($permission, $subject = null)
{
if ($permission === 'custom-permission') {
return $this->isAdmin();
}
return parent::can($permission, $subject);
}
Event Listeners: Listen for permission changes:
\MateusJunges\LaravelAcl\Events\PermissionAttached::class => [
\App\Listeners\LogPermissionChange::class,
],
Custom Storage:
Extend the Permission model to use a custom storage backend (e.g., Redis).
Localization:
Localize permission names by overriding the getDisplayName() method in the Permission model.
Testing:
Use actingAs() with permissions in tests:
$user = User::factory()->create();
$user->attachRole($adminRole);
$this->actingAs($user)->get('/admin')->assertOk();
How can I help you explore Laravel packages today?