Passed
Push — 4.x ( ac334b...b71b4a )
by Marc
41s
created

EnumMap::offsetSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MabeEnum;
6
7
use ArrayAccess;
8
use Countable;
9
use InvalidArgumentException;
10
use Iterator;
11
use IteratorAggregate;
12
use UnexpectedValueException;
13
14
/**
15
 * A map of enumerators (EnumMap<T>) and mixed values.
16
 *
17
 * @copyright 2019 Marc Bennewitz
18
 * @license http://github.com/marc-mabe/php-enum/blob/master/LICENSE.txt New BSD License
19
 * @link http://github.com/marc-mabe/php-enum for the canonical source repository
20
 */
3 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
21
class EnumMap implements ArrayAccess, Countable, IteratorAggregate
22
{
23
    /**
24
     * The classname of the enumeration type
25
     * @var string
26
     */
27
    private $enumeration;
1 ignored issue
show
Coding Style introduced by
Expected 1 blank line before member var; 0 found
Loading history...
Coding Style introduced by
Private member variable "enumeration" must contain a leading underscore
Loading history...
28
29
    /**
30
     * Internal map of ordinal number and value
31
     * @var array
32
     */
33
    private $map = [];
1 ignored issue
show
Coding Style introduced by
Private member variable "map" must contain a leading underscore
Loading history...
34
35
    /**
36
     * Constructor
37
     * @param string $enumeration The classname of the enumeration type
1 ignored issue
show
introduced by
Parameter comment must end with a full stop
Loading history...
38
     * @throws InvalidArgumentException
0 ignored issues
show
introduced by
Comment missing for @throws tag in function comment
Loading history...
39
     */
40 14
    public function __construct(string $enumeration)
41
    {
42 14
        if (!\is_subclass_of($enumeration, Enum::class)) {
43 1
            throw new InvalidArgumentException(\sprintf(
44 1
                '%s can handle subclasses of %s only',
45 1
                 __CLASS__,
46 1
                Enum::class
47
            ));
48
        }
49 13
        $this->enumeration = $enumeration;
50 13
    }
51
52
    /**
53
     * Get the classname of the enumeration
54
     * @return string
55
     */
56 1
    public function getEnumeration(): string
57
    {
58 1
        return $this->enumeration;
59
    }
60
61
    /**
62
     * Get a list of map keys
63
     * @return Enum[]
64
     */
65 3
    public function getKeys(): array
66
    {
67 3
        return \array_map([$this->enumeration, 'byOrdinal'], \array_keys($this->map));
68
    }
69
70
    /**
71
     * Get a list of map values
72
     * @return mixed[]
73
     */
74 3
    public function getValues(): array
75
    {
76 3
        return \array_values($this->map);
77
    }
78
79
    /**
80
     * Search for the given value
81
     * @param mixed $value
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
82
     * @param bool $strict Use strict type comparison
2 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for parameter type
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter type; 1 found
Loading history...
introduced by
Parameter comment must end with a full stop
Loading history...
83
     * @return Enum|null The found key or NULL
84
     */
85 2
    public function search($value, bool $strict = false)
2 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$strict" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$strict"; expected 0 but found 1
Loading history...
86
    {
87 2
        $ord = \array_search($value, $this->map, $strict);
88 2
        if ($ord !== false) {
89 2
            return ($this->enumeration)::byOrdinal($ord);
90
        }
91
92 2
        return null;
93
    }
94
95
    /**
96
     * Test if the given enumerator exists
97
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
98
     * @return bool
1 ignored issue
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
99
     * @see offsetExists
100
     */
101 4
    public function contains($enumerator): bool
102
    {
103
        try {
104 4
            $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
105 3
            return \array_key_exists($ord, $this->map);
106 1
        } catch (InvalidArgumentException $e) {
107
            // An invalid enumerator can't be contained in this map
108 1
            return false;
109
        }
110
    }
111
112
    /**
113
     * Test if the given enumerator key exists and is not NULL
114
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
115
     * @return bool
1 ignored issue
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
116
     * @see contains
117
     */
118 5
    public function offsetExists($enumerator): bool
119
    {
120
        try {
121 5
            return isset($this->map[($this->enumeration)::get($enumerator)->getOrdinal()]);
122 1
        } catch (InvalidArgumentException $e) {
123
            // An invalid enumerator can't be an offset of this map
124 1
            return false;
125
        }
126
    }
127
128
    /**
129
     * Get mapped data for the given enumerator
130
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
131
     * @return mixed
132
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
133
     * @throws UnexpectedValueException If the given enumerator does not exist in this map
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
134
     */
135 7
    public function offsetGet($enumerator)
136
    {
137 7
        $enumerator = ($this->enumeration)::get($enumerator);
138 7
        $ord = $enumerator->getOrdinal();
139 7
        if (!isset($this->map[$ord]) && !\array_key_exists($ord, $this->map)) {
140 2
            throw new UnexpectedValueException(sprintf(
141 2
                'Enumerator %s could not be found',
142 2
                \var_export($enumerator->getValue(), true)
143
            ));
144
        }
145
146 5
        return $this->map[$ord];
147
    }
148
149
    /**
150
     * Attach a new enumerator or overwrite an existing one
151
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
152
     * @param mixed                                 $value
0 ignored issues
show
Documentation introduced by
Missing parameter comment
Loading history...
153
     * @return void
154
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
155
     * @see attach()
156
     */
157 10
    public function offsetSet($enumerator, $value = null): void
2 ignored issues
show
Coding Style introduced by
Incorrect spacing between argument "$value" and equals sign; expected 0 but found 1
Loading history...
Coding Style introduced by
Incorrect spacing between default value and equals sign for argument "$value"; expected 0 but found 1
Loading history...
158
    {
159 10
        $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
160 9
        $this->map[$ord] = $value;
161 9
    }
162
163
    /**
164
     * Detach an existing enumerator
165
     * @param Enum|null|bool|int|float|string|array $enumerator
1 ignored issue
show
Documentation introduced by
Missing parameter comment
Loading history...
Coding Style introduced by
Expected "Enum|null|boolean|integer|float|string|array" but found "Enum|null|bool|int|float|string|array" for parameter type
Loading history...
166
     * @return void
167
     * @throws InvalidArgumentException On an invalid given enumerator
0 ignored issues
show
introduced by
@throws tag comment must end with a full stop
Loading history...
168
     * @see detach()
169
     */
170 4
    public function offsetUnset($enumerator): void
171
    {
172 4
        $ord = ($this->enumeration)::get($enumerator)->getOrdinal();
173 4
        unset($this->map[$ord]);
174 4
    }
175
176
    /**
177
     * Get a new Iterator.
178
     *
179
     * @return Iterator
180
     */
181 2
    public function getIterator(): Iterator
182
    {
183 2
        $map = $this->map;
184 2
        foreach ($map as $ordinal => $value) {
185 2
            yield ($this->enumeration)::byOrdinal($ordinal) => $value;
186
        }
187 2
    }
188
189
    /**
190
     * Count the number of elements
191
     *
192
     * @return int
1 ignored issue
show
Coding Style introduced by
Expected "integer" but found "int" for function return type
Loading history...
193
     */
194 2
    public function count(): int
195
    {
196 2
        return \count($this->map);
197
    }
198
}
199