vendor/shopware/core/System/SalesChannel/Entity/SalesChannelRepository.php line 152

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\System\SalesChannel\Entity;
  3. use Shopware\Core\Framework\DataAbstractionLayer\Entity;
  4. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityDefinition;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityAggregationResultLoadedEvent;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchResultLoadedEvent;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Field\AssociationField;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Read\EntityReaderInterface;
  12. use Shopware\Core\Framework\DataAbstractionLayer\RepositorySearchDetector;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResultCollection;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntityAggregatorInterface;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearcherInterface;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Search\IdSearchResult;
  19. use Shopware\Core\Framework\Struct\ArrayEntity;
  20. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  21. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  22. class SalesChannelRepository implements SalesChannelRepositoryInterface
  23. {
  24.     /**
  25.      * @var EntityDefinition|SalesChannelDefinitionInterface
  26.      */
  27.     protected $definition;
  28.     /**
  29.      * @var EntityReaderInterface
  30.      */
  31.     protected $reader;
  32.     /**
  33.      * @var EntitySearcherInterface
  34.      */
  35.     protected $searcher;
  36.     /**
  37.      * @var EntityAggregatorInterface
  38.      */
  39.     protected $aggregator;
  40.     /**
  41.      * @var EventDispatcherInterface
  42.      */
  43.     protected $eventDispatcher;
  44.     public function __construct(
  45.         EntityDefinition $definition,
  46.         EntityReaderInterface $reader,
  47.         EntitySearcherInterface $searcher,
  48.         EntityAggregatorInterface $aggregator,
  49.         EventDispatcherInterface $eventDispatcher
  50.     ) {
  51.         $this->definition $definition;
  52.         $this->reader $reader;
  53.         $this->searcher $searcher;
  54.         $this->aggregator $aggregator;
  55.         $this->eventDispatcher $eventDispatcher;
  56.     }
  57.     /**
  58.      * @throws InconsistentCriteriaIdsException
  59.      */
  60.     public function search(Criteria $criteriaSalesChannelContext $salesChannelContext): EntitySearchResult
  61.     {
  62.         $aggregations null;
  63.         if ($criteria->getAggregations()) {
  64.             $aggregations $this->aggregate($criteria$salesChannelContext);
  65.         } else {
  66.             $this->processCriteria($criteria$salesChannelContext);
  67.         }
  68.         if (!RepositorySearchDetector::isSearchRequired($this->definition$criteria)) {
  69.             $entities $this->read($criteria$salesChannelContext);
  70.             return new EntitySearchResult(
  71.                 $entities->count(),
  72.                 $entities,
  73.                 $aggregations,
  74.                 $criteria,
  75.                 $salesChannelContext->getContext()
  76.             );
  77.         }
  78.         $ids $this->doSearch($criteria$salesChannelContext);
  79.         $readCriteria $criteria->cloneForRead($ids->getIds());
  80.         $entities $this->read($readCriteria$salesChannelContext);
  81.         $search $ids->getData();
  82.         /** @var Entity $element */
  83.         foreach ($entities as $element) {
  84.             if (!\array_key_exists($element->getUniqueIdentifier(), $search)) {
  85.                 continue;
  86.             }
  87.             $data $search[$element->getUniqueIdentifier()];
  88.             unset($data['id']);
  89.             if (empty($data)) {
  90.                 continue;
  91.             }
  92.             $element->addExtension('search', new ArrayEntity($data));
  93.         }
  94.         $result = new EntitySearchResult(
  95.             $ids->getTotal(),
  96.             $entities,
  97.             $aggregations,
  98.             $criteria,
  99.             $salesChannelContext->getContext()
  100.         );
  101.         $event = new EntitySearchResultLoadedEvent($this->definition$result);
  102.         $this->eventDispatcher->dispatch($event$event->getName());
  103.         $event = new SalesChannelEntitySearchResultLoadedEvent($this->definition$result$salesChannelContext);
  104.         $this->eventDispatcher->dispatch($event$event->getName());
  105.         return $result;
  106.     }
  107.     public function aggregate(Criteria $criteriaSalesChannelContext $salesChannelContext): AggregationResultCollection
  108.     {
  109.         $this->processCriteria($criteria$salesChannelContext);
  110.         $result $this->aggregator->aggregate($this->definition$criteria$salesChannelContext->getContext());
  111.         $event = new EntityAggregationResultLoadedEvent($this->definition$result$salesChannelContext->getContext());
  112.         $this->eventDispatcher->dispatch($event$event->getName());
  113.         return $result;
  114.     }
  115.     public function searchIds(Criteria $criteriaSalesChannelContext $salesChannelContext): IdSearchResult
  116.     {
  117.         $this->processCriteria($criteria$salesChannelContext);
  118.         return $this->doSearch($criteria$salesChannelContext);
  119.     }
  120.     private function read(Criteria $criteriaSalesChannelContext $salesChannelContext): EntityCollection
  121.     {
  122.         $entities $this->reader->read($this->definition$criteria$salesChannelContext->getContext());
  123.         $event = new EntityLoadedEvent($this->definition$entities->getElements(), $salesChannelContext->getContext());
  124.         $this->eventDispatcher->dispatch($event$event->getName());
  125.         $event = new SalesChannelEntityLoadedEvent($this->definition$entities->getElements(), $salesChannelContext);
  126.         $this->eventDispatcher->dispatch($event$event->getName());
  127.         return $entities;
  128.     }
  129.     private function doSearch(Criteria $criteriaSalesChannelContext $salesChannelContext): IdSearchResult
  130.     {
  131.         $result $this->searcher->search($this->definition$criteria$salesChannelContext->getContext());
  132.         $event = new SalesChannelEntityIdSearchResultLoadedEvent($this->definition$result$salesChannelContext);
  133.         $this->eventDispatcher->dispatch($event$event->getName());
  134.         return $result;
  135.     }
  136.     private function processCriteria(Criteria $topCriteriaSalesChannelContext $salesChannelContext): void
  137.     {
  138.         if (!$this->definition instanceof SalesChannelDefinitionInterface) {
  139.             return;
  140.         }
  141.         $queue = [
  142.             ['definition' => $this->definition'criteria' => $topCriteria],
  143.         ];
  144.         $maxCount 100;
  145.         $processed = [];
  146.         // process all associations breadth-first
  147.         while (!empty($queue) && --$maxCount 0) {
  148.             $cur array_shift($queue);
  149.             /** @var EntityDefinition $definition */
  150.             $definition $cur['definition'];
  151.             /** @var Criteria $criteria */
  152.             $criteria $cur['criteria'];
  153.             if (isset($processed[get_class($definition)])) {
  154.                 continue;
  155.             }
  156.             if ($definition instanceof SalesChannelDefinitionInterface) {
  157.                 $definition->processCriteria($criteria$salesChannelContext);
  158.             }
  159.             $processed[get_class($definition)] = true;
  160.             foreach ($criteria->getAssociations() as $associationName => $associationCriteria) {
  161.                 // find definition
  162.                 $field $definition->getField($associationName);
  163.                 if (!$field instanceof AssociationField) {
  164.                     continue;
  165.                 }
  166.                 $referenceDefinition $field->getReferenceDefinition();
  167.                 $queue[] = ['definition' => $referenceDefinition'criteria' => $associationCriteria];
  168.             }
  169.         }
  170.     }
  171. }