So what i'm basically trying to do is refactor my long bit of code to something more simpler. I found this snippet of code at this website and I don't really understand what's going on inside the code. I don't think that this snippet of code will work considering I am using different policies and methods then what's standard.
Code Snippet From Site:
//PermissionsServiceProvider.php
public function boot()
{
Permission::get()->map(function($permission){
Gate::define($permission->slug, function($user) use ($permission){
return $user->hasPermissionTo($permission);
});
});
}
Can someone please explain what exactly is going on in this bit of code?
My Code:
// Posts Policy
Gate::define('post.view', 'App\Policies\Blog\PostsPolicy@view');
Gate::define('post.create', 'App\Policies\Blog\PostsPolicy@create');
Gate::define('post.update', 'App\Policies\Blog\PostsPolicy@update');
Gate::define('post.delete', 'App\Policies\Blog\PostsPolicy@delete');
Gate::define('post.publish', 'App\Policies\Blog\PostsPolicy@publish');
Gate::define('post.edit', 'App\Policies\Blog\PostsPolicy@edit');
Gate::define('post.global', 'App\Policies\Blog\PostsPolicy@global');
// Categories Policy
Gate::define('category.view', 'App\Policies\Blog\CategoriesPolicy@view');
Gate::define('category.create', 'App\Policies\Blog\CategoriesPolicy@create');
Gate::define('category.update', 'App\Policies\Blog\CategoriesPolicy@update');
Gate::define('category.delete', 'App\Policies\Blog\CategoriesPolicy@delete');
Gate::define('category.edit', 'App\Policies\Blog\CategoriesPolicy@edit');
Gate::define('category.global', 'App\Policies\Blog\CategoriesPolicy@global');
// Tags Policy
Gate::define('tag.view', 'App\Policies\Blog\TagsPolicy@view');
Gate::define('tag.create', 'App\Policies\Blog\TagsPolicy@create');
Gate::define('tag.update', 'App\Policies\Blog\TagsPolicy@update');
Gate::define('tag.delete', 'App\Policies\Blog\TagsPolicy@delete');
Gate::define('tag.edit', 'App\Policies\Blog\TagsPolicy@edit');
Gate::define('tag.global', 'App\Policies\Blog\TagsPolicy@global');
// Parts Section Policy
Gate::define('part.section.view', 'App\Policies\Parts\PartSectionsPolicy@view');
Gate::define('part.section.create', 'App\Policies\Parts\PartSectionsPolicy@create');
Gate::define('part.section.update', 'App\Policies\Parts\PartSectionsPolicy@update');
Gate::define('part.section.delete', 'App\Policies\Parts\PartSectionsPolicy@delete');
Gate::define('part.section.edit', 'App\Policies\Parts\PartSectionsPolicy@edit');
Gate::define('part.section.global', 'App\Policies\Parts\PartSectionsPolicy@global');
// Parts Policy
Gate::define('part.view', 'App\Policies\Parts\PartsPolicy@view');
Gate::define('part.create', 'App\Policies\Parts\PartsPolicy@create');
Gate::define('part.update', 'App\Policies\Parts\PartsPolicy@update');
Gate::define('part.delete', 'App\Policies\Parts\PartsPolicy@delete');
Gate::define('part.edit', 'App\Policies\Parts\PartsPolicy@edit');
Gate::define('part.global', 'App\Policies\Parts\PartsPolicy@global');
// Admin Management Policy
Gate::define('admin.global', 'App\Policies\AdminManagementPolicy@global');
// User Management Policy
Gate::define('user.global', 'App\Policies\UserManagementPolicy@global');
Is there a way to do this as a foreach loop from my permissions table? Here's some Pseudo code:
foreach($permissions as $permission) {
Gate::define($permission->slug, 'App\Policies\' . $permission->category . 'Policy@' . $permission->name);
}
Question: Any way to make my code more compact and easier to read like the code snippet from the website?
First of all, the author of that article did not use policies at all, he created a permissions table and then bound the permissions he created to laravel gates by the code snippet
Permission::get()->map(function($permission){
Gate::define($permission->slug, function($user) use ($permission){
return $user->hasPermissionTo($permission);
});
});
Let's break it line by line
Permission::get() // Query all permissions defined in permissions database table
->map(function($permission){ // Foreach permission do the following
Gate::define($permission->slug, // Create new gate with the permission slug
function($user) use ($permission){
return $user->hasPermissionTo($permission); // the user table has many to many relation with permissions table, here we only check if $user is associated with $permission
});
});
To make your code more dynamic, I suggest you to do the following:
Create permission
database table
Create roles
database table
Create permission_role
pivot database table
Create role_user
pivot database table
Role has many permissions ( many to many relationship, define it with belongsToMany
)
Permission belongs to many roles ( many to many relationship, define it with belongsToMany
)
User has many roles ( many to many relationship, define it with belongsToMany
)
global
permissionsBy utilising Gate::before
you can allow specific user who has global
or root
permission to authorise all defined abilities:
Gate::before(function ($user, $ability) {
if ($user->hasPermission('root-access')) {
return true;
}
});
If you implement the database permissions you no longer need to create policies for every model, and the gates will be defined using the above code dynamically.