Skip to content

Commit 7c690d9

Browse files
committed
Merge branch 'release/1.1'
2 parents 993d084 + fb62fcf commit 7c690d9

3 files changed

Lines changed: 87 additions & 3 deletions

File tree

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Table of Contents
1818
* [To loop a enum object](#to-loop-a-enum-object)
1919
* [To compare the enum values, use === operator](#to-compare-the-enum-values-use--operator)
2020
* [Convert a string to enum object](#convert-a-string-to-enum-object)
21+
* [Convert a value to enum object](#convert-a-value-to-enum-object)
2122
* [Switch case](#switch-case)
2223
* [Use enum in the type hint](#use-enum-in-the-type-hint)
2324
* [Add some logic to enum](#add-some-logic-to-enum)
@@ -98,6 +99,15 @@ $enum = UserStatus::valueOf('ACTIVE');
9899
assert(UserStatus::ACTIVE() === UserStatus::valueOf('ACTIVE'));
99100
```
100101

102+
## Convert a value to enum object
103+
```php
104+
$enum = UserStatus::valueOf('ACTIVE');
105+
$value = $enum->value();
106+
107+
assert(UserStatus::fromValue($value) === $enum);
108+
assert(UserStatus::fromValue($value) === UserStatus::valueOf('ACTIVE'));
109+
```
110+
101111
## Switch case
102112
```php
103113
$enum = UserStatus::PENDING();
@@ -322,8 +332,10 @@ abstract class Nelexa\Enum {
322332
final public static values ( void ) : static[]
323333
final public static containsKey ( string $name ) : bool
324334
final public static containsValue ( mixed $value [, bool $strict = true ] ) : bool
335+
final public static function fromValue( mixed $value ): static
325336
final public ordinal ( void ) : int
326337
public __toString ( void ) : string
338+
protected static function getEnumConstants(): array
327339
}
328340
```
329341

src/Enum.php

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ final public static function valueOf(string $name): self
101101
*
102102
* @return array Array of constants.
103103
*/
104-
private static function getEnumConstants(): array
104+
protected static function getEnumConstants(): array
105105
{
106106
static $enumConstants = [];
107107
if (!isset($enumConstants[static::class])) {
@@ -168,7 +168,7 @@ final public static function containsKey(string $name): bool
168168
/**
169169
* Checks if enum contains a passed value.
170170
*
171-
* @param mixed $value Checked value.
171+
* @param string|int|float|bool|array|null $value Checked value.
172172
* @param bool $strict Strict check.
173173
*
174174
* @return bool Returns true if the value is defined in one of the constants.
@@ -178,6 +178,26 @@ final public static function containsValue($value, bool $strict = true): bool
178178
return in_array($value, self::getEnumConstants(), $strict);
179179
}
180180

181+
/**
182+
* Returns first enum of the specified constant value.
183+
*
184+
* @param string|int|float|bool|array|null $value Checked value.
185+
*
186+
* @return static the enum constant of the specified constant value.
187+
*/
188+
final public static function fromValue($value): self
189+
{
190+
$key = array_search($value, self::getEnumConstants(), true);
191+
if ($key === false) {
192+
throw new \InvalidArgumentException(sprintf(
193+
'Constant value "%s" is not defined in the %s class.',
194+
$value,
195+
static::class
196+
));
197+
}
198+
return self::valueOf($key);
199+
}
200+
181201
/**
182202
* Returns the ordinal of this enum constant.
183203
*

tests/EnumTest.php

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
namespace Nelexa\Tests;
55

6-
use Nelexa\Tests\Enums\ExampleEnum;
76
use Nelexa\Tests\Enums\EnumExtended;
7+
use Nelexa\Tests\Enums\ExampleEnum;
88
use Nelexa\Tests\Enums\OverrideToStringEnum;
99
use PHPUnit\Framework\TestCase;
1010

@@ -195,4 +195,56 @@ public function testEnumProperty(): void
195195

196196
unset($enum->new_field_name); // __unset invoke
197197
}
198+
199+
/**
200+
* @dataProvider provideEnumFromValue
201+
*
202+
* @param string $name
203+
* @param mixed $value
204+
*/
205+
public function testEnumFromValue(string $name, $value): void
206+
{
207+
$enum = ExampleEnum::valueOf($name);
208+
209+
$this->assertSame(ExampleEnum::fromValue($value), $enum);
210+
}
211+
212+
/**
213+
* @return array
214+
*/
215+
public function provideEnumFromValue(): array
216+
{
217+
return [
218+
['VALUE_INT', ExampleEnum::VALUE_INT],
219+
['VALUE_INT_1000', ExampleEnum::VALUE_INT_1000],
220+
['VALUE_STRING', ExampleEnum::VALUE_STRING],
221+
['VALUE_BOOL_TRUE', ExampleEnum::VALUE_BOOL_TRUE],
222+
['VALUE_BOOL_FALSE', ExampleEnum::VALUE_BOOL_FALSE],
223+
['VALUE_FLOAT', ExampleEnum::VALUE_FLOAT],
224+
['VALUE_NULL', ExampleEnum::VALUE_NULL],
225+
['VALUE_EMPTY_STRING', ExampleEnum::VALUE_EMPTY_STRING],
226+
['SCALAR_EXPRESSION', ExampleEnum::SCALAR_EXPRESSION],
227+
['CONST', ExampleEnum::CONST],
228+
['PUBLIC_CONST', ExampleEnum::PUBLIC_CONST],
229+
['PRIVATE_CONST', 'private'],
230+
['PROTECTED_CONST', 'protected'],
231+
['LANG_CODES', ExampleEnum::LANG_CODES],
232+
['COUNTRY_CODES', ExampleEnum::COUNTRY_CODES],
233+
];
234+
}
235+
236+
public function testEnumFromValueForSameValues(): void
237+
{
238+
$this->assertSame(ExampleEnum::fromValue(ExampleEnum::VALUE_EQUALS_1), ExampleEnum::VALUE_EQUALS_1());
239+
$this->assertSame(ExampleEnum::fromValue(ExampleEnum::VALUE_EQUALS_2), ExampleEnum::VALUE_EQUALS_1());
240+
$this->assertNotSame(ExampleEnum::fromValue(ExampleEnum::VALUE_EQUALS_2), ExampleEnum::VALUE_EQUALS_2());
241+
}
242+
243+
public function testEnumFromValueIncorrectValue(): void
244+
{
245+
$this->expectException(\InvalidArgumentException::class);
246+
$this->expectExceptionMessage('Constant value "Unknown value" is not defined');
247+
248+
ExampleEnum::fromValue('Unknown value');
249+
}
198250
}

0 commit comments

Comments
 (0)