Completed
Pull Request — master (#23)
by ARCANEDEV
07:46
created

Role::users()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 10
c 0
b 0
f 0
ccs 6
cts 6
cp 1
rs 9.4285
cc 1
eloc 7
nc 1
nop 0
crap 1
1
<?php namespace Arcanedev\LaravelAuth\Models;
2
3
use Arcanedev\LaravelAuth\Bases\Model;
4
use Arcanedev\LaravelAuth\Models\Traits\Activatable;
5
use Arcanesoft\Contracts\Auth\Models\Permission as PermissionContract;
6
use Arcanesoft\Contracts\Auth\Models\Role as RoleContract;
7
use Illuminate\Database\Eloquent\Model as Eloquent;
8
use Illuminate\Support\Str;
9
10
/**
11
 * Class     Role
12
 *
13
 * @package  Arcanedev\LaravelAuth\Models
14
 * @author   ARCANEDEV <[email protected]>
15
 *
16
 * @property  int                                       id
17
 * @property  string                                    name
18
 * @property  string                                    slug
19
 * @property  string                                    description
20
 * @property  bool                                      is_active
21
 * @property  bool                                      is_locked
22
 * @property  \Carbon\Carbon                            created_at
23
 * @property  \Carbon\Carbon                            updated_at
24
 *
25
 * @property  \Illuminate\Database\Eloquent\Collection       users
26
 * @property  \Illuminate\Database\Eloquent\Collection       permissions
27
 *
28
 * @property  \Arcanedev\LaravelAuth\Models\Pivots\RoleUser|\Arcanedev\LaravelAuth\Models\Pivots\PermissionRole  pivot
29
 */
30
class Role extends Model implements RoleContract
31
{
32
    /* ------------------------------------------------------------------------------------------------
33
     |  Traits
34
     | ------------------------------------------------------------------------------------------------
35
     */
36
    use Activatable;
37
38
    /* ------------------------------------------------------------------------------------------------
39
     |  Properties
40
     | ------------------------------------------------------------------------------------------------
41
     */
42
    /**
43
     * The attributes that are mass assignable.
44
     *
45
     * @var array
46
     */
47
    protected $fillable = ['name', 'slug', 'description'];
48
49
    /**
50
     * The attributes that should be casted to native types.
51
     *
52
     * @var array
53
     */
54
    protected $casts = [
55
        'is_active' => 'boolean',
56
        'is_locked' => 'boolean',
57
    ];
58
59
    /* ------------------------------------------------------------------------------------------------
60
     |  Constructor
61
     | ------------------------------------------------------------------------------------------------
62
     */
63
    /**
64
     * Create a new Eloquent model instance.
65
     *
66
     * @param  array  $attributes
67
     */
68 225
    public function __construct(array $attributes = [])
69
    {
70 225
        $this->setTable(config('laravel-auth.roles.table', 'roles'));
71
72 225
        parent::__construct($attributes);
73 225
    }
74
75
    /* ------------------------------------------------------------------------------------------------
76
     |  Relationships
77
     | ------------------------------------------------------------------------------------------------
78
     */
79
    /**
80
     * Role belongs to many users.
81
     *
82
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
83
     */
84 15
    public function users()
85
    {
86
        return $this
87 15
            ->belongsToMany(
88 15
                config('laravel-auth.users.model', User::class),
89 15
                $this->getPrefix().config('laravel-auth.role-user.table', 'permission_role')
90
            )
91 15
            ->using(Pivots\RoleUser::class)
92 15
            ->withTimestamps();
93
    }
94
95
    /**
96
     * Role belongs to many permissions.
97
     *
98
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
99
     */
100 33
    public function permissions()
101
    {
102
        return $this
103 33
            ->belongsToMany(
104 33
                config('laravel-auth.permissions.model', Permission::class),
105 33
                $this->getPrefix().config('laravel-auth.permission-role.table', 'permission_role')
106
            )
107 33
            ->using(Pivots\PermissionRole::class)
108 33
            ->withTimestamps();
109
    }
110
111
    /* ------------------------------------------------------------------------------------------------
112
     |  Getters & Setters
113
     | ------------------------------------------------------------------------------------------------
114
     */
115
    /**
116
     * Set the name attribute.
117
     *
118
     * @param  string  $name
119
     */
120 90
    public function setNameAttribute($name)
121
    {
122 90
        $this->attributes['name'] = $name;
123 90
        $this->setSlugAttribute($name);
124 90
    }
125
126
    /**
127
     * Set the slug attribute.
128
     *
129
     * @param  string  $slug
130
     */
131 90
    public function setSlugAttribute($slug)
132
    {
133 90
        $this->attributes['slug'] = $this->slugify($slug);
134 90
    }
135
136
    /* ------------------------------------------------------------------------------------------------
137
     |  CRUD Functions
138
     | ------------------------------------------------------------------------------------------------
139
     */
140
    /**
141
     * Attach a permission to a role.
142
     *
143
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $user
144
     * @param  bool                                        $reload
145
     */
146 9
    public function attachUser($user, $reload = true)
147
    {
148 9
        if ( ! $this->hasUser($user)) {
149 9
            $this->users()->attach($user);
150 9
            $this->loadUsers($reload);
151
        }
152 9
    }
153
154
    /**
155
     * Detach a user from a role.
156
     *
157
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $user
158
     * @param  bool                                        $reload
159
     *
160
     * @return int
161
     */
162 3
    public function detachUser($user, $reload = true)
163
    {
164 3
        if ($user instanceof Eloquent)
0 ignored issues
show
Bug introduced by
The class Illuminate\Database\Eloquent\Model does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
165 3
            $user = (array) $user->getKey();
166
167 3
        $result = $this->users()->detach($user);
168 3
        $this->loadUsers($reload);
169
170 3
        return $result;
171
    }
172
173
    /**
174
     * Detach all users from a role.
175
     *
176
     * @param  bool  $reload
177
     *
178
     * @return int
179
     */
180 3
    public function detachAllUsers($reload = true)
181
    {
182 3
        $result = $this->users()->detach();
183 3
        $this->loadUsers($reload);
184
185 3
        return $result;
186
    }
187
188
    /**
189
     * Check if role has the given user (User Model or Id).
190
     *
191
     * @param  \Arcanesoft\Contracts\Auth\Models\User|int  $id
192
     *
193
     * @return bool
194
     */
195 9
    public function hasUser($id)
196
    {
197 9
        if ($id instanceof Eloquent)
0 ignored issues
show
Bug introduced by
The class Illuminate\Database\Eloquent\Model does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
198 9
            $id = $id->getKey();
199
200 9
        return $this->users->contains($id);
201
    }
202
203
    /**
204
     * Attach a permission to a role.
205
     *
206
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $permission
207
     * @param  bool                                              $reload
208
     */
209 27
    public function attachPermission($permission, $reload = true)
210
    {
211 27
        if ( ! $this->hasPermission($permission)) {
212 27
            $this->permissions()->attach($permission);
213 27
            $this->loadPermissions($reload);
214
        }
215 27
    }
216
217
    /**
218
     * Detach a permission from a role.
219
     *
220
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $permission
221
     * @param  bool                                              $reload
222
     *
223
     * @return int
224
     */
225 3
    public function detachPermission($permission, $reload = true)
226
    {
227 3
        if ($permission instanceof Eloquent)
0 ignored issues
show
Bug introduced by
The class Illuminate\Database\Eloquent\Model does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
228 3
            $permission = (array) $permission->getKey();
229
230 3
        $result = $this->permissions()->detach($permission);
231 3
        $this->loadPermissions($reload);
232
233 3
        return $result;
234
    }
235
236
    /**
237
     * Detach all permissions from a role.
238
     *
239
     * @param  bool  $reload
240
     *
241
     * @return int
242
     */
243 3
    public function detachAllPermissions($reload = true)
244
    {
245 3
        $result = $this->permissions()->detach();
246 3
        $this->loadPermissions($reload);
247
248 3
        return $result;
249
    }
250
251
    /**
252
     * Check if role has the given permission (Permission Model or Id).
253
     *
254
     * @param  mixed  $id
255
     *
256
     * @return bool
257
     */
258 27
    public function hasPermission($id)
259
    {
260 27
        if ($id instanceof Eloquent)
0 ignored issues
show
Bug introduced by
The class Illuminate\Database\Eloquent\Model does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
261 27
            $id = $id->getKey();
262
263 27
        return $this->permissions->contains($id);
264
    }
265
266
    /* ------------------------------------------------------------------------------------------------
267
     |  Check Functions
268
     | ------------------------------------------------------------------------------------------------
269
     */
270
    /**
271
     * Check if role is associated with a permission by slug.
272
     *
273
     * @param  string  $slug
274
     *
275
     * @return bool
276
     */
277
    public function can($slug)
278
    {
279 9
        $permissions = $this->permissions->filter(function(PermissionContract $permission) use ($slug) {
280 9
            return $permission->checkSlug($slug);
281 9
        });
282
283 9
        return $permissions->count() === 1;
284
    }
285
286
    /**
287
     * Check if a role is associated with any of given permissions.
288
     *
289
     * @param  array  $permissions
290
     * @param  array  &$failedPermissions
291
     *
292
     * @return bool
293
     */
294 6
    public function canAny(array $permissions, array &$failedPermissions = [])
295
    {
296 6
        foreach ($permissions as $permission) {
297 6
            if ( ! $this->can($permission))
298 6
                $failedPermissions[] = $permission;
299
        }
300
301 6
        return count($permissions) !== count($failedPermissions);
302
    }
303
304
    /**
305
     * Check if role is associated with all given permissions.
306
     *
307
     * @param  array  $permissions
308
     * @param  array  &$failedPermissions
309
     *
310
     * @return bool
311
     */
312 3
    public function canAll(array $permissions, array &$failedPermissions = [])
313
    {
314 3
        $this->canAny($permissions, $failedPermissions);
315
316 3
        return count($failedPermissions) === 0;
317
    }
318
319
    /**
320
     * Check if the role is locked.
321
     *
322
     * @return bool
323
     */
324 6
    public function isLocked()
325
    {
326 6
        return $this->is_locked;
327
    }
328
329
    /**
330
     * Check if slug is the same as the given value.
331
     *
332
     * @param  string  $value
333
     *
334
     * @return bool
335
     */
336 18
    public function checkSlug($value)
337
    {
338 18
        return $this->slug === $this->slugify($value);
339
    }
340
341
    /* ------------------------------------------------------------------------------------------------
342
     |  Other Functions
343
     | ------------------------------------------------------------------------------------------------
344
     */
345
    /**
346
     * Load the users.
347
     *
348
     * @param  bool  $load
349
     *
350
     * @return self
351
     */
352 9
    protected function loadUsers($load = true)
353
    {
354 9
        return $load ? $this->load('users') : $this;
355
    }
356
357
    /**
358
     * Load the permissions.
359
     *
360
     * @param  bool  $load
361
     *
362
     * @return self
363
     */
364 27
    protected function loadPermissions($load = true)
365
    {
366 27
        return $load ? $this->load('permissions') : $this;
367
    }
368
369
    /**
370
     * Slugify the value.
371
     *
372
     * @param  string  $value
373
     *
374
     * @return string
375
     */
376 90
    protected function slugify($value)
377
    {
378 90
        return Str::slug($value, config('laravel-auth.roles.slug-separator', '-'));
379
    }
380
}
381