Completed
Push — master ( 4d8dce...e624ea )
by ARCANEDEV
13s
created

PermissionsGroup   B

Complexity

Total Complexity 23

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 16

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 23
c 0
b 0
f 0
lcom 2
cbo 16
dl 0
loc 316
ccs 78
cts 78
cp 1
rs 8.4614

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A permissions() 0 7 1
A setNameAttribute() 0 5 1
A setSlugAttribute() 0 4 1
A createPermission() 0 6 1
A attachPermission() 0 10 2
A attachPermissionById() 0 9 2
A attachPermissions() 0 10 1
A detachPermission() 0 14 2
A detachPermissionById() 0 7 2
A detachPermissions() 0 10 1
A detachAllPermissions() 0 10 1
A hasPermission() 0 6 2
A getPermissionFromGroup() 0 12 2
A getPermissionById() 0 4 1
A loadPermissions() 0 4 2
1
<?php namespace Arcanedev\LaravelAuth\Models;
2
3
use Arcanedev\LaravelAuth\Events\PermissionsGroups\AttachedPermissionsToGroup;
4
use Arcanedev\LaravelAuth\Events\PermissionsGroups\AttachedPermissionToGroup;
5
use Arcanedev\LaravelAuth\Events\PermissionsGroups\AttachingPermissionsToGroup;
6
use Arcanedev\LaravelAuth\Events\PermissionsGroups\AttachingPermissionToGroup;
7
use Arcanedev\LaravelAuth\Events\PermissionsGroups\CreatedPermissionsGroup;
8
use Arcanedev\LaravelAuth\Events\PermissionsGroups\CreatingPermissionsGroup;
9
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DeletedPermissionsGroup;
10
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DeletingPermissionsGroup;
11
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachedAllPermissions;
12
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachedPermissionFromGroup;
13
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachedPermissionsFromGroup;
14
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachingAllPermissions;
15
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachingPermissionFromGroup;
16
use Arcanedev\LaravelAuth\Events\PermissionsGroups\DetachingPermissionsFromGroup;
17
use Arcanedev\LaravelAuth\Events\PermissionsGroups\SavedPermissionsGroup;
18
use Arcanedev\LaravelAuth\Events\PermissionsGroups\SavingPermissionsGroup;
19
use Arcanedev\LaravelAuth\Events\PermissionsGroups\UpdatedPermissionsGroup;
20
use Arcanedev\LaravelAuth\Events\PermissionsGroups\UpdatingPermissionsGroup;
21
use Arcanesoft\Contracts\Auth\Models\Permission as PermissionContract;
22
use Arcanesoft\Contracts\Auth\Models\PermissionsGroup as PermissionsGroupContract;
23
use Illuminate\Database\Eloquent\Model as Eloquent;
24
use Illuminate\Support\Str;
25
26
/**
27
 * Class     PermissionsGroup
28
 *
29
 * @package  Arcanedev\LaravelAuth\Models
30
 * @author   ARCANEDEV <[email protected]>
31
 *
32
 * @property  int                                       id
33
 * @property  string                                    name
34
 * @property  string                                    slug
35
 * @property  string                                    description
36
 * @property  \Carbon\Carbon                            created_at
37
 * @property  \Carbon\Carbon                            updated_at
38
 * @property  \Illuminate\Database\Eloquent\Collection  permissions
39
 */
40
class PermissionsGroup extends AbstractModel implements PermissionsGroupContract
41
{
42
    /* -----------------------------------------------------------------
43
     |  Properties
44
     | -----------------------------------------------------------------
45
     */
46
47
    /**
48
     * The attributes that are mass assignable.
49
     *
50
     * @var array
51
     */
52
    protected $fillable = ['name', 'slug', 'description'];
53
54
    /**
55
     * The event map for the model.
56
     *
57
     * @var array
58
     */
59
    protected $dispatchesEvents = [
60
        'creating' => CreatingPermissionsGroup::class,
61
        'created'  => CreatedPermissionsGroup::class,
62
        'updating' => UpdatingPermissionsGroup::class,
63
        'updated'  => UpdatedPermissionsGroup::class,
64
        'saving'   => SavingPermissionsGroup::class,
65
        'saved'    => SavedPermissionsGroup::class,
66
        'deleting' => DeletingPermissionsGroup::class,
67
        'deleted'  => DeletedPermissionsGroup::class,
68
    ];
69
70
    /**
71
     * The attributes that should be cast to native types.
72
     *
73
     * @var array
74
     */
75
    protected $casts = [
76
        'id' => 'integer',
77
    ];
78
79
    /* -----------------------------------------------------------------
80
     |  Constructor
81
     | -----------------------------------------------------------------
82
     */
83
84
    /**
85
     * Create a new Eloquent model instance.
86
     *
87
     * @param  array  $attributes
88
     */
89 32
    public function __construct(array $attributes = [])
90
    {
91 32
        parent::__construct($attributes);
92
93 32
        $this->setTable(
94 32
            config('laravel-auth.permissions-groups.table', 'permissions_groups')
95
        );
96 32
    }
97
98
    /* -----------------------------------------------------------------
99
     |  Relationships
100
     | -----------------------------------------------------------------
101
     */
102
103
    /**
104
     * Permissions Groups has many permissions.
105
     *
106
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
107
     */
108 26
    public function permissions()
109
    {
110 26
        return $this->hasMany(
111 26
            config('laravel-auth.permissions.model', Permission::class),
112 26
            'group_id'
113
        );
114
    }
115
116
    /* -----------------------------------------------------------------
117
     |  Getters & Setters
118
     | -----------------------------------------------------------------
119
     */
120
121
    /**
122
     * Set the name attribute.
123
     *
124
     * @param  string  $name
125
     */
126 26
    public function setNameAttribute($name)
127
    {
128 26
        $this->attributes['name'] = $name;
129 26
        $this->setSlugAttribute($name);
130 26
    }
131
132
    /**
133
     * Set the slug attribute.
134
     *
135
     * @param  string  $slug
136
     */
137 26
    public function setSlugAttribute($slug)
138
    {
139 26
        $this->attributes['slug'] = Str::slug($slug, config('laravel-auth.permissions-groups.slug-separator', '-'));
140 26
    }
141
142
    /* -----------------------------------------------------------------
143
     |  Main Methods
144
     | -----------------------------------------------------------------
145
     */
146
147
    /**
148
     * Create and attach a permission.
149
     *
150
     * @param  array  $attributes
151
     * @param  bool   $reload
152
     */
153 4
    public function createPermission(array $attributes, $reload = true)
154
    {
155 4
        $this->permissions()->create($attributes);
156
157 4
        $this->loadPermissions($reload);
158 4
    }
159
160
    /**
161
     * Attach the permission to a group.
162
     *
163
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission  $permission
164
     * @param  bool                                          $reload
165
     */
166 12
    public function attachPermission(&$permission, $reload = true)
167
    {
168 12
        if ($this->hasPermission($permission)) return;
169
170 12
        event(new AttachingPermissionToGroup($this, $permission));
171 12
        $permission = $this->permissions()->save($permission);
0 ignored issues
show
Compatibility introduced by
$permission of type object<Arcanesoft\Contra...Auth\Models\Permission> is not a sub-type of object<Illuminate\Database\Eloquent\Model>. It seems like you assume a concrete implementation of the interface Arcanesoft\Contracts\Auth\Models\Permission to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
172 12
        event(new AttachedPermissionToGroup($this, $permission));
0 ignored issues
show
Security Bug introduced by
It seems like $permission defined by $this->permissions()->save($permission) on line 171 can also be of type false; however, Arcanedev\LaravelAuth\Ev...nToGroup::__construct() does only seem to accept object<Arcanesoft\Contra...Auth\Models\Permission>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
173
174 12
        $this->loadPermissions($reload);
175 12
    }
176
177
    /**
178
     * Attach the permission by id to a group.
179
     *
180
     * @param  int   $id
181
     * @param  bool  $reload
182
     *
183
     * @return \Arcanesoft\Contracts\Auth\Models\Permission|null
184
     */
185 2
    public function attachPermissionById($id, $reload = true)
186
    {
187 2
        $permission = $this->getPermissionById($id);
188
189 2
        if ($permission !== null)
190 2
            $this->attachPermission($permission, $reload);
191
192 2
        return $permission;
193
    }
194
195
    /**
196
     * Attach a collection of permissions to the group.
197
     *
198
     * @param  \Illuminate\Database\Eloquent\Collection|array  $permissions
199
     * @param  bool                                            $reload
200
     *
201
     * @return \Illuminate\Database\Eloquent\Collection|array
202
     */
203 6
    public function attachPermissions($permissions, $reload = true)
204
    {
205 6
        event(new AttachingPermissionsToGroup($this, $permissions));
206 6
        $permissions = $this->permissions()->saveMany($permissions);
207 6
        event(new AttachedPermissionsToGroup($this, $permissions));
0 ignored issues
show
Bug introduced by
It seems like $permissions defined by $this->permissions()->saveMany($permissions) on line 206 can also be of type object<Traversable>; however, Arcanedev\LaravelAuth\Ev...sToGroup::__construct() does only seem to accept object<Illuminate\Support\Collection>|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
208
209 6
        $this->loadPermissions($reload);
210
211 6
        return $permissions;
212
    }
213
214
    /**
215
     * Attach the permission from a group.
216
     *
217
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission  $permission
218
     * @param  bool                                          $reload
219
     */
220 6
    public function detachPermission(&$permission, $reload = true)
221
    {
222 6
        if ( ! $this->hasPermission($permission))
223 4
            return;
224
225
        /** @var  \Arcanesoft\Contracts\Auth\Models\Permission  $permission */
226 6
        $permission = $this->getPermissionFromGroup($permission);
227
228 6
        event(new DetachingPermissionFromGroup($this, $permission));
229 6
        $permission->update(['group_id' => 0]);
230 6
        event(new DetachedPermissionFromGroup($this, $permission));
231
232 6
        $this->loadPermissions($reload);
233 6
    }
234
235
    /**
236
     * Attach the permission by id to a group.
237
     *
238
     * @param  int   $id
239
     * @param  bool  $reload
240
     *
241
     * @return \Arcanesoft\Contracts\Auth\Models\Permission
242
     */
243 2
    public function detachPermissionById($id, $reload = true)
244
    {
245 2
        if ( ! is_null($permission = $this->getPermissionById($id)))
246 2
            $this->detachPermission($permission, $reload);
247
248 2
        return $permission;
249
    }
250
251
    /**
252
     * Detach multiple permissions by ids.
253
     *
254
     * @param  array  $ids
255
     * @param  bool   $reload
256
     *
257
     * @return int
258
     */
259 2
    public function detachPermissions(array $ids, $reload = true)
260
    {
261 2
        event(new DetachingPermissionsFromGroup($this, $ids));
262 2
        $detached = $this->permissions()->whereIn('id', $ids)->update(['group_id' => 0]);
263 2
        event(new DetachedPermissionsFromGroup($this, $ids, $detached));
264
265 2
        $this->loadPermissions($reload);
266
267 2
        return $detached;
268
    }
269
270
    /**
271
     * Detach all permissions from the group.
272
     *
273
     * @param  bool  $reload
274
     *
275
     * @return int
276
     */
277 4
    public function detachAllPermissions($reload = true)
278
    {
279 4
        event(new DetachingAllPermissions($this));
280 4
        $detached = $this->permissions()->update(['group_id' => 0]);
281 4
        event(new DetachedAllPermissions($this, $detached));
282
283 4
        $this->loadPermissions($reload);
284
285 4
        return $detached;
286
    }
287
288
    /* -----------------------------------------------------------------
289
     |  Check Methods
290
     | -----------------------------------------------------------------
291
     */
292
293
    /**
294
     * Check if role has the given permission (Permission Model or Id).
295
     *
296
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $id
297
     *
298
     * @return bool
299
     */
300 16
    public function hasPermission($id)
301
    {
302 16
        if ($id instanceof Eloquent) $id = $id->getKey();
303
304 16
        return $this->getPermissionFromGroup($id) !== null;
305
    }
306
307
    /* -----------------------------------------------------------------
308
     |  Other Methods
309
     | -----------------------------------------------------------------
310
     */
311
312
    /**
313
     * Get a permission from the group.
314
     *
315
     * @param  \Arcanesoft\Contracts\Auth\Models\Permission|int  $id
316
     *
317
     * @return \Arcanesoft\Contracts\Auth\Models\Permission|null
318
     */
319 16
    private function getPermissionFromGroup($id)
320
    {
321 16
        if ($id instanceof Eloquent) $id = $id->getKey();
322
323 16
        $this->loadPermissions();
324
325 16
        return $this->permissions
326 16
            ->filter(function (PermissionContract $permission) use ($id) {
327 16
                return $permission->getKey() == $id;
328 16
            })
329 16
            ->first();
330
    }
331
332
    /**
333
     * Get a permission by id.
334
     *
335
     * @param  int  $id
336
     *
337
     * @return \Arcanesoft\Contracts\Auth\Models\Permission|null
338
     */
339 4
    private function getPermissionById($id)
340
    {
341 4
        return $this->permissions()->getRelated()->where('id', $id)->first();
342
    }
343
344
    /**
345
     * Load the permissions.
346
     *
347
     * @param  bool  $load
348
     *
349
     * @return self
350
     */
351 22
    protected function loadPermissions($load = true)
352
    {
353 22
        return $load ? $this->load('permissions') : $this;
354
    }
355
}
356