From 583811558239bd7f8f375e7c2c363628537b5625 Mon Sep 17 00:00:00 2001 From: Asmir Mustafic Date: Thu, 29 Jan 2015 00:43:32 +0100 Subject: [PATCH] Fixed type checking on to-many relations --- .../Entity/BasicEntityPersister.php | 53 ++++++------------- .../ORM/Utility/IdentifierFlattener.php | 6 ++- lib/Doctrine/ORM/Utility/PersisterHelper.php | 20 ++++--- 3 files changed, 29 insertions(+), 50 deletions(-) diff --git a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php index 715a0696d..a7c5a8d27 100644 --- a/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php +++ b/lib/Doctrine/ORM/Persisters/Entity/BasicEntityPersister.php @@ -1809,7 +1809,6 @@ class BasicEntityPersister implements EntityPersister $types = array_merge($types, $this->getTypes($field, $value, $this->class)); $params = array_merge($params, $this->getValues($value)); } - return array($params, $types); } @@ -1838,7 +1837,6 @@ class BasicEntityPersister implements EntityPersister $types = array_merge($types, $this->getTypes($criterion['field'], $criterion['value'], $criterion['class'])); $params = array_merge($params, $this->getValues($criterion['value'])); } - return array($params, $types); } @@ -1855,27 +1853,32 @@ class BasicEntityPersister implements EntityPersister private function getTypes($field, $value, ClassMetadata $class) { $types = array(); + switch (true) { - case (isset($this->class->fieldMappings[$field])): - $types[] = $this->class->fieldMappings[$field]['type']; + case (isset($class->fieldMappings[$field])): + $types = array_merge($types, PersisterHelper::getTypeOfField($field, $class, $this->em)); break; + case (isset($class->associationMappings[$field])): + $assoc = $class->associationMappings[$field]; - case (isset($this->class->associationMappings[$field])): - $assoc = $this->class->associationMappings[$field]; + $class = $this->em->getClassMetadata($assoc['targetEntity']); + if (!$assoc['isOwningSide']) { + $assoc = $class->associationMappings[$assoc['mappedBy']]; + $class = $this->em->getClassMetadata($assoc['targetEntity']); + } - $targetPersister = $this->em->getUnitOfWork()->getEntityPersister($assoc['targetEntity']); if ($assoc['type'] === ClassMetadata::MANY_TO_MANY) { - if(!$assoc['isOwningSide']){ - $class = $this->em->getClassMetadata($assoc['targetEntity']); - $assoc = $class->associationMappings[$assoc['mappedBy']]; + foreach ($assoc['relationToSourceKeyColumns'] as $field => $val){ + $types = array_merge($types, PersisterHelper::getTypeOfField($val, $class, $this->em)); } - $parameters = $targetPersister->expandParameters($assoc['relationToSourceKeyColumns']); } else { - $parameters = $targetPersister->expandParameters($assoc['isOwningSide']?$assoc['targetToSourceKeyColumns']:$assoc['sourceToTargetKeyColumns']); + + foreach ($assoc['targetToSourceKeyColumns'] as $field => $val){ + $types = array_merge($types, PersisterHelper::getTypeOfField($field, $class, $this->em)); + } } - $types = array_merge($types, $parameters[1]); break; default: @@ -1889,7 +1892,6 @@ class BasicEntityPersister implements EntityPersister return $type + Connection::ARRAY_PARAM_OFFSET; }, $types); } - return $types; } @@ -1927,29 +1929,6 @@ class BasicEntityPersister implements EntityPersister return array($this->getIndividualValue($value)); } - /** - * Infers field type to be used by parameter type casting. - * - * @param string $fieldName - * @param mixed $value - * @param ClassMetadata $class - * - * @return integer - * - * @throws \Doctrine\ORM\Query\QueryException - */ - private function getType($fieldName, $value, ClassMetadata $class) - { - $type = PersisterHelper::getTypeOfField($fieldName, $class, $this->em); - - if (is_array($value)) { - $type = Type::getType($type)->getBindingType(); - $type += Connection::ARRAY_PARAM_OFFSET; - } - - return $type; - } - /** * Retrieves an individual parameter value. * diff --git a/lib/Doctrine/ORM/Utility/IdentifierFlattener.php b/lib/Doctrine/ORM/Utility/IdentifierFlattener.php index fbad711e3..bb6e33464 100644 --- a/lib/Doctrine/ORM/Utility/IdentifierFlattener.php +++ b/lib/Doctrine/ORM/Utility/IdentifierFlattener.php @@ -71,8 +71,10 @@ final class IdentifierFlattener { $flatId = array(); - foreach ($class->identifier as $field) { - if (isset($class->associationMappings[$field]) && isset($id[$field]) && is_object($id[$field])) { + foreach ($class->identifier as $field) { + if (isset($class->associationMappings[$field]) && isset($id[$field]) && $id[$field] instanceof \Doctrine\ORM\Cache\AssociationCacheEntry) { + $flatId[$field] = implode(' ', $id[$field]->identifier); + } elseif (isset($class->associationMappings[$field]) && isset($id[$field]) && is_object($id[$field])) { $targetClassMetadata = $this->metadataFactory->getMetadataFor( $class->associationMappings[$field]['targetEntity'] ); diff --git a/lib/Doctrine/ORM/Utility/PersisterHelper.php b/lib/Doctrine/ORM/Utility/PersisterHelper.php index 6c3af11da..662e6c74a 100644 --- a/lib/Doctrine/ORM/Utility/PersisterHelper.php +++ b/lib/Doctrine/ORM/Utility/PersisterHelper.php @@ -40,18 +40,18 @@ class PersisterHelper * @param ClassMetadata $class * @param EntityManagerInterface $em * - * @return string|null + * @return array * * @throws QueryException */ public static function getTypeOfField($fieldName, ClassMetadata $class, EntityManagerInterface $em) { if (isset($class->fieldMappings[$fieldName])) { - return $class->fieldMappings[$fieldName]['type']; + return array($class->fieldMappings[$fieldName]['type']); } if ( ! isset($class->associationMappings[$fieldName])) { - return null; + return array(); } $assoc = $class->associationMappings[$fieldName]; @@ -60,20 +60,18 @@ class PersisterHelper return self::getTypeOfField($assoc['mappedBy'], $em->getClassMetadata($assoc['targetEntity']), $em); } - if (($assoc['type'] & ClassMetadata::MANY_TO_MANY) > 0) { + if ($assoc['type'] & ClassMetadata::MANY_TO_MANY) { $joinData = $assoc['joinTable']; } else { $joinData = $assoc; } - if (count($joinData['joinColumns']) > 1) { - throw QueryException::associationPathCompositeKeyNotSupported(); + $types = array(); + $targetClass = $em->getClassMetadata($assoc['targetEntity']); + foreach ($joinData['joinColumns'] as $joinColumn) { + $types[] = self::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $em); } - - $targetColumnName = $joinData['joinColumns'][0]['referencedColumnName']; - $targetClass = $em->getClassMetadata($assoc['targetEntity']); - - return self::getTypeOfColumn($targetColumnName, $targetClass, $em); + return $types; } /**