Enum   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Importance

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

10 Methods

Rating   Name   Duplication   Size   Complexity  
A toArray() 0 3 1
A getKey() 0 3 1
A __toString() 0 3 1
A __construct() 0 7 2
A getValue() 0 3 1
A getKeys() 0 3 1
A __callStatic() 0 12 3
A searchNameByValue() 0 8 2
A getValues() 0 3 1
A constants() 0 11 2
1
<?php
2
3
namespace Tleckie\Enum;
4
5
use InvalidArgumentException;
6
use ReflectionClass;
7
use function array_key_exists;
8
use function array_keys;
9
use function array_search;
10
use function array_values;
11
12
/**
13
 * Class Enum
14
 *
15
 * @package Tleckie\Enum
16
 * @author  Teodoro Leckie Westberg <[email protected]>
17
 */
18
class Enum implements EnumInterface
19
{
20
    /** @var array */
21
    private static array $constants = [];
22
23
    protected static array $instances = [];
24
25
    /** @var mixed */
26
    private mixed $value;
27
28
    /** @var mixed */
29
    private mixed $key;
30
31
    /**
32
     * Enum constructor.
33
     *
34
     * @param mixed $value
35
     */
36
    final public function __construct(mixed $value)
37
    {
38
        $value = ($value instanceof EnumInterface) ? $value->getValue() : $value;
39
40
        $this->key = static::searchNameByValue($value);
41
42
        $this->value = $value;
43
    }
44
45
    /**
46
     * @return mixed[]
47
     */
48
    private static function constants(): array
49
    {
50
        if (isset(static::$constants[static::class])) {
51
            return static::$constants[static::class];
52
        }
53
54
        $reflection = new ReflectionClass(static::class);
55
56
        static::$constants[static::class] =  $reflection->getConstants();
57
58
        return static::$constants[static::class];
59
    }
60
61
    /**
62
     * @return mixed
63
     */
64
    public function getValue(): mixed
65
    {
66
        return $this->value;
67
    }
68
69
    /**
70
     * @param mixed $value
71
     * @return string
72
     */
73
    private static function searchNameByValue(mixed $value): string
74
    {
75
        $name = array_search($value, static::constants(), true);
76
        if (false === $name) {
77
            throw new InvalidArgumentException(sprintf('Constant value [%s] not found', $value));
78
        }
79
80
        return $name;
81
    }
82
83
    /**
84
     * @param string $name
85
     * @param array  $arguments
86
     * @return self
87
     */
88
    final public static function __callStatic(string $name, array $arguments): self
89
    {
90
        if (!array_key_exists($name, static::constants())) {
91
            throw new InvalidArgumentException(sprintf('Constant [%s] is not defined', $name));
92
        }
93
        if (isset(static::$instances[static::class][$name])) {
94
            return static::$instances[static::class][$name];
95
        }
96
97
        static::$instances[static::class][$name] = new static(static::constants()[$name]);
98
99
        return static::$instances[static::class][$name];
100
    }
101
102
    /**
103
     * @return mixed[]
104
     */
105
    public function getValues(): array
106
    {
107
        return array_values(static::$constants[static::class]);
108
    }
109
110
    /**
111
     * @return string[]
112
     */
113
    public function getKeys(): array
114
    {
115
        return array_keys(static::$constants[static::class]);
116
    }
117
118
    /**
119
     * @return string
120
     */
121
    public function getKey(): string
122
    {
123
        return $this->key;
124
    }
125
126
    /**
127
     * @return array
128
     */
129
    public function toArray(): array
130
    {
131
        return static::$constants[static::class];
132
    }
133
134
    /**
135
     * @return string
136
     */
137
    public function __toString(): string
138
    {
139
        return $this->value;
140
    }
141
}
142