### Install Spatie Laravel Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/new-app Installs the spatie/laravel-permission package via Composer, publishes its assets, and runs database migrations. ```bash composer require spatie/laravel-permission php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" git add . git commit -m "Add Spatie Laravel Permissions package" php artisan migrate:fresh ``` -------------------------------- ### Create New Laravel Project Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/new-app Use the Laravel installer to create a new project for your permission demo. Navigate to your desired directory and run the command. ```bash cd ~/Sites laravel new mypermissionsdemo ``` -------------------------------- ### Example PostPolicy for Access Control Source: https://spatie.be/docs/laravel-permission/v7/best-practices/using-policies This example demonstrates a basic PostPolicy that integrates permission checks with application logic. It shows how to define authorization methods like 'view' and 'create' that can be used to gate access to Post model resources. ```php hasPermissionTo('view posts'); } /** * Determine whether the user can view the model. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return \Illuminate\Auth\Access\Response|bool */ public function view(User $user, Post $post) { return $user->hasPermissionTo('view posts'); } /** * Determine whether the user can create models. * * @param \App\Models\User $user * @return \Illuminate\Auth\Access\Response|bool */ public function create(User $user) { return $user->hasPermissionTo('create posts'); } /** * Determine whether the user can update the model. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return \Illuminate\Auth\Access\Response|bool */ public function update(User $user, Post $post) { return $user->hasPermissionTo('edit posts'); } /** * Determine whether the user can delete the model. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return \Illuminate\Auth\Access\Response|bool */ public function delete(User $user, Post $post) { return $user->hasPermissionTo('delete posts'); } /** * Determine whether the user can restore the model. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return \Illuminate\Auth\Access\Response|bool */ public function restore(User $user, Post $post) { // } /** * Determine whether the user can permanently delete the model. * * @param \App\Models\User $user * @param \App\Models\Post $post * @return \Illuminate\Auth\Access\Response|bool */ public function forceDelete(User $user, Post $post) { // } } ``` -------------------------------- ### Install Laravel UI Bootstrap with Auth Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/new-app Installs the laravel/ui package and scaffolds basic Bootstrap-based authentication. This provides login and registration functionality for testing. ```bash composer require laravel/ui --dev php artisan ui bootstrap --auth # npm install && npm run build git add . && git commit -m "Setup auth scaffold" ``` -------------------------------- ### Initialize Git Repository Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/new-app Initializes a new Git repository and commits the fresh Laravel installation. This is optional if Git was initialized during the 'laravel new' command. ```bash cd mypermissionsdemo git init git add . git commit -m "Fresh Laravel Install" ``` -------------------------------- ### Install spatie/laravel-permission via Composer Source: https://spatie.be/docs/laravel-permission/v7/installation-laravel Use this command to add the package to your Laravel project dependencies. ```bash composer require spatie/laravel-permission ``` -------------------------------- ### Example Team Middleware Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions This middleware sets the global team ID for permissions based on a session variable. Ensure this middleware is registered correctly in your Kernel.php. ```php namespace App\Http\Middleware; class TeamsPermission { public function handle($request, \Closure $next){ if(!empty(auth()->user())){ // session value set on login setPermissionsTeamId(session('team_id')); } // other custom ways to get team_id /*if(!empty(auth('api')->user())){ // `getTeamIdFromToken()` example of custom method for getting the set team_id setPermissionsTeamId(auth('api')->user()->getTeamIdFromToken()); }*/ return $next($request); } } ``` -------------------------------- ### Get User Permissions and Roles Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Retrieve permissions and roles associated with a user. This includes direct permissions, permissions via roles, and role names. ```php // get a list of all permissions directly assigned to the user $permissionNames = $user->getPermissionNames(); // collection of name strings $permissions = $user->permissions; // collection of permission objects // get all permissions for the user, either directly, or from roles, or from both $permissions = $user->getDirectPermissions(); $permissions = $user->getPermissionsViaRoles(); $permissions = $user->getAllPermissions(); // get the names of the user's roles $roles = $user->getRoleNames(); // Returns a collection ``` -------------------------------- ### Get Permissions Assigned to a Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Retrieve all permissions associated with a role. You can also get just the names of the permissions or count them. ```php $role->permissions; ``` ```php // return only the permission names: $role->permissions->pluck('name'); ``` ```php // count the number of permissions assigned to a role count($role->permissions); // or $role->permissions->count(); ``` -------------------------------- ### Retrieve User Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Get all permissions associated with a user, including those inherited from roles and direct assignments. ```php // Direct permissions $user->getDirectPermissions() // Or $user->permissions; ``` ```php // Permissions inherited from the user's roles $user->getPermissionsViaRoles(); ``` ```php // All permissions which apply on the user (inherited and direct) $user->getAllPermissions(); ``` -------------------------------- ### Run Database Migrations Source: https://spatie.be/docs/laravel-permission/v7/installation-laravel Execute this command to create the necessary database tables for the package. ```bash php artisan migrate ``` -------------------------------- ### Configure SQLite Database Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/new-app Copies the environment file, sets the database connection to SQLite, and creates an empty SQLite database file. These steps are not needed if SQLite was selected during project creation. ```bash cp -n .env.example .env sed -i '' 's/DB_CONNECTION=mysql/DB_CONNECTION=sqlite/' .env sed -i '' 's/DB_DATABASE=/#DB_DATABASE=/' .env touch database/database.sqlite ``` -------------------------------- ### Create Role and Link Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan Create a role and assign permissions to it simultaneously using the command. ```bash php artisan permission:create-role writer web "create articles|edit articles" ``` -------------------------------- ### Publish Migrations and Config File Source: https://spatie.be/docs/laravel-permission/v7/installation-laravel Run this command to publish the package's migration files and the `permission.php` configuration file to your project. ```bash php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" ``` -------------------------------- ### Adding Permissions and Roles to Users Source: https://spatie.be/docs/laravel-permission/v7 Demonstrates how to assign permissions directly to a user or indirectly through roles. Ensure the user model is configured correctly. ```php // Adding permissions to a user $user->givePermissionTo('edit articles'); // Adding permissions via a role $user->assignRole('writer'); $role->givePermissionTo('edit articles'); ``` -------------------------------- ### Show Roles and Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan Display a table of all roles and permissions, categorized by guard, in the console. ```bash php artisan permission:show ``` -------------------------------- ### Create Permission Using make() and saveOrFail() Source: https://spatie.be/docs/laravel-permission/v7/best-practices/performance For large databases or frequent permission creations, using `Permission::make()` followed by `$permission->saveOrFail()` can be more performant than `Permission::create()`. This approach separates object instantiation from saving, potentially reducing overhead. ```php $permission = Permission::make([ 'name' => 'new permission', ]); $permission->saveOrFail(); ``` -------------------------------- ### Assigning and Checking Wildcard Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/wildcard-permissions When assigning 'posts.*', it's equivalent to assigning 'posts'. This grants all actions on posts. Ensure the wildcard permission pattern is created. ```php Permission::create(['name'=>'posts.*']); $user->givePermissionTo('posts.*'); // is the same as Permission::create(['name'=>'posts']); $user->givePermissionTo('posts'); ``` ```php // will be true $user->can('posts.create'); $user->can('posts.edit'); $user->can('posts.delete'); ``` -------------------------------- ### Create Permission with Artisan Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan Use this command to create a new permission. You can optionally specify the guard name. ```bash php artisan permission:create-permission "edit articles" ``` ```bash php artisan permission:create-permission "edit articles" web ``` -------------------------------- ### Create Roles and Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Create new roles and permissions using Eloquent models. Ensure the 'name' attribute is provided for each. ```php use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; $role = Role::create(['name' => 'writer']); $permission = Permission::create(['name' => 'edit articles']); ``` -------------------------------- ### Enable Wildcard Permissions in Config Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/wildcard-permissions To enable wildcard permissions, set 'enable_wildcard_permission' to true in your permission configuration file. ```php // config/permission.php 'enable_wildcard_permission' => true, ``` -------------------------------- ### Configure Permission Package for Passport Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/passport Enable Passport client credentials in the permission configuration file. This setting ensures that the permission package performs the correct checks when using the client credentials grant with Passport. ```php // config/permission.php 'use_passport_client_credentials' => true, ``` -------------------------------- ### Create Role with Artisan Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan Use this command to create a new role. You can optionally specify the guard name. ```bash php artisan permission:create-role writer ``` ```bash php artisan permission:create-role writer web ``` -------------------------------- ### Grant Super Admin All Permissions with Policy before() Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/super-admin Alternatively, grant super-admin control by checking the role in individual Policy classes using the `before()` method. This approach requires returning `null` to avoid interfering with normal policy operation. ```php use App\Models\User; // could be any Authorizable model /** * Perform pre-authorization checks on the model. */ public function before(User $user, string $ability): ?bool { if ($user->hasRole('Super Admin')) { return true; } return null; // see the note above in Gate::before about why null must be returned here. } ``` -------------------------------- ### Enable Teams Permissions in Config Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions Set the 'teams' configuration option to true to enable the teams permissions feature. This should be done before running migrations. ```php 'teams' => true, ``` -------------------------------- ### Applying Middleware to Routes Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/middleware Apply middleware to route groups using the `middleware` key. The `using` static method can accept an array or a pipe-separated string for defining roles or permissions. ```php Route::group(['middleware' => [\Spatie\Permission\Middleware\RoleMiddleware::using('manager')]], function () { ... }); ``` ```php Route::group(['middleware' => [\Spatie\Permission\Middleware\PermissionMiddleware::using('publish articles|edit articles')]], function () { ... }); ``` ```php Route::group(['middleware' => [\Spatie\Permission\Middleware\RoleOrPermissionMiddleware::using(['manager', 'edit articles'])]], function () { ... }); ``` -------------------------------- ### Add Middleware to Priority in AppServiceProvider Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions Register your custom team middleware in the `$middlewarePriority` array within your `AppServiceProvider`'s `boot` method. This ensures it runs before `SubstituteBindings` to prevent potential 404 errors. ```php use App\Http\Middleware\YourCustomMiddlewareClass; use Illuminate\Foundation\Http\Kernel; use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider { public function register(): void { // } public function boot(): void { /** @var Kernel $kernel */ $kernel = app()->make(Kernel::class); $kernel->addToMiddlewarePriorityBefore( YourCustomMiddlewareClass::class, SubstituteBindings::class, ); } } ``` -------------------------------- ### Sync Permissions to Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Synchronize multiple permissions to a role using the `syncPermissions` method on the role or `syncRoles` on the permission. This will replace existing permissions with the provided list. ```php $role->syncPermissions($permissions); $permission->syncRoles($roles); ``` -------------------------------- ### Retrieve All Users with Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Fetches all users and eager loads their direct permissions. ```php $allUsersWithAllTheirDirectPermissions = User::with('permissions')->get(); ``` -------------------------------- ### Create Roles and Permissions for Specific Guards Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/multiple-guards When creating roles or permissions, explicitly specify the `guard_name` to associate them with a particular authentication guard. If no guard is specified, the first guard in your `auth.guards` configuration will be used. ```php // Create a manager role for users authenticating with the admin guard: $role = Role::create(['guard_name' => 'admin', 'name' => 'manager']); // Define a `publish articles` permission for the admin users belonging to the admin guard $permission = Permission::create(['guard_name' => 'admin', 'name' => 'publish articles']); // Define a *different* `publish articles` permission for the regular users belonging to the web guard $permission = Permission::create(['guard_name' => 'web', 'name' => 'publish articles']); ``` -------------------------------- ### Checking for All Direct Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/direct-permissions Use `hasAllPermissions` to verify if a user has all the permissions specified in a given list of permission names or IDs. ```php $user->hasAllPermissions(['edit articles', 'publish articles', 'unpublish articles']); ``` -------------------------------- ### Using Package Middleware with OR Logic Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/middleware Combine multiple roles or permissions within a single middleware using the pipe `|` character for OR logic. This applies to roles, permissions, and role_or_permission middleware, with optional guard specification. ```php Route::group(['middleware' => ['role:manager|writer']], function () { ... }); Route::group(['middleware' => ['permission:publish articles|edit articles']], function () { ... }); Route::group(['middleware' => ['role_or_permission:manager|edit articles']], function () { ... }); ``` ```php // for a specific guard Route::group(['middleware' => ['permission:publish articles|edit articles,api']], function () { ... }); ``` -------------------------------- ### Registering Controller Middleware Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/middleware Implement the `HasMiddleware` interface in your controller and define the `middleware()` static method to register controller middleware. Supports aliases, pipe-separated names, and guards. ```php public static function middleware(): array { return [ // examples with aliases, pipe-separated names, guards, etc: 'role_or_permission:manager|edit articles', new Middleware('role:author', only: ['index']), new Middleware("Spatie\Permission\Middleware\RoleMiddleware::using('manager')", except:['show']), new Middleware("Spatie\Permission\Middleware\PermissionMiddleware::using('delete records,api')", only:['destroy']), ]; } ``` -------------------------------- ### Using Package Middleware in Routes Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/middleware Apply the registered package middleware aliases ('role', 'permission', 'role_or_permission') to route groups. You can specify a guard and multiple middleware. ```php Route::group(['middleware' => ['role:manager']], function () { ... }); Route::group(['middleware' => ['permission:publish articles']], function () { ... }); Route::group(['middleware' => ['role_or_permission:publish articles']], function () { ... }); ``` ```php // for a specific guard: Route::group(['middleware' => ['role:manager,api']], function () { ... }); ``` ```php // multiple middleware Route::group(['middleware' => ['role:manager','permission:publish articles']], function () { ... }); ``` -------------------------------- ### Grant Super Admin All Permissions with Gate::before Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/super-admin Use this in your AppServiceProvider to implicitly grant the 'Super Admin' role all permissions. This method works with gate-related functions like `auth()->user()->can()` and `@can()`. ```php use Illuminate\Support\Facades\Gate; // ... public function boot(): void { // Implicitly grant "Super Admin" role all permissions // This works in the app by using gate-related functions like auth()->user->can() and @can() Gate::before(function ($user, $ability) { return $user->hasRole('Super Admin') ? true : null; }); } ``` -------------------------------- ### Create Role with Team ID Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan When using teams, specify the team ID for the role using the --team-id parameter. ```bash php artisan permission:create-role --team-id=1 writer ``` ```bash php artisan permission:create-role writer api --team-id=1 ``` -------------------------------- ### Granting Direct Permissions to a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/direct-permissions Use `givePermissionTo` to assign single or multiple permissions directly to a user. You can pass permissions as individual arguments or as an array. ```php $user->givePermissionTo('edit articles'); ``` ```php $user->givePermissionTo('edit articles', 'delete articles'); ``` ```php $user->givePermissionTo(['edit articles', 'delete articles']); ``` -------------------------------- ### Checking for Any Direct Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/direct-permissions Use `hasAnyPermission` to check if a user possesses at least one permission from a given list of permission names or IDs. ```php $user->hasAnyPermission(['edit articles', 'publish articles', 'unpublish articles']); ``` ```php $user->hasAnyPermission(['edit articles', 1, 5]); ``` -------------------------------- ### Retrieve All Role Names Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Fetches all roles from the database and retrieves only their names. ```php $allRolesInDatabase = Role::all()->pluck('name'); ``` -------------------------------- ### Define Multiple Guards in User Model Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/multiple-guards Configure the User model to support multiple guards by setting the `$guard_name` property to an array of guard names. ```php protected $guard_name = ['web', 'admin']; ``` -------------------------------- ### Synchronizing Direct Permissions for a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/direct-permissions Use `syncPermissions` to update a user's permissions to match a given list, removing any existing permissions not in the list and adding any new ones. ```php $user->syncPermissions(['edit articles', 'delete articles']); ``` -------------------------------- ### Define Multiple Guards using guardName() Method Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/multiple-guards Alternatively, define multiple guards by implementing the `guardName()` method in your User model to return an array of guard names. ```php public function guardName() { return ['web', 'admin']; } ``` -------------------------------- ### Type Hint Updates in Contracts (v6 to v7) Source: https://spatie.be/docs/laravel-permission/v7/upgrading Updated type hints for parameters and return types in contracts. Ensure your implementations match these changes. ```php Contracts\PermissionsTeamResolver::setPermissionsTeamId() now has typed parameter int|string|Model|null $id ``` ```php Contracts\Role::hasPermissionTo() now has typed parameter and optional $guardName ``` -------------------------------- ### Giving a Permission to a Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Assign a specific permission to a role. The permission can be given by its string name. ```php $role->givePermissionTo('edit articles'); ``` -------------------------------- ### Assigning Roles to a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Assign a single role, multiple roles at once, or roles from an array to a user. Ensure the roles already exist. ```php $user->assignRole('writer'); // You can also assign multiple roles at once $user->assignRole('writer', 'admin'); // or as an array $user->assignRole(['writer', 'admin']); ``` -------------------------------- ### Syncing Permissions for a Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Update the permissions for a role by providing an array of permission names. This will remove any permissions not included in the array and add any new ones. ```php $role->syncPermissions(['edit articles', 'delete articles']); ``` -------------------------------- ### Switching Active Team ID for Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions To check roles and permissions for a different team after login, use `setPermissionsTeamId()`. It's crucial to unset the user's 'roles' and 'permissions' relations afterward to ensure fresh data is loaded for the new team context. ```php // set active global team_id setPermissionsTeamId($new_team_id); // $user = Auth::user(); // unset cached model relations so new team relations will get reloaded $user->unsetRelation('roles')->unsetRelation('permissions'); // Now you can check: $roles = $user->roles; $hasRole = $user->hasRole('my_role'); $user->hasPermissionTo('foo'); $user->can('bar'); // etc ``` -------------------------------- ### Create Roles with Team Association Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions When creating roles, you can specify a `team_id`. A `null` team_id creates a global role, while a specific `team_id` creates a team-specific role. Omitting `team_id` uses the default global team ID. ```php Role::create(['name' => 'writer', 'team_id' => null]); Role::create(['name' => 'reader', 'team_id' => 1]); Role::create(['name' => 'reviewer']); ``` -------------------------------- ### Reset Cache Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/artisan Manually reset the package's cache using this Artisan command. Note that API operations typically handle cache resets automatically. ```bash php artisan permission:cache-reset ``` -------------------------------- ### Assigning Global Roles to New Teams Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions When a new team is created, you can automatically assign a global role, like 'Super Admin', to a specific user for that team. This is typically done within the `boot` method of your team model. ```php namespace App\Models; class YourTeamModel extends \Illuminate\Database\Eloquent\Model { // ... public static function boot() { parent::boot(); // here assign this team to a global user with global default role self::created(function ($model) { // temporary: get session team_id for restore at end $session_team_id = getPermissionsTeamId(); // set actual new team_id to package instance setPermissionsTeamId($model); // get the admin user and assign roles/permissions on new team model User::find('your_user_id')->assignRole('Super Admin'); // restore session team_id to package instance using temporary value stored above setPermissionsTeamId($session_team_id); }); } // ... } ``` -------------------------------- ### Update Composer Dependency Source: https://spatie.be/docs/laravel-permission/v7/upgrading Update your composer.json to specify the new major version and then run composer update. ```bash composer update spatie/laravel-permission ``` -------------------------------- ### Syncing Roles for a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Replace all current roles assigned to a user with a new set of roles provided in an array. This will remove any roles not present in the new array. ```php // All current roles will be removed from the user and replaced by the array given $user->syncRoles(['writer', 'admin']); ``` -------------------------------- ### Registering Package Middleware Aliases Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/middleware Register aliases for the package's middleware in bootstrap/app.php for easier use in routes and controllers. Ensure you are using the singular 'Middleware' namespace for versions 6 and above. ```php ->withMiddleware(function (Middleware $middleware) { $middleware->alias([ 'role' => \Spatie\Permission\Middleware\RoleMiddleware::class, 'permission' => \Spatie\Permission\Middleware\PermissionMiddleware::class, 'role_or_permission' => \Spatie\Permission\Middleware\RoleOrPermissionMiddleware::class, ]); }) ``` -------------------------------- ### Checking User Permissions with Laravel's Gate Source: https://spatie.be/docs/laravel-permission/v7 Shows how to verify if a user has a specific permission using Laravel's built-in 'can' method. This works seamlessly with permissions registered on Laravel's gate. ```php $user->can('edit articles'); ``` -------------------------------- ### Type Hint Updates in Traits (v6 to v7) Source: https://spatie.be/docs/laravel-permission/v7/upgrading Method signatures in the HasPermissions and HasRoles traits now return 'static'. Update your custom models if you have extended these traits. ```php givePermissionTo(), syncPermissions(), revokePermissionTo() now return static ``` ```php assignRole(), removeRole(), syncRoles() now return static ``` -------------------------------- ### Retrieve Users Without Any Roles Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Fetches all users who have not been assigned any roles. ```php $usersWithoutAnyRoles = User::doesntHave('roles')->get(); ``` -------------------------------- ### Check Any Permission using Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Check if a user has any of the specified permissions by passing an array of Enum cases to hasAnyPermission. ```php $user->hasAnyPermission([PermissionsEnum::EDITPOSTS, PermissionsEnum::VIEWPOSTS]); ``` -------------------------------- ### Scope Users by Permission Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Apply Eloquent scopes to filter users based on their permissions. `permission` includes users with the specified permission, and `withoutPermission` excludes them. ```php $users = User::permission('edit articles')->get(); // Returns only users with the permission 'edit articles' (inherited or directly) $usersWhoCannotEditArticles = User::withoutPermission('edit articles')->get(); // Returns all users without the permission 'edit articles' (inherited or directly) ``` -------------------------------- ### Assign Permission to Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Assign a permission to a role using either the role's `givePermissionTo` method or the permission's `assignRole` method. ```php $role->givePermissionTo($permission); $permission->assignRole($role); ``` -------------------------------- ### Authorize Actions with Enums Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Check for permissions using Enum cases directly. The package automatically handles the conversion to string values where supported. ```php $user->hasPermissionTo(PermissionsEnum::VIEWPOSTS); ``` ```php $user->hasPermissionTo(PermissionsEnum::VIEWPOSTS->value); ``` ```php $user->hasPermissionTo(enum_value(PermissionsEnum::VIEWPOSTS)); ``` -------------------------------- ### Define a Wildcard Permission String Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/wildcard-permissions A wildcard permission string consists of parts separated by dots. The meaning of each part is application-defined. ```php $permission = 'posts.create.1'; ``` -------------------------------- ### Check All Roles using Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Check if a user has all the specified roles by passing an array of Enum cases to hasAllRoles. ```php $user->hasAllRoles([RolesEnum::WRITER, RolesEnum::EDITOR]); ``` -------------------------------- ### Configure Custom Team Foreign Key Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/teams-permissions If using a custom foreign key for teams, specify its name in the 'team_foreign_key' configuration option. This also requires the 'teams' option to be enabled. ```php 'team_foreign_key' => 'custom_team_id', ``` -------------------------------- ### Assigning Models to a Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Assign a role to multiple models (users) at once using their model instances or IDs. Ensure the role exists. ```php $role = Role::findByName('writer'); // Give the role to two users at once. $role->assignToModels([$user1, $user2]); ``` -------------------------------- ### Check User Permissions for a Specific Guard Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/multiple-guards Verify if a user possesses a specific permission, optionally specifying the guard to check against. This is crucial when dealing with multiple guards that might have overlapping permission names. ```php $user->hasPermissionTo('publish articles', 'admin'); ``` -------------------------------- ### Checking if a User Has All Specified Roles Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Verify if a user has been assigned all roles from a provided list, such as all roles returned by `Role::all()`. This checks for a comprehensive set of assigned roles. ```php $user->hasAllRoles(Role::all()); ``` -------------------------------- ### Using Subparts with Commas in Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/wildcard-permissions Subparts separated by commas allow for complex permission schemes, enabling multiple actions or targets within a single permission string. ```php Permission::create(['name'=>'posts,users.create,update,view']); $user->givePermissionTo('posts,users.create,update,view'); // user can do the actions create, update, view on any available resource Permission::create(['name'=>'*.create,update,view']); $user->givePermissionTo('*.create,update,view'); // user can do any action on posts with ids 1, 4 and 6 Permission::create(['name'=>'posts.*.1,4,6']); $user->givePermissionTo('posts.*.1,4,6'); ``` -------------------------------- ### Check for Any Role with @hasanyrole Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/blade-directives Use @hasanyrole to verify if the user has at least one role from a given collection or a pipe-separated string of roles. ```blade @hasanyrole($collectionOfRoles) I have one or more of these roles! @else I have none of these roles... @endhasanyrole ``` ```blade @hasanyrole('writer|admin') I am either a writer or an admin or both! @else I have none of these roles... @endhasanyrole ``` -------------------------------- ### Command Class Renames (v6 to v7) Source: https://spatie.be/docs/laravel-permission/v7/upgrading Command classes have been renamed by adding a 'Command' suffix. The artisan command signatures remain unchanged. ```php Spatie\Permission\Commands\CacheReset Spatie\Permission\Commands\CacheResetCommand ``` ```php Spatie\Permission\Commands\CreateRole Spatie\Permission\Commands\CreateRoleCommand ``` ```php Spatie\Permission\Commands\CreatePermission Spatie\Permission\Commands\CreatePermissionCommand ``` ```php Spatie\Permission\Commands\Show Spatie\Permission\Commands\ShowCommand ``` ```php Spatie\Permission\Commands\UpgradeForTeams Spatie\Permission\Commands\UpgradeForTeamsCommand ``` ```php Spatie\Permission\Commands\AssignRole Spatie\Permission\Commands\AssignRoleCommand ``` -------------------------------- ### Eloquent Relationship Loading Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Load roles and other relationships for users using Eloquent's eager loading capabilities. ```php $allUsersWithAllTheirRoles = User::with('roles')->get(); ``` -------------------------------- ### Control Super Admin Permissions with Gate::after Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/super-admin Use `Gate::after()` to move the Super Admin check to the after phase. This is useful if the Super Admin should not be allowed to perform certain actions that the application restricts for everyone. Note that this method returns a boolean. ```php // somewhere in a service provider Gate::after(function ($user, $ability) { return $user->hasRole('Super Admin'); // note this returns boolean }); ``` -------------------------------- ### Assign Permission to Role Source: https://spatie.be/docs/laravel-permission/v7/best-practices/performance When frequently adding or removing permissions, assigning a permission to a role directly can be more performant than looking up the role and giving it the permission. This is a common optimization for dynamic permission management. ```php $permission->assignRole($role); ``` -------------------------------- ### Specify String Length in Migration Files Source: https://spatie.be/docs/laravel-permission/v7/prerequisites Explicitly set shorter lengths for 'name' and 'guard_name' fields within migration files. This approach requires manual validation limits in your application's forms. ```php $table->string('name'); // For MyISAM use string('name', 225); // (or 166 for InnoDB with Redundant/Compact row format) ``` ```php $table->string('guard_name'); // For MyISAM use string('guard_name', 25); ``` -------------------------------- ### Assign Direct Permissions to a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Assign permissions directly to a user, independent of their roles. This is useful for fine-grained control over user abilities. ```php $role = Role::findByName('writer'); $role->givePermissionTo('edit articles'); $user->assignRole('writer'); $user->givePermissionTo('delete articles'); ``` -------------------------------- ### Give Permission using Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Grant permissions to roles or users by passing Enum cases directly to the givePermissionTo method. ```php $role->givePermissionTo(PermissionsEnum::EDITPOSTS); ``` ```php $user->givePermissionTo(PermissionsEnum::EDITPOSTS); ``` -------------------------------- ### Check for Direct Permissions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Verify if a user possesses specific permissions directly assigned to them, not inherited through roles. ```php // Check if the user has Direct permission $user->hasDirectPermission('edit articles') ``` ```php // Check if the user has All direct permissions $user->hasAllDirectPermissions(['edit articles', 'delete articles']); ``` ```php // Check if the user has Any permission directly $user->hasAnyDirectPermission(['create articles', 'delete articles']); ``` -------------------------------- ### Define Roles Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Define a BackedEnum for roles, including an optional label method for display purposes. This helps in organizing and managing role names. ```php namespace App\Enums; enum RolesEnum: string { // case NAMEINAPP = 'name-in-database'; case WRITER = 'writer'; case EDITOR = 'editor'; case USERMANAGER = 'user-manager'; // extra helper to allow for greater customization of displayed values, without disclosing the name/value data directly public function label(): string { return match ($this) { static::WRITER => 'Writers', static::EDITOR => 'Editors', static::USERMANAGER => 'User Managers', }; } } ``` -------------------------------- ### Check Exact Roles using Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Check if a user has the exact set of specified roles by passing an array of Enum cases to hasExactRoles. ```php $user->hasExactRoles([RolesEnum::WRITER, RolesEnum::EDITOR, RolesEnum::MANAGER]); ``` -------------------------------- ### Update Middleware Namespace Source: https://spatie.be/docs/laravel-permission/v7/upgrading The namespace for permission middleware has changed from `Spatie\Permission\Middlewares` to `Spatie\Permission\Middleware`. Update all references in your application's kernel and routes. ```php \Spatie\Permission\Middlewares\ ``` ```php \Spatie\Permission\Middleware\ ``` -------------------------------- ### Type Hint Updates in PermissionRegistrar (v6 to v7) Source: https://spatie.be/docs/laravel-permission/v7/upgrading Methods in PermissionRegistrar have updated return types. 'setPermissionClass()' and 'setRoleClass()' now return 'static', while 'forgetCachedPermissions()' returns 'bool'. ```php PermissionRegistrar::setPermissionClass() PermissionRegistrar::setRoleClass() now return static ``` ```php PermissionRegistrar::forgetCachedPermissions() now returns bool ``` -------------------------------- ### Remove registerPermissions() from Tests Source: https://spatie.be/docs/laravel-permission/v7/upgrading When upgrading to v6, calls to `registerPermissions()` in test suites must be deleted. Cache clearing and re-registration are no longer necessary in this manner. ```php app()[\Spatie\Permission\PermissionRegistrar::class]->registerPermissions(); ``` -------------------------------- ### Event Class Renames (v6 to v7) Source: https://spatie.be/docs/laravel-permission/v7/upgrading Event classes have been renamed by adding an 'Event' suffix. Update any event listeners referencing these classes. ```php Spatie\Permission\Events\PermissionAttached Spatie\Permission\Events\PermissionAttachedEvent ``` ```php Spatie\Permission\Events\PermissionDetached Spatie\Permission\Events\PermissionDetachedEvent ``` ```php Spatie\Permission\Events\RoleAttached Spatie\Permission\Events\RoleAttachedEvent ``` ```php Spatie\Permission\Events\RoleDetached Spatie\Permission\Events\RoleDetachedEvent ``` -------------------------------- ### Syncing Models for a Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Replace all models currently assigned a role with a new set of models. This operation removes the role from any models not included in the new set. ```php // Replace every model that currently has this role with a new set. $role->syncModels([$user2, $user3]); ``` -------------------------------- ### Keep Cached Permissions Source: https://spatie.be/docs/laravel-permission/v7/upgrading It is still recommended to forget cached permissions after creating roles and permissions in migrations, factories, and seeders. This ensures the cache is up-to-date. ```php app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); ``` -------------------------------- ### Assign Role using Enum Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Assign roles to users by passing Enum cases directly to the assignRole method. ```php $user->assignRole(RolesEnum::WRITER); ``` -------------------------------- ### Checking if a User Has Exact Roles Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Confirm if a user has precisely the specified set of roles and no others. This is a strict check for an exact role match. ```php $user->hasExactRoles(Role::all()); ``` -------------------------------- ### Extend Passport Client Model Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/passport Extend the base Passport Client model to include Spatie's HasRoles trait and define the guard name for API authentication. This allows Passport clients to be associated with roles and permissions. ```php use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Foundation\Auth\Access\Authorizable; use Laravel\Passport\Client as BaseClient; use Spatie\Permission\Traits\HasRoles; class Client extends BaseClient implements AuthorizableContract { use HasRoles; use Authorizable; public $guard_name = 'api'; // or public function guardName() { return 'api'; } } ``` -------------------------------- ### Create Role using Enum Value Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/enums Use the enum_value() helper function to create roles or permissions from Enum values, as Eloquent expects string inputs for names. ```php $role = app(Role::class)->findOrCreate(enum_value(RolesEnum::WRITER), 'web'); ``` -------------------------------- ### Assigning Roles to Models with Specific Class Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions When using raw IDs, specify the model class to ensure the role is assigned to the correct type of model. This overrides the default model configuration. ```php $role->assignToModels([1, 2, 3], User::class); ``` -------------------------------- ### Check for Any Permission with @canany Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/blade-directives Use @canany to check if the user has at least one of the specified permissions. This is the recommended directive for checking any permission. ```blade @canany(['edit articles', 'publish articles']) // User has at least one of the permissions @endcanany ``` -------------------------------- ### Revoking Direct Permissions from a User Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/direct-permissions Use `revokePermissionTo` to remove a specific permission from a user. ```php $user->revokePermissionTo('edit articles'); ``` -------------------------------- ### Using Blade Directives for Permission Checks Source: https://spatie.be/docs/laravel-permission/v7 Illustrates how to use Blade directives to conditionally display content based on a user's permissions. This is a convenient way to manage UI elements. ```blade @can('edit articles') ... @endcan ``` -------------------------------- ### Check User Permission with @can and Conditions Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/blade-directives Combine the @can directive with other conditions using standard Blade syntax for more complex access control. ```blade @if(auth()->user()->can('edit articles') && $some_other_condition) // @endif ``` -------------------------------- ### Register Extended Client Model Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/passport Configure the AuthServiceProvider to use your custom extended Client model with Passport. This ensures that Passport utilizes your model for all client-related operations, including role and permission checks. ```php use Laravel\Passport\Passport; // In your App\Providers\AuthServiceProvider boot method: Passport::useClientModel(\'App\Models\Client::class\'); // Use the namespace of your extended Client. ``` -------------------------------- ### Clear Laravel Configuration Cache Source: https://spatie.be/docs/laravel-permission/v7/installation-laravel After publishing or modifying configuration files, clear the cache to ensure the changes are loaded. ```bash php artisan optimize:clear ``` ```bash php artisan config:clear ``` -------------------------------- ### Retrieve Roles Excluding Specific Names Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Fetches all roles from the database, excluding those named 'role A' or 'role B'. ```php $allRolesExceptAandB = Role::whereNotIn('name', ['role A', 'role B'])->get(); ``` -------------------------------- ### Scope Users by Role Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/basic-usage Use Eloquent scopes to filter users based on their roles. The `role` scope includes users with the specified role, while `withoutRole` excludes them. ```php $users = User::role('writer')->get(); // Returns only users with the role 'writer' $nonEditors = User::withoutRole('editor')->get(); // Returns only users without the role 'editor' ``` -------------------------------- ### Checking if a Role Has a Permission Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Determine if a role has been granted a specific permission. The permission can be checked by its string name. ```php $role->hasPermissionTo('edit articles'); ``` -------------------------------- ### Assigning Roles to Models by ID or Collection Source: https://spatie.be/docs/laravel-permission/v7/basic-usage/role-permissions Assign a role to models using various input types including single models, single IDs, arrays of IDs, Eloquent Collections, or mixed arrays of models and IDs. ```php $role->assignToModels($user); // a single model $role->assignToModels($user->id); // a single ID $role->assignToModels([1, 2, 3]); // an array of IDs $role->assignToModels(User::query()->get()); // a Collection $role->assignToModels([$user1, 5, $user2]); // mixed ```