From 264f7fc169e74e6eb413cc99d840828689f9089c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 4 Feb 2024 13:31:34 +0100 Subject: [PATCH] forward-compatibility with field mappings in Doctrine ORM 4 --- .../Doctrine/Form/DoctrineOrmTypeGuesser.php | 14 ++++++-- .../PropertyInfo/DoctrineExtractor.php | 34 +++++++++++++------ .../Doctrine/Validator/DoctrineLoader.php | 28 ++++++++++----- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php index 6386318ef97d9..33cfb0eb3b432 100644 --- a/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php +++ b/src/Symfony/Bridge/Doctrine/Form/DoctrineOrmTypeGuesser.php @@ -13,6 +13,7 @@ use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\ORM\Mapping\JoinColumnMapping; use Doctrine\ORM\Mapping\MappingException as LegacyMappingException; use Doctrine\Persistence\ManagerRegistry; use Doctrine\Persistence\Mapping\MappingException; @@ -119,13 +120,13 @@ public function guessRequired(string $class, string $property) if ($classMetadata->isAssociationWithSingleJoinColumn($property)) { $mapping = $classMetadata->getAssociationMapping($property); - if (!isset($mapping['joinColumns'][0]['nullable'])) { + if (null === self::getMappingValue($mapping['joinColumns'][0], 'nullable')) { // The "nullable" option defaults to true, in that case the // field should not be required. return new ValueGuess(false, Guess::HIGH_CONFIDENCE); } - return new ValueGuess(!$mapping['joinColumns'][0]['nullable'], Guess::HIGH_CONFIDENCE); + return new ValueGuess(!self::getMappingValue($mapping['joinColumns'][0], 'nullable'), Guess::HIGH_CONFIDENCE); } return null; @@ -198,4 +199,13 @@ private static function getRealClass(string $class): string return substr($class, $pos + Proxy::MARKER_LENGTH + 2); } + + private static function getMappingValue(array|JoinColumnMapping $mapping, string $key): mixed + { + if ($mapping instanceof JoinColumnMapping) { + return $mapping->$key; + } + + return $mapping[$key] ?? null; + } } diff --git a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php index f33a62cb6257c..d4156b48f1bfb 100644 --- a/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php +++ b/src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php @@ -16,6 +16,9 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\AssociationMapping; use Doctrine\ORM\Mapping\ClassMetadata; +use Doctrine\ORM\Mapping\EmbeddedClassMapping; +use Doctrine\ORM\Mapping\FieldMapping; +use Doctrine\ORM\Mapping\JoinColumnMapping; use Doctrine\ORM\Mapping\MappingException as OrmMappingException; use Doctrine\Persistence\Mapping\MappingException; use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface; @@ -88,20 +91,20 @@ public function getTypes(string $class, string $property, array $context = []) if ($metadata instanceof ClassMetadata) { $associationMapping = $metadata->getAssociationMapping($property); - if (isset($associationMapping['indexBy'])) { - $subMetadata = $this->entityManager->getClassMetadata($associationMapping['targetEntity']); + if (self::getMappingValue($associationMapping, 'indexBy')) { + $subMetadata = $this->entityManager->getClassMetadata(self::getMappingValue($associationMapping, 'targetEntity')); // Check if indexBy value is a property - $fieldName = $associationMapping['indexBy']; + $fieldName = self::getMappingValue($associationMapping, 'indexBy'); if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) { - $fieldName = $subMetadata->getFieldForColumn($associationMapping['indexBy']); + $fieldName = $subMetadata->getFieldForColumn(self::getMappingValue($associationMapping, 'indexBy')); // Not a property, maybe a column name? if (null === ($typeOfField = $subMetadata->getTypeOfField($fieldName))) { // Maybe the column name is the association join column? $associationMapping = $subMetadata->getAssociationMapping($fieldName); $indexProperty = $subMetadata->getSingleAssociationReferencedJoinColumnName($fieldName); - $subMetadata = $this->entityManager->getClassMetadata($associationMapping['targetEntity']); + $subMetadata = $this->entityManager->getClassMetadata(self::getMappingValue($associationMapping, 'targetEntity')); // Not a property, maybe a column name? if (null === ($typeOfField = $subMetadata->getTypeOfField($indexProperty))) { @@ -128,7 +131,7 @@ public function getTypes(string $class, string $property, array $context = []) } if ($metadata instanceof ClassMetadata && isset($metadata->embeddedClasses[$property])) { - return [new Type(Type::BUILTIN_TYPE_OBJECT, false, $metadata->embeddedClasses[$property]['class'])]; + return [new Type(Type::BUILTIN_TYPE_OBJECT, false, self::getMappingValue($metadata->embeddedClasses[$property], 'class'))]; } if ($metadata->hasField($property)) { @@ -140,7 +143,7 @@ public function getTypes(string $class, string $property, array $context = []) $nullable = $metadata instanceof ClassMetadata && $metadata->isNullable($property); $enumType = null; - if (null !== $enumClass = $metadata->getFieldMapping($property)['enumType'] ?? null) { + if (null !== $enumClass = self::getMappingValue($metadata->getFieldMapping($property), 'enumType') ?? null) { $enumType = new Type(Type::BUILTIN_TYPE_OBJECT, $nullable, $enumClass); } @@ -236,17 +239,17 @@ private function getMetadata(string $class): ?ClassMetadata */ private function isAssociationNullable($associationMapping): bool { - if (isset($associationMapping['id']) && $associationMapping['id']) { + if (self::getMappingValue($associationMapping, 'id')) { return false; } - if (!isset($associationMapping['joinColumns'])) { + if (!self::getMappingValue($associationMapping, 'joinColumns')) { return true; } - $joinColumns = $associationMapping['joinColumns']; + $joinColumns = self::getMappingValue($associationMapping, 'joinColumns'); foreach ($joinColumns as $joinColumn) { - if (isset($joinColumn['nullable']) && !$joinColumn['nullable']) { + if (false === self::getMappingValue($joinColumn, 'nullable')) { return false; } } @@ -302,4 +305,13 @@ private function getPhpType(string $doctrineType): ?string return null; } + + private static function getMappingValue(array|AssociationMapping|EmbeddedClassMapping|FieldMapping|JoinColumnMapping $mapping, string $key): mixed + { + if ($mapping instanceof AssociationMapping || $mapping instanceof EmbeddedClassMapping || $mapping instanceof FieldMapping || $mapping instanceof JoinColumnMapping) { + return $mapping->$key; + } + + return $mapping[$key] ?? null; + } } diff --git a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php index 601ef0f2b5fa6..d33224a6513d1 100644 --- a/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php +++ b/src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php @@ -13,6 +13,7 @@ use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata as OrmClassMetadata; +use Doctrine\ORM\Mapping\FieldMapping; use Doctrine\ORM\Mapping\MappingException as OrmMappingException; use Doctrine\Persistence\Mapping\MappingException; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -75,7 +76,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool foreach ($doctrineMetadata->fieldMappings as $mapping) { $enabledForProperty = $enabledForClass; $lengthConstraint = null; - foreach ($metadata->getPropertyMetadata($mapping['fieldName']) as $propertyMetadata) { + foreach ($metadata->getPropertyMetadata(self::getFieldMappingValue($mapping, 'fieldName')) as $propertyMetadata) { // Enabling or disabling auto-mapping explicitly always takes precedence if (AutoMappingStrategy::DISABLED === $propertyMetadata->getAutoMappingStrategy()) { continue 2; @@ -95,26 +96,26 @@ public function loadClassMetadata(ClassMetadata $metadata): bool continue; } - if (true === ($mapping['unique'] ?? false) && !isset($existingUniqueFields[$mapping['fieldName']])) { - $metadata->addConstraint(new UniqueEntity(['fields' => $mapping['fieldName']])); + if (true === (self::getFieldMappingValue($mapping, 'unique') ?? false) && !isset($existingUniqueFields[self::getFieldMappingValue($mapping, 'fieldName')])) { + $metadata->addConstraint(new UniqueEntity(['fields' => self::getFieldMappingValue($mapping, 'fieldName')])); $loaded = true; } - if (null === ($mapping['length'] ?? null) || null !== ($mapping['enumType'] ?? null) || !\in_array($mapping['type'], ['string', 'text'], true)) { + if (null === (self::getFieldMappingValue($mapping, 'length') ?? null) || null !== (self::getFieldMappingValue($mapping, 'enumType') ?? null) || !\in_array(self::getFieldMappingValue($mapping, 'type'), ['string', 'text'], true)) { continue; } if (null === $lengthConstraint) { - if (isset($mapping['originalClass']) && !str_contains($mapping['declaredField'], '.')) { - $metadata->addPropertyConstraint($mapping['declaredField'], new Valid()); + if (self::getFieldMappingValue($mapping, 'originalClass') && !str_contains(self::getFieldMappingValue($mapping, 'declaredField'), '.')) { + $metadata->addPropertyConstraint(self::getFieldMappingValue($mapping, 'declaredField'), new Valid()); $loaded = true; - } elseif (property_exists($className, $mapping['fieldName']) && (!$doctrineMetadata->isMappedSuperclass || $metadata->getReflectionClass()->getProperty($mapping['fieldName'])->isPrivate())) { - $metadata->addPropertyConstraint($mapping['fieldName'], new Length(['max' => $mapping['length']])); + } elseif (property_exists($className, self::getFieldMappingValue($mapping, 'fieldName')) && (!$doctrineMetadata->isMappedSuperclass || $metadata->getReflectionClass()->getProperty(self::getFieldMappingValue($mapping, 'fieldName'))->isPrivate())) { + $metadata->addPropertyConstraint(self::getFieldMappingValue($mapping, 'fieldName'), new Length(['max' => self::getFieldMappingValue($mapping, 'length')])); $loaded = true; } } elseif (null === $lengthConstraint->max) { // If a Length constraint exists and no max length has been explicitly defined, set it - $lengthConstraint->max = $mapping['length']; + $lengthConstraint->max = self::getFieldMappingValue($mapping, 'length'); } } @@ -138,4 +139,13 @@ private function getExistingUniqueFields(ClassMetadata $metadata): array return $fields; } + + private static function getFieldMappingValue(array|FieldMapping $mapping, string $key): mixed + { + if ($mapping instanceof FieldMapping) { + return $mapping->$key; + } + + return $mapping[$key] ?? null; + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy