Completed
Push — master ( 1af3cf...ff825a )
by Arjay
27:57 queued 13:02
created

HasPermission   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 187
Duplicated Lines 16.04 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 15
lcom 2
cbo 2
dl 30
loc 187
ccs 0
cts 48
cp 0
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A grantPermissionBySlug() 11 11 1
A getPermissionClass() 8 8 2
A permissions() 0 4 1
A grantPermissionByResource() 11 11 1
A assignPermission() 0 4 1
A grantPermission() 0 4 1
A syncPermissions() 0 4 1
A revokeAllPermissions() 0 4 1
A can() 0 14 2
A getPermissions() 0 4 1
A canAtLeast() 0 9 1
A revokePermissionBySlug() 0 11 1
A revokePermission() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Yajra\Acl\Traits;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
6
use Yajra\Acl\Models\Permission;
7
8
/**
9
 * @property \Illuminate\Database\Eloquent\Collection permissions
10
 */
11
trait HasPermission
12
{
13
    private $permissionClass;
14
15
    /**
16
     * Grant role permissions by slug(/s).
17
     *
18
     * @param  string|array  $slug
19
     */
20 View Code Duplication
    public function grantPermissionBySlug($slug)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
21
    {
22
        $this->getPermissionClass()
23
            ->newQuery()
24
            ->whereIn('slug', (array) $slug)
25
            ->each(function ($permission) {
26
                $this->permissions()->attach($permission);
27
            });
28
29
        $this->load('permissions');
0 ignored issues
show
Bug introduced by
It seems like load() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
30
    }
31
32
    /**
33
     * Get Permission class.
34
     *
35
     * @return \Yajra\Acl\Models\Permission
36
     */
37 View Code Duplication
    public function getPermissionClass(): Permission
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
    {
39
        if (!isset($this->permissionClass)) {
40
            $this->permissionClass = resolve(config('acl.permission'));
41
        }
42
43
        return $this->permissionClass;
44
    }
45
46
    /**
47
     * Get related permissions.
48
     *
49
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
50
     */
51
    public function permissions(): BelongsToMany
52
    {
53
        return $this->belongsToMany(config('acl.permission', Permission::class))->withTimestamps();
0 ignored issues
show
Bug introduced by
It seems like belongsToMany() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
54
    }
55
56
    /**
57
     * Grant role permissions by resource.
58
     *
59
     * @param  string|array  $resource
60
     */
61 View Code Duplication
    public function grantPermissionByResource($resource)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
62
    {
63
        $this->getPermissionClass()
64
            ->newQuery()
65
            ->whereIn('resource', (array) $resource)
66
            ->each(function ($permission) {
67
                $this->permissions()->attach($permission);
68
            });
69
70
        $this->load('permissions');
0 ignored issues
show
Bug introduced by
It seems like load() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
71
    }
72
73
    /**
74
     * Assigns the given permission to the role.
75
     *
76
     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
77
     * @param  array  $attributes
78
     * @param  bool  $touch
79
     * @return void
80
     * @deprecated Use grantPermission
81
     */
82
    public function assignPermission($ids, array $attributes = [], $touch = true)
83
    {
84
        $this->grantPermission($ids, $attributes, $touch);
85
    }
86
87
    /**
88
     * Assigns the given permission to the role.
89
     *
90
     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
91
     * @param  array  $attributes
92
     * @param  bool  $touch
93
     * @return void
94
     */
95
    public function grantPermission($ids, array $attributes = [], $touch = true)
96
    {
97
        $this->permissions()->attach($ids, $attributes, $touch);
98
    }
99
100
    /**
101
     * Revoke permissions by the given slug(/s).
102
     *
103
     * @param  string|array  $slug
104
     */
105
    public function revokePermissionBySlug($slug)
106
    {
107
        $this->getPermissionClass()
108
            ->newQuery()
109
            ->whereIn('slug', (array) $slug)
110
            ->each(function ($permission) {
111
                $this->revokePermission($permission);
112
            });
113
114
        $this->load('permissions');
0 ignored issues
show
Bug introduced by
It seems like load() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
115
    }
116
117
    /**
118
     * Revokes the given permission from the role.
119
     *
120
     * @param  mixed  $id
121
     * @param  bool  $touch
122
     * @return int
123
     */
124
    public function revokePermission($id = null, $touch = true): int
125
    {
126
        return $this->permissions()->detach($id, $touch);
127
    }
128
129
    /**
130
     * Syncs the given permission(s) with the role.
131
     *
132
     * @param  \Illuminate\Support\Collection|\Illuminate\Database\Eloquent\Model|array  $ids
133
     * @param  bool  $detaching
134
     * @return array
135
     */
136
    public function syncPermissions($ids, $detaching = true): array
137
    {
138
        return $this->permissions()->sync($ids, $detaching);
139
    }
140
141
    /**
142
     * Revokes all permissions from the role.
143
     *
144
     * @return int
145
     */
146
    public function revokeAllPermissions(): int
147
    {
148
        return $this->permissions()->detach();
149
    }
150
151
    /**
152
     * Checks if the role has the given permission.
153
     *
154
     * @param  array|string  $permission
155
     * @return bool
156
     */
157
    public function can($permission): bool
158
    {
159
        $permissions = $this->getPermissions();
160
161
        if (is_array($permission)) {
162
            $permissionCount = count($permission);
163
            $intersection = array_intersect($permissions, $permission);
164
            $intersectionCount = count($intersection);
165
166
            return $permissionCount == $intersectionCount;
167
        }
168
169
        return in_array($permission, $permissions);
170
    }
171
172
    /**
173
     * Get list of permissions slug.
174
     *
175
     * @return array
176
     */
177
    public function getPermissions(): array
178
    {
179
        return $this->permissions->pluck('slug')->toArray();
180
    }
181
182
    /**
183
     * Check if the role has at least one of the given permissions.
184
     *
185
     * @param  array  $permission
186
     * @return bool
187
     */
188
    public function canAtLeast(array $permission = []): bool
189
    {
190
        $permissions = $this->getPermissions();
191
192
        $intersection = array_intersect($permissions, $permission);
193
        $intersectionCount = count($intersection);
194
195
        return $intersectionCount > 0;
196
    }
197
}
198