Completed
Push — master ( 80411a...1281a7 )
by wen
03:35
created

EntrustRoleTrait::boot()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 1
nop 0
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 bootEntrustRoleTrait()
103
    {
104
        static::deleting(function ($role) {
105
            if (!method_exists(Config::get('admin.role'),
106
                'bootSoftDeletes')
107
            ) {
108
                $role->users()->sync([]);
109
                $role->perms()->sync([]);
110
            }
111
112
            return true;
113
        });
114
    }
115
116
    /**
117
     * Checks if the role has a permission by its name.
118
     *
119
     * @param string|array $name       Permission name or array of permission
120
     *                                 names.
121
     * @param bool         $requireAll All permissions in the array are
122
     *                                 required.
123
     *
124
     * @return bool
125
     */
126
    public function hasPermission($name, $requireAll = false)
127
    {
128
        if (is_array($name)) {
129
            foreach ($name as $permissionName) {
130
                $hasPermission = $this->hasPermission($permissionName);
131
132
                if ($hasPermission && !$requireAll) {
133
                    return true;
134
                } elseif (!$hasPermission && $requireAll) {
135
                    return false;
136
                }
137
            }
138
139
            // If we've made it this far and $requireAll is FALSE, then NONE of the permissions were found
140
            // If we've made it this far and $requireAll is TRUE, then ALL of the permissions were found.
141
            // Return the value of $requireAll;
142
            return $requireAll;
143
        } else {
144
            foreach ($this->cachedPermissions() as $permission) {
145
                if ($permission->name == $name) {
146
                    return true;
147
                }
148
            }
149
        }
150
151
        return false;
152
    }
153
154
    /**
155
     * Save the inputted permissions.
156
     *
157
     * @param mixed $inputPermissions
158
     *
159
     * @return void
160
     */
161
    public function savePermissions($inputPermissions)
162
    {
163
        if (!empty($inputPermissions)) {
164
            $this->perms()->sync($inputPermissions);
165
        } else {
166
            $this->perms()->detach();
167
        }
168
169
        if (Cache::getStore() instanceof TaggableStore) {
170
            Cache::tags(Config::get('admin.permission_role_table'))->flush();
171
        }
172
    }
173
174
    /**
175
     * Attach permission to current role.
176
     *
177
     * @param object|array $permission
178
     *
179
     * @return void
180
     */
181
    public function attachPermission($permission)
182
    {
183
        if (is_object($permission)) {
184
            $permission = $permission->getKey();
185
        }
186
187
        if (is_array($permission)) {
188
            return $this->attachPermissions($permission);
189
        }
190
191
        $this->perms()->attach($permission);
192
    }
193
194
    /**
195
     * Detach permission from current role.
196
     *
197
     * @param object|array $permission
198
     *
199
     * @return void
200
     */
201
    public function detachPermission($permission)
202
    {
203
        if (is_object($permission)) {
204
            $permission = $permission->getKey();
205
        }
206
207
        if (is_array($permission)) {
208
            return $this->detachPermissions($permission);
209
        }
210
211
        $this->perms()->detach($permission);
212
    }
213
214
    /**
215
     * Attach multiple permissions to current role.
216
     *
217
     * @param mixed $permissions
218
     *
219
     * @return void
220
     */
221
    public function attachPermissions($permissions)
222
    {
223
        foreach ($permissions as $permission) {
224
            $this->attachPermission($permission);
225
        }
226
    }
227
228
    /**
229
     * Detach multiple permissions from current role
230
     *
231
     * @param mixed $permissions
232
     *
233
     * @return void
234
     */
235
    public function detachPermissions($permissions = null)
236
    {
237
        if (!$permissions) {
238
            $permissions = $this->perms()->get();
239
        }
240
241
        foreach ($permissions as $permission) {
242
            $this->detachPermission($permission);
243
        }
244
    }
245
}
246