UserAccess   A
last analyzed

Complexity

Total Complexity 42

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 42
eloc 65
dl 0
loc 251
rs 9.0399
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A hasPermission() 0 3 1
A detachRoles() 0 4 2
A attachRoles() 0 4 2
A hasPermissions() 0 3 1
A attachRole() 0 11 3
A hasCredential() 0 7 3
A hasRole() 0 22 6
A detachRole() 0 11 3
B hasRoles() 0 29 7

How to fix   Complexity   

Complex Class

Complex classes like UserAccess often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use UserAccess, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace App\Models\Access\User\Traits;
4
5
/**
6
 * Class UserAccess.
7
 */
8
trait UserAccess
9
{
10
    /**
11
     * Checks if the user has a Role by its name or id.
12
     *
13
     * @param string $nameOrId role name or id
14
     *
15
     * @return bool
16
     */
17
    public function hasRole($nameOrId)
18
    {
19
        foreach ($this->roles as $role) {
20
            //See if role has all permissions
21
            if ($role->all) {
22
                return true;
23
            }
24
25
            //First check to see if it's an ID
26
            if (is_numeric($nameOrId)) {
27
                if ($role->id == $nameOrId) {
28
                    return true;
29
                }
30
            }
31
32
            //Otherwise check by name
33
            if ($role->name == $nameOrId) {
34
                return true;
35
            }
36
        }
37
38
        return false;
39
    }
40
41
    /**
42
     * Checks to see if user has array of roles.
43
     * All must return true.
44
     *
45
     * @param  $roles
46
     * @param  $needsAll
47
     *
48
     * @return bool
49
     */
50
    public function hasRoles($roles, $needsAll = false)
51
    {
52
        //If not an array, make a one item array
53
        if (! is_array($roles)) {
54
            $roles = [$roles];
55
        }
56
57
        //User has to possess all of the roles specified
58
        if ($needsAll) {
59
            $hasRoles = 0;
60
            $numRoles = count($roles);
61
62
            foreach ($roles as $role) {
63
                if ($this->hasRole($role)) {
64
                    $hasRoles++;
65
                }
66
            }
67
68
            return $numRoles == $hasRoles;
69
        }
70
71
        //User has to possess one of the roles specified
72
        foreach ($roles as $role) {
73
            if ($this->hasRole($role)) {
74
                return true;
75
            }
76
        }
77
78
        return false;
79
    }
80
81
    /**
82
     * Check if user has a permission by its name or id.
83
     *
84
     * @param string $nameOrId permission name or id
85
     *
86
     * @return bool
87
     */
88
    public function allow($nameOrId)
89
    {
90
        foreach ($this->roles as $role) {
91
            // See if role has all permissions
92
            if ($role->all) {
93
                return true;
94
            }
95
96
            // Validate against the Permission table
97
            foreach ($role->permissions as $perm) {
98
99
                // First check to see if it's an ID
100
                if (is_numeric($nameOrId)) {
101
                    if ($perm->id == $nameOrId) {
102
                        return true;
103
                    }
104
                }
105
106
                // Otherwise check by name
107
                if ($perm->name == $nameOrId) {
108
                    return true;
109
                }
110
            }
111
        }
112
113
        return false;
114
    }
115
116
    /**
117
     * Check an array of permissions and whether or not all are required to continue.
118
     *
119
     * @param  $permissions
120
     * @param  $needsAll
121
     *
122
     * @return bool
123
     */
124
    public function allowMultiple($permissions, $needsAll = false)
125
    {
126
        //If not an array, make a one item array
127
        if (! is_array($permissions)) {
128
            $permissions = [$permissions];
129
        }
130
131
        //User has to possess all of the permissions specified
132
        if ($needsAll) {
133
            $hasPermissions = 0;
134
            $numPermissions = count($permissions);
135
136
            foreach ($permissions as $perm) {
137
                if ($this->allow($perm)) {
138
                    $hasPermissions++;
139
                }
140
            }
141
142
            return $numPermissions == $hasPermissions;
143
        }
144
145
        //User has to possess one of the permissions specified
146
        foreach ($permissions as $perm) {
147
            if ($this->allow($perm)) {
148
                return true;
149
            }
150
        }
151
152
        return false;
153
    }
154
155
    /**
156
     * @param  $nameOrId
157
     *
158
     * @return bool
159
     */
160
    public function hasPermission($nameOrId)
161
    {
162
        return $this->allow($nameOrId);
163
    }
164
165
    /**
166
     * @param      $permissions
167
     * @param bool $needsAll
168
     *
169
     * @return bool
170
     */
171
    public function hasPermissions($permissions, $needsAll = false)
172
    {
173
        return $this->allowMultiple($permissions, $needsAll);
174
    }
175
176
    /**
177
     * Alias to eloquent many-to-many relation's attach() method.
178
     *
179
     * @param mixed $role
180
     *
181
     * @return void
182
     */
183
    public function attachRole($role): void
184
    {
185
        if (is_object($role)) {
186
            $role = $role->getKey();
187
        }
188
189
        if (is_array($role)) {
190
            $role = $role['id'];
191
        }
192
193
        $this->roles()->attach($role);
0 ignored issues
show
Bug introduced by
It seems like roles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

193
        $this->/** @scrutinizer ignore-call */ 
194
               roles()->attach($role);
Loading history...
194
    }
195
196
    /**
197
     * Alias to eloquent many-to-many relation's detach() method.
198
     *
199
     * @param mixed $role
200
     *
201
     * @return void
202
     */
203
    public function detachRole($role)
204
    {
205
        if (is_object($role)) {
206
            $role = $role->getKey();
207
        }
208
209
        if (is_array($role)) {
210
            $role = $role['id'];
211
        }
212
213
        $this->roles()->detach($role);
214
    }
215
216
    /**
217
     * Attach multiple roles to a user.
218
     *
219
     * @param mixed $roles
220
     *
221
     * @return void
222
     */
223
    public function attachRoles($roles)
224
    {
225
        foreach ($roles as $role) {
226
            $this->attachRole($role);
227
        }
228
    }
229
230
    /**
231
     * Detach multiple roles from a user.
232
     *
233
     * @param mixed $roles
234
     *
235
     * @return void
236
     */
237
    public function detachRoles($roles)
238
    {
239
        foreach ($roles as $role) {
240
            $this->detachRole($role);
241
        }
242
    }
243
244
    /**
245
     * This is an alias for hasRoles.
246
     *
247
     * @param      $credentials
248
     * @param bool $needsAll
249
     *
250
     * @return bool
251
     */
252
    public function hasCredential($credentials, $needsAll = false)
253
    {
254
        if (is_array($credentials) && is_array($credentials[0])) {
255
            $credentials = $credentials[0];
256
        }
257
258
        return $this->hasRoles($credentials, $needsAll);
259
    }
260
}
261