From e70bc39af4705261d9a8bf50ab2d1858df646b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Paris?= Date: Tue, 27 Feb 2024 19:18:58 +0100 Subject: [PATCH] Add support for enum arguments to setValue() The ORM is relying on that feature. --- phpstan-baseline.neon | 10 ++++++++++ psalm-baseline.xml | 8 ++++++++ .../Reflection/EnumReflectionProperty.php | 14 ++++++++++++-- .../Reflection/EnumReflectionPropertyTest.php | 18 ++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 09d78ad0..532bcde2 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -10,6 +10,16 @@ parameters: count: 1 path: src/Persistence/Reflection/EnumReflectionProperty.php + - + message: "#^Method Doctrine\\\\Persistence\\\\Reflection\\\\EnumReflectionProperty\\:\\:toEnum\\(\\) should return array\\\\|BackedEnum but returns array\\\\.$#" + count: 1 + path: src/Persistence/Reflection/EnumReflectionProperty.php + + - + message: "#^Parameter \\#1 \\$callback of function array_map expects \\(callable\\(BackedEnum\\|int\\|string\\)\\: mixed\\)\\|null, array\\{class\\-string\\, 'from'\\} given\\.$#" + count: 1 + path: src/Persistence/Reflection/EnumReflectionProperty.php + - message: "#^Variable property access on \\$this\\(Doctrine\\\\Persistence\\\\Reflection\\\\TypedNoDefaultRuntimePublicReflectionProperty\\)\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 691a7da4..d2e52875 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -8,4 +8,12 @@ $parentClass === false + + + $value + + + $value + + diff --git a/src/Persistence/Reflection/EnumReflectionProperty.php b/src/Persistence/Reflection/EnumReflectionProperty.php index 8565884d..023e542a 100644 --- a/src/Persistence/Reflection/EnumReflectionProperty.php +++ b/src/Persistence/Reflection/EnumReflectionProperty.php @@ -10,6 +10,7 @@ use function array_map; use function is_array; +use function reset; /** * PHP Enum Reflection Property - special override for backed enums. @@ -86,13 +87,22 @@ private function fromEnum($enum) } /** - * @param int|string|int[]|string[] $value + * @param int|string|int[]|string[]|BackedEnum|BackedEnum[] $value * - * @return ($value is int|string ? BackedEnum : BackedEnum[]) + * @return ($value is int|string|BackedEnum ? BackedEnum : BackedEnum[]) */ private function toEnum($value) { + if ($value instanceof BackedEnum) { + return $value; + } + if (is_array($value)) { + $v = reset($value); + if ($v instanceof BackedEnum) { + return $value; + } + return array_map([$this->enumType, 'from'], $value); } diff --git a/tests_php81/Persistence/Reflection/EnumReflectionPropertyTest.php b/tests_php81/Persistence/Reflection/EnumReflectionPropertyTest.php index 14c81f0a..bf5fed7a 100644 --- a/tests_php81/Persistence/Reflection/EnumReflectionPropertyTest.php +++ b/tests_php81/Persistence/Reflection/EnumReflectionPropertyTest.php @@ -64,6 +64,24 @@ public function testSetValidArrayValue(): void self::assertSame(['H', 'D'], $reflProperty->getValue($object)); self::assertSame([Suit::Hearts, Suit::Diamonds], $object->suits); } + + public function testSetEnum(): void + { + $object = new TypedEnumClass(); + $reflProperty = new EnumReflectionProperty(new ReflectionProperty(TypedEnumClass::class, 'suit'), Suit::class); + $reflProperty->setValue($object, Suit::Hearts); + + self::assertSame(Suit::Hearts, $object->suit); + } + + public function testSetEnumArray(): void + { + $object = new TypedEnumClass(); + $reflProperty = new EnumReflectionProperty(new ReflectionProperty(TypedEnumClass::class, 'suits'), Suit::class); + $reflProperty->setValue($object, [Suit::Hearts, Suit::Diamonds]); + + self::assertSame([Suit::Hearts, Suit::Diamonds], $object->suits); + } } class TypedEnumClass