custom/plugins/LeopardSearchExtension/src/Subscriber/ProductSuggestCriteriaSubscriber.php line 70

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4.  * LeopardSearchExtension
  5.  * Copyright (c) Die Leoparden GmbH
  6.  */
  7. namespace LeopardSearchExtension\Subscriber;
  8. use LeopardSearchExtension\LeopardSearchExtension;
  9. use LeopardSearchExtension\Util\IdStruct;
  10. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  11. use Shopware\Core\Content\Product\Events\ProductListingResolvePreviewEvent;
  12. use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;
  13. use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  16. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\Filter;
  17. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  18. use Shopware\Core\System\SalesChannel\Event\SalesChannelProcessCriteriaEvent;
  19. class ProductSuggestCriteriaSubscriber extends AbstractSubscriber
  20. {
  21.     /**
  22.      * {@inheritDoc}
  23.      */
  24.     public static function getSubscribedEvents(): array
  25.     {
  26.         return [
  27.             ProductSuggestCriteriaEvent::class => 'onProductSuggestCriteria',
  28.             'sales_channel.product.process.criteria' => 'onSalesChannelProcessCriteria',
  29.             ProductListingResolvePreviewEvent::class => 'onProductListingResolvePreview',
  30.         ];
  31.     }
  32.     /**
  33.      * @param ProductListingCriteriaEvent $event
  34.      */
  35.     public function onProductSuggestCriteria(ProductListingCriteriaEvent $event): void
  36.     {
  37.         $productEntity $this->onSearchCriteria($event);
  38.         if (is_null($productEntity)) {
  39.             return;
  40.         }
  41.         $event->getContext()->addExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID, new IdStruct($productEntity->getId()));
  42.         $event->getRequest()->query->set('search'$productEntity->getProductNumber());
  43.         $criteria $event->getCriteria();
  44.         $this->filterNonAvailableFilter($criteria);
  45.         $criteria->addFilter(
  46.             new EqualsFilter(
  47.                 'productNumber',
  48.                 $productEntity->getProductNumber()
  49.             )
  50.         );
  51.     }
  52.     public function onSalesChannelProcessCriteria(SalesChannelProcessCriteriaEvent $event): void
  53.     {
  54.         if (!$event->getContext()->hasExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID)) {
  55.             return;
  56.         }
  57.         $this->removeDisplayGroupFilter($event->getCriteria());
  58.     }
  59.     public function onProductListingResolvePreview(ProductListingResolvePreviewEvent $event): void
  60.     {
  61.         /** @var IdStruct|null $idStruct */
  62.         $idStruct $event->getContext()->getExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID);
  63.         if (!$idStruct instanceof IdStruct) {
  64.             return;
  65.         }
  66.         // Affects variant product
  67.         // Set mapping of product to self instead of chosen variant of "Storefront presentation" configuration
  68.         $productId $idStruct->id;
  69.         $event->replace($productId$productId);
  70.         // Last use of the extension
  71.         $event->getContext()->removeExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID);
  72.     }
  73.     /**
  74.      * For variant products remove the displayGroup filter
  75.      * ??? Something to do with the "Storefront presentation" configuration
  76.      *
  77.      * @param Criteria $criteria
  78.      *
  79.      * @return void
  80.      */
  81.     private function removeDisplayGroupFilter(Criteria $criteria): void
  82.     {
  83.         $filters $criteria->getFilters();
  84.         $criteria->resetFilters();
  85.         foreach ($filters as $filter) {
  86.             if (!($filter instanceof NotFilter)) {
  87.                 $criteria->addFilter($filter);
  88.                 continue;
  89.             }
  90.             $add true;
  91.             foreach ($filter->getQueries() as $query) {
  92.                 if ($query instanceof EqualsFilter && $query->getField() === 'displayGroup') {
  93.                     $add false;
  94.                     break;
  95.                 }
  96.             }
  97.             if ($add) {
  98.                 $criteria->addFilter($filter);
  99.             }
  100.         }
  101.     }
  102.     /**
  103.      * @param Criteria $criteria
  104.      *
  105.      * @return void
  106.      */
  107.     private function filterNonAvailableFilter(Criteria $criteria): void
  108.     {
  109.         /** @var Filter[] $filters_original */
  110.         $filters_original $criteria->getFilters();
  111.         $criteria->resetQueries();
  112.         $criteria->resetFilters();
  113.         /** @var Filter $filter */
  114.         foreach ($filters_original as $filter) {
  115.             if ($filter instanceof ProductAvailableFilter) {
  116.                 $criteria->addFilter($filter);
  117.             }
  118.         }
  119.     }
  120. }