Completed
Push — master ( e58965...e4fdff )
by Julián
11:30
created

AbstractEnum::isAnyOf()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
/*
4
 * enum (https://github.com/phpgears/enum).
5
 * Enum object for PHP.
6
 *
7
 * @license MIT
8
 * @link https://github.com/phpgears/enum
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Gears\Enum;
15
16
use Gears\Enum\Exception\InvalidEnumValueException;
17
use Gears\Immutability\ImmutabilityBehaviour;
18
19
/**
20
 * Base immutable enum class.
21
 */
22
abstract class AbstractEnum implements Enum
23
{
24
    use ImmutabilityBehaviour;
25
26
    /**
27
     * Enum class constants map.
28
     *
29
     * @var array
30
     */
31
    protected static $enumCacheMap = [];
32
33
    /**
34
     * Enum value.
35
     *
36
     * @var mixed
37
     */
38
    private $value;
39
40
    /**
41
     * AbstractEnum constructor.
42
     *
43
     * @param mixed $value
44
     *
45
     * @throws InvalidEnumValueException
46
     */
47
    final public function __construct($value)
48
    {
49
        $this->checkImmutability();
50
51
        $this->checkValue($value);
52
53
        $this->value = $value;
54
    }
55
56
    /**
57
     * Value based static constructor.
58
     *
59
     * @param string  $value
60
     * @param mixed[] $params
61
     *
62
     * @return self
63
     */
64
    final public static function __callStatic(string $value, array $params)
65
    {
66
        if (\count($params) !== 0) {
67
            throw new InvalidEnumValueException('Enum static constructor must be called with no parameters');
68
        }
69
70
        $validValues = static::getValidValues();
0 ignored issues
show
Bug introduced by
Since getValidValues() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getValidValues() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
71
72
        if (!\array_key_exists($value, $validValues)) {
73
            throw new InvalidEnumValueException(\sprintf(
74
                '%s is not a valid value for enum %s',
75
                $value,
76
                static::class
77
            ));
78
        }
79
80
        return new static($validValues[$value]);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86
    final public function isEqualTo(Enum $enum): bool
87
    {
88
        return \get_class($enum) === static::class && $enum->getValue() === $this->value;
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    final public function isAnyOf(array $enums): bool
95
    {
96
        foreach ($enums as $enum) {
97
            if ($this->isEqualTo($enum)) {
98
                return true;
99
            }
100
        }
101
102
        return false;
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     */
108
    final public function getValue()
109
    {
110
        return $this->value;
111
    }
112
113
    /**
114
     * Check enum value validity.
115
     *
116
     * @param mixed $value
117
     *
118
     * @throws InvalidEnumValueException
119
     */
120
    private function checkValue($value): void
121
    {
122
        if (!\in_array($value, static::getValidValues(), true)) {
0 ignored issues
show
Bug introduced by
Since getValidValues() is declared private, calling it with static will lead to errors in possible sub-classes. You can either use self, or increase the visibility of getValidValues() to at least protected.

Let’s assume you have a class which uses late-static binding:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
}

public static function getSomeVariable()
{
    return static::getTemperature();
}

}

The code above will run fine in your PHP runtime. However, if you now create a sub-class and call the getSomeVariable() on that sub-class, you will receive a runtime error:

class YourSubClass extends YourClass {
      private static function getTemperature() {
        return "-182 °C";
    }
}

print YourSubClass::getSomeVariable(); // Will cause an access error.

In the case above, it makes sense to update SomeClass to use self instead:

class YourClass
{
    private static function getTemperature() {
        return "3422 °C";
    }

    public static function getSomeVariable()
    {
        return self::getTemperature();
    }
}
Loading history...
123
            throw new InvalidEnumValueException(\sprintf(
124
                '%s is not a valid value for enum %s',
125
                $value,
126
                static::class
127
            ));
128
        }
129
    }
130
131
    /**
132
     * Get list of valid enum values.
133
     *
134
     * @return array<string, mixed>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
135
     */
136
    private static function getValidValues(): array
137
    {
138
        $enumClass = static::class;
139
140
        if (!isset(static::$enumCacheMap[$enumClass])) {
141
            static::$enumCacheMap[$enumClass] = (new \ReflectionClass($enumClass))->getConstants();
142
        }
143
144
        return static::$enumCacheMap[$enumClass];
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     *
150
     * @return string[]
151
     */
152
    final protected function getAllowedInterfaces(): array
153
    {
154
        return [Enum::class];
155
    }
156
}
157