PHP code example of scabarcas / laravel-permissions-redis
1. Go to this page and download the library: Download scabarcas/laravel-permissions-redis library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
scabarcas / laravel-permissions-redis example snippets
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Scabarcas\LaravelPermissionsRedis\Traits\HasRedisPermissions;
class User extends Authenticatable
{
use HasRedisPermissions;
}
use Scabarcas\LaravelPermissionsRedis\Models\Permission;
use Scabarcas\LaravelPermissionsRedis\Models\Role;
// Create permissions
$createPosts = Permission::findOrCreate('posts.create');
$editPosts = Permission::findOrCreate('posts.edit');
$deletePosts = Permission::findOrCreate('posts.delete');
// Create with group
$manageUsers = Permission::findOrCreate('users.manage', 'web', 'user-management');
// Create roles
$admin = Role::findOrCreate('admin');
$editor = Role::findOrCreate('editor');
// Assign permissions to a role
$editor->syncPermissions(['posts.create', 'posts.edit']);
// Or add permissions individually
$editor->givePermissionTo('posts.create', 'posts.edit');
// Remove permissions
$editor->revokePermissionTo('posts.delete');
// Check whether a role grants a specific permission (reads Redis)
$editor->hasPermission('posts.create'); // bool
$editor->hasPermission('reports.export', 'api'); // optional guard
$user = User::find(1);
// Assign roles (additive, does not remove existing roles)
$user->assignRole('admin');
$user->assignRole('editor', 'moderator');
// Replace all roles
$user->syncRoles('editor');
// Remove a role
$user->removeRole('moderator');
// Give direct permissions (in addition to role-inherited permissions)
$user->givePermissionTo('reports.export', 'reports.view');
// Revoke direct permissions
$user->revokePermissionTo('reports.export');
// Replace all direct permissions
$user->syncPermissions(['reports.view']);
// Single permission check
$user->hasPermissionTo('posts.edit'); // bool
// Any of multiple permissions
$user->hasAnyPermission('posts.edit', 'posts.delete'); // bool
// All permissions / bool
// All roles adata (e.g., "user-management", "billing")
$user->getAllPermissions()->groupBy('group');
// Get permission names only
$user->getPermissionNames(); // Collection<string>
// Get role names
$user->getRoleNames(); // Collection<string>
// Find users with a specific role (SQL query)
User::role('admin')->get();
// Find users with a specific permission (SQL query)
User::permission('posts.edit')->get();
// Single permission
Route::get('/posts/create', [PostController::class, 'create'])
->middleware('permission:posts.create');
// OR (user needs ANY of these)
Route::get('/posts', [PostController::class, 'index'])
->middleware('permission:posts.view|posts.manage');
// AND (user needs ALL of these)
Route::put('/posts/{id}/publish', [PostController::class, 'publish'])
->middleware('permission:posts.edit&posts.publish');
// Single role
Route::get('/admin', [AdminController::class, 'index'])
->middleware('role:admin');
// OR (user needs ANY role)
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('role:admin|editor');
// AND (user needs ALL roles)
Route::get('/super', [SuperController::class, 'index'])
->middleware('role:admin&super_admin');
// In controllers
$this->authorize('posts.edit');
// In policies
Gate::allows('posts.edit');
// In Blade
@can('posts.edit')
<button>Edit</button>
@endcan
$admin = Role::findOrCreate('admin');
$wildcard = Permission::findOrCreate('users.*');
$admin->permissions()->sync([$wildcard->id]);
$user->assignRole('admin');
// All these return true:
$user->hasPermissionTo('users.create'); // matched by users.*
$user->hasPermissionTo('users.edit'); // matched by users.*
$user->hasPermissionTo('users.delete'); // matched by users.*
// This returns false:
$user->hasPermissionTo('posts.create'); // no match
Role::findOrCreate('super_admin');
$user->assignRole('super_admin');
// All permission checks return true, no actual lookup needed
$user->hasPermissionTo('anything.at.all'); // true
use Scabarcas\LaravelPermissionsRedis\Cache\AuthorizationCacheManager;
$manager = app(AuthorizationCacheManager::class);
$manager->warmAll(); // Full cache rebuild (flush + warm)
$manager->rewarmAll(); // Rewarm without flushing
$manager->warmUser($userId); // Warm specific user
$manager->warmRole($roleId); // Warm specific role
$manager->evictUser($userId); // Remove user from cache
$manager->evictRole($roleId); // Remove role from cache
// Targeted warming after permission changes
$manager->warmPermissionAffectedUsers($permissionId);
use Scabarcas\LaravelPermissionsRedis\Traits\DispatchesPermissionEvents;
class User extends Authenticatable
{
use HasRedisPermissions, DispatchesPermissionEvents;
}
// config/permissions-redis.php
'seed' => [
'roles' => [
'admin' => ['users.*', 'posts.*', 'settings.update'],
'editor' => ['posts.create', 'posts.edit', 'posts.delete'],
'viewer' => ['posts.view', 'reports.view'],
],
'permissions' => [
'reports.export', // standalone permissions not tied to any role
],
],
// In a controller, checks Redis first, then PostPolicy::update()
$this->authorize('posts.edit', $post);
// In Blade, same behavior
@can('posts.edit', $post)
<button>Edit</button>
@endcan
class PostPolicy
{
// Only called if user does NOT have 'posts.edit' in Redis
public function update(User $user, Post $post): bool
{
return $post->user_id === $user->id; // fallback: owners can edit
}
}
$user->assignRole('admin', 'editor'); // additive
$user->syncRoles('editor'); // replaces all, user now has only 'editor'
$user->removeRole('editor'); // removes 'editor'
$user->givePermissionTo('reports.export'); // direct permission
$user->revokePermissionTo('reports.export'); // revoke
$user->syncPermissions('reports.view'); // replace all direct permissions
$user->syncPermissions(['reports.view']); // array form works too
User::role('admin')->get(); // all admins
User::role(['admin', 'editor'])->get(); // users with admin OR editor
User::permission('posts.edit')->get(); // users who can edit posts (direct or via role)
$role = Role::findOrCreate('editor');
$role->syncPermissions('posts.create', 'posts.edit'); // replace (array form works too)
$role->givePermissionTo('posts.publish'); // additive
$role->revokePermissionTo('posts.publish'); // remove
$manager = app(AuthorizationCacheManager::class);
$manager->warmAll(); // full rebuild
$manager->warmUser($user->id); // single user
$manager->evictUser($user->id); // remove from cache
$manager->warmPermissionAffectedUsers($perm->id); // rewarm after manual DB change
try {
// middleware check
} catch (UnauthorizedException $e) {
$e->getStatusCode(); // 403
$e->getMessage(); // 'User does not have the
// Listen to events in your app
use Scabarcas\LaravelPermissionsRedis\Events\RolesAssigned;
Event::listen(RolesAssigned::class, function (RolesAssigned $event) {
Log::info("Roles changed for user {$event->user->id}");
});
// Manually dispatch UserDeleted when deleting users
use Scabarcas\LaravelPermissionsRedis\Events\UserDeleted;
User::deleted(function (User $user) {
event(new UserDeleted($user->id));
});
use Scabarcas\LaravelPermissionsRedis\Testing\WithPermissions;
class PostControllerTest extends TestCase
{
use WithPermissions;
public function test_admin_can_create_posts(): void
{
$user = User::factory()->create();
// Seeds permissions + assigns them + acts as the user
$this->actingAsWithPermissions($user, ['posts.create', 'posts.edit'])
->post('/posts', ['title' => 'Hello'])
->assertStatus(201);
}
public function test_editor_role_can_edit(): void
{
$user = User::factory()->create();
// Seeds role + assigns it + acts as the user
$this->actingAsWithRoles($user, ['editor'])
->put('/posts/1', ['title' => 'Updated'])
->assertOk();
}
}
use Scabarcas\LaravelPermissionsRedis\Testing\WithPermissions;
uses(WithPermissions::class);
it('allows admins to manage users', function () {
$user = User::factory()->create();
$this->actingAsWithRoles($user, ['admin'])
->get('/admin/users')
->assertOk();
});
use Scabarcas\LaravelPermissionsRedis\Contracts\PermissionRepositoryInterface;
use Scabarcas\LaravelPermissionsRedis\Testing\InMemoryPermissionRepository;
// In your TestCase::setUp()
$this->app->singleton(
PermissionRepositoryInterface::class,
InMemoryPermissionRepository::class,
);
// This will NOT invalidate cache:
Model::withoutEvents(fn () => $user->roles()->attach($roleId));
// This WILL invalidate cache (use the trait method):
$user->assignRole('admin');
// Created with 'web' guard (default)
Permission::findOrCreate('posts.edit');
// Checking from 'api' guard, won't find it!
$user->hasPermissionTo('posts.edit', 'api'); // false
// Fix: create the permission for the correct guard
Permission::findOrCreate('posts.edit', 'api');
// Or use forGuard() to check explicitly
$user->forGuard('web')->hasPermissionTo('posts.edit'); // true
$role = Role::findOrCreate('editor');
$role->syncPermissions(['posts.create']); // 'posts.edit' is not here
$user->assignRole('editor');
$user->hasPermissionTo('posts.edit'); // false, not in role
mermaid
flowchart TD
A["hasPermissionTo('posts.edit')"] --> B{In-memory\ncache?}
B -- "Hit" --> C["Return cached result"]
B -- "Miss" --> D{"Redis\nSISMEMBER?"}
D -- "Hit" --> E["Cache in memory\nand return"]
D -- "Miss" --> F{"User cache\nexists in Redis?"}
F -- "Yes" --> K{"Wildcard\nenabled?"}
F -- "No (cold start)" --> H["AuthorizationCacheManager\n::warmUser()"]
H --> I["Query DB:\ndirect perms + role perms"]
I --> J["Write merged SETs\nto Redis"]
J --> D
K -- "No" --> L["Permission denied"]
K -- "Yes" --> M["fnmatch() scan\nall user perms"]
M -- "Match" --> N["Return true"]
M -- "No match" --> L