. */ namespace Doctrine\ORM\Utility; use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadata; use Doctrine\ORM\Query\QueryException; /** * The PersisterHelper contains logic to infer binding types which is used in * several persisters. * * @link www.doctrine-project.org * @since 2.5 * @author Jasper N. Brouwer */ class PersisterHelper { /** * @param string $fieldName * @param ClassMetadata $class * @param EntityManagerInterface $em * * @return string|null * * @throws QueryException */ public static function getTypeOfField($fieldName, ClassMetadata $class, EntityManagerInterface $em) { if (isset($class->fieldMappings[$fieldName])) { return $class->fieldMappings[$fieldName]['type']; } if ( ! isset($class->associationMappings[$fieldName])) { return null; } $assoc = $class->associationMappings[$fieldName]; if (! $assoc['isOwningSide']) { return self::getTypeOfField($assoc['mappedBy'], $em->getClassMetadata($assoc['targetEntity']), $em); } if (($assoc['type'] & ClassMetadata::MANY_TO_MANY) > 0) { $joinData = $assoc['joinTable']; } else { $joinData = $assoc; } if (count($joinData['joinColumns']) > 1) { throw QueryException::associationPathCompositeKeyNotSupported(); } $targetColumnName = $joinData['joinColumns'][0]['referencedColumnName']; $targetClass = $em->getClassMetadata($assoc['targetEntity']); return self::getTypeOfColumn($targetColumnName, $targetClass, $em); } /** * @param string $columnName * @param ClassMetadata $class * @param EntityManagerInterface $em * * @return string * * @throws \RuntimeException */ public static function getTypeOfColumn($columnName, ClassMetadata $class, EntityManagerInterface $em) { if (isset($class->fieldNames[$columnName])) { $fieldName = $class->fieldNames[$columnName]; if (isset($class->fieldMappings[$fieldName])) { return $class->fieldMappings[$fieldName]['type']; } } // iterate over to-one association mappings foreach ($class->associationMappings as $assoc) { if ( ! isset($assoc['joinColumns'])) { continue; } foreach ($assoc['joinColumns'] as $joinColumn) { if ($joinColumn['name'] == $columnName) { $targetColumnName = $joinColumn['referencedColumnName']; $targetClass = $em->getClassMetadata($assoc['targetEntity']); return self::getTypeOfColumn($targetColumnName, $targetClass, $em); } } } // iterate over to-many association mappings foreach ($class->associationMappings as $assoc) { if ( ! (isset($assoc['joinTable']) && isset($assoc['joinTable']['joinColumns']))) { continue; } foreach ($assoc['joinTable']['joinColumns'] as $joinColumn) { if ($joinColumn['name'] == $columnName) { $targetColumnName = $joinColumn['referencedColumnName']; $targetClass = $em->getClassMetadata($assoc['targetEntity']); return self::getTypeOfColumn($targetColumnName, $targetClass, $em); } } } throw new \RuntimeException(sprintf( 'Could not resolve type of column "%s" of class "%s"', $columnName, $class->getName() )); } /** * @param mixed $value * @param EntityManagerInterface $em * * @return mixed */ public static function getIdentifierValues($value, EntityManagerInterface $em) { if ( ! is_array($value)) { return self::getIndividualValue($value, $em); } $newValue = array(); foreach ($value as $fieldName => $fieldValue) { $newValue[$fieldName] = self::getIndividualValue($fieldValue, $em); } return $newValue; } /** * @param mixed $value * @param EntityManagerInterface $em * * @return mixed */ private static function getIndividualValue($value, EntityManagerInterface $em) { if ( ! is_object($value) || ! $em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value))) { return $value; } return $em->getUnitOfWork()->getSingleIdentifierValue($value); } }