To extend the @can and @canany Blade directives to check both user and company permissions, you can create custom Blade directives. Here's a step-by-step solution:
-
Create a Custom Gate: First, define a custom gate that checks both user and company permissions. You can do this in the
AuthServiceProvider. -
Register the Custom Blade Directives: Use the
Blade::directivemethod to create custom directives. -
Use the Custom Directives in Blade: Replace the default
@canand@cananywith your custom directives.
Here's how you can implement this:
Step 1: Define a Custom Gate
In your AuthServiceProvider, define a custom gate that checks both user and company permissions.
use Illuminate\Support\Facades\Gate;
use App\Models\User;
public function boot()
{
$this->registerPolicies();
Gate::define('access-permission', function (User $user, $permission) {
// Check if the user has the permission
if ($user->can($permission)) {
return true;
}
// Check if the user's company has the permission
$company = $user->company; // Assuming you have a relationship set up
if ($company && $company->hasPermissionTo($permission)) {
return true;
}
return false;
});
}
Step 2: Register Custom Blade Directives
In a service provider, register custom Blade directives.
use Illuminate\Support\Facades\Blade;
public function boot()
{
Blade::directive('canCompany', function ($permission) {
return "<?php if(auth()->check() && auth()->user()->can('access-permission', {$permission})): ?>";
});
Blade::directive('endcanCompany', function () {
return "<?php endif; ?>";
});
Blade::directive('canAnyCompany', function ($permissions) {
return "<?php if(auth()->check() && collect({$permissions})->contains(fn($permission) => auth()->user()->can('access-permission', $permission))): ?>";
});
Blade::directive('endcanAnyCompany', function () {
return "<?php endif; ?>";
});
}
Step 3: Use the Custom Directives in Blade
Now, you can use these custom directives in your Blade templates.
@canCompany('edit articles')
<!-- The user or their company can edit articles -->
@endcanCompany
@canAnyCompany(['edit articles', 'delete articles'])
<!-- The user or their company can either edit or delete articles -->
@endcanAnyCompany
This approach allows you to extend the functionality of the @can and @canany directives to include company-level permissions, making it easier to manage permissions across both users and their associated companies.