<?phpdeclare(strict_types=1);/** * LeopardSearchExtension * Copyright (c) Die Leoparden GmbH */namespace LeopardSearchExtension\Subscriber;use LeopardSearchExtension\LeopardSearchExtension;use LeopardSearchExtension\Util\IdStruct;use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;use Shopware\Core\Content\Product\Events\ProductListingResolvePreviewEvent;use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\Filter;use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;use Shopware\Core\System\SalesChannel\Event\SalesChannelProcessCriteriaEvent;class ProductSuggestCriteriaSubscriber extends AbstractSubscriber{ /** * {@inheritDoc} */ public static function getSubscribedEvents(): array { return [ ProductSuggestCriteriaEvent::class => 'onProductSuggestCriteria', 'sales_channel.product.process.criteria' => 'onSalesChannelProcessCriteria', ProductListingResolvePreviewEvent::class => 'onProductListingResolvePreview', ]; } /** * @param ProductListingCriteriaEvent $event */ public function onProductSuggestCriteria(ProductListingCriteriaEvent $event): void { $productEntity = $this->onSearchCriteria($event); if (is_null($productEntity)) { return; } $event->getContext()->addExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID, new IdStruct($productEntity->getId())); $event->getRequest()->query->set('search', $productEntity->getProductNumber()); $criteria = $event->getCriteria(); $this->filterNonAvailableFilter($criteria); $criteria->addFilter( new EqualsFilter( 'productNumber', $productEntity->getProductNumber() ) ); } public function onSalesChannelProcessCriteria(SalesChannelProcessCriteriaEvent $event): void { if (!$event->getContext()->hasExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID)) { return; } $this->removeDisplayGroupFilter($event->getCriteria()); } public function onProductListingResolvePreview(ProductListingResolvePreviewEvent $event): void { /** @var IdStruct|null $idStruct */ $idStruct = $event->getContext()->getExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID); if (!$idStruct instanceof IdStruct) { return; } // Affects variant product // Set mapping of product to self instead of chosen variant of "Storefront presentation" configuration $productId = $idStruct->id; $event->replace($productId, $productId); // Last use of the extension $event->getContext()->removeExtension(LeopardSearchExtension::SUGGEST_EXTENSION_PRODUCT_ID); } /** * For variant products remove the displayGroup filter * ??? Something to do with the "Storefront presentation" configuration * * @param Criteria $criteria * * @return void */ private function removeDisplayGroupFilter(Criteria $criteria): void { $filters = $criteria->getFilters(); $criteria->resetFilters(); foreach ($filters as $filter) { if (!($filter instanceof NotFilter)) { $criteria->addFilter($filter); continue; } $add = true; foreach ($filter->getQueries() as $query) { if ($query instanceof EqualsFilter && $query->getField() === 'displayGroup') { $add = false; break; } } if ($add) { $criteria->addFilter($filter); } } } /** * @param Criteria $criteria * * @return void */ private function filterNonAvailableFilter(Criteria $criteria): void { /** @var Filter[] $filters_original */ $filters_original = $criteria->getFilters(); $criteria->resetQueries(); $criteria->resetFilters(); /** @var Filter $filter */ foreach ($filters_original as $filter) { if ($filter instanceof ProductAvailableFilter) { $criteria->addFilter($filter); } } }}