vendor/symfony/doctrine-bridge/Form/ChoiceList/ORMQueryBuilderLoader.php line 46

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Bridge\Doctrine\Form\ChoiceList;
  11. use Doctrine\DBAL\Connection;
  12. use Doctrine\DBAL\Types\ConversionException;
  13. use Doctrine\DBAL\Types\Type;
  14. use Doctrine\ORM\QueryBuilder;
  15. use Symfony\Component\Form\Exception\TransformationFailedException;
  16. /**
  17.  * Loads entities using a {@link QueryBuilder} instance.
  18.  *
  19.  * @author Benjamin Eberlei <kontakt@beberlei.de>
  20.  * @author Bernhard Schussek <bschussek@gmail.com>
  21.  */
  22. class ORMQueryBuilderLoader implements EntityLoaderInterface
  23. {
  24.     /**
  25.      * Contains the query builder that builds the query for fetching the
  26.      * entities.
  27.      *
  28.      * This property should only be accessed through queryBuilder.
  29.      */
  30.     private $queryBuilder;
  31.     public function __construct(QueryBuilder $queryBuilder)
  32.     {
  33.         $this->queryBuilder $queryBuilder;
  34.     }
  35.     /**
  36.      * {@inheritdoc}
  37.      */
  38.     public function getEntities(): array
  39.     {
  40.         return $this->queryBuilder->getQuery()->execute();
  41.     }
  42.     /**
  43.      * {@inheritdoc}
  44.      */
  45.     public function getEntitiesByIds(string $identifier, array $values): array
  46.     {
  47.         if (null !== $this->queryBuilder->getMaxResults() || < (int) $this->queryBuilder->getFirstResult()) {
  48.             // an offset or a limit would apply on results including the where clause with submitted id values
  49.             // that could make invalid choices valid
  50.             $choices = [];
  51.             $metadata $this->queryBuilder->getEntityManager()->getClassMetadata(current($this->queryBuilder->getRootEntities()));
  52.             foreach ($this->getEntities() as $entity) {
  53.                 if (\in_array((string) current($metadata->getIdentifierValues($entity)), $valuestrue)) {
  54.                     $choices[] = $entity;
  55.                 }
  56.             }
  57.             return $choices;
  58.         }
  59.         $qb = clone $this->queryBuilder;
  60.         $alias current($qb->getRootAliases());
  61.         $parameter 'ORMQueryBuilderLoader_getEntitiesByIds_'.$identifier;
  62.         $parameter str_replace('.''_'$parameter);
  63.         $where $qb->expr()->in($alias.'.'.$identifier':'.$parameter);
  64.         // Guess type
  65.         $entity current($qb->getRootEntities());
  66.         $metadata $qb->getEntityManager()->getClassMetadata($entity);
  67.         if (\in_array($type $metadata->getTypeOfField($identifier), ['integer''bigint''smallint'])) {
  68.             $parameterType Connection::PARAM_INT_ARRAY;
  69.             // Filter out non-integer values (e.g. ""). If we don't, some
  70.             // databases such as PostgreSQL fail.
  71.             $values array_values(array_filter($values, function ($v) {
  72.                 return (string) $v === (string) (int) $v || ctype_digit($v);
  73.             }));
  74.         } elseif (\in_array($type, ['ulid''uuid''guid'])) {
  75.             $parameterType Connection::PARAM_STR_ARRAY;
  76.             // Like above, but we just filter out empty strings.
  77.             $values array_values(array_filter($values, function ($v) {
  78.                 return '' !== (string) $v;
  79.             }));
  80.             // Convert values into right type
  81.             if (Type::hasType($type)) {
  82.                 $doctrineType Type::getType($type);
  83.                 $platform $qb->getEntityManager()->getConnection()->getDatabasePlatform();
  84.                 foreach ($values as &$value) {
  85.                     try {
  86.                         $value $doctrineType->convertToDatabaseValue($value$platform);
  87.                     } catch (ConversionException $e) {
  88.                         throw new TransformationFailedException(sprintf('Failed to transform "%s" into "%s".'$value$type), 0$e);
  89.                     }
  90.                 }
  91.                 unset($value);
  92.             }
  93.         } else {
  94.             $parameterType Connection::PARAM_STR_ARRAY;
  95.         }
  96.         if (!$values) {
  97.             return [];
  98.         }
  99.         return $qb->andWhere($where)
  100.                   ->getQuery()
  101.                   ->setParameter($parameter$values$parameterType)
  102.                   ->getResult();
  103.     }
  104. }