1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Yajra\Acl\Traits; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Str; |
6
|
|
|
use Yajra\Acl\Models\Role; |
7
|
|
|
|
8
|
|
|
trait HasRole |
9
|
|
|
{ |
10
|
|
|
/** |
11
|
|
|
* Check if user have access using any of the acl. |
12
|
|
|
* |
13
|
|
|
* @param string|array $acl |
14
|
|
|
* @return boolean |
15
|
|
|
*/ |
16
|
|
|
public function canAccess($acl) |
17
|
|
|
{ |
18
|
|
|
return $this->canAtLeast($acl) || $this->hasRole($acl); |
|
|
|
|
19
|
|
|
} |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* Check if user has at least one of the given permissions |
23
|
|
|
* |
24
|
|
|
* @param array $permissions |
25
|
|
|
* @return bool |
26
|
|
|
*/ |
27
|
|
|
public function canAtLeast(array $permissions) |
28
|
|
|
{ |
29
|
|
|
$can = false; |
30
|
|
|
|
31
|
|
|
if (auth()->check()) { |
32
|
|
|
foreach ($this->roles as $role) { |
|
|
|
|
33
|
|
|
if ($role->canAtLeast($permissions)) { |
34
|
|
|
$can = true; |
35
|
|
|
} |
36
|
|
|
} |
37
|
|
|
} else { |
38
|
|
|
$guest = Role::whereSlug('guest')->first(); |
39
|
|
|
|
40
|
|
|
if ($guest) { |
41
|
|
|
return $guest->canAtLeast($permissions); |
42
|
|
|
} |
43
|
|
|
} |
44
|
|
|
|
45
|
|
|
return $can; |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Check if user has the given role. |
50
|
|
|
* |
51
|
|
|
* @param $role |
52
|
|
|
* @return bool |
53
|
|
|
*/ |
54
|
|
|
public function hasRole($role) |
55
|
|
|
{ |
56
|
|
|
if (is_string($role)) { |
57
|
|
|
return $this->roles->contains('name', $role); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
if (is_array($role)) { |
61
|
|
|
$roles = $this->getRoleSlugs(); |
62
|
|
|
|
63
|
|
|
$intersection = array_intersect($roles, (array) $role); |
64
|
|
|
$intersectionCount = count($intersection); |
65
|
|
|
|
66
|
|
|
return ($intersectionCount > 0) ? true : false; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
return ! ! $role->intersect($this->roles)->count(); |
70
|
|
|
} |
71
|
|
|
|
72
|
|
|
/** |
73
|
|
|
* Get all user roles. |
74
|
|
|
* |
75
|
|
|
* @return array|null |
76
|
|
|
*/ |
77
|
|
|
public function getRoleSlugs() |
78
|
|
|
{ |
79
|
|
|
if (! is_null($this->roles)) { |
80
|
|
|
return $this->roles->pluck('slug')->toArray(); |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
return null; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* Attach a role to user using slug. |
88
|
|
|
* |
89
|
|
|
* @param $slug |
90
|
|
|
* @return bool |
91
|
|
|
*/ |
92
|
|
|
public function attachRoleBySlug($slug) |
93
|
|
|
{ |
94
|
|
|
$role = Role::where('slug', $slug)->first(); |
95
|
|
|
|
96
|
|
|
return $this->attachRole($role); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Attach a role to user |
101
|
|
|
* |
102
|
|
|
* @param Role $role |
103
|
|
|
* @return boolean |
104
|
|
|
*/ |
105
|
|
|
public function attachRole(Role $role) |
106
|
|
|
{ |
107
|
|
|
return $this->assignRole($role->id); |
|
|
|
|
108
|
|
|
} |
109
|
|
|
|
110
|
|
|
/** |
111
|
|
|
* Assigns the given role to the user. |
112
|
|
|
* |
113
|
|
|
* @param int $roleId |
114
|
|
|
* @return bool |
115
|
|
|
*/ |
116
|
|
|
public function assignRole($roleId = null) |
117
|
|
|
{ |
118
|
|
|
$roles = $this->roles; |
119
|
|
|
|
120
|
|
|
if (! $roles->contains($roleId)) { |
121
|
|
|
return $this->roles()->attach($roleId); |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
return false; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* Model can have many roles. |
129
|
|
|
* |
130
|
|
|
* @return \Illuminate\Database\Eloquent\Model |
131
|
|
|
*/ |
132
|
|
|
public function roles() |
133
|
|
|
{ |
134
|
|
|
return $this->belongsToMany(config('acl.role', Role::class))->withTimestamps(); |
|
|
|
|
135
|
|
|
} |
136
|
|
|
|
137
|
|
|
/** |
138
|
|
|
* @param $query |
139
|
|
|
* @param array $roles |
140
|
|
|
* @return mixed |
141
|
|
|
*/ |
142
|
|
|
public function scopeHavingRoles($query, array $roles) |
143
|
|
|
{ |
144
|
|
|
return $query->whereExists(function ($query) use ($roles) { |
145
|
|
|
$query->selectRaw('1') |
146
|
|
|
->from('role_user') |
147
|
|
|
->whereRaw('role_user.user_id = users.id') |
148
|
|
|
->whereIn('role_id', $roles); |
149
|
|
|
}); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
/** |
153
|
|
|
* Revokes the given role from the user. |
154
|
|
|
* |
155
|
|
|
* @param $role |
156
|
|
|
* @return bool |
157
|
|
|
*/ |
158
|
|
|
public function revokeRole($role = "") |
159
|
|
|
{ |
160
|
|
|
return $this->roles()->detach($role); |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Syncs the given role(s) with the user. |
165
|
|
|
* |
166
|
|
|
* @param array $roles |
167
|
|
|
* @return bool |
168
|
|
|
*/ |
169
|
|
|
public function syncRoles(array $roles) |
170
|
|
|
{ |
171
|
|
|
return $this->roles()->sync($roles); |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* Revokes all roles from the user. |
176
|
|
|
* |
177
|
|
|
* @return bool |
178
|
|
|
*/ |
179
|
|
|
public function revokeAllRoles() |
180
|
|
|
{ |
181
|
|
|
return $this->roles()->detach(); |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* Get all user role permissions. |
186
|
|
|
* |
187
|
|
|
* @return array|null |
188
|
|
|
*/ |
189
|
|
|
public function getPermissions() |
190
|
|
|
{ |
191
|
|
|
$permissions = [[], []]; |
192
|
|
|
|
193
|
|
|
foreach ($this->roles as $role) { |
194
|
|
|
$permissions[] = $role->getPermissions(); |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return call_user_func_array('array_merge', $permissions); |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* Magic __call method to handle dynamic methods. |
202
|
|
|
* |
203
|
|
|
* @param string $method |
204
|
|
|
* @param array $arguments |
205
|
|
|
* @return mixed |
206
|
|
|
*/ |
207
|
|
|
public function __call($method, $arguments = []) |
208
|
|
|
{ |
209
|
|
|
// Handle isRoleSlug() methods |
210
|
|
|
if (Str::startsWith($method, 'is') and $method !== 'is') { |
|
|
|
|
211
|
|
|
$role = substr($method, 2); |
212
|
|
|
|
213
|
|
|
return $this->is($role); |
|
|
|
|
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
// Handle canDoSomething() methods |
217
|
|
|
if (Str::startsWith($method, 'can') and $method !== 'can') { |
|
|
|
|
218
|
|
|
$permission = substr($method, 3); |
219
|
|
|
|
220
|
|
|
return $this->can($permission); |
|
|
|
|
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
return parent::__call($method, $arguments); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* Checks if the user has the given role. |
228
|
|
|
* |
229
|
|
|
* @param string $slug |
230
|
|
|
* @return bool |
231
|
|
|
*/ |
232
|
|
|
public function isRole($slug) |
233
|
|
|
{ |
234
|
|
|
$slug = Str::lower($slug); |
235
|
|
|
|
236
|
|
|
foreach ($this->roles as $role) { |
237
|
|
|
if ($role->slug == $slug) { |
238
|
|
|
return true; |
239
|
|
|
} |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
return false; |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
/** |
246
|
|
|
* Check if the given entity/model is owned by the user. |
247
|
|
|
* |
248
|
|
|
* @param \Illuminate\Database\Eloquent\Model $entity |
249
|
|
|
* @param string $relation |
250
|
|
|
* @return bool |
251
|
|
|
*/ |
252
|
|
|
public function owns($entity, $relation = 'user_id') |
253
|
|
|
{ |
254
|
|
|
return $this->id === $entity->{$relation}; |
|
|
|
|
255
|
|
|
} |
256
|
|
|
} |
257
|
|
|
|
This check looks at variables that have been passed in as parameters and are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.