Abstracted infering binding types away in a helper
This commit is contained in:
parent
4f9f7eedf5
commit
f7b14085f2
@ -25,6 +25,8 @@ use Doctrine\ORM\Persisters\SqlExpressionVisitor;
|
||||
use Doctrine\ORM\Persisters\SqlValueVisitor;
|
||||
use Doctrine\ORM\PersistentCollection;
|
||||
use Doctrine\ORM\Query;
|
||||
use Doctrine\ORM\UnitOfWork;
|
||||
use Doctrine\ORM\Utility\PersisterHelper as Helper;
|
||||
|
||||
/**
|
||||
* Persister for many-to-many collections.
|
||||
@ -384,7 +386,7 @@ class ManyToManyPersister extends AbstractCollectionPersister
|
||||
: $sourceClass->getFieldForColumn($columnName);
|
||||
|
||||
$params[] = $identifier[$field];
|
||||
$types[] = $this->getType($field, $sourceClass);
|
||||
$types[] = Helper::getTypeOfField($field, $sourceClass, $this->em);
|
||||
}
|
||||
|
||||
return array($params, $types);
|
||||
|
@ -863,12 +863,12 @@ class BasicEntityPersister implements EntityPersister
|
||||
list($params, $types) = $valueVisitor->getParamsAndTypes();
|
||||
|
||||
foreach ($params as $param) {
|
||||
$sqlParams[] = $this->getValue($param);
|
||||
$sqlParams[] = Helper::getValue($param, $this->em);
|
||||
}
|
||||
|
||||
foreach ($types as $type) {
|
||||
list($field, $value) = $type;
|
||||
$sqlTypes[] = $this->getType($field, $value);
|
||||
$sqlTypes[] = $this->getType($field, $value, $this->class);
|
||||
}
|
||||
|
||||
return array($sqlParams, $sqlTypes);
|
||||
@ -1306,13 +1306,14 @@ class BasicEntityPersister implements EntityPersister
|
||||
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
$type = $this->getColumnType($joinColumn['referencedColumnName'], null, $targetClass);
|
||||
$isIdentifier = isset($assoc['id']) && $assoc['id'] === true;
|
||||
$quotedColumn = $this->quoteStrategy->getJoinColumnName($joinColumn, $this->class, $this->platform);
|
||||
$resultColumnName = $this->getSQLColumnAlias($joinColumn['name']);
|
||||
$columnList[] = $this->getSQLTableAlias($class->name, ($alias == 'r' ? '' : $alias) )
|
||||
. '.' . $quotedColumn . ' AS ' . $resultColumnName;
|
||||
|
||||
$type = Helper::getTypeOfColumn($joinColumn['referencedColumnName'], $targetClass, $this->em);
|
||||
|
||||
$this->rsm->addMetaResult($alias, $resultColumnName, $quotedColumn, $isIdentifier, $type);
|
||||
}
|
||||
|
||||
@ -1762,8 +1763,8 @@ class BasicEntityPersister implements EntityPersister
|
||||
continue; // skip null values.
|
||||
}
|
||||
|
||||
$types[] = $this->getType($field, $value);
|
||||
$params[] = $this->getValue($value);
|
||||
$types[] = $this->getType($field, $value, $this->class);
|
||||
$params[] = Helper::getValue($value, $this->em);
|
||||
}
|
||||
|
||||
return array($params, $types);
|
||||
@ -1788,7 +1789,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
}
|
||||
|
||||
$types[] = $this->getType($criterion['field'], $criterion['value'], $criterion['class']);
|
||||
$params[] = $this->getValue($criterion['value']);
|
||||
$params[] = Helper::getValue($criterion['value'], $this->em);
|
||||
}
|
||||
|
||||
return array($params, $types);
|
||||
@ -1797,7 +1798,7 @@ class BasicEntityPersister implements EntityPersister
|
||||
/**
|
||||
* Infers the binding type of a field by parameter type casting.
|
||||
*
|
||||
* @param string $field
|
||||
* @param string $fieldName
|
||||
* @param mixed $value
|
||||
* @param ClassMetadata|null $class
|
||||
*
|
||||
@ -1805,11 +1806,9 @@ class BasicEntityPersister implements EntityPersister
|
||||
*
|
||||
* @throws \Doctrine\ORM\Query\QueryException
|
||||
*/
|
||||
private function getType($field, $value, ClassMetadata $class = null)
|
||||
private function getType($fieldName, $value, ClassMetadata $class)
|
||||
{
|
||||
if ($class === null) {
|
||||
$class = $this->class;
|
||||
}
|
||||
$type = Helper::getTypeOfField($fieldName, $class, $this->em);
|
||||
|
||||
switch (true) {
|
||||
case (isset($this->class->fieldMappings[$field])):
|
||||
@ -1867,105 +1866,6 @@ class BasicEntityPersister implements EntityPersister
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infers the binding type of a column by parameter type casting.
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param mixed $value
|
||||
* @param ClassMetadata $class
|
||||
* @return int|string|null
|
||||
*/
|
||||
private function getColumnType($columnName, $value, ClassMetadata $class)
|
||||
{
|
||||
$type = null;
|
||||
|
||||
switch (true) {
|
||||
case (isset($class->fieldNames[$columnName])):
|
||||
$fieldName = $class->fieldNames[$columnName];
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName])) {
|
||||
$type = $class->fieldMappings[$fieldName]['type'];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
$type = $this->getAssociationColumnType($columnName, $class);
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
$type = Type::getType($type)->getBindingType();
|
||||
$type += Connection::ARRAY_PARAM_OFFSET;
|
||||
}
|
||||
|
||||
return $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infers the binding type of a column by traversing association mappings.
|
||||
*
|
||||
* @param string $columnName
|
||||
* @param ClassMetadata $class
|
||||
* @return string|null
|
||||
*/
|
||||
private function getAssociationColumnType($columnName, ClassMetadata $class)
|
||||
{
|
||||
foreach ($class->associationMappings as $assoc) {
|
||||
foreach ($assoc['joinColumns'] as $joinColumn) {
|
||||
if ($joinColumn['name'] == $columnName) {
|
||||
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
|
||||
$targetColumn = $joinColumn['referencedColumnName'];
|
||||
|
||||
if (isset($targetClass->fieldNames[$targetColumn])) {
|
||||
return $targetClass->fieldMappings[$targetClass->fieldNames[$targetColumn]]['type'];
|
||||
}
|
||||
|
||||
return $this->getAssociationColumnType($targetColumn, $class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves parameter value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getValue($value)
|
||||
{
|
||||
if ( ! is_array($value)) {
|
||||
return $this->getIndividualValue($value);
|
||||
}
|
||||
|
||||
$newValue = array();
|
||||
|
||||
foreach ($value as $itemValue) {
|
||||
$newValue[] = $this->getIndividualValue($itemValue);
|
||||
}
|
||||
|
||||
return $newValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves an individual parameter value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function getIndividualValue($value)
|
||||
{
|
||||
if ( ! is_object($value) || ! $this->em->getMetadataFactory()->hasMetadataFor(ClassUtils::getClass($value))) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $this->em->getUnitOfWork()->getSingleIdentifierValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
144
lib/Doctrine/ORM/Utility/PersisterHelper.php
Normal file
144
lib/Doctrine/ORM/Utility/PersisterHelper.php
Normal file
@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* This software consists of voluntary contributions made by many individuals
|
||||
* and is licensed under the MIT license. For more information, see
|
||||
* <http://www.doctrine-project.org>.
|
||||
*/
|
||||
|
||||
namespace Doctrine\ORM\Utility;
|
||||
|
||||
use Doctrine\Common\Persistence\Mapping\ClassMetadata;
|
||||
use Doctrine\Common\Util\ClassUtils;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
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 <jasper@nerdsweide.nl>
|
||||
*/
|
||||
class PersisterHelper
|
||||
{
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param EntityManagerInterface $em
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public static function getValue($value, EntityManagerInterface $em)
|
||||
{
|
||||
if ( ! is_array($value)) {
|
||||
return self::getIndividualValue($value, $em);
|
||||
}
|
||||
|
||||
$newValue = array();
|
||||
|
||||
foreach ($value as $itemValue) {
|
||||
$newValue[] = self::getIndividualValue($itemValue, $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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $fieldName
|
||||
* @param ClassMetadata $class
|
||||
* @param EntityManagerInterface $em
|
||||
*
|
||||
* @throws QueryException
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getTypeOfField($fieldName, ClassMetadata $class, EntityManagerInterface $em)
|
||||
{
|
||||
/** @var \Doctrine\ORM\Mapping\ClassMetadataInfo $class */
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName])) {
|
||||
return $class->fieldMappings[$fieldName]['type'];
|
||||
}
|
||||
|
||||
if ( ! isset($class->associationMappings[$fieldName])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assoc = $class->associationMappings[$fieldName];
|
||||
|
||||
if (count($assoc['sourceToTargetKeyColumns']) > 1) {
|
||||
throw QueryException::associationPathCompositeKeyNotSupported();
|
||||
}
|
||||
|
||||
$targetColumnName = $assoc['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|null
|
||||
*/
|
||||
public static function getTypeOfColumn($columnName, ClassMetadata $class, EntityManagerInterface $em)
|
||||
{
|
||||
/** @var \Doctrine\ORM\Mapping\ClassMetadataInfo $class */
|
||||
|
||||
if (isset($class->fieldNames[$columnName])) {
|
||||
$fieldName = $class->fieldNames[$columnName];
|
||||
|
||||
if (isset($class->fieldMappings[$fieldName])) {
|
||||
return $class->fieldMappings[$fieldName]['type'];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user