Skip to content

Commit

Permalink
Ensure consistent original data with enums
Browse files Browse the repository at this point in the history
Previously different hydrators would store the original data for enum
fields in different ways, the SimpleObjectHydrator would keep them as
strings while other hydrators would convert then to native php enums.

This would make the data in the internal UnitOfWork::$originalEntityData
array inconsistent which could've caused problems in the long run.

Now, all hydrators convert enum fields to native php enums ensuring the
original data is always consistent regardless of the hydrator used.
  • Loading branch information
HypeMC committed Dec 7, 2022
1 parent a2b5bae commit 9d5ab4c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
Expand Up @@ -697,7 +697,7 @@ protected function registerManaged(ClassMetadata $class, $entity, array $data)
*
* @return BackedEnum|array<BackedEnum>
*/
private function buildEnum($value, string $enumType)
final protected function buildEnum($value, string $enumType)
{
if (is_array($value)) {
return array_map(static function ($value) use ($enumType): BackedEnum {
Expand Down
17 changes: 17 additions & 0 deletions lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php
Expand Up @@ -6,9 +6,11 @@

use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\ORM\Query;
use Exception;
use RuntimeException;
use ValueError;

use function array_keys;
use function array_search;
Expand Down Expand Up @@ -140,6 +142,21 @@ protected function hydrateRowData(array $row, array &$result)
$value = $type->convertToPHPValue($value, $this->_platform);
}

if ($value !== null && isset($cacheKeyInfo['enumType'])) {
$originalValue = $value;
try {
$value = $this->buildEnum($originalValue, $cacheKeyInfo['enumType']);
} catch (ValueError $e) {
throw MappingException::invalidEnumValue(
$entityName,
$cacheKeyInfo['fieldName'],
(string) $originalValue,
$cacheKeyInfo['enumType'],
$e
);
}
}

$fieldName = $cacheKeyInfo['fieldName'];

// Prevent overwrite in case of inherit classes using same property name (See AbstractHydrator)
Expand Down
3 changes: 3 additions & 0 deletions lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php
Expand Up @@ -1506,6 +1506,9 @@ protected function getSelectColumnSQL($field, ClassMetadata $class, $alias = 'r'
$columnAlias = $this->getSQLColumnAlias($fieldMapping['columnName']);

$this->currentPersisterContext->rsm->addFieldResult($alias, $columnAlias, $field);
if (! empty($fieldMapping['enumType'])) {
$this->currentPersisterContext->rsm->addEnumResult($columnAlias, $fieldMapping['enumType']);
}

if (isset($fieldMapping['requireSQLConversion'])) {
$type = Type::getType($fieldMapping['type']);
Expand Down

0 comments on commit 9d5ab4c

Please sign in to comment.