Skip to content

Commit

Permalink
Container::getValue() supports conversion to enums [Close #337]
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Aug 5, 2024
1 parent bcd18af commit 0fe57bf
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/Forms/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
Expand Down
15 changes: 15 additions & 0 deletions src/Forms/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down
38 changes: 38 additions & 0 deletions tests/Forms/Container.values.mapping-enum.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

use Nette\Forms\Form;
use Tester\Assert;


require __DIR__ . '/../bootstrap.php';


enum TestEnum: string
{
case Case1 = 'case 1';
case Case2 = 'case 2';
}

class FormWithEnum
{
public function __construct(
public TestEnum $enum1,
public ?TestEnum $enum2,
) {
}
}


test('getValues() + enum', function () {
$form = new Form;
$form->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));
});

0 comments on commit 0fe57bf

Please sign in to comment.