Completed
Push — master ( 2fbacb...a9c471 )
by ARCANEDEV
03:25
created

Item::checkPermission()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
1
<?php namespace Arcanesoft\Sidebar\Entities;
2
3
use Arcanesoft\Contracts\Auth\Models\User;
4
use Illuminate\Contracts\Support\Arrayable;
5
use Illuminate\Contracts\Support\Jsonable;
6
use Illuminate\Support\Arr;
7
use JsonSerializable;
8
9
/**
10
 * Class     Item
11
 *
12
 * @package  Arcanesoft\Sidebar\Entitites
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
class Item implements Arrayable, Jsonable, JsonSerializable
16
{
17
    /* -----------------------------------------------------------------
18
     |  Properties
19
     | -----------------------------------------------------------------
20
     */
21
22
    /**
23
     * The item name.
24
     *
25
     * @var string
26
     */
27
    protected $name;
28
29
    /**
30
     * The item title.
31
     *
32
     * @var string
33
     */
34
    protected $title;
35
36
    /**
37
     * The item url.
38
     *
39
     * @var string
40
     */
41
    protected $url;
42
43
    /**
44
     * The item icon.
45
     *
46
     * @var string
47
     */
48
    protected $icon;
49
50
    /**
51
     * The item active state.
52
     *
53
     * @var bool
54
     */
55
    protected $active = false;
56
57
    /**
58
     * The item roles.
59
     *
60
     * @var array
61
     */
62
    protected $roles      = [];
63
64
    /**
65
     * The item permissions.
66
     *
67
     * @var array
68
     */
69
    protected $permissions = [];
70
71
    /**
72
     * The item children (sub-items).
73
     *
74
     * @var \Arcanesoft\Sidebar\Entities\ItemCollection
75
     */
76
    protected $children;
77
78
    /* -----------------------------------------------------------------
79
     |  Constructor
80
     | -----------------------------------------------------------------
81
     */
82
83
    /**
84
     * Item constructor.
85
     *
86
     * @param  string       $name
87
     * @param  string       $title
88
     * @param  string       $url
89
     * @param  string|null  $icon
90
     */
91 42
    public function __construct($name, $title, $url, $icon = null)
92
    {
93 42
        $this->name     = $name;
94 42
        $this->title    = $title;
95 42
        $this->url      = $url;
96 42
        $this->icon     = $icon;
97 42
        $this->active   = false;
98 42
        $this->children = new ItemCollection;
99 42
    }
100
101
    /* -----------------------------------------------------------------
102
     |  Getters & Setters
103
     | -----------------------------------------------------------------
104
     */
105
106
    /**
107
     * Get the item name.
108
     *
109
     * @return string
110
     */
111 18
    public function name()
112
    {
113 18
        return $this->name;
114
    }
115
116
    /**
117
     * Get the item title.
118
     *
119
     * @return string
120
     */
121 27
    public function title()
122
    {
123
        /** @var \Illuminate\Translation\Translator $trans */
124 27
        $trans = trans();
125
126 27
        return $trans->has($this->title) ? $trans->get($this->title) : $this->title;
127
    }
128
129
    /**
130
     * Get the item url.
131
     *
132
     * @return string
133
     */
134 21
    public function url()
135
    {
136 21
        return $this->url;
137
    }
138
139
    /**
140
     * Get the item icon.
141
     *
142
     * @return string|null
143
     */
144 24
    public function icon()
145
    {
146 24
        return $this->icon;
147
    }
148
149
    /**
150
     * Set the current name.
151
     *
152
     * @param  string  $name
153
     *
154
     * @return self
155
     */
156 9
    public function setCurrent($name)
157
    {
158 9
        $this->children->setCurrent($name);
159 9
        $this->active = ($this->name === $name || $this->children->hasActiveItem());
160
161 9
        return $this;
162
    }
163
164
    /**
165
     * Get the roles.
166
     *
167
     * @return array
168
     */
169 12
    public function getRoles()
170
    {
171 12
        return $this->roles;
172
    }
173
174
    /**
175
     * Set the roles.
176
     *
177
     * @param  array  $roles
178
     *
179
     * @return self
180
     */
181 33
    public function setRoles(array $roles)
182
    {
183 33
        $this->roles = $roles;
184
185 33
        return $this;
186
    }
187
188
    /**
189
     * Get the permissions.
190
     *
191
     * @return array
192
     */
193 12
    public function getPermissions()
194
    {
195 12
        return $this->permissions;
196
    }
197
198
    /**
199
     * Set the permissions.
200
     *
201
     * @param  array  $permissions
202
     *
203
     * @return self
204
     */
205 33
    public function setPermissions(array $permissions)
206
    {
207 33
        $this->permissions = $permissions;
208
209 33
        return $this;
210
    }
211
212
    /**
213
     * Get the sub-items.
214
     *
215
     * @return \Arcanesoft\Sidebar\Entities\ItemCollection
216
     */
217 15
    public function children()
218
    {
219 15
        return $this->children;
220
    }
221
222
    /**
223
     * Get the active class.
224
     *
225
     * @param  string  $class
226
     *
227
     * @return string
228
     */
229 6
    public function activeClass($class = 'active')
230
    {
231 6
        return $this->isActive() ? $class : '';
232
    }
233
234
    /**
235
     * Get the sub-items class.
236
     *
237
     * @param  string  $class
238
     *
239
     * @return string
240
     */
241 6
    public function childrenClass($class = 'treeview')
242
    {
243 6
        return $this->hasChildren() ? $class : '';
244
    }
245
246
    /* -----------------------------------------------------------------
247
     |  Main Methods
248
     | -----------------------------------------------------------------
249
     */
250
    /**
251
     * Make the item.
252
     *
253
     * @param  string       $name
254
     * @param  string       $title
255
     * @param  string       $url
256
     * @param  string|null  $icon
257
     *
258
     * @return self
259
     */
260 27
    public static function make($name, $title, $url, $icon = null)
261
    {
262 27
        return new self($name, $title, $url, $icon);
263
    }
264
265
    /**
266
     * Make a Sidebar item from array.
267
     *
268
     * @param  array  $array
269
     *
270
     * @return self
271
     */
272 18
    public static function makeFromArray(array $array)
273
    {
274 18
        return tap(
275 18
            self::make($array['name'], $array['title'], self::getUrlFromArray($array), Arr::get($array, 'icon', null)),
276
            function (Item $item) use ($array) {
277 18
                $item->setRoles(Arr::get($array, 'roles', []));
278 18
                $item->setPermissions(Arr::get($array, 'permissions', []));
279 18
                $item->addChildren(Arr::get($array, 'children', []));
280 18
            }
281 6
        );
282
    }
283
284
    /**
285
     * Get url from array.
286
     *
287
     * @param  array  $array
288
     *
289
     * @return string
290
     */
291 18
    private static function getUrlFromArray(array $array)
292
    {
293 18
        return Arr::has($array, 'route')
294 8
            ? route(Arr::get($array, 'route'))
295 18
            : Arr::get($array, 'url', '#');
296
    }
297
298
    /**
299
     * Add children to the parent.
300
     *
301
     * @param  array  $children
302
     *
303
     * @return self
304
     */
305 18
    public function addChildren(array $children)
306
    {
307 18
        foreach ($children as $child) {
308 12
            $this->addChild($child);
309 6
        }
310
311 18
        return $this;
312
    }
313
314
    /**
315
     * Add a sub-item to the parent.
316
     *
317
     * @param  array  $child
318
     *
319
     * @return self
320
     */
321 12
    public function addChild(array $child)
322
    {
323 12
        $item = self::makeFromArray($child);
324
325 12
        if ($item->allowed())
326 12
            $this->children->push($item);
327
328 12
        return $this;
329
    }
330
331
    /* -----------------------------------------------------------------
332
     |  Check Methods
333
     | -----------------------------------------------------------------
334
     */
335
336
    /**
337
     * Check if the item is active one.
338
     *
339
     * @return bool
340
     */
341 27
    public function isActive()
342
    {
343 27
        return $this->active;
344
    }
345
346
    /**
347
     * Check if the item has children.
348
     *
349
     * @return bool
350
     */
351 12
    public function hasChildren()
352
    {
353 12
        return ! $this->children->isEmpty();
354
    }
355
356
    /**
357
     * Check the user is allowed to see this item.
358
     *
359
     * @return bool
360
     */
361 18
    public function allowed()
362
    {
363
        /** @var  \Arcanesoft\Contracts\Auth\Models\User  $user */
364 18
        $user = auth()->user();
365
366 18
        if (is_null($user) || ( ! $this->hasRoles() && ! $this->hasPermissions()))
367 18
            return true;
368
369 3
        return $user->isAdmin()
370 3
            || $this->checkRoles($user)
371 3
            || $this->checkPermission($user)
372 3
            || $this->hasAllowedChild();
373
    }
374
375
    /**
376
     * Check if the item has roles.
377
     *
378
     * @return bool
379
     */
380 9
    public function hasRoles()
381
    {
382 9
        return ! empty($this->roles);
383
    }
384
385
    /**
386
     * Check if the item has permissions.
387
     *
388
     * @return bool
389
     */
390 6
    public function hasPermissions()
391
    {
392 6
        return ! empty($this->permissions);
393
    }
394
395
    /* -----------------------------------------------------------------
396
     |  Other Methods
397
     | -----------------------------------------------------------------
398
     */
399
400
    /**
401
     * Get the instance as an array.
402
     *
403
     * @return array
404
     */
405 12
    public function toArray()
406
    {
407
        return [
408 12
            'name'        => $this->name(),
409 12
            'title'       => $this->title(),
410 12
            'url'         => $this->url(),
411 12
            'icon'        => $this->icon(),
412 12
            'active'      => $this->isActive(),
413 12
            'roles'       => $this->roles,
414 12
            'permissions' => $this->permissions,
415 12
            'children'    => $this->children->toArray(),
416 4
        ];
417
    }
418
419
    /**
420
     * Convert the object to its JSON representation.
421
     *
422
     * @param  int  $options
423
     *
424
     * @return string
425
     */
426 3
    public function toJson($options = 0)
427
    {
428 3
        return json_encode($this->jsonSerialize(), $options);
429
    }
430
431
    /**
432
     * Convert the object into something JSON serializable.
433
     *
434
     * @return array
435
     */
436 6
    public function jsonSerialize()
437
    {
438 6
        return $this->toArray();
439
    }
440
441
    /**
442
     * Check if the user has role.
443
     *
444
     * @param  \Arcanesoft\Contracts\Auth\Models\User  $user
445
     *
446
     * @return bool
447
     */
448 3
    private function checkRoles(User $user)
449
    {
450 3
        foreach ($this->getRoles() as $roleSlug) {
451 3
            if ($user->hasRoleSlug($roleSlug)) return true;
452 1
        }
453
454 3
        return false;
455
    }
456
457
    /**
458
     * Check if the user has permission.
459
     *
460
     * @param  \Arcanesoft\Contracts\Auth\Models\User  $user
461
     *
462
     * @return bool
463
     */
464 3
    private function checkPermission(User $user)
465
    {
466 3
        foreach ($this->getPermissions() as $permissionSlug) {
467 3
            if ($user->may($permissionSlug)) return true;
468 1
        }
469
470 3
        return false;
471
    }
472
473
    /**
474
     * Check if has an allowed child.
475
     *
476
     * @return bool
477
     */
478
    private function hasAllowedChild()
479
    {
480 3
        return $this->children()->filter(function (Item $child) {
481 3
            return $child->allowed();
482 3
        })->isNotEmpty();
483
    }
484
}
485