vendor/shopware/platform/src/Core/Framework/DataAbstractionLayer/EntityRepository.php line 115

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\DataAbstractionLayer;
  3. use Shopware\Core\Framework\Context;
  4. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityAggregationResultLoadedEvent;
  5. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityIdSearchResultLoadedEvent;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEventFactory;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchedEvent;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchResultLoadedEvent;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenContainerEvent;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Read\EntityReaderInterface;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\AggregationResult\AggregationResultCollection;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntityAggregatorInterface;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearcherInterface;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\IdSearchResult;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Write\CloneBehavior;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Write\WriteContext;
  19. use Shopware\Core\Framework\Feature;
  20. use Shopware\Core\Framework\Struct\ArrayEntity;
  21. use Shopware\Core\Framework\Uuid\Exception\InvalidUuidException;
  22. use Shopware\Core\Framework\Uuid\Uuid;
  23. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  24. class EntityRepository implements EntityRepositoryInterface
  25. {
  26.     /**
  27.      * @var EntityReaderInterface
  28.      */
  29.     private $reader;
  30.     /**
  31.      * @var EntitySearcherInterface
  32.      */
  33.     private $searcher;
  34.     /**
  35.      * @var EntityAggregatorInterface
  36.      */
  37.     private $aggregator;
  38.     /**
  39.      * @var EventDispatcherInterface
  40.      */
  41.     private $eventDispatcher;
  42.     /**
  43.      * @var VersionManager
  44.      */
  45.     private $versionManager;
  46.     /**
  47.      * @var EntityDefinition
  48.      */
  49.     private $definition;
  50.     private ?EntityLoadedEventFactory $eventFactory;
  51.     public function __construct(
  52.         EntityDefinition $definition,
  53.         EntityReaderInterface $reader,
  54.         VersionManager $versionManager,
  55.         EntitySearcherInterface $searcher,
  56.         EntityAggregatorInterface $aggregator,
  57.         EventDispatcherInterface $eventDispatcher,
  58.         ?EntityLoadedEventFactory $eventFactory null
  59.     ) {
  60.         $this->reader $reader;
  61.         $this->searcher $searcher;
  62.         $this->aggregator $aggregator;
  63.         $this->eventDispatcher $eventDispatcher;
  64.         $this->versionManager $versionManager;
  65.         $this->definition $definition;
  66.         if ($eventFactory !== null) {
  67.             $this->eventFactory $eventFactory;
  68.         } else {
  69.             Feature::throwException('FEATURE_NEXT_16155'sprintf('Repository for definition %s requires the event factory as __construct parameter'$definition->getEntityName()));
  70.         }
  71.     }
  72.     /**
  73.      * @deprecated tag:v6.5.0 - Will be removed, inject entity loaded event factory in __construct
  74.      */
  75.     public function setEntityLoadedEventFactory(EntityLoadedEventFactory $eventFactory): void
  76.     {
  77.         if (isset($this->eventFactory)) {
  78.             return;
  79.         }
  80.         Feature::throwException('FEATURE_NEXT_16155'sprintf('Repository for definition %s requires the event factory as __construct parameter'$this->definition->getEntityName()));
  81.         $this->eventFactory $eventFactory;
  82.     }
  83.     public function getDefinition(): EntityDefinition
  84.     {
  85.         return $this->definition;
  86.     }
  87.     public function search(Criteria $criteriaContext $context): EntitySearchResult
  88.     {
  89.         $criteria = clone $criteria;
  90.         $aggregations null;
  91.         if ($criteria->getAggregations()) {
  92.             $aggregations $this->aggregate($criteria$context);
  93.         }
  94.         if (!RepositorySearchDetector::isSearchRequired($this->definition$criteria)) {
  95.             $this->eventDispatcher->dispatch(
  96.                 new EntitySearchedEvent($criteria$this->definition$context)
  97.             );
  98.             $entities $this->read($criteria$context);
  99.             return new EntitySearchResult($this->definition->getEntityName(), $entities->count(), $entities$aggregations$criteria$context);
  100.         }
  101.         $ids $this->searchIds($criteria$context);
  102.         if (empty($ids->getIds())) {
  103.             $collection $this->definition->getCollectionClass();
  104.             return new EntitySearchResult($this->definition->getEntityName(), $ids->getTotal(), new $collection(), $aggregations$criteria$context);
  105.         }
  106.         $readCriteria $criteria->cloneForRead($ids->getIds());
  107.         $entities $this->read($readCriteria$context);
  108.         $search $ids->getData();
  109.         /** @var Entity $element */
  110.         foreach ($entities as $element) {
  111.             if (!\array_key_exists($element->getUniqueIdentifier(), $search)) {
  112.                 continue;
  113.             }
  114.             $data $search[$element->getUniqueIdentifier()];
  115.             unset($data['id']);
  116.             if (empty($data)) {
  117.                 continue;
  118.             }
  119.             $element->addExtension('search', new ArrayEntity($data));
  120.         }
  121.         $result = new EntitySearchResult($this->definition->getEntityName(), $ids->getTotal(), $entities$aggregations$criteria$context);
  122.         $result->addState(...$ids->getStates());
  123.         $event = new EntitySearchResultLoadedEvent($this->definition$result);
  124.         $this->eventDispatcher->dispatch($event$event->getName());
  125.         return $result;
  126.     }
  127.     public function aggregate(Criteria $criteriaContext $context): AggregationResultCollection
  128.     {
  129.         $criteria = clone $criteria;
  130.         $result $this->aggregator->aggregate($this->definition, clone $criteria$context);
  131.         $event = new EntityAggregationResultLoadedEvent($this->definition$result$context);
  132.         $this->eventDispatcher->dispatch($event$event->getName());
  133.         return $result;
  134.     }
  135.     public function searchIds(Criteria $criteriaContext $context): IdSearchResult
  136.     {
  137.         $criteria = clone $criteria;
  138.         $this->eventDispatcher->dispatch(
  139.             new EntitySearchedEvent($criteria$this->definition$context)
  140.         );
  141.         $result $this->searcher->search($this->definition$criteria$context);
  142.         $event = new EntityIdSearchResultLoadedEvent($this->definition$result);
  143.         $this->eventDispatcher->dispatch($event$event->getName());
  144.         return $result;
  145.     }
  146.     public function update(array $dataContext $context): EntityWrittenContainerEvent
  147.     {
  148.         $affected $this->versionManager->update($this->definition$dataWriteContext::createFromContext($context));
  149.         $event EntityWrittenContainerEvent::createWithWrittenEvents($affected$context, []);
  150.         $this->eventDispatcher->dispatch($event);
  151.         return $event;
  152.     }
  153.     public function upsert(array $dataContext $context): EntityWrittenContainerEvent
  154.     {
  155.         $affected $this->versionManager->upsert($this->definition$dataWriteContext::createFromContext($context));
  156.         $event EntityWrittenContainerEvent::createWithWrittenEvents($affected$context, []);
  157.         $this->eventDispatcher->dispatch($event);
  158.         return $event;
  159.     }
  160.     public function create(array $dataContext $context): EntityWrittenContainerEvent
  161.     {
  162.         $affected $this->versionManager->insert($this->definition$dataWriteContext::createFromContext($context));
  163.         $event EntityWrittenContainerEvent::createWithWrittenEvents($affected$context, []);
  164.         $this->eventDispatcher->dispatch($event);
  165.         return $event;
  166.     }
  167.     public function delete(array $idsContext $context): EntityWrittenContainerEvent
  168.     {
  169.         $affected $this->versionManager->delete($this->definition$idsWriteContext::createFromContext($context));
  170.         $event EntityWrittenContainerEvent::createWithDeletedEvents($affected->getDeleted(), $context$affected->getNotFound());
  171.         if ($affected->getWritten()) {
  172.             $updates EntityWrittenContainerEvent::createWithWrittenEvents($affected->getWritten(), $context, []);
  173.             $event->addEvent(...$updates->getEvents());
  174.         }
  175.         $this->eventDispatcher->dispatch($event);
  176.         return $event;
  177.     }
  178.     public function createVersion(string $idContext $context, ?string $name null, ?string $versionId null): string
  179.     {
  180.         if (!$this->definition->isVersionAware()) {
  181.             throw new \RuntimeException(sprintf('Entity %s is not version aware'$this->definition->getEntityName()));
  182.         }
  183.         return $this->versionManager->createVersion($this->definition$idWriteContext::createFromContext($context), $name$versionId);
  184.     }
  185.     public function merge(string $versionIdContext $context): void
  186.     {
  187.         if (!$this->definition->isVersionAware()) {
  188.             throw new \RuntimeException(sprintf('Entity %s is not version aware'$this->definition->getEntityName()));
  189.         }
  190.         $this->versionManager->merge($versionIdWriteContext::createFromContext($context));
  191.     }
  192.     public function clone(string $idContext $context, ?string $newId null, ?CloneBehavior $behavior null): EntityWrittenContainerEvent
  193.     {
  194.         $newId $newId ?? Uuid::randomHex();
  195.         if (!Uuid::isValid($newId)) {
  196.             throw new InvalidUuidException($newId);
  197.         }
  198.         $affected $this->versionManager->clone(
  199.             $this->definition,
  200.             $id,
  201.             $newId,
  202.             $context->getVersionId(),
  203.             WriteContext::createFromContext($context),
  204.             $behavior ?? new CloneBehavior()
  205.         );
  206.         $event EntityWrittenContainerEvent::createWithWrittenEvents($affected$context, []);
  207.         $this->eventDispatcher->dispatch($event);
  208.         return $event;
  209.     }
  210.     private function read(Criteria $criteriaContext $context): EntityCollection
  211.     {
  212.         $entities $this->reader->read($this->definition$criteria$context);
  213.         if ($this->eventFactory === null) {
  214.             throw new \RuntimeException('Event loaded factory was not injected');
  215.         }
  216.         if ($criteria->getFields() === []) {
  217.             $event $this->eventFactory->create($entities->getElements(), $context);
  218.         } else {
  219.             $event $this->eventFactory->createPartial($entities->getElements(), $context);
  220.         }
  221.         $this->eventDispatcher->dispatch($event);
  222.         return $entities;
  223.     }
  224. }