From 0fe57bf2381f28dff40be32723355ddba3091100 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 3 Aug 2024 21:59:17 +0200 Subject: [PATCH] Container::getValue() supports conversion to enums [Close #337] --- src/Forms/Container.php | 5 ++- src/Forms/Helpers.php | 15 ++++++++ .../Forms/Container.values.mapping-enum.phpt | 38 +++++++++++++++++++ 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 tests/Forms/Container.values.mapping-enum.phpt diff --git a/src/Forms/Container.php b/src/Forms/Container.php index d68686d3..5a5fcde1 100644 --- a/src/Forms/Container.php +++ b/src/Forms/Container.php @@ -147,17 +147,18 @@ public function getUntrustedValues(string|object|null $returnType = null, ?array foreach ($this->getComponents() as $name => $control) { $allowed = $controls === null || in_array($this, $controls, true) || in_array($control, $controls, true); $name = (string) $name; + $property = $properties[$name] ?? null; if ( $control instanceof Control && $allowed && !$control->isOmitted() ) { - $resultObj->$name = $control->getValue(); + $resultObj->$name = Helpers::tryEnumConversion($control->getValue(), $property); } elseif ($control instanceof self) { $type = $returnType === self::Array && !$control->mappedType ? self::Array - : (isset($properties[$name]) ? Helpers::getSingleType($properties[$name]) : null); + : ($property ? Helpers::getSingleType($property) : null); $resultObj->$name = $control->getUntrustedValues($type, $allowed ? null : $controls); } } diff --git a/src/Forms/Helpers.php b/src/Forms/Helpers.php index 8aedb1f7..772fa540 100644 --- a/src/Forms/Helpers.php +++ b/src/Forms/Helpers.php @@ -299,6 +299,21 @@ public static function getSingleType($reflection): ?string } + /** @internal */ + public static function tryEnumConversion(mixed $value, $reflection): mixed + { + if ($value !== null + && $reflection + && ($type = Nette\Utils\Type::fromReflection($reflection)?->getSingleName()) + && is_a($type, \BackedEnum::class, allow_string: true) + ) { + return $type::from($value); + } + + return $value; + } + + /** @internal */ public static function getSupportedImages(): array { diff --git a/tests/Forms/Container.values.mapping-enum.phpt b/tests/Forms/Container.values.mapping-enum.phpt new file mode 100644 index 00000000..20c6d674 --- /dev/null +++ b/tests/Forms/Container.values.mapping-enum.phpt @@ -0,0 +1,38 @@ +addText('enum1'); + $form->addText('enum2')->setNullable(); + $form->setValues(['enum1' => 'case 1', 'enum2' => null]); + + Assert::equal(new FormWithEnum( + enum1: TestEnum::Case1, + enum2: null, + ), $form->getValues(FormWithEnum::class)); +});