GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#4)
by Tom
04:15
created

HasEnums::scopeOrWhereNotEnum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 0
cts 7
cp 0
rs 9.8666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 2
1
<?php
2
3
namespace Spatie\Enum\Laravel;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
use InvalidArgumentException;
8
use Spatie\Enum\Enumerable;
9
use Spatie\Enum\Laravel\Exceptions\InvalidEnumError;
10
use Spatie\Enum\Laravel\Exceptions\NoSuchEnumField;
11
12
/**
13
 * @mixin Model
14
 */
15
trait HasEnums
16
{
17 52
    public function setAttribute($key, $value)
18
    {
19 52
        return $this->isEnumAttribute($key)
20 52
            ? $this->setEnumAttribute($key, $value)
21 44
            : parent::setAttribute($key, $value);
22
    }
23
24 28
    public function getAttribute($key)
25
    {
26 28
        $value = parent::getAttribute($key);
27
28 28
        return $this->isEnumAttribute($key)
29 28
            ? $this->getEnumAttribute($key, $value)
30 28
            : $value;
31
    }
32
33
    /**
34
     * @param Builder $builder
35
     * @param string $key
36
     * @param int|string|Enumerable|int[]|string[]|Enumerable[] $enumerables
37
     *
38
     * @see Builder::whereIn()
39
     */
40 12
    public function scopeWhereEnum(
41
        Builder $builder,
42
        string $key,
43
        $enumerables
44
    ): void {
45 12
        $this->buildEnumScope(
46 12
            $builder,
47 12
            'whereIn',
48 6
            $key,
49 6
            $enumerables
50
        );
51 8
    }
52
53
    /**
54
     * @param Builder $builder
55
     * @param string $key
56
     * @param int|string|Enumerable|int[]|string[]|Enumerable[] $enumerables
57
     *
58
     * @see Builder::orWhereIn()
59
     */
60
    public function scopeOrWhereEnum(
61
        Builder $builder,
62
        string $key,
63
        $enumerables
64
    ): void {
65
        $this->buildEnumScope(
66
            $builder,
67
            'orWhereIn',
68
            $key,
69
            $enumerables
70
        );
71
    }
72
73
    /**
74
     * @param Builder $builder
75
     * @param string $key
76
     * @param int|string|Enumerable|int[]|string[]|Enumerable[] $enumerables
77
     *
78
     * @see Builder::whereNotIn()
79
     */
80 12
    public function scopeWhereNotEnum(
81
        Builder $builder,
82
        string $key,
83
        $enumerables
84
    ): void {
85 12
        $this->buildEnumScope(
86 12
            $builder,
87 12
            'whereNotIn',
88 6
            $key,
89 6
            $enumerables
90
        );
91 8
    }
92
93
    /**
94
     * @param Builder $builder
95
     * @param string $key
96
     * @param int|string|Enumerable|int[]|string[]|Enumerable[] $enumerables
97
     *
98
     * @see Builder::orWhereNotIn()
99
     */
100
    public function scopeOrWhereNotEnum(
101
        Builder $builder,
102
        string $key,
103
        $enumerables
104
    ): void {
105
        $this->buildEnumScope(
106
            $builder,
107
            'orWhereNotIn',
108
            $key,
109
            $enumerables
110
        );
111
    }
112
113
    /**
114
     * @param string $key
115
     * @param int|string|Enumerable $value
116
     *
117
     * @return $this
118
     */
119 52
    protected function setEnumAttribute(string $key, $value)
120
    {
121 52
        $enumClass = $this->getEnumClass($key);
122
123 48
        if (is_string($value) || is_int($value)) {
124 16
            $value = $this->asEnum($enumClass, $value);
125
        }
126
127 48
        if (! is_a($value, $enumClass)) {
128 4
            throw InvalidEnumError::make(static::class, $key, $enumClass, get_class($value));
129
        }
130
131 44
        $this->attributes[$key] = $this->getStoredValue($key, $value);
0 ignored issues
show
Bug introduced by
The property attributes 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...
132
133 44
        return $this;
134
    }
135
136
    /**
137
     * @param string $key
138
     * @param Enumerable $enum
139
     *
140
     * @return int|string
141
     */
142 44
    protected function getStoredValue(string $key, Enumerable $enum)
143
    {
144 44
        return $this->hasCast($key, ['int', 'integer'])
0 ignored issues
show
Bug introduced by
It seems like hasCast() 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...
145 4
            ? $enum->getIndex()
146 44
            : $enum->getValue();
147
    }
148
149
    /**
150
     * @param string $key
151
     * @param int|string $value
152
     * @return Enumerable
153
     */
154 28
    protected function getEnumAttribute(string $key, $value): Enumerable
155
    {
156 28
        return $this->asEnum($this->getEnumClass($key), $value);
157
    }
158
159 60
    protected function isEnumAttribute(string $key): bool
160
    {
161 60
        return isset($this->enums[$key]);
0 ignored issues
show
Bug introduced by
The property enums 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...
162
    }
163
164 52
    protected function getEnumClass(string $key): string
165
    {
166 52
        $enumClass = $this->enums[$key];
167 52
        $enumInterface = Enumerable::class;
168 52
        $classImplementsEnumerable = class_implements($enumClass)[$enumInterface] ?? false;
169
170 52
        if (! $classImplementsEnumerable) {
171 4
            throw new InvalidArgumentException("Expected {$enumClass} to implement {$enumInterface}");
172
        }
173
174 48
        return $enumClass;
175
    }
176
177
    /**
178
     * @param string $class
179
     * @param int|string $value
180
     *
181
     * @return Enumerable
182
     */
183 44
    protected function asEnum(string $class, $value): Enumerable
184
    {
185 44
        if ($value instanceof Enumerable) {
186 16
            return $value;
187
        }
188
189 28
        return forward_static_call(
190 28
            $class . '::make',
191 14
            $value
192
        );
193
    }
194
195
    /**
196
     * @param Builder $builder
197
     * @param string $method
198
     * @param string $key
199
     * @param int|string|Enumerable|int[]|string[]|Enumerable[] $enumerables
200
     */
201 24
    protected function buildEnumScope(
202
        Builder $builder,
203
        string $method,
204
        string $key,
205
        $enumerables
206
    ): void {
207 24
        if (! $this->isEnumAttribute($key)) {
208 8
            throw NoSuchEnumField::make($key, get_class($this));
209
        }
210
211 16
        $enumerables = is_array($enumerables) ? $enumerables : [$enumerables];
212
213 16
        $builder->$method(
214 16
            $key,
215
            array_map(function ($enumerable) use ($key) {
216 16
                $this->getStoredValue($key, $this->asEnum($key, $enumerable));
217 16
            }, $enumerables)
218
        );
219 16
    }
220
}
221