Passed
Pull Request — master (#56)
by Brent
08:20 queued 48s
created

Enum   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 85
Duplicated Lines 0 %

Importance

Changes 32
Bugs 5 Features 3
Metric Value
eloc 34
dl 0
loc 85
rs 10
c 32
b 5
f 3
wmc 15

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __get() 0 8 3
A resolveDefinition() 0 23 3
A labels() 0 3 1
A __callStatic() 0 3 1
A equals() 0 12 4
A __construct() 0 12 2
A toArray() 0 3 1
1
<?php
2
3
namespace Spatie\Enum;
4
5
use BadMethodCallException;
6
use ReflectionClass;
7
8
/**
9
 * @property-read string value
10
 * @property-read string label
11
 */
12
abstract class Enum
13
{
14
    protected string $value;
15
16
    protected string $label;
17
18
    private static array $definitionCache = [];
19
20
    public static function toArray(): array
21
    {
22
        return static::resolveDefinition();
23
    }
24
25
    public function __construct(string $value)
26
    {
27
        $definition = static::resolveDefinition();
28
29
        if (! isset($definition[$value])) {
30
            $enumClass = static::class;
31
32
            throw new BadMethodCallException("There's no value {$value} defined for enum {$enumClass}, consider adding it in the docblock definition.");
33
        }
34
35
        $this->value = $value;
0 ignored issues
show
Bug introduced by
The property value is declared read-only in Spatie\Enum\Enum.
Loading history...
36
        $this->label = $definition[$value];
0 ignored issues
show
Bug introduced by
The property label is declared read-only in Spatie\Enum\Enum.
Loading history...
37
    }
38
39
    public function __get($name)
40
    {
41
        if ($name === 'label') {
42
            return $this->label;
43
        }
44
45
        if ($name === 'value') {
46
            return $this->value;
47
        }
48
    }
49
50
    public static function __callStatic(string $name, array $arguments)
51
    {
52
        return new static($name);
53
    }
54
55
    public function equals(Enum ...$others): bool
56
    {
57
        foreach ($others as $other) {
58
            if (
59
                get_class($this) === get_class($other)
60
                && $this->value === $other->value
61
            ) {
62
                return true;
63
            }
64
        }
65
66
        return false;
67
    }
68
69
    protected static function labels(): array
70
    {
71
        return [];
72
    }
73
74
    private static function resolveDefinition(): array
75
    {
76
        $className = static::class;
77
78
        if (static::$definitionCache[$className] ?? null) {
0 ignored issues
show
Bug introduced by
Since $definitionCache is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $definitionCache to at least protected.
Loading history...
79
            return static::$definitionCache[$className];
80
        }
81
82
        $reflectionClass = new ReflectionClass($className);
83
84
        $docComment = $reflectionClass->getDocComment();
85
86
        preg_match_all('/@method static self ([\w_]+)\(\)/', $docComment, $matches);
87
88
        $definition = [];
89
90
        $labels = static::labels();
91
92
        foreach ($matches[1] as $value) {
93
            $definition[$value] = $labels[$value] ?? $value;
94
        }
95
96
        return static::$definitionCache[$className] ??= $definition;
97
    }
98
}
99