vendor/doctrine/orm/src/Query/FilterCollection.php line 114

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Doctrine\ORM\Query;
  4. use Doctrine\ORM\Configuration;
  5. use Doctrine\ORM\EntityManagerInterface;
  6. use Doctrine\ORM\Query\Filter\SQLFilter;
  7. use InvalidArgumentException;
  8. use function assert;
  9. use function ksort;
  10. /**
  11.  * Collection class for all the query filters.
  12.  */
  13. class FilterCollection
  14. {
  15.     /* Filter STATES */
  16.     /**
  17.      * A filter object is in CLEAN state when it has no changed parameters.
  18.      */
  19.     public const FILTERS_STATE_CLEAN 1;
  20.     /**
  21.      * A filter object is in DIRTY state when it has changed parameters.
  22.      */
  23.     public const FILTERS_STATE_DIRTY 2;
  24.     /**
  25.      * The used Configuration.
  26.      *
  27.      * @var Configuration
  28.      */
  29.     private $config;
  30.     /**
  31.      * The EntityManager that "owns" this FilterCollection instance.
  32.      *
  33.      * @var EntityManagerInterface
  34.      */
  35.     private $em;
  36.     /**
  37.      * Instances of enabled filters.
  38.      *
  39.      * @var SQLFilter[]
  40.      * @phpstan-var array<string, SQLFilter>
  41.      */
  42.     private $enabledFilters = [];
  43.     /**
  44.      * Instances of suspended filters.
  45.      *
  46.      * @var SQLFilter[]
  47.      * @phpstan-var array<string, SQLFilter>
  48.      */
  49.     private $suspendedFilters = [];
  50.     /**
  51.      * The filter hash from the last time the query was parsed.
  52.      *
  53.      * @var string
  54.      */
  55.     private $filterHash '';
  56.     /**
  57.      * The current state of this filter.
  58.      *
  59.      * @var int
  60.      * @phpstan-var self::FILTERS_STATE_*
  61.      */
  62.     private $filtersState self::FILTERS_STATE_CLEAN;
  63.     public function __construct(EntityManagerInterface $em)
  64.     {
  65.         $this->em     $em;
  66.         $this->config $em->getConfiguration();
  67.     }
  68.     /**
  69.      * Gets all the enabled filters.
  70.      *
  71.      * @return SQLFilter[] The enabled filters.
  72.      * @phpstan-return array<string, SQLFilter>
  73.      */
  74.     public function getEnabledFilters()
  75.     {
  76.         return $this->enabledFilters;
  77.     }
  78.     /**
  79.      * Gets all the suspended filters.
  80.      *
  81.      * @return SQLFilter[] The suspended filters.
  82.      * @phpstan-return array<string, SQLFilter>
  83.      */
  84.     public function getSuspendedFilters(): array
  85.     {
  86.         return $this->suspendedFilters;
  87.     }
  88.     /**
  89.      * Enables a filter from the collection.
  90.      *
  91.      * @param string $name Name of the filter.
  92.      *
  93.      * @return SQLFilter The enabled filter.
  94.      *
  95.      * @throws InvalidArgumentException If the filter does not exist.
  96.      */
  97.     public function enable($name)
  98.     {
  99.         if (! $this->has($name)) {
  100.             throw new InvalidArgumentException("Filter '" $name "' does not exist.");
  101.         }
  102.         if (! $this->isEnabled($name)) {
  103.             $filterClass $this->config->getFilterClassName($name);
  104.             assert($filterClass !== null);
  105.             $this->enabledFilters[$name] = new $filterClass($this->em);
  106.             // In case a suspended filter with the same name was forgotten
  107.             unset($this->suspendedFilters[$name]);
  108.             // Keep the enabled filters sorted for the hash
  109.             ksort($this->enabledFilters);
  110.             $this->setFiltersStateDirty();
  111.         }
  112.         return $this->enabledFilters[$name];
  113.     }
  114.     /**
  115.      * Disables a filter.
  116.      *
  117.      * @param string $name Name of the filter.
  118.      *
  119.      * @return SQLFilter The disabled filter.
  120.      *
  121.      * @throws InvalidArgumentException If the filter does not exist.
  122.      */
  123.     public function disable($name)
  124.     {
  125.         // Get the filter to return it
  126.         $filter $this->getFilter($name);
  127.         unset($this->enabledFilters[$name]);
  128.         $this->setFiltersStateDirty();
  129.         return $filter;
  130.     }
  131.     /**
  132.      * Suspend a filter.
  133.      *
  134.      * @param string $name Name of the filter.
  135.      *
  136.      * @return SQLFilter The suspended filter.
  137.      *
  138.      * @throws InvalidArgumentException If the filter does not exist.
  139.      */
  140.     public function suspend(string $name): SQLFilter
  141.     {
  142.         // Get the filter to return it
  143.         $filter $this->getFilter($name);
  144.         $this->suspendedFilters[$name] = $filter;
  145.         unset($this->enabledFilters[$name]);
  146.         $this->setFiltersStateDirty();
  147.         return $filter;
  148.     }
  149.     /**
  150.      * Restore a disabled filter from the collection.
  151.      *
  152.      * @param string $name Name of the filter.
  153.      *
  154.      * @return SQLFilter The restored filter.
  155.      *
  156.      * @throws InvalidArgumentException If the filter does not exist.
  157.      */
  158.     public function restore(string $name): SQLFilter
  159.     {
  160.         if (! $this->isSuspended($name)) {
  161.             throw new InvalidArgumentException("Filter '" $name "' is not suspended.");
  162.         }
  163.         $this->enabledFilters[$name] = $this->suspendedFilters[$name];
  164.         unset($this->suspendedFilters[$name]);
  165.         // Keep the enabled filters sorted for the hash
  166.         ksort($this->enabledFilters);
  167.         $this->setFiltersStateDirty();
  168.         return $this->enabledFilters[$name];
  169.     }
  170.     /**
  171.      * Gets an enabled filter from the collection.
  172.      *
  173.      * @param string $name Name of the filter.
  174.      *
  175.      * @return SQLFilter The filter.
  176.      *
  177.      * @throws InvalidArgumentException If the filter is not enabled.
  178.      */
  179.     public function getFilter($name)
  180.     {
  181.         if (! $this->isEnabled($name)) {
  182.             throw new InvalidArgumentException("Filter '" $name "' is not enabled.");
  183.         }
  184.         return $this->enabledFilters[$name];
  185.     }
  186.     /**
  187.      * Checks whether filter with given name is defined.
  188.      *
  189.      * @param string $name Name of the filter.
  190.      *
  191.      * @return bool true if the filter exists, false if not.
  192.      */
  193.     public function has($name)
  194.     {
  195.         return $this->config->getFilterClassName($name) !== null;
  196.     }
  197.     /**
  198.      * Checks if a filter is enabled.
  199.      *
  200.      * @param string $name Name of the filter.
  201.      *
  202.      * @return bool True if the filter is enabled, false otherwise.
  203.      */
  204.     public function isEnabled($name)
  205.     {
  206.         return isset($this->enabledFilters[$name]);
  207.     }
  208.     /**
  209.      * Checks if a filter is suspended.
  210.      *
  211.      * @param string $name Name of the filter.
  212.      *
  213.      * @return bool True if the filter is suspended, false otherwise.
  214.      */
  215.     public function isSuspended(string $name): bool
  216.     {
  217.         return isset($this->suspendedFilters[$name]);
  218.     }
  219.     /**
  220.      * Checks if the filter collection is clean.
  221.      *
  222.      * @return bool
  223.      */
  224.     public function isClean()
  225.     {
  226.         return $this->filtersState === self::FILTERS_STATE_CLEAN;
  227.     }
  228.     /**
  229.      * Generates a string of currently enabled filters to use for the cache id.
  230.      *
  231.      * @return string
  232.      */
  233.     public function getHash()
  234.     {
  235.         // If there are only clean filters, the previous hash can be returned
  236.         if ($this->filtersState === self::FILTERS_STATE_CLEAN) {
  237.             return $this->filterHash;
  238.         }
  239.         $filterHash '';
  240.         foreach ($this->enabledFilters as $name => $filter) {
  241.             $filterHash .= $name $filter;
  242.         }
  243.         $this->filterHash   $filterHash;
  244.         $this->filtersState self::FILTERS_STATE_CLEAN;
  245.         return $filterHash;
  246.     }
  247.     /**
  248.      * Sets the filter state to dirty.
  249.      *
  250.      * @return void
  251.      */
  252.     public function setFiltersStateDirty()
  253.     {
  254.         $this->filtersState self::FILTERS_STATE_DIRTY;
  255.     }
  256. }