{"action":"closed","issue":{"url":"https://api.github.com/repos/kodeine/laravel-acl/issues/31","labels_url":"https://api.github.com/repos/kodeine/laravel-acl/issues/31/labels{/name}","comments_url":"https://api.github.com/repos/kodeine/laravel-acl/issues/31/comments","events_url":"https://api.github.com/repos/kodeine/laravel-acl/issues/31/events","html_url":"https://github.com/kodeine/laravel-acl/issues/31","id":64918245,"number":31,"title":"[Possible bug] Problem with multiple roles","user":{"login":"MarcoROG","id":6250285,"avatar_url":"https://avatars.githubusercontent.com/u/6250285?v=3","gravatar_id":"","url":"https://api.github.com/users/MarcoROG","html_url":"https://github.com/MarcoROG","followers_url":"https://api.github.com/users/MarcoROG/followers","following_url":"https://api.github.com/users/MarcoROG/following{/other_user}","gists_url":"https://api.github.com/users/MarcoROG/gists{/gist_id}","starred_url":"https://api.github.com/users/MarcoROG/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MarcoROG/subscriptions","organizations_url":"https://api.github.com/users/MarcoROG/orgs","repos_url":"https://api.github.com/users/MarcoROG/repos","events_url":"https://api.github.com/users/MarcoROG/events{/privacy}","received_events_url":"https://api.github.com/users/MarcoROG/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":10,"created_at":"2015-03-28T08:35:21Z","updated_at":"2015-03-28T19:26:12Z","closed_at":"2015-03-28T19:26:12Z","body":"#Problem\r\nI have just noticed something that doesn't look quite right to me, i have the following situation:\r\nAn user has two roles: student and secretary both have a different kind of permission regarding users obtained via permission inheritance:\r\n```PHP\r\n$genericUser=Permission::create([\r\n            'name' => 'users',\r\n            'slug' => [\r\n                'create' => false,\r\n                'view' => true,\r\n                'update' => false,\r\n                'approve' => false,\r\n                'delete' => false,\r\n            ],\r\n            'description' => 'generic permission regarding users'\r\n        ]);\r\n        $secretaryUser = Permission::create([\r\n            'name' => 'users.secretary',\r\n            'slug' => [\r\n                'create' => true,\r\n                'edit' => true,\r\n                'approve' => true,\r\n                'delete' => true,\r\n            ],\r\n            'inherit_id' => $genericUser->getKey(),\r\n            'description' => 'secretary permission regarding users'\r\n        ]);\r\n```\r\nSince the user has both roles, it has both the permission users and users.secretary.\r\nThe problem is that when i call can('edit.users') it returns false, if i call $user->getPermissions() i get the permissions of the last role assigned to the user (if i assign the generic first, i get the permissions of the secretary and vice versa).\r\n\r\n#Where the issue is\r\nI think that depends on the fact that the method 'can' in 'HasPermission' trait calls the method 'getPermissions' which uses an array_replace_recursive, which replaces the permission set with the latest extracted from the database and not the higher in clearance\r\n\r\n#Proposal\r\nWhen the user has more roles, each one with a different permission regarding the same thing, they should be merged granting the highest level of clearence, for example\r\n```PHP\r\nUser has role1 and role2\r\nrole1 has permission1:\r\n'name' => 'generic'\r\n 'slug' => [\r\n                'create' => true,\r\n                'edit' => false,\r\n            ],\r\nrole2 has permission2:\r\n'name' => 'generic'\r\n 'slug' => [\r\n                'create' => false,\r\n                'edit' => true,\r\n            ],\r\n```\r\nCalling getPermissions() on him should return\r\n```PHP\r\n\"users\"=>array:2[\r\n\"create\"=>\"true\"\r\n\"edit\"=>\"true\"\r\n]\r\n```\r\n\r\n#Workaround\r\narray_replace_recursive overwrites everything previously existing, even if this means loosing some clearence, to avoid that we need to check for every key that it's value is higher than the one we currently have, i can't find any fancy function in PHP to do this:\r\n```PHP\r\nforeach($this->roles as $role){\r\n  foreach($role->getPermissions() as $slug=>$array){\r\n    if(array_key_exists($slug,$permissions){\r\n      foreach($array as $clearence=>$value){\r\n       !$value?:$permissions[$slug][$clearance]=true;\r\n     }\r\n   }else{\r\n      $permissions = array_merge($permissions,array($slug => $array));\r\n   }\r\n }\r\n}\r\n```\r\nIt's quite an ugly piece of code and i'm sorry for that, maybe you can come up with something better.\r\nSorry for my horrible english"}}