Search code examples
laravelpermissionslaravel-permission

How to make multiple roles in Spatie Laravel package?


Is possible with Spatie's laravel-permission package to achieve something like what Facebook have with their permissions for pages?

Case study,

On Facebook you can create a page, then automatically you'll become Admin (assuming it's a role) of that page. Then you can invite you friend and make him/her a Publisher role

After that, your friend can also invite you to their Page and make you an Editor ( that's another role for you)

so at the end you will have two roles for two different profiles/Pages.

I want to achieve something like that on my app.

EDIT

what i know for now is that i can use:

$user->assignRole('editor');

and i can check if the user has a roles with :

$user->hasRole('writer')

But the thing is how do i link that role with the page that i want them to manage?

Like if you have admin role in one page and editor role in another page. and if you just check if $user->hasRole('admin') the results will always be true. so i want to know if there is anything i can do to assign and also check which page are you admin for.

I hope i am making sense.


Solution

  • Assuming your table structure looks like this:

    Pages table

    |---------------------|------------------|------------------|------------------|
    |          id         |       name       |   created_at     |   updated_at     |
    |---------------------|------------------|------------------|------------------|
    |          12         |    PHP masters   |    2019-02-31    |   2019-03-12     |
    |---------------------|------------------|------------------|------------------|
    

    Pages admin

    |---------------------|------------------|------------------|------------------|
    |          id         |      page_id     |      role_id     |     user_id      |
    |---------------------|------------------|------------------|------------------|
    |          1          |         12       |         2        |        2         |
    |---------------------|------------------|------------------|------------------|
    

    Roles table

    |---------------------|------------------|------------------|------------------|
    |          id         |       name       |   created_at     |   updated_at     |
    |---------------------|------------------|------------------|------------------|
    |          12         |      Editor      |    2019-02-31    |   2019-03-12     |
    |---------------------|------------------|------------------|------------------|
    |          12         |   System Admin   |    2019-02-31    |   2019-03-12     |
    |---------------------|------------------|------------------|------------------|
    |          12         |    Page Admin    |    2019-02-31    |   2019-03-12     |
    |---------------------|------------------|------------------|------------------|
    

    Now inside User model add this method

    #do not forget to import Roles
    #use Spatie\Permission\Models\Role;
    
        public function can_manage($page_id) : bool;
        {
    
            #Backdoor for the system admin
            if ($this->hasRole(['System Admin'])) {
                return true;
            }
    
    
            #now we check if the user has the role for that page
            $role = Role::select('name')
                            ->join("page_admins", 'page_admins.role_id', '=', 'roles.id')
                            ->where("page_id", $page_id)
                            ->where("user_id",   $this->id)
                            ->first();
    
    
            #return true if roles was found
            if (!empty($role)) {
                return true;
            }
    
    
            #else false
            return false;
    
    
        }
    
    

    Lastly if you want to check if the user can access the page's admin you use:

    #for jwt-auth
    #$user = $request->user(); 
    
    if ( $user->can_manage($page_id) )
    {
       #then do you things
    }
    

    Now that you saw how to check if someone is among page administration, you can get creative with that. you can create a method that :

    #Get user role in the page
    #etc