Skip to content

Commit

Permalink
Automatic conversion enum/int - when mapping to class
Browse files Browse the repository at this point in the history
Nette forms doesnt support data type Enum when mapping form values to class. This makes problems when using forms - see error reported here: https://forum.nette.org/cs/36594-prevod-vybraneho-optionu-v-selectu-na-enum-type

The fix isnt complicated and makes no BC break. The case is in more details discussed here: https://forum.nette.org/cs/36601-rfc-konverze-na-datovy-typ-enum-a-int-pri-mapovani-hodnot-formulare
  • Loading branch information
mildabre authored Aug 3, 2024
1 parent 2c13c05 commit b17fa58
Showing 1 changed file with 35 additions and 2 deletions.
37 changes: 35 additions & 2 deletions src/Forms/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,13 @@ public function getUntrustedValues(string|object|null $returnType = null, ?array
&& $allowed
&& !$control->isOmitted()
) {
$obj->$name = $control->getValue();
$value = $control->getValue();
$property = $rc->hasProperty($name)? $rc->getProperty($name) : null;
$obj->$name = $property ? match(true){
static::isPropertyEnum($property) => static::getEnumCaseByName($property->getType()->getName(), $value),
Helpers::getSingleType($property) === 'int' => static::stringToInt($value, $name),
default => $value,
} : $value;

} elseif ($control instanceof self) {
$type = $returnType === self::Array && !$control->mappedType
Expand All @@ -172,7 +178,34 @@ public function getUntrustedValues(string|object|null $returnType = null, ?array
: $obj;
}



private static function isPropertyEnum(ReflectionProperty $property): bool
{
return !$property->getType()->isBuiltin() && (new ReflectionClass($property->getType()->getName()))->isEnum();
}


private static function getEnumCaseByName(string $class, ?string $name): ?object
{
foreach($class::cases() as $case){
if($case->name === $name){
return $case;
}
}
return null;
}


private static function stringToInt(?string $value, string $name): ?int
{
if($value === null){
return $value;
}
$intValue = (int)$value;
return $value === (string)$intValue ? $intValue : throw new InvalidValueException("Value '$value' of field '$name' is not valid integer number");
}


/** @deprecated use getUntrustedValues() */
public function getUnsafeValues($returnType, ?array $controls = null)
{
Expand Down

0 comments on commit b17fa58

Please sign in to comment.