custom/plugins/ThemeOkeonline/src/Storefront/Product/Subscriber/StorefrontProductSearchResultLoadedSubscriber.php line 72

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace ThemeOkeOnline\Storefront\Product\Subscriber;
  3. use Psr\Log\LoggerInterface;
  4. use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
  5. use Shopware\Core\Content\Product\ProductCollection;
  6. use Shopware\Core\Content\Product\ProductEntity;
  7. use Shopware\Core\Framework\Adapter\Cache\CacheCompressor;
  8. use Shopware\Core\Framework\Context;
  9. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchResultLoadedEvent;
  11. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Symfony\Component\Cache\Adapter\TagAwareAdapterInterface;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use ThemeOkeOnline\Core\Content\Product\ProductSiblingService;
  18. class StorefrontProductSearchResultLoadedSubscriber implements EventSubscriberInterface
  19. {
  20.     /**
  21.      * @var ProductSiblingService
  22.      */
  23.     private $productSiblingService;
  24.     /**
  25.      * @var SystemConfigService
  26.      */
  27.     private $systemConfigService;
  28.     /**
  29.      * @var Context
  30.      */
  31.     private $context;
  32.     /**
  33.      * @var string
  34.      */
  35.     public $commonPropertyGroupId;
  36.     public function __construct(
  37.         ProductSiblingService $productSiblingService,
  38.         SystemConfigService $systemConfigService
  39.     )
  40.     {
  41.         $this->productSiblingService $productSiblingService;
  42.         $this->systemConfigService $systemConfigService;
  43.         $this->commonPropertyGroupId $this->systemConfigService->get('ThemeOkeOnline.config.parentProperty') ?? null;
  44.     }
  45.     public static function getSubscribedEvents(): array
  46.     {
  47.         // ProductListingCriteriaEvent::class => ['addPropertiesToProductListingCriteria'],
  48.         return [
  49.             'sales_channel.product.process.criteria' => ['addPropertiesToProductListingCriteria'],
  50.             'sales_channel.product.search.result.loaded' => ['productListingLoaded']
  51.         ];
  52.     }
  53.     public function addPropertiesToProductListingCriteria($event): void
  54.     {
  55.         if( $this->commonPropertyGroupId )
  56.         {
  57.             $criteria $event->getCriteria();
  58.             $criteria->addAssociation('options');
  59.             $criteria->addAssociation('properties');
  60.         }
  61.     }
  62.     public function productListingLoaded(EntitySearchResultLoadedEvent $event): void
  63.     {
  64.         $this->context $event->getContext();
  65.         // Stop when settings are missing
  66.         if(!$this->commonPropertyGroupId)
  67.             return;
  68.         // Collect a list with all used property-connections
  69.         $loadedProducts $event->getResult()->getElements();
  70.         foreach($loadedProducts as $product)
  71.         {
  72.             // Get the propertyGroupOptionIds based on the setting which defines the common-PropertyGroup
  73.             $commonPropertyGroupOptionIds $this->getCommonPropertyGroupOptionIds($product$this->commonPropertyGroupId);
  74.             // Get the siblings, and remove current product from list of siblings.
  75.             $data $this->productSiblingService->getSiblingsForProduct($product$this->context);
  76.             $product->addExtension('siblings'$data);
  77.             // Old implementation
  78.             // $siblings = $this->getSiblingsOfProduct($product, $commonPropertyGroupOptionIds, true);
  79.             // $product->addExtension('siblings', $siblings);
  80.             // Removal of 'selected' sibling. this feature has been permanently disabled
  81.             //$siblings = $this->without($siblings, $product->getId());
  82.         }
  83.     }
  84.     private function getCommonPropertyGroupOptionIds(ProductEntity $product$commonPropertyGroupId): array
  85.     {
  86.         // Get the properties from the product, this can be null or an empty array, if so, we can return an empty array
  87.         $commonProductPropertyGroupOptions $product->getProperties();
  88.         if( !$commonProductPropertyGroupOptions)
  89.             return [];
  90.         $commonProductPropertyGroupOptionValues $commonProductPropertyGroupOptions->filterByGroupId($commonPropertyGroupId);
  91.         if( $commonProductPropertyGroupOptionValues->count() == )
  92.             return [];
  93.         // eventually, return the ids as an array
  94.         return $commonProductPropertyGroupOptionValues->getIds();
  95.     }
  96.     // Has been replaced by productSiblingService: remove soon
  97.     // private function getSiblingsOfProduct(ProductEntity $product, array $commonPropertyGroupOptionIds): ProductCollection
  98.     // {
  99.     //     if( !count($commonPropertyGroupOptionIds) > 0 )
  100.     //     {
  101.     //         $result = new ProductCollection();
  102.     //         //$item = CacheCompressor::compress($item, $result);
  103.     //         //$this->cache->save($item);
  104.     //         return $result;
  105.     //     }
  106.     //     // We have commonPropertyGroupOptionIds, so we should query them, to find any siblings
  107.     //     $criteria = new Criteria();
  108.     //     $criteria->setTitle('load-siblings');
  109.     //     $criteria->resetAssociations();
  110.     //     $criteria->addAssociation('cover');
  111.     //     $criteria->addAssociation('seoUrls');
  112.     //     // Create a multi-filter, because the product we're checking could have more than one common-propertyGroupOptions (it is a multi-select in back-office)
  113.     //     $multiFilter = [];
  114.     //     foreach($commonPropertyGroupOptionIds as $commonPropertyGroupOptionId)
  115.     //     {
  116.     //         $multiFilter[] = new EqualsFilter('properties.id', $commonPropertyGroupOptionId);
  117.     //     }
  118.     //     $criteria->addFilter(
  119.     //         new MultiFilter(
  120.     //             MultiFilter::CONNECTION_OR,
  121.     //             $multiFilter
  122.     //         )
  123.     //     );
  124.     //     //Filter by options
  125.     //     $productOptionsKeyValue = $this->mapToKeyValue($product->getOptions());
  126.     //     $persistentOptions = $this->systemConfigService->get('ThemeOkeOnline.config.persistentOptions');
  127.     //     if(sizeof($productOptionsKeyValue) > 0) foreach($persistentOptions as $option){
  128.     //         $criteria->addFilter(
  129.     //         //Always take first value of this option (no multi-selects)
  130.     //             new EqualsFilter('options.id', $productOptionsKeyValue[$option][0])
  131.     //         );
  132.     //     }
  133.     //     // query it!
  134.     //     $result = $this->productRepository->search($criteria, $this->getContext());
  135.     //     // fallback, empty product Collection
  136.     //     return new ProductCollection();
  137.     // }
  138.     // private function mapToKeyValue($items){
  139.     //     $keyValue = [];
  140.     //     foreach ($items as $item) {
  141.     //         $key = $item->getGroupId();
  142.     //         $value = $item->getId();
  143.     //         if(!array_key_exists($key, $keyValue))
  144.     //             $keyValue[$key] = [];
  145.     //         $keyValue[$key][] = $value;
  146.     //     }
  147.     //     return $keyValue;
  148.     // }
  149.     // ToDo: Remove soon
  150.     // private function without(ProductCollection $collection, $id): ProductCollection
  151.     // {
  152.     //     $collection->remove($id);
  153.     //     return $collection;
  154.     // }
  155.     private function getContext(): ?Context
  156.     {
  157.         return $this->context;
  158.     }
  159. }