Completed
Pull Request — master (#27)
by ARCANEDEV
07:32
created

Role   C

Complexity

Total Complexity 33

Size/Duplication

Total Lines 420
Duplicated Lines 0 %

Coupling/Cohesion

Components 3
Dependencies 19

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 33
lcom 3
cbo 19
dl 0
loc 420
rs 6.4625
c 0
b 0
f 0
ccs 95
cts 95
cp 1

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A users() 0 10 1
A permissions() 0 10 1
A setNameAttribute() 0 5 1
A setSlugAttribute() 0 4 1
A activate() 0 4 1
A deactivate() 0 4 1
A attachUser() 0 10 2
A detachUser() 0 10 1
A detachAllUsers() 0 10 1
A attachPermission() 0 10 2
A detachPermission() 0 12 2
A detachAllPermissions() 0 12 2
A hasUser() 0 6 2
A hasPermission() 0 6 2
A can() 0 6 2
A canAny() 0 10 2
A canAll() 0 6 1
A isLocked() 0 4 1
A hasSlug() 0 4 1
A loadUsers() 0 4 2
A loadPermissions() 0 4 2
A slugify() 0 4 1
1
<?php namespace Arcanedev\LaravelAuth\Models;
2
3
use Arcanedev\LaravelAuth\Events\Roles\AttachedPermissionToRole;
4
use Arcanedev\LaravelAuth\Events\Roles\AttachedUserToRole;
5
use Arcanedev\LaravelAuth\Events\Roles\AttachingPermissionToRole;
6
use Arcanedev\LaravelAuth\Events\Roles\AttachingUserToRole;
7
use Arcanedev\LaravelAuth\Events\Roles\CreatedRole;
8
use Arcanedev\LaravelAuth\Events\Roles\CreatingRole;
9
use Arcanedev\LaravelAuth\Events\Roles\DeletedRole;
10
use Arcanedev\LaravelAuth\Events\Roles\DeletingRole;
11
use Arcanedev\LaravelAuth\Events\Roles\DetachedAllPermissionsFromRole;
12
use Arcanedev\LaravelAuth\Events\Roles\DetachedAllUsersFromRole;
13
use Arcanedev\LaravelAuth\Events\Roles\DetachedPermissionFromRole;
14
use Arcanedev\LaravelAuth\Events\Roles\DetachedUserFromRole;
15
use Arcanedev\LaravelAuth\Events\Roles\DetachingAllPermissionsFromRole;
16
use Arcanedev\LaravelAuth\Events\Roles\DetachingAllUsersFromRole;
17
use Arcanedev\LaravelAuth\Events\Roles\DetachingPermissionFromRole;
18
use Arcanedev\LaravelAuth\Events\Roles\DetachingUserFromRole;
19
use Arcanedev\LaravelAuth\Events\Roles\SavedRole;
20
use Arcanedev\LaravelAuth\Events\Roles\SavingRole;
21
use Arcanedev\LaravelAuth\Events\Roles\UpdatedRole;
22
use Arcanedev\LaravelAuth\Events\Roles\UpdatingRole;
23
use Arcanedev\LaravelAuth\Models\Traits\Activatable;
24
use Arcanesoft\Contracts\Auth\Models\Role as RoleContract;
25
use Illuminate\Database\Eloquent\Model as Eloquent;
26
use Illuminate\Support\Str;
27
28
/**
29
 * Class     Role
30
 *
31
 * @package  Arcanedev\LaravelAuth\Models
32
 * @author   ARCANEDEV <[email protected]>
33
 *
34
 * @property  int                                       id
35
 * @property  string                                    name
36
 * @property  string                                    slug
37
 * @property  string                                    description
38
 * @property  bool                                      is_active
39
 * @property  bool                                      is_locked
40
 * @property  \Carbon\Carbon                            created_at
41
 * @property  \Carbon\Carbon                            updated_at
42
 *
43
 * @property  \Illuminate\Database\Eloquent\Collection       users
44
 * @property  \Illuminate\Database\Eloquent\Collection       permissions
45
 *
46
 * @property  \Arcanedev\LaravelAuth\Models\Pivots\RoleUser|\Arcanedev\LaravelAuth\Models\Pivots\PermissionRole  pivot
47
 */
48
class Role extends AbstractModel implements RoleContract
49
{
50
    /* -----------------------------------------------------------------
51
     |  Traits
52
     | -----------------------------------------------------------------
53
     */
54
55
    use Activatable;
56
57
    /* -----------------------------------------------------------------
58
     |  Properties
59
     | -----------------------------------------------------------------
60
     */
61
62
    /**
63
     * The attributes that are mass assignable.
64
     *
65
     * @var array
66
     */
67
    protected $fillable = ['name', 'slug', 'description'];
68
69
    /**
70
     * The attributes that should be casted to native types.
71
     *
72
     * @var array
73
     */
74
    protected $casts = [
75
        'is_active' => 'boolean',
76
        'is_locked' => 'boolean',
77
    ];
78
79
    /**
80
     * The event map for the model.
81
     *
82
     * @var array
83
     */
84
    protected $dispatchesEvents = [
85
        'creating' => CreatingRole::class,
86
        'created'  => CreatedRole::class,
87
        'updating' => UpdatingRole::class,
88
        'updated'  => UpdatedRole::class,
89
        'saving'   => SavingRole::class,
90
        'saved'    => SavedRole::class,
91
        'deleting' => DeletingRole::class,
92
        'deleted'  => DeletedRole::class,
93
    ];
94
95
    /* -----------------------------------------------------------------
96
     |  Constructor
97
     | -----------------------------------------------------------------
98
     */
99
100
    /**
101
     * Create a new Eloquent model instance.
102
     *
103
     * @param  array  $attributes
104
     */
105 76
    public function __construct(array $attributes = [])
106
    {
107 76
        parent::__construct($attributes);
108
109 76
        $this->setTable(config('laravel-auth.roles.table', 'roles'));
110 76
    }
111
112
    /* -----------------------------------------------------------------
113
     |  Relationships
114
     | -----------------------------------------------------------------
115
     */
116
117
    /**
118
     * Role belongs to many users.
119
     *
120
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
121
     */
122 12
    public function users()
123
    {
124
        return $this
125 12
            ->belongsToMany(
126 12
                config('laravel-auth.users.model', User::class),
127 12
                $this->getPrefix().config('laravel-auth.role-user.table', 'permission_role')
128
            )
129 12
            ->using(Pivots\RoleUser::class)
130 12
            ->withTimestamps();
131
    }
132
133
    /**
134
     * Role belongs to many permissions.
135
     *
136
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
137
     */
138 22
    public function permissions()
139
    {
140
        return $this
141 22
            ->belongsToMany(
142 22
                config('laravel-auth.permissions.model', Permission::class),
143 22
                $this->getPrefix().config('laravel-auth.permission-role.table', 'permission_role')
144
            )
145 22
            ->using(Pivots\PermissionRole::class)
146 22
            ->withTimestamps();
147
    }
148
149
    /* -----------------------------------------------------------------
150
     |  Getters & Setters
151
     | -----------------------------------------------------------------
152
     */
153
154
    /**
155
     * Set the name attribute.
156
     *
157
     * @param  string  $name
158
     */
159 66
    public function setNameAttribute($name)
160
    {
161 66
        $this->attributes['name'] = $name;
162 66
        $this->setSlugAttribute($name);
163 66
    }
164
165
    /**
166
     * Set the slug attribute.
167
     *
168
     * @param  string  $slug
169
     */
170 66
    public function setSlugAttribute($slug)
171
    {
172 66
        $this->attributes['slug'] = $this->slugify($slug);
173 66
    }
174
175
    /* ------------------------------------------------------------------------------------------------
176
     |  CRUD Functions
177
     | ------------------------------------------------------------------------------------------------
178
     */
179
180
    /**
181
     * Activate the model.
182
     *
183
     * @param  bool  $save
184
     *
185
     * @return bool
186
     */
187 2
    public function activate($save = true)
188
    {
189 2
        return $this->switchActive(true, $save);
190
    }
191
192
    /**
193
     * Deactivate the model.
194
     *
195
     * @param  bool  $save
196
     *
197
     * @return bool
198
     */
199 4
    public function deactivate($save = true)
200
    {
201 4
        return $this->switchActive(false, $save);
202
    }
203
204
    /**
205
     * Attach a permission to a role.
206
     *
207
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $user
208
     * @param  bool                                        $reload
209
     */
210 6
    public function attachUser($user, $reload = true)
211
    {
212 6
        if ($this->hasUser($user)) return;
213
214 6
        event(new AttachingUserToRole($this, $user));
215 6
        $this->users()->attach($user);
216 6
        event(new AttachedUserToRole($this, $user));
217
218 6
        $this->loadUsers($reload);
219 6
    }
220
221
    // TODO: Adding attach multiple users to a role ?
222
223
    /**
224
     * Detach a user from a role.
225
     *
226
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $user
227
     * @param  bool                                        $reload
228
     *
229
     * @return int
230
     */
231 2
    public function detachUser($user, $reload = true)
232
    {
233 2
        event(new DetachingUserFromRole($this, $user));
234 2
        $results = $this->users()->detach($user);
235 2
        event(new DetachedUserFromRole($this, $user, $results));
236
237 2
        $this->loadUsers($reload);
238
239 2
        return $results;
240
    }
241
242
    // TODO: Adding detach multiple users to a role ?
243
244
    /**
245
     * Detach all users from a role.
246
     *
247
     * @param  bool  $reload
248
     *
249
     * @return int
250
     */
251 4
    public function detachAllUsers($reload = true)
252
    {
253 4
        event(new DetachingAllUsersFromRole($this));
254 4
        $results = $this->users()->detach();
255 4
        event(new DetachedAllUsersFromRole($this, $results));
256
257 4
        $this->loadUsers($reload);
258
259 4
        return $results;
260
    }
261
262
    /**
263
     * Attach a permission to a role.
264
     *
265
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $permission
266
     * @param  bool                                              $reload
267
     */
268 18
    public function attachPermission($permission, $reload = true)
269
    {
270 18
        if ($this->hasPermission($permission)) return;
271
272 18
        event(new AttachingPermissionToRole($this, $permission));
273 18
        $this->permissions()->attach($permission);
274 18
        event(new AttachedPermissionToRole($this, $permission));
275
276 18
        $this->loadPermissions($reload);
277 18
    }
278
279
    // TODO: Adding attach multiple permissions to a role ?
280
281
    /**
282
     * Detach a permission from a role.
283
     *
284
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $permission
285
     * @param  bool                                              $reload
286
     *
287
     * @return int
288
     */
289 2
    public function detachPermission($permission, $reload = true)
290
    {
291 2
        if ( ! $this->hasPermission($permission)) return 0;
292
293 2
        event(new DetachingPermissionFromRole($this, $permission));
294 2
        $results = $this->permissions()->detach($permission);
295 2
        event(new DetachedPermissionFromRole($this, $permission, $results));
296
297 2
        $this->loadPermissions($reload);
298
299 2
        return $results;
300
    }
301
302
    // TODO: Adding detach multiple permissions to a role ?
303
304
    /**
305
     * Detach all permissions from a role.
306
     *
307
     * @param  bool  $reload
308
     *
309
     * @return int
310
     */
311 4
    public function detachAllPermissions($reload = true)
312
    {
313 4
        if ($this->permissions->isEmpty()) return 0;
314
315 2
        event(new DetachingAllPermissionsFromRole($this));
316 2
        $results = $this->permissions()->detach();
317 2
        event(new DetachedAllPermissionsFromRole($this, $results));
318
319 2
        $this->loadPermissions($reload);
320
321 2
        return $results;
322
    }
323
324
    /* -----------------------------------------------------------------
325
     |  Check Methods
326
     | -----------------------------------------------------------------
327
     */
328
329
    /**
330
     * Check if role has the given user (User Model or Id).
331
     *
332
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $id
333
     *
334
     * @return bool
335
     */
336 6
    public function hasUser($id)
337
    {
338 6
        if ($id instanceof Eloquent) $id = $id->getKey();
339
340 6
        return $this->users->contains('id', $id);
341
    }
342
343
    /**
344
     * Check if role has the given permission (Permission Model or Id).
345
     *
346
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $id
347
     *
348
     * @return bool
349
     */
350 18
    public function hasPermission($id)
351
    {
352 18
        if ($id instanceof Eloquent) $id = $id->getKey();
353
354 18
        return $this->permissions->contains('id', $id);
355
    }
356
357
    /**
358
     * Check if role is associated with a permission by slug.
359
     *
360
     * @param  string  $slug
361
     *
362
     * @return bool
363
     */
364 6
    public function can($slug)
365
    {
366 6
        if ( ! $this->isActive()) return false;
367
368 6
        return $this->permissions->filter->hasSlug($slug)->first() !== null;
369
    }
370
371
    /**
372
     * Check if a role is associated with any of given permissions.
373
     *
374
     * @param  \Illuminate\Support\Collection|array  $permissions
375
     * @param  \Illuminate\Support\Collection        &$failed
376
     *
377
     * @return bool
378
     */
379 4
    public function canAny($permissions, &$failed = null)
380
    {
381 4
        $permissions = is_array($permissions) ? collect($permissions) : $permissions;
382
383 4
        $failed = $permissions->reject(function ($permission) {
384 4
            return $this->can($permission);
385 4
        })->values();
386
387 4
        return $permissions->count() !== $failed->count();
388
    }
389
390
    /**
391
     * Check if role is associated with all given permissions.
392
     *
393
     * @param  \Illuminate\Support\Collection|array  $permissions
394
     * @param  \Illuminate\Support\Collection        &$failed
395
     *
396
     * @return bool
397
     */
398 2
    public function canAll($permissions, &$failed = null)
399
    {
400 2
        $this->canAny($permissions, $failed);
401
402 2
        return $failed->isEmpty();
403
    }
404
405
    /**
406
     * Check if the role is locked.
407
     *
408
     * @return bool
409
     */
410 4
    public function isLocked()
411
    {
412 4
        return $this->is_locked;
413
    }
414
415
    /**
416
     * Check if slug is the same as the given value.
417
     *
418
     * @param  string  $value
419
     *
420
     * @return bool
421
     */
422 14
    public function hasSlug($value)
423
    {
424 14
        return $this->slug === $this->slugify($value);
425
    }
426
427
    /* -----------------------------------------------------------------
428
     |  Other Methods
429
     | -----------------------------------------------------------------
430
     */
431
432
    /**
433
     * Load the users.
434
     *
435
     * @param  bool  $load
436
     *
437
     * @return self
438
     */
439 8
    protected function loadUsers($load = true)
440
    {
441 8
        return $load ? $this->load('users') : $this;
442
    }
443
444
    /**
445
     * Load the permissions.
446
     *
447
     * @param  bool  $load
448
     *
449
     * @return self
450
     */
451 18
    protected function loadPermissions($load = true)
452
    {
453 18
        return $load ? $this->load('permissions') : $this;
454
    }
455
456
    /**
457
     * Slugify the value.
458
     *
459
     * @param  string  $value
460
     *
461
     * @return string
462
     */
463 66
    protected function slugify($value)
464
    {
465 66
        return Str::slug($value, config('laravel-auth.roles.slug-separator', '-'));
466
    }
467
}
468