Completed
Push — develop ( 4264eb...5ad3b4 )
by Abdelrahman
9s
created

HasAbilities::bootHasAbilities()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Rinvex\Fort\Traits;
6
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Collection;
10
use Illuminate\Support\Collection as BaseCollection;
11
12
trait HasAbilities
13
{
14
    /**
15
     * Register a saved model event with the dispatcher.
16
     *
17
     * @param \Closure|string $callback
18
     *
19
     * @return void
20
     */
21
    abstract public static function saved($callback);
22
23
    /**
24
     * Register a deleted model event with the dispatcher.
25
     *
26
     * @param \Closure|string $callback
27
     *
28
     * @return void
29
     */
30
    abstract public static function deleted($callback);
31
32
    /**
33
     * Boot the HasAbilities trait for the model.
34
     *
35
     * @return void
36
     */
37
    public static function bootHasAbilities()
38
    {
39
        static::deleted(function (self $model) {
40
            $model->abilities()->detach();
41
        });
42
    }
43
44
    /**
45
     * Attach the given abilities to the model.
46
     *
47
     * @param mixed $abilities
48
     *
49
     * @return void
50
     */
51
    public function setAbilitiesAttribute($abilities)
52
    {
53
        static::saved(function (self $model) use ($abilities) {
54
            $model->syncAbilities($abilities);
55
        });
56
    }
57
58
    /**
59
     * Attach the given abilities to the model.
60
     *
61
     * @param mixed $abilities
62
     *
63
     * @return $this
64
     */
65
    public function grantAbilities($abilities)
66
    {
67
        // Use 'sync' not 'attach' to avoid Integrity constraint violation
68
        $this->abilities()->sync($this->parseAbilities($abilities), false);
0 ignored issues
show
Bug introduced by
The method abilities() does not exist on Rinvex\Fort\Traits\HasAbilities. Did you maybe mean bootHasAbilities()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
69
70
        return $this;
71
    }
72
73
    /**
74
     * Sync the given abilities to the model.
75
     *
76
     * @param mixed $abilities
77
     * @param bool  $detaching
78
     *
79
     * @return $this
80
     */
81
    public function syncAbilities($abilities, bool $detaching = true)
82
    {
83
        $this->abilities()->sync($this->parseAbilities($abilities), $detaching);
0 ignored issues
show
Bug introduced by
The method abilities() does not exist on Rinvex\Fort\Traits\HasAbilities. Did you maybe mean bootHasAbilities()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
84
85
        return $this;
86
    }
87
88
    /**
89
     * Detach the given abilities from the model.
90
     *
91
     * @param mixed $abilities
92
     *
93
     * @return $this
94
     */
95
    public function revokeAbilities($abilities = null)
96
    {
97
        ! $abilities || $abilities = $this->parseAbilities($abilities);
98
99
        $this->abilities()->detach($abilities);
0 ignored issues
show
Bug introduced by
The method abilities() does not exist on Rinvex\Fort\Traits\HasAbilities. Did you maybe mean bootHasAbilities()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
100
101
        return $this;
102
    }
103
104
    /**
105
     * Parse slugged abilities.
106
     *
107
     * @param mixed $abilities
108
     *
109
     * @return array
110
     */
111
    protected function parseSluggedAbilities($abilities)
112
    {
113
        $model = app('rinvex.fort.ability')->query();
114
115
        collect($abilities)->map(function ($item) use ($model) {
116
            return $model->when(mb_strpos($item, '-') !== false, function (Builder $builder) use ($item) {
117
                $builder->orWhere(function (Builder $builder) use ($item) {
118
                    $builder->where('action', explode('-', $item)[0])->where('resource', explode('-', $item)[1]);
119
                });
120
            });
121
        });
122
123
        return $model->get()->pluck('id')->toArray();
124
    }
125
126
    /**
127
     * Parse abilities.
128
     *
129
     * @param mixed $abilities
130
     *
131
     * @return array
132
     */
133
    protected function parseAbilities($abilities): array
134
    {
135
        ! $abilities instanceof Model || $abilities = [$abilities->getKey()];
136
        ! $abilities instanceof Collection || $abilities = $abilities->modelKeys();
137
        ! $abilities instanceof BaseCollection || $abilities = $abilities->toArray();
138
139
        if (is_string($abilities) || (is_array($abilities) && is_string(array_first($abilities)))) {
140
            $abilities = $this->parseSluggedAbilities($abilities);
141
        }
142
143
        return (array) $abilities;
144
    }
145
}
146