Completed
Push — master ( 27aaeb...0eb7b3 )
by wen
03:21
created

EntrustRoleTrait::attachPermission()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 6
nc 4
nop 1
1
<?php
2
3
namespace Sco\Admin\Traits;
4
5
/**
6
 * This file is part of Entrust,
7
 * a role & permission management solution for Laravel.
8
 *
9
 * @license MIT
10
 * @package Zizaco\Entrust
11
 */
12
13
use Illuminate\Cache\TaggableStore;
14
use Illuminate\Support\Facades\Config;
15
use Illuminate\Support\Facades\Cache;
16
17
trait EntrustRoleTrait
18
{
19
    //Big block of caching functionality.
20 View Code Duplication
    public function cachedPermissions()
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
        $rolePrimaryKey = $this->primaryKey;
0 ignored issues
show
Bug introduced by
The property primaryKey does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
23
        $cacheKey       = 'entrust_permissions_for_role_' . $this->$rolePrimaryKey;
24
        if (Cache::getStore() instanceof TaggableStore) {
25
            return Cache::tags(Config::get('admin.permission_role_table'))->remember($cacheKey,
26
                Config::get('cache.ttl', 60), function () {
27
                    return $this->perms()->get();
28
                });
29
        } else {
30
            return $this->perms()->get();
31
        }
32
    }
33
34 View Code Duplication
    public function save(array $options = [])
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...
35
    {   //both inserts and updates
36
        if (!parent::save($options)) {
37
            return false;
38
        }
39
        if (Cache::getStore() instanceof TaggableStore) {
40
            Cache::tags(Config::get('admin.permission_role_table'))->flush();
41
        }
42
        return true;
43
    }
44
45 View Code Duplication
    public function delete(array $options = [])
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...
46
    {   //soft or hard
47
        if (!parent::delete($options)) {
48
            return false;
49
        }
50
        if (Cache::getStore() instanceof TaggableStore) {
51
            Cache::tags(Config::get('admin.permission_role_table'))->flush();
52
        }
53
        return true;
54
    }
55
56 View Code Duplication
    public function restore()
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...
57
    {   //soft delete undo's
58
        if (!parent::restore()) {
59
            return false;
60
        }
61
        if (Cache::getStore() instanceof TaggableStore) {
62
            Cache::tags(Config::get('admin.permission_role_table'))->flush();
63
        }
64
        return true;
65
    }
66
67
    /**
68
     * Many-to-Many relations with the user model.
69
     *
70
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
71
     */
72
    public function users()
73
    {
74
        return $this->belongsToMany(Config::get('admin.user'),
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...
75
            Config::get('admin.role_user_table'),
76
            Config::get('admin.role_foreign_key'),
77
            Config::get('admin.user_foreign_key'));
78
    }
79
80
    /**
81
     * Many-to-Many relations with the permission model.
82
     * Named "perms" for backwards compatibility. Also because "perms" is short
83
     * and sweet.
84
     *
85
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
86
     */
87
    public function perms()
88
    {
89
        return $this->belongsToMany(Config::get('admin.permission'),
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...
90
            Config::get('admin.permission_role_table'),
91
            Config::get('admin.role_foreign_key'),
92
            Config::get('admin.permission_foreign_key'));
93
    }
94
95
    /**
96
     * Boot the role model
97
     * Attach event listener to remove the many-to-many records when trying to
98
     * delete Will NOT delete any records if the role model uses soft deletes.
99
     *
100
     * @return void|bool
101
     */
102
    public static function boot()
103
    {
104
        parent::boot();
105
106
        static::deleting(function ($role) {
107
            if (!method_exists(Config::get('admin.role'),
108
                'bootSoftDeletes')
109
            ) {
110
                $role->users()->sync([]);
111
                $role->perms()->sync([]);
112
            }
113
114
            return true;
115
        });
116
    }
117
118
    /**
119
     * Checks if the role has a permission by its name.
120
     *
121
     * @param string|array $name       Permission name or array of permission
122
     *                                 names.
123
     * @param bool         $requireAll All permissions in the array are
124
     *                                 required.
125
     *
126
     * @return bool
127
     */
128
    public function hasPermission($name, $requireAll = false)
129
    {
130
        if (is_array($name)) {
131
            foreach ($name as $permissionName) {
132
                $hasPermission = $this->hasPermission($permissionName);
133
134
                if ($hasPermission && !$requireAll) {
135
                    return true;
136
                } elseif (!$hasPermission && $requireAll) {
137
                    return false;
138
                }
139
            }
140
141
            // If we've made it this far and $requireAll is FALSE, then NONE of the permissions were found
142
            // If we've made it this far and $requireAll is TRUE, then ALL of the permissions were found.
143
            // Return the value of $requireAll;
144
            return $requireAll;
145
        } else {
146
            foreach ($this->cachedPermissions() as $permission) {
147
                if ($permission->name == $name) {
148
                    return true;
149
                }
150
            }
151
        }
152
153
        return false;
154
    }
155
156
    /**
157
     * Save the inputted permissions.
158
     *
159
     * @param mixed $inputPermissions
160
     *
161
     * @return void
162
     */
163
    public function savePermissions($inputPermissions)
164
    {
165
        if (!empty($inputPermissions)) {
166
            $this->perms()->sync($inputPermissions);
167
        } else {
168
            $this->perms()->detach();
169
        }
170
171
        if (Cache::getStore() instanceof TaggableStore) {
172
            Cache::tags(Config::get('admin.permission_role_table'))->flush();
173
        }
174
    }
175
176
    /**
177
     * Attach permission to current role.
178
     *
179
     * @param object|array $permission
180
     *
181
     * @return void
182
     */
183
    public function attachPermission($permission)
184
    {
185
        if (is_object($permission)) {
186
            $permission = $permission->getKey();
187
        }
188
189
        if (is_array($permission)) {
190
            return $this->attachPermissions($permission);
191
        }
192
193
        $this->perms()->attach($permission);
194
    }
195
196
    /**
197
     * Detach permission from current role.
198
     *
199
     * @param object|array $permission
200
     *
201
     * @return void
202
     */
203
    public function detachPermission($permission)
204
    {
205
        if (is_object($permission)) {
206
            $permission = $permission->getKey();
207
        }
208
209
        if (is_array($permission)) {
210
            return $this->detachPermissions($permission);
211
        }
212
213
        $this->perms()->detach($permission);
214
    }
215
216
    /**
217
     * Attach multiple permissions to current role.
218
     *
219
     * @param mixed $permissions
220
     *
221
     * @return void
222
     */
223
    public function attachPermissions($permissions)
224
    {
225
        foreach ($permissions as $permission) {
226
            $this->attachPermission($permission);
227
        }
228
    }
229
230
    /**
231
     * Detach multiple permissions from current role
232
     *
233
     * @param mixed $permissions
234
     *
235
     * @return void
236
     */
237
    public function detachPermissions($permissions = null)
238
    {
239
        if (!$permissions) {
240
            $permissions = $this->perms()->get();
241
        }
242
243
        foreach ($permissions as $permission) {
244
            $this->detachPermission($permission);
245
        }
246
    }
247
}
248