custom/plugins/CoeProductNumberSearchSw6/src/Subscriber/SuggestPageSubscriber.php line 94

Open in your IDE?
  1. <?php
  2. namespace CoeProductNumberSearchSw6\Subscriber;
  3. use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingResult;
  4. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  5. use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
  6. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  7. use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\PrefixFilter;
  11. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
  12. use Shopware\Core\System\SystemConfig\SystemConfigService;
  13. use Shopware\Storefront\Page\Search\SearchPageLoadedEvent;
  14. use Shopware\Storefront\Page\Suggest\SuggestPageLoadedEvent;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. /**
  17.  * Class SuggestPageSubscriber
  18.  * @package CoeProductNumberSearchSw6\Subscriber
  19.  * @author Jeffry Block <jeffry.block@codeenterprise.de>
  20.  */
  21. class SuggestPageSubscriber implements EventSubscriberInterface {
  22.     private SalesChannelRepository $salesChannelProductRepository;
  23.     private SystemConfigService $systemConfigService;
  24.     public function __construct(
  25.         SalesChannelRepository $salesChannelProductRepository,
  26.         SystemConfigService $systemConfigService
  27.     ) {
  28.         $this->salesChannelProductRepository $salesChannelProductRepository;
  29.         $this->systemConfigService $systemConfigService;
  30.     }
  31.     public static function getSubscribedEvents(): array {
  32.         return [
  33.             SuggestPageLoadedEvent::class => "onSuggestPageLoaded",
  34.             SearchPageLoadedEvent::class => "onSearchPageLoaded"
  35.         ];
  36.     }
  37.     /**
  38.      * @param SuggestPageLoadedEvent $event
  39.      * @author Jeffry Block <jeffry.block@codeenterprise.de>
  40.      */
  41.     public function onSuggestPageLoaded(SuggestPageLoadedEvent $event) :void{
  42.         /** @var string $term */
  43.         $term $event->getPage()->getSearchTerm();
  44.         /** @var EntitySearchResult $result */
  45.         $result $event->getPage()->getSearchResult();
  46.         $event->getPage()->assign(['displayProductNumber' =>
  47.             $this->systemConfigService->get('CoeProductNumberSearchSw6.config.displayProductNumber',
  48.                 $event->getSalesChannelContext()->getSalesChannelId())]);
  49.         #Check if the product number of the first result matches the search term
  50.         if($result->count() == 0){
  51.             return;
  52.         }
  53.         /** @var SalesChannelProductEntity $firstProduct */
  54.         $firstProduct $result->first();
  55.         if($firstProduct === null){
  56.             return;
  57.         }
  58.         $newListingItems $this->matchSearchString($term$result->getEntities(), $event);
  59.         if($newListingItems){
  60.             $searchResultsItems = new EntityCollection($newListingItems);
  61.                 $res = new EntitySearchResult(
  62.                     $result->getEntity(),
  63.                     count($newListingItems), // overwrite the count
  64.                     $searchResultsItems,
  65.                     $result->getAggregations(),
  66.                     $result->getCriteria(),
  67.                     $result->getContext()
  68.                 );
  69.             $event->getPage()->setSearchResult($res);
  70.         }
  71.     }
  72.     /**
  73.      * @param SearchPageLoadedEvent $event
  74.      * @author Robin Gratz <robin.gratz@codeenterprise.de>
  75.      */
  76.     public function onSearchPageLoaded(SearchPageLoadedEvent $event) :void{
  77.         $page $event->getPage();
  78.         $searchTerm $page->getSearchTerm();
  79.         /** @var ProductListingResult $listing */
  80.         $listing $page->getListing();
  81.         $newListingItems $this->matchSearchString($searchTerm$listing$event);
  82.         if ($newListingItems && $newListingItems->getTotal() > 0) {
  83.             $newListing $this->createNewListing($newListingItems$listing);
  84.             $page->setListing($newListing);
  85.         }
  86.     }
  87.     private function matchSearchString(string $searchTerm$products$event)
  88.     {
  89.         $criteria = new Criteria();
  90.         $criteria->addAssociations([
  91.             'cover',
  92.             'media'
  93.         ]);
  94.         $criteria->addFilter(new EqualsFilter('productNumber'$searchTerm));
  95.         $criteria->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter('active'0)]));
  96.         $directHit $this->salesChannelProductRepository->search($criteria$event->getSalesChannelContext());
  97.         if($directHit && $directHit->getTotal() == 1) {
  98.             return $directHit;
  99.         }
  100.         $newListingItems = [];
  101.         if(is_numeric($searchTerm) && $this->systemConfigService->get('CoeProductNumberSearchSw6.config.numericalSearch'$event->getSalesChannelContext()->getSalesChannelId())) {
  102.             $criteria = new Criteria();
  103.             $criteria->addAssociations([
  104.                 'cover',
  105.                 'media'
  106.             ]);
  107.             $criteria->addFilter(new PrefixFilter('productNumber'$searchTerm));
  108.             $criteria->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter('active'0)]));
  109.             $numericalHit $this->salesChannelProductRepository->search($criteria$event->getSalesChannelContext());
  110.             return $numericalHit;
  111.         }
  112.         return $newListingItems;
  113.     }
  114.     private function createNewListing(EntitySearchResult $searchResultProductListingResult $listing) :ProductListingResult
  115.     {
  116.         $newListing = new ProductListingResult(
  117.             $searchResult->getEntity(),
  118.             $searchResult->getTotal(),
  119.             $searchResult->getEntities(),
  120.             $searchResult->getAggregations(),
  121.             $listing->getCriteria(),
  122.             $searchResult->getContext(),
  123.         );
  124.         $newListing->setAvailableSortings($listing->getAvailableSortings());
  125.         return $newListing;
  126.     }
  127. }