From 9d5ab4ce763810f42d2079bf42b8bf48264ffa5c Mon Sep 17 00:00:00 2001 From: HypeMC Date: Sat, 1 Oct 2022 19:48:04 +0200 Subject: [PATCH] Ensure consistent original data with enums 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. --- .../ORM/Internal/Hydration/AbstractHydrator.php | 2 +- .../Internal/Hydration/SimpleObjectHydrator.php | 17 +++++++++++++++++ .../Persisters/Entity/BasicEntityPersister.php | 3 +++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php index 5af8b876691..b4c945cc10d 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php @@ -697,7 +697,7 @@ protected function registerManaged(ClassMetadata $class, $entity, array $data) * * @return BackedEnum|array */ - 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 { diff --git a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php index 454330290eb..f6c66b7f3dc 100644 --- a/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php +++ b/lib/Doctrine/ORM/Internal/Hydration/SimpleObjectHydrator.php @@ -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; @@ -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) diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index bb974993133..6e6877e8952 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -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']);