vendor/doctrine/orm/src/Query/Filter/SQLFilter.php line 111

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\ORM\Query\Filter;
  4. use Doctrine\DBAL\Connection;
  5. use Doctrine\DBAL\Types\Types;
  6. use Doctrine\ORM\EntityManagerInterface;
  7. use Doctrine\ORM\Mapping\ClassMetadata;
  8. use Doctrine\ORM\Query\ParameterTypeInferer;
  9. use InvalidArgumentException;
  10. use function array_map;
  11. use function implode;
  12. use function ksort;
  13. use function serialize;
  14. /**
  15.  * The base class that user defined filters should extend.
  16.  *
  17.  * Handles the setting and escaping of parameters.
  18.  *
  19.  * @abstract
  20.  */
  21. abstract class SQLFilter
  22. {
  23.     /**
  24.      * The entity manager.
  25.      *
  26.      * @var EntityManagerInterface
  27.      */
  28.     private $em;
  29.     /**
  30.      * Parameters for the filter.
  31.      *
  32.      * @psalm-var array<string,array{type: string, value: mixed, is_list: bool}>
  33.      */
  34.     private $parameters = [];
  35.     /** @param EntityManagerInterface $em The entity manager. */
  36.     final public function __construct(EntityManagerInterface $em)
  37.     {
  38.         $this->em $em;
  39.     }
  40.     /**
  41.      * Sets a parameter list that can be used by the filter.
  42.      *
  43.      * @param string       $name   Name of the parameter.
  44.      * @param array<mixed> $values List of parameter values.
  45.      * @param string       $type   The parameter type. If specified, the given value will be run through
  46.      *                             the type conversion of this type.
  47.      *
  48.      * @return $this
  49.      */
  50.     final public function setParameterList(string $name, array $valuesstring $type Types::STRING): self
  51.     {
  52.         $this->parameters[$name] = ['value' => $values'type' => $type'is_list' => true];
  53.         // Keep the parameters sorted for the hash
  54.         ksort($this->parameters);
  55.         // The filter collection of the EM is now dirty
  56.         $this->em->getFilters()->setFiltersStateDirty();
  57.         return $this;
  58.     }
  59.     /**
  60.      * Sets a parameter that can be used by the filter.
  61.      *
  62.      * @param string      $name  Name of the parameter.
  63.      * @param mixed       $value Value of the parameter.
  64.      * @param string|null $type  The parameter type. If specified, the given value will be run through
  65.      *                           the type conversion of this type. This is usually not needed for
  66.      *                           strings and numeric types.
  67.      *
  68.      * @return $this
  69.      */
  70.     final public function setParameter($name$value$type null): self
  71.     {
  72.         if ($type === null) {
  73.             $type ParameterTypeInferer::inferType($value);
  74.         }
  75.         $this->parameters[$name] = ['value' => $value'type' => $type'is_list' => false];
  76.         // Keep the parameters sorted for the hash
  77.         ksort($this->parameters);
  78.         // The filter collection of the EM is now dirty
  79.         $this->em->getFilters()->setFiltersStateDirty();
  80.         return $this;
  81.     }
  82.     /**
  83.      * Gets a parameter to use in a query.
  84.      *
  85.      * The function is responsible for the right output escaping to use the
  86.      * value in a query.
  87.      *
  88.      * @param string $name Name of the parameter.
  89.      *
  90.      * @return string The SQL escaped parameter to use in a query.
  91.      *
  92.      * @throws InvalidArgumentException
  93.      */
  94.     final public function getParameter($name)
  95.     {
  96.         if (! isset($this->parameters[$name])) {
  97.             throw new InvalidArgumentException("Parameter '" $name "' does not exist.");
  98.         }
  99.         if ($this->parameters[$name]['is_list']) {
  100.             throw FilterException::cannotConvertListParameterIntoSingleValue($name);
  101.         }
  102.         $param $this->parameters[$name];
  103.         return $this->em->getConnection()->quote($param['value'], $param['type']);
  104.     }
  105.     /**
  106.      * Gets a parameter to use in a query assuming it's a list of entries.
  107.      *
  108.      * The function is responsible for the right output escaping to use the
  109.      * value in a query, separating each entry by comma to inline it into
  110.      * an IN() query part.
  111.      *
  112.      * @param string $name Name of the parameter.
  113.      *
  114.      * @return string The SQL escaped parameter to use in a query.
  115.      *
  116.      * @throws InvalidArgumentException
  117.      */
  118.     final public function getParameterList(string $name): string
  119.     {
  120.         if (! isset($this->parameters[$name])) {
  121.             throw new InvalidArgumentException("Parameter '" $name "' does not exist.");
  122.         }
  123.         if ($this->parameters[$name]['is_list'] === false) {
  124.             throw FilterException::cannotConvertSingleParameterIntoListValue($name);
  125.         }
  126.         $param      $this->parameters[$name];
  127.         $connection $this->em->getConnection();
  128.         $quoted array_map(static function ($value) use ($connection$param) {
  129.             return $connection->quote($value$param['type']);
  130.         }, $param['value']);
  131.         return implode(','$quoted);
  132.     }
  133.     /**
  134.      * Checks if a parameter was set for the filter.
  135.      *
  136.      * @param string $name Name of the parameter.
  137.      *
  138.      * @return bool
  139.      */
  140.     final public function hasParameter($name)
  141.     {
  142.         return isset($this->parameters[$name]);
  143.     }
  144.     /**
  145.      * Returns as string representation of the SQLFilter parameters (the state).
  146.      *
  147.      * @return string String representation of the SQLFilter.
  148.      */
  149.     final public function __toString()
  150.     {
  151.         return serialize($this->parameters);
  152.     }
  153.     /**
  154.      * Returns the database connection used by the entity manager
  155.      */
  156.     final protected function getConnection(): Connection
  157.     {
  158.         return $this->em->getConnection();
  159.     }
  160.     /**
  161.      * Gets the SQL query part to add to a query.
  162.      *
  163.      * @param string $targetTableAlias
  164.      * @psalm-param ClassMetadata<object> $targetEntity
  165.      *
  166.      * @return string The constraint SQL if there is available, empty string otherwise.
  167.      */
  168.     abstract public function addFilterConstraint(ClassMetadata $targetEntity$targetTableAlias);
  169. }