custom/plugins/SwagEnterpriseSearchPlatform/src/Action/ActionSearchProcessor.php line 138

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Swag\EnterpriseSearch\Action;
  4. use Shopware\Core\Framework\Api\Context\SalesChannelApiSource;
  5. use Shopware\Core\Framework\Context;
  6. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  11. use Swag\EnterpriseSearch\Action\ActionSearchTerm\ActionSearchTermCollection;
  12. use Swag\EnterpriseSearch\Action\ActionType\ActionTypeEntityInterface;
  13. use Swag\EnterpriseSearch\Action\ActionType\ActionTypeProvider;
  14. use Swag\EnterpriseSearch\Action\ActionType\InvalidActionTypeException;
  15. use Swag\EnterpriseSearch\Action\ActionType\InvalidActionTypeFieldsException;
  16. use Swag\EnterpriseSearch\Relevance\TokenizerInterface;
  17. class ActionSearchProcessor
  18. {
  19.     public const STATE_ELASTICSEARCH_AWARE 'elasticsearchAware';
  20.     /**
  21.      * @var EntityRepositoryInterface
  22.      */
  23.     private $actionSearchTermRepository;
  24.     /**
  25.      * @var ActionTypeProvider
  26.      */
  27.     private $actionTypeProvider;
  28.     /**
  29.      * @var TokenizerInterface
  30.      */
  31.     private $tokenizer;
  32.     /**
  33.      * @var ActionCollection[]|null
  34.      */
  35.     private $cachedActions;
  36.     public function __construct(
  37.         EntityRepositoryInterface $actionSearchTermRepository,
  38.         ActionTypeProvider $actionTypeProvider,
  39.         TokenizerInterface $tokenizer
  40.     ) {
  41.         $this->actionSearchTermRepository $actionSearchTermRepository;
  42.         $this->actionTypeProvider $actionTypeProvider;
  43.         $this->tokenizer $tokenizer;
  44.     }
  45.     public function applySearchActions(Context $contextstring $searchTermActionProcessorEnvironmentInterface $actionExecution): void
  46.     {
  47.         $source $context->getSource();
  48.         if (!($source instanceof SalesChannelApiSource)) {
  49.             return;
  50.         }
  51.         $matchingActions $this->getMatchingActions($context$searchTerm);
  52.         foreach ($matchingActions as $action) {
  53.             $actionTypeProcessor $this->actionTypeProvider->getActionType($action->getType());
  54.             if (!$actionTypeProcessor) {
  55.                 continue;
  56.             }
  57.             $actionTypeEntityClass $actionTypeProcessor->getEntityClass();
  58.             if (!class_exists($actionTypeEntityClass) || !is_a($actionTypeEntityClassActionTypeEntityInterface::class, true)) {
  59.                 throw new InvalidActionTypeException('Invalid ActionType entity class provided.');
  60.             }
  61.             try {
  62.                 $actionTypeEntity $actionTypeEntityClass::fromTypeFieldsArray($action->getTypeFields());
  63.             } catch (InvalidActionTypeFieldsException $invalidActionTypeFieldsException) {
  64.                 continue;
  65.             }
  66.             $actionExecution->executeAction($action$actionTypeEntity$actionTypeProcessor);
  67.         }
  68.     }
  69.     private function getMatchingActions(Context $contextstring $searchTerm): ActionCollection
  70.     {
  71.         if ($this->cachedActions !== null && isset($this->cachedActions[$searchTerm])) {
  72.             return $this->cachedActions[$searchTerm];
  73.         }
  74.         $matchingActions = new ActionCollection();
  75.         $matchingSearchTerms $this->getMatchingSearchTerms($context$searchTerm);
  76.         foreach ($matchingSearchTerms as $matchingSearchTerm) {
  77.             $action $matchingSearchTerm->getAction();
  78.             if (!$action->isValid()) {
  79.                 continue;
  80.             }
  81.             $matchingActions->add($action);
  82.         }
  83.         $this->cachedActions[$searchTerm] = $matchingActions;
  84.         return $matchingActions;
  85.     }
  86.     private function getMatchingSearchTerms(Context $contextstring $searchTerm): ActionSearchTermCollection
  87.     {
  88.         $context = clone $context;
  89.         /** @var SalesChannelApiSource $source */
  90.         $source $context->getSource();
  91.         $criteria = new Criteria();
  92.         if (method_exists($context'addState')) {
  93.             $context->addState(self::STATE_ELASTICSEARCH_AWARE);
  94.             $criteria->setTerm($searchTerm);
  95.         } else {
  96.             $splitSearchTerms $this->tokenizer->tokenize($searchTerm);
  97.             $criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_OR, [
  98.                 new EqualsFilter('term'$searchTerm),
  99.                 new EqualsAnyFilter('term'$splitSearchTerms),
  100.             ]));
  101.         }
  102.         $criteria->addFilter(new EqualsFilter('action.active'true));
  103.         $criteria->addFilter(new EqualsFilter('action.salesChannelId'$source->getSalesChannelId()));
  104.         $criteria->addAssociation('action');
  105.         $searchResult $this->actionSearchTermRepository->search($criteria$context);
  106.         /** @var ActionSearchTermCollection $actionSearchTermCollection */
  107.         $actionSearchTermCollection $searchResult->getEntities();
  108.         return $actionSearchTermCollection;
  109.     }
  110. }