Skip to content

Commit 7dd7c20

Browse files
committed
Parent Roles version
Roles parent - child relationship implemented.
1 parent 1ebbf0a commit 7dd7c20

File tree

5 files changed

+152
-12
lines changed

5 files changed

+152
-12
lines changed

src/Contracts/Role.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ public function permissions();
1818
*/
1919
public function users();
2020

21+
/**
22+
* A role can have een parent role.
23+
*
24+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
25+
*/
26+
public function parentrole();
27+
2128
/**
2229
* Find a role by its name.
2330
*
@@ -35,4 +42,27 @@ public static function findByName($name);
3542
* @return bool
3643
*/
3744
public function hasPermissionTo($permission);
45+
46+
/**
47+
* Get all parent roles.
48+
*
49+
* @return \Illuminate\Support\Collection
50+
*/
51+
public function getParentRoles();
52+
53+
/**
54+
* Get permissions from all parent roles.
55+
*
56+
* @return \Illuminate\Support\Collection
57+
*/
58+
public function parentPermissions();
59+
60+
/**
61+
* Determine if the user may perform the given permission for any parent role.
62+
*
63+
* @param string|Permission $permission
64+
*
65+
* @return bool
66+
*/
67+
public function parentsHavePermissionTo($permission);
3868
}

src/Models/Action.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function __construct(array $attributes = [])
3838
public function permissions()
3939
{
4040
return $this->belongsToMany(
41-
config('laravel-authorisation.models.permission'),
41+
config('laravel-authorisation.models.permission')
4242
);
4343
}
4444

src/Models/Permission.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,22 @@ class Permission extends Model implements PermissionContract
1818
*/
1919
public $guarded = ['id'];
2020

21+
/**
22+
* @var array
23+
*/
24+
protected $defaults = array(
25+
'object_id' => 0,
26+
'action_id' => 0,
27+
);
28+
2129
/**
2230
* Create a new Eloquent model instance.
2331
*
2432
* @param array $attributes
2533
*/
2634
public function __construct(array $attributes = [])
2735
{
36+
$this->setRawAttributes($this->defaults, true);
2837
parent::__construct($attributes);
2938

3039
$this->setTable(config('laravel-authorisation.table_names.permissions'));
@@ -69,7 +78,7 @@ public static function findByName($name)
6978
{
7079
$permission = static::getPermissions()->where('name', $name)->first();
7180

72-
if (! $permission) {
81+
if (!$permission) {
7382
throw new PermissionDoesNotExist();
7483
}
7584

src/Models/Role.php

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
use Ribedesign\Authorisation\Contracts\Role as RoleContract;
99
use Ribedesign\Authorisation\Traits\RefreshesAuthorisationCache;
1010

11+
/**
12+
* Class Role
13+
* @package Ribedesign\Authorisation\Models
14+
*/
1115
class Role extends Model implements RoleContract
1216
{
1317
use HasPermissions;
@@ -58,6 +62,16 @@ public function users()
5862
);
5963
}
6064

65+
/**
66+
* A role can have een parent role.
67+
*
68+
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
69+
*/
70+
public function parentrole()
71+
{
72+
return $this->belongsTo(self::class, 'parent_id');
73+
}
74+
6175
/**
6276
* Find a role by its name.
6377
*
@@ -71,7 +85,7 @@ public static function findByName($name)
7185
{
7286
$role = static::where('name', $name)->first();
7387

74-
if (! $role) {
88+
if (!$role) {
7589
throw new RoleDoesNotExist();
7690
}
7791

@@ -93,4 +107,67 @@ public function hasPermissionTo($permission)
93107

94108
return $this->permissions->contains('id', $permission->id);
95109
}
110+
111+
/**
112+
* Get all parent roles.
113+
*
114+
* @return \Illuminate\Support\Collection
115+
*/
116+
public function getParentRoles()
117+
{
118+
$parents = collect([]);
119+
120+
$parent = $this->parent;
121+
122+
while (!is_null($parent)) {
123+
$parents->push($parent);
124+
$parent = $parent->parent;
125+
}
126+
127+
return $parents;
128+
}
129+
130+
/**
131+
* Get permissions from all parent roles.
132+
*
133+
* @return \Illuminate\Support\Collection
134+
*/
135+
public function parentPermissions()
136+
{
137+
$parentPermissions = collect([]);
138+
139+
$parent = $this->parentrole;
140+
141+
while (!is_null($parent)) {
142+
if ($parent->permissions->count()) {
143+
$parentPermissions->push($parent->permissions);
144+
}
145+
$parent = $parent->parentrole;
146+
}
147+
148+
return $parentPermissions;
149+
}
150+
151+
/**
152+
* Determine if the user may perform the given permission for any parent role.
153+
*
154+
* @param string|Permission $permission
155+
*
156+
* @return bool
157+
*/
158+
public function parentsHavePermissionTo($permission)
159+
{
160+
if (is_string($permission)) {
161+
$permission = app(Permission::class)->findByName($permission);
162+
}
163+
164+
$parent = $this->parent;
165+
while (!is_null($parent)) {
166+
if ($parent->permissions->contains('id', $permission->id)) {
167+
return true;
168+
}
169+
$parent = $parent->parent;
170+
}
171+
return false;
172+
}
96173
}

src/Traits/HasRoles.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function scopeRole($query, $roles)
5050
$roles = $roles->toArray();
5151
}
5252

53-
if (! is_array($roles)) {
53+
if (!is_array($roles)) {
5454
$roles = [$roles];
5555
}
5656

@@ -65,7 +65,7 @@ public function scopeRole($query, $roles)
6565
return $query->whereHas('roles', function ($query) use ($roles) {
6666
$query->where(function ($query) use ($roles) {
6767
foreach ($roles as $role) {
68-
$query->orWhere(config('laravel-authorisation.table_names.roles').'.id', $role->id);
68+
$query->orWhere(config('laravel-authorisation.table_names.roles') . '.id', $role->id);
6969
}
7070
});
7171
});
@@ -127,12 +127,24 @@ public function syncRoles(...$roles)
127127
*/
128128
public function hasRole($roles)
129129
{
130+
$allroles = new Collection();
131+
if ($this->roles instanceof Collection) {
132+
foreach ($this->roles as $role) {
133+
$parent = $role->parentrole;
134+
while (!is_null($parent)) {
135+
$allroles->push($parent);
136+
$parent = $parent->parentrole;
137+
}
138+
}
139+
$allroles = $allroles->merge($this->roles)->unique('id')->values();
140+
}
141+
130142
if (is_string($roles)) {
131-
return $this->roles->contains('name', $roles);
143+
return $allroles->contains('name', $roles);
132144
}
133145

134146
if ($roles instanceof Role) {
135-
return $this->roles->contains('id', $roles->id);
147+
return $allroles->contains('id', $roles->id);
136148
}
137149

138150
if (is_array($roles)) {
@@ -145,7 +157,7 @@ public function hasRole($roles)
145157
return false;
146158
}
147159

148-
return (bool) $roles->intersect($this->roles)->count();
160+
return (bool)$roles->intersect($allroles)->count();
149161
}
150162

151163
/**
@@ -169,19 +181,31 @@ public function hasAnyRole($roles)
169181
*/
170182
public function hasAllRoles($roles)
171183
{
184+
$allroles = new Collection();
185+
if ($this->roles instanceof Collection) {
186+
foreach ($this->roles as $role) {
187+
$parent = $role->parentrole;
188+
while (!is_null($parent)) {
189+
$allroles->push($parent);
190+
$parent = $parent->parentrole;
191+
}
192+
}
193+
$allroles = $allroles->merge($this->roles)->unique('id')->values();
194+
}
195+
172196
if (is_string($roles)) {
173-
return $this->roles->contains('name', $roles);
197+
return $allroles->contains('name', $roles);
174198
}
175199

176200
if ($roles instanceof Role) {
177-
return $this->roles->contains('id', $roles->id);
201+
return $allroles->contains('id', $roles->id);
178202
}
179203

180204
$roles = collect()->make($roles)->map(function ($role) {
181205
return $role instanceof Role ? $role->name : $role;
182206
});
183207

184-
return $roles->intersect($this->roles->pluck('name')) == $roles;
208+
return $roles->intersect($allroles->pluck('name')) == $roles;
185209
}
186210

187211
/**
@@ -256,7 +280,7 @@ public function hasDirectPermission($permission)
256280
if (is_string($permission)) {
257281
$permission = app(Permission::class)->findByName($permission);
258282

259-
if (! $permission) {
283+
if (!$permission) {
260284
return false;
261285
}
262286
}

0 commit comments

Comments
 (0)