Rbac   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 342
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 73
c 1
b 0
f 0
dl 0
loc 342
rs 10
wmc 28

14 Methods

Rating   Name   Duplication   Size   Complexity  
A updateData() 0 15 3
A init() 0 8 3
A createData() 0 13 3
A filterChlidrenBeforeAdd() 0 18 4
A checkForNewRecord() 0 3 1
A findOne() 0 9 1
A addChildren() 0 7 2
A save() 0 13 3
A delete() 0 3 1
A checkNameForUnique() 0 10 3
A getId() 0 3 1
A setAuthManager() 0 4 1
A rules() 0 35 1
A getAuthManager() 0 3 1
1
<?php
2
3
namespace Itstructure\RbacModule\models;
4
5
use Yii;
6
use yii\base\{Model, InvalidConfigException};
7
use yii\rbac\{Item, ManagerInterface};
8
use Itstructure\RbacModule\Module;
9
10
/**
11
 * Class Rbac
12
 * Model Rbac to work with roles and permissions.
13
 *
14
 * @property string $name
15
 * @property string $description
16
 * @property ManagerInterface $authManager
17
 *
18
 * @package Itstructure\RbacModule\models
19
 */
20
abstract class Rbac extends Model
21
{
22
    /**
23
     * Role name.
24
     *
25
     * @var string
26
     */
27
    public $name;
28
29
    /**
30
     * Role description.
31
     *
32
     * @var string
33
     */
34
    public $description;
35
36
    /**
37
     * Auth manager.
38
     *
39
     * @var ManagerInterface
40
     */
41
    private $authManager;
42
43
    /**
44
     * Create new item (Role or permission).
45
     *
46
     * @param string $name
47
     *
48
     * @return Item
49
     */
50
    abstract protected function createItem(string $name): Item;
51
52
    /**
53
     * Create child item.
54
     * Example: parent - role, child - permission.
55
     *
56
     * @param string $name
57
     *
58
     * @return Item
59
     */
60
    abstract protected function createChild(string $name): Item;
61
62
    /**
63
     * Get current child items.
64
     *
65
     * @return array
66
     */
67
    abstract protected function getCurrentChildren(): array ;
68
69
    /**
70
     * Get new child items.
71
     *
72
     * @return array
73
     */
74
    abstract protected function getNewChildren(): array ;
75
76
    /**
77
     * Returns old name in current object, which is set before new value.
78
     *
79
     * @return mixed
80
     */
81
    abstract protected function getOldName();
82
83
    /**
84
     * Returns item object: Role or Permission.
85
     *
86
     * @param string $key
87
     *
88
     * @return Item|null
89
     */
90
    abstract protected function getItem(string $key);
91
92
    /**
93
     * Set item (role or permission) for instance of Rbac.
94
     *
95
     * @param Rbac $instance
96
     * @param Item      $item
97
     *
98
     * @return Rbac
99
     */
100
    abstract protected function setItemForInstance(Rbac $instance, Item $item): Rbac;
101
102
    /**
103
     * Set children for instance of Rbac (for Role or Permission).
104
     *
105
     * @param Rbac $instance
106
     *
107
     * @return Rbac
108
     */
109
    abstract protected function setChildrenForInstance(Rbac $instance): Rbac;
110
111
    /**
112
     * Initialize.
113
     */
114
    public function init()
115
    {
116
        if (null === $this->authManager) {
117
            $this->setAuthManager(Yii::$app->authManager);
118
        }
119
120
        if (null === $this->authManager) {
121
            throw new InvalidConfigException('The authManager is not defined.');
122
        }
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function rules()
129
    {
130
        return [
131
            [
132
                [
133
                    'name',
134
                    'description',
135
                ],
136
                'required',
137
            ],
138
            [
139
                [
140
                    'name',
141
                ],
142
                'string',
143
                'min' => 3,
144
                'max' => 64,
145
            ],
146
            [
147
                'name',
148
                'match',
149
                'pattern' => '/^[a-z]\w*$/i',
150
                'message' => Module::t('rbac', 'Name must contain latin symbols and numeric without spaces.')
151
            ],
152
            [
153
                [
154
                    'description',
155
                ],
156
                'string',
157
            ],
158
            [
159
                [
160
                    'name',
161
                ],
162
                'checkNameForUnique',
163
            ],
164
        ];
165
    }
166
167
    /**
168
     * Set auth manager.
169
     *
170
     * @param ManagerInterface $authManager
171
     *
172
     * @return $this
173
     */
174
    public function setAuthManager(ManagerInterface $authManager)
175
    {
176
        $this->authManager = $authManager;
177
        return $this;
178
    }
179
180
    /**
181
     * Get auth manager.
182
     *
183
     * @return ManagerInterface
184
     */
185
    public function getAuthManager(): ManagerInterface
186
    {
187
        return $this->authManager;
188
    }
189
190
    /**
191
     * @param string $key
192
     *
193
     * @return static
194
     */
195
    public function findOne(string $key)
196
    {
197
        $item = $this->getItem($key);
198
199
        $instance = new static();
200
        $instance->name = $item->name;
201
        $instance->description = $item->description;
202
203
        return $this->setChildrenForInstance($this->setItemForInstance($instance, $item));
0 ignored issues
show
Bug introduced by
It seems like $item can also be of type null; however, parameter $item of Itstructure\RbacModule\m...c::setItemForInstance() does only seem to accept yii\rbac\Item, maybe add an additional type check? ( Ignorable by Annotation )

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

203
        return $this->setChildrenForInstance($this->setItemForInstance($instance, /** @scrutinizer ignore-type */ $item));
Loading history...
204
    }
205
206
    /**
207
     * Save item data.
208
     *
209
     * @return bool
210
     */
211
    public function save(): bool
212
    {
213
        if (!$this->validate()) {
214
            return false;
215
        }
216
217
        $item = $this->createItem($this->name);
218
        $item->description = $this->description;
219
220
        if ($this->checkForNewRecord()) {
221
            return $this->createData($item);
222
        } else {
223
            return $this->updateData($item);
224
        }
225
    }
226
227
    /**
228
     * Returns current model id.
229
     *
230
     * @return string
231
     */
232
    public function getId(): string
233
    {
234
        return $this->name;
235
    }
236
237
    /**
238
     * Delete current role.
239
     *
240
     * @return bool
241
     */
242
    public function delete(): bool
243
    {
244
        return $this->authManager->remove($this->createItem($this->name));
245
    }
246
247
    /**
248
     * Delete from general list children items, which can't be assigned to parent.
249
     *
250
     * @param array $chlidren
251
     *
252
     * @return array
253
     */
254
    public function filterChlidrenBeforeAdd(array $chlidren): array
255
    {
256
        if (null === $this->getOldName()) {
257
            return $chlidren;
258
        }
259
260
        foreach ($chlidren as $key => $value) {
261
262
            $parent = $this->createItem($this->getOldName());
263
264
            $child = $this->createChild($key);
265
266
            if (!$this->authManager->canAddChild($parent, $child)) {
0 ignored issues
show
Bug introduced by
The method canAddChild() does not exist on yii\rbac\ManagerInterface. Did you maybe mean addChild()? ( Ignorable by Annotation )

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

266
            if (!$this->authManager->/** @scrutinizer ignore-call */ canAddChild($parent, $child)) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
267
                unset($chlidren[$key]);
268
            }
269
        }
270
271
        return $chlidren;
272
    }
273
274
    /**
275
     * Check name for unique.
276
     *
277
     * @param $attribute
278
     *
279
     * @return bool
280
     */
281
    public function checkNameForUnique($attribute): bool
282
    {
283
        $item = $this->getItem($this->name);
284
285
        if (null !== $item && $this->getOldName() !== $item->name) {
286
            $this->addError($attribute, Module::t('rbac', 'This name already exists.'));
287
            return false;
288
        }
289
290
        return true;
291
    }
292
293
    /**
294
     * Check if current model is new record.
295
     * Return true if there is a new record.
296
     *
297
     * @return bool
298
     */
299
    private function checkForNewRecord(): bool
300
    {
301
        return null === $this->getOldName();
302
    }
303
304
    /**
305
     * Function for creating record.
306
     *
307
     * @param Item $item
308
     *
309
     * @return bool
310
     */
311
    private function createData(Item $item): bool
312
    {
313
        if (!$this->authManager->add($item)) {
314
            return false;
315
        }
316
317
        $newChildren = $this->getNewChildren();
318
319
        if (count($newChildren) > 0) {
320
            $this->addChildren($newChildren);
321
        }
322
323
        return true;
324
    }
325
326
    /**
327
     * Function for updating record.
328
     *
329
     * @param Item $item
330
     *
331
     * @return bool
332
     */
333
    private function updateData(Item $item): bool
334
    {
335
        if (!$this->authManager->update($this->getOldName(), $item)) {
336
            return false;
337
        }
338
339
        $this->authManager->removeChildren($item);
0 ignored issues
show
Bug introduced by
The method removeChildren() does not exist on yii\rbac\ManagerInterface. Did you maybe mean remove()? ( Ignorable by Annotation )

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

339
        $this->authManager->/** @scrutinizer ignore-call */ 
340
                            removeChildren($item);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
340
341
        $newChildren = $this->getNewChildren();
342
343
        if (count($newChildren) > 0) {
344
            $this->addChildren($newChildren);
345
        }
346
347
        return true;
348
    }
349
350
    /**
351
     * Add childs items for parent item.
352
     *
353
     * @param array $childs
354
     */
355
    private function addChildren(array $childs): void
356
    {
357
        foreach ($childs as $child) {
358
359
            $this->authManager->addChild(
360
                $this->createItem($this->name),
361
                $this->createChild($child)
362
            );
363
        }
364
    }
365
}
366