vendor/shopware/core/Framework/DataAbstractionLayer/Search/Criteria.php line 14

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\DataAbstractionLayer\Search;
  3. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  4. use Shopware\Core\Framework\DataAbstractionLayer\Search\Aggregation\Aggregation;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\Filter;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Grouping\FieldGrouping;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Query\ScoreQuery;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
  10. use Shopware\Core\Framework\Struct\Struct;
  11. class Criteria extends Struct
  12. {
  13.     /**
  14.      * no total count will be selected. Should be used if no pagination required (fastest)
  15.      */
  16.     public const TOTAL_COUNT_MODE_NONE 0;
  17.     /**
  18.      * exact total count will be selected. Should be used if an exact pagination is required (slow)
  19.      */
  20.     public const TOTAL_COUNT_MODE_EXACT 1;
  21.     /**
  22.      * fetches limit * 5 + 1. Should be used if pagination can work with "next page exists" (fast)
  23.      */
  24.     public const TOTAL_COUNT_MODE_NEXT_PAGES 2;
  25.     /**
  26.      * @var FieldSorting[]
  27.      */
  28.     protected $sorting = [];
  29.     /**
  30.      * @var Filter[]
  31.      */
  32.     protected $filters = [];
  33.     /**
  34.      * @var Filter[]
  35.      */
  36.     protected $postFilters = [];
  37.     /**
  38.      * @var Aggregation[]
  39.      */
  40.     protected $aggregations = [];
  41.     /**
  42.      * @var ScoreQuery[]
  43.      */
  44.     protected $queries = [];
  45.     /**
  46.      * @var FieldGrouping[]
  47.      */
  48.     protected $groupFields = [];
  49.     /**
  50.      * @var int|null
  51.      */
  52.     protected $offset;
  53.     /**
  54.      * @var int|null
  55.      */
  56.     protected $limit;
  57.     /**
  58.      * @var int
  59.      */
  60.     protected $totalCountMode self::TOTAL_COUNT_MODE_NONE;
  61.     /**
  62.      * @var Criteria[]
  63.      */
  64.     protected $associations = [];
  65.     /**
  66.      * @var string[]|array<int, string[]>
  67.      */
  68.     protected $ids;
  69.     /**
  70.      * @var array
  71.      */
  72.     protected $states = [];
  73.     /**
  74.      * @var bool
  75.      */
  76.     protected $inherited false;
  77.     /**
  78.      * @var string|null
  79.      */
  80.     protected $term;
  81.     /**
  82.      * @var array|null
  83.      */
  84.     protected $includes;
  85.     /**
  86.      * @var string|null
  87.      */
  88.     protected $title;
  89.     /**
  90.      * @param string[]|array<int, string[]> $ids
  91.      *
  92.      * @throws InconsistentCriteriaIdsException
  93.      */
  94.     public function __construct(array $ids = [])
  95.     {
  96.         if (\count($ids) > \count(array_filter($ids))) {
  97.             throw new InconsistentCriteriaIdsException();
  98.         }
  99.         $this->ids $ids;
  100.     }
  101.     /**
  102.      * @return string[]|array<int, string[]>
  103.      */
  104.     public function getIds(): array
  105.     {
  106.         return $this->ids;
  107.     }
  108.     public function getOffset(): ?int
  109.     {
  110.         return $this->offset;
  111.     }
  112.     public function getLimit(): ?int
  113.     {
  114.         return $this->limit;
  115.     }
  116.     public function getTotalCountMode(): int
  117.     {
  118.         return $this->totalCountMode;
  119.     }
  120.     /**
  121.      * @return FieldSorting[]
  122.      */
  123.     public function getSorting(): array
  124.     {
  125.         return $this->sorting;
  126.     }
  127.     /**
  128.      * @return Aggregation[]
  129.      */
  130.     public function getAggregations(): array
  131.     {
  132.         return $this->aggregations;
  133.     }
  134.     public function getAggregation(string $name): ?Aggregation
  135.     {
  136.         return $this->aggregations[$name] ?? null;
  137.     }
  138.     /**
  139.      * @return Filter[]
  140.      */
  141.     public function getFilters(): array
  142.     {
  143.         return $this->filters;
  144.     }
  145.     public function hasEqualsFilter($field): bool
  146.     {
  147.         return count(array_filter($this->filters, static function (Filter $filter) use ($field) {
  148.             /* EqualsFilter $filter */
  149.             return $filter instanceof EqualsFilter && $filter->getField() === $field;
  150.         })) > 0;
  151.     }
  152.     /**
  153.      * @return Filter[]
  154.      */
  155.     public function getPostFilters(): array
  156.     {
  157.         return $this->postFilters;
  158.     }
  159.     /**
  160.      * @return ScoreQuery[]
  161.      */
  162.     public function getQueries(): array
  163.     {
  164.         return $this->queries;
  165.     }
  166.     /**
  167.      * @return Criteria[]
  168.      */
  169.     public function getAssociations(): array
  170.     {
  171.         return $this->associations;
  172.     }
  173.     /**
  174.      * Returns the criteria for the provided association path. Also supports nested paths
  175.      *
  176.      * e.g `$criteria->getAssociation('categories.media.thumbnails')`
  177.      *
  178.      * @throws InconsistentCriteriaIdsException
  179.      */
  180.     public function getAssociation(string $path): Criteria
  181.     {
  182.         $parts explode('.'$path);
  183.         $criteria $this;
  184.         foreach ($parts as $part) {
  185.             if ($part === 'extensions') {
  186.                 continue;
  187.             }
  188.             if (!$criteria->hasAssociation($part)) {
  189.                 $criteria->associations[$part] = new Criteria();
  190.             }
  191.             $criteria $criteria->associations[$part];
  192.         }
  193.         return $criteria;
  194.     }
  195.     public function addFilter(Filter ...$queries): self
  196.     {
  197.         foreach ($queries as $query) {
  198.             $this->filters[] = $query;
  199.         }
  200.         return $this;
  201.     }
  202.     public function addSorting(FieldSorting ...$sorting): self
  203.     {
  204.         foreach ($sorting as $sort) {
  205.             $this->sorting[] = $sort;
  206.         }
  207.         return $this;
  208.     }
  209.     public function addAggregation(Aggregation ...$aggregations): self
  210.     {
  211.         foreach ($aggregations as $aggregation) {
  212.             $this->aggregations[$aggregation->getName()] = $aggregation;
  213.         }
  214.         return $this;
  215.     }
  216.     public function addPostFilter(Filter ...$queries): self
  217.     {
  218.         foreach ($queries as $query) {
  219.             $this->postFilters[] = $query;
  220.         }
  221.         return $this;
  222.     }
  223.     public function addQuery(ScoreQuery ...$queries): self
  224.     {
  225.         foreach ($queries as $query) {
  226.             $this->queries[] = $query;
  227.         }
  228.         return $this;
  229.     }
  230.     /**
  231.      * Add for each part of the provided path an association
  232.      *
  233.      * e.g
  234.      *
  235.      * $criteria->addAssociation('categories.media.thumbnails')
  236.      *
  237.      * @throws InconsistentCriteriaIdsException
  238.      */
  239.     public function addAssociation(string $path): self
  240.     {
  241.         $parts explode('.'$path);
  242.         $criteria $this;
  243.         foreach ($parts as $part) {
  244.             if (\mb_strtolower($part) === 'extensions') {
  245.                 continue;
  246.             }
  247.             $criteria $criteria->getAssociation($part);
  248.         }
  249.         return $this;
  250.     }
  251.     /**
  252.      * Allows to add multiple associations paths
  253.      *
  254.      * e.g.:
  255.      *
  256.      * $criteria->addAssociations([
  257.      *      'prices',
  258.      *      'cover.media',
  259.      *      'categories.cover.media'
  260.      * ]);
  261.      *
  262.      * @throws InconsistentCriteriaIdsException
  263.      */
  264.     public function addAssociations(array $paths): self
  265.     {
  266.         foreach ($paths as $path) {
  267.             $this->addAssociation($path);
  268.         }
  269.         return $this;
  270.     }
  271.     public function hasAssociation(string $field): bool
  272.     {
  273.         return isset($this->associations[$field]);
  274.     }
  275.     public function resetSorting(): self
  276.     {
  277.         $this->sorting = [];
  278.         return $this;
  279.     }
  280.     public function resetAssociations(): self
  281.     {
  282.         $this->associations = [];
  283.         return $this;
  284.     }
  285.     public function resetQueries(): self
  286.     {
  287.         $this->queries = [];
  288.         return $this;
  289.     }
  290.     public function resetFilters(): self
  291.     {
  292.         $this->filters = [];
  293.         return $this;
  294.     }
  295.     public function resetPostFilters(): self
  296.     {
  297.         $this->postFilters = [];
  298.         return $this;
  299.     }
  300.     public function resetAggregations(): self
  301.     {
  302.         $this->aggregations = [];
  303.         return $this;
  304.     }
  305.     public function setTotalCountMode(int $totalCountMode): self
  306.     {
  307.         $this->totalCountMode $totalCountMode;
  308.         return $this;
  309.     }
  310.     public function setLimit(?int $limit): self
  311.     {
  312.         $this->limit $limit;
  313.         return $this;
  314.     }
  315.     public function setOffset(?int $offset): self
  316.     {
  317.         $this->offset $offset;
  318.         return $this;
  319.     }
  320.     public function getAggregationQueryFields(): array
  321.     {
  322.         return $this->collectFields([
  323.             $this->filters,
  324.             $this->queries,
  325.         ]);
  326.     }
  327.     public function getSearchQueryFields(): array
  328.     {
  329.         return $this->collectFields([
  330.             $this->filters,
  331.             $this->postFilters,
  332.             $this->sorting,
  333.             $this->queries,
  334.             $this->groupFields,
  335.         ]);
  336.     }
  337.     public function getFilterFields(): array
  338.     {
  339.         return $this->collectFields([
  340.             $this->filters,
  341.             $this->postFilters,
  342.         ]);
  343.     }
  344.     public function getAllFields(): array
  345.     {
  346.         return $this->collectFields([
  347.             $this->filters,
  348.             $this->postFilters,
  349.             $this->sorting,
  350.             $this->queries,
  351.             $this->groupFields,
  352.             $this->aggregations,
  353.         ]);
  354.     }
  355.     /**
  356.      * @param string[]|array<int, string[]> $ids
  357.      */
  358.     public function setIds(array $ids): self
  359.     {
  360.         $this->ids $ids;
  361.         return $this;
  362.     }
  363.     public function addState(string $state): self
  364.     {
  365.         $this->states[$state] = true;
  366.         return $this;
  367.     }
  368.     public function hasState(string $state): bool
  369.     {
  370.         return isset($this->states[$state]);
  371.     }
  372.     public function getTerm(): ?string
  373.     {
  374.         return $this->term;
  375.     }
  376.     public function setTerm(?string $term): self
  377.     {
  378.         $this->term $term;
  379.         return $this;
  380.     }
  381.     /**
  382.      * @param string[]|array<int, string[]> $ids
  383.      */
  384.     public function cloneForRead(array $ids = []): Criteria
  385.     {
  386.         $self = new self($ids);
  387.         $self->setTitle($this->getTitle());
  388.         $associations = [];
  389.         foreach ($this->associations as $name => $association) {
  390.             $associations[$name] = clone $association;
  391.         }
  392.         $self->associations $associations;
  393.         return $self;
  394.     }
  395.     public function addGroupField(FieldGrouping $grouping): self
  396.     {
  397.         $this->groupFields[] = $grouping;
  398.         return $this;
  399.     }
  400.     /**
  401.      * @return FieldGrouping[]
  402.      */
  403.     public function getGroupFields(): array
  404.     {
  405.         return $this->groupFields;
  406.     }
  407.     public function resetGroupFields(): self
  408.     {
  409.         $this->groupFields = [];
  410.         return $this;
  411.     }
  412.     public function setIncludes(?array $includes): void
  413.     {
  414.         $this->includes $includes;
  415.     }
  416.     public function getIncludes()
  417.     {
  418.         return $this->includes;
  419.     }
  420.     public function getApiAlias(): string
  421.     {
  422.         return 'dal_criteria';
  423.     }
  424.     public function useIdSorting(): bool
  425.     {
  426.         if (empty($this->getIds())) {
  427.             return false;
  428.         }
  429.         // manual sorting provided
  430.         if (!empty($this->getSorting())) {
  431.             return false;
  432.         }
  433.         // result will be sorted by interpreted search term and the calculated ranking
  434.         if (!empty($this->getTerm())) {
  435.             return false;
  436.         }
  437.         // result will be sorted by calculated ranking
  438.         if (!empty($this->getQueries())) {
  439.             return false;
  440.         }
  441.         return true;
  442.     }
  443.     public function removeAssociation(string $association): void
  444.     {
  445.         unset($this->associations[$association]);
  446.     }
  447.     public function getTitle(): ?string
  448.     {
  449.         return $this->title;
  450.     }
  451.     public function setTitle(?string $title): void
  452.     {
  453.         $this->title $title;
  454.     }
  455.     private function collectFields(array $parts): array
  456.     {
  457.         $fields = [];
  458.         foreach ($parts as $part) {
  459.             /** @var CriteriaPartInterface $item */
  460.             foreach ($part as $item) {
  461.                 foreach ($item->getFields() as $field) {
  462.                     $fields[] = $field;
  463.                 }
  464.             }
  465.         }
  466.         return $fields;
  467.     }
  468. }