custom/plugins/FroshProductCompare/src/Subscriber/FroshCrossSellingProductListingSubscriber.php line 50

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Frosh\FroshProductCompare\Subscriber;
  3. use Frosh\FroshProductCompare\CrossSellingComparable\CrossSellingComparableEntity;
  4. use Frosh\FroshProductCompare\Page\CompareProductPageLoader;
  5. use Shopware\Core\Content\Product\Cart\ProductGatewayInterface;
  6. use Shopware\Core\Content\Product\Events\ProductCrossSellingCriteriaEvent;
  7. use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;
  8. use Shopware\Core\Content\Product\Events\ProductCrossSellingsLoadedEvent;
  9. use Shopware\Core\Content\Product\Events\ProductCrossSellingStreamCriteriaEvent;
  10. use Shopware\Core\Content\Product\ProductCollection;
  11. use Shopware\Core\Content\Product\SalesChannel\CrossSelling\CrossSellingElement;
  12. use Shopware\Core\Content\Product\SalesChannel\Listing\ProductListingResult;
  13. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
  16. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. class FroshCrossSellingProductListingSubscriber implements EventSubscriberInterface
  19. {
  20.     private CompareProductPageLoader $compareProductPageLoader;
  21.     private ProductGatewayInterface $productGateway;
  22.     public function __construct(
  23.         CompareProductPageLoader $compareProductPageLoader,
  24.         ProductGatewayInterface $productGateway
  25.     ) {
  26.         $this->compareProductPageLoader $compareProductPageLoader;
  27.         $this->productGateway $productGateway;
  28.     }
  29.     public static function getSubscribedEvents()
  30.     {
  31.         return [
  32.             ProductCrossSellingStreamCriteriaEvent::class => [
  33.                 ['handleCriteriaLoadedRequest'201]
  34.             ],
  35.             ProductCrossSellingIdsCriteriaEvent::class => [
  36.                 ['handleCriteriaLoadedRequest'201]
  37.             ],
  38.             ProductCrossSellingsLoadedEvent::class => [
  39.                 ['handleCrossSellingLoadedEvent'201]
  40.             ]
  41.         ];
  42.     }
  43.     public function handleCriteriaLoadedRequest(ProductCrossSellingCriteriaEvent $event): void
  44.     {
  45.         $crossSelling $event->getCrossSelling();
  46.         /** @var CrossSellingComparableEntity $crossSellingComparable */
  47.         $crossSellingComparable $crossSelling->getExtension('crossSellingComparable');
  48.         if (!$crossSellingComparable || !$crossSellingComparable->isComparable()) {
  49.             return;
  50.         }
  51.         $criteria $event->getCriteria();
  52.         $criteria
  53.             ->addAssociation('media')
  54.             ->addAssociation('prices')
  55.             ->addAssociation('manufacturer')
  56.             ->addAssociation('manufacturer.media')
  57.             ->addAssociation('cover')
  58.             ->addAssociation('options.group')
  59.             ->addAssociation('properties.group')
  60.             ->addAssociation('properties.media')
  61.             ->addAssociation('mainCategories.category')
  62.             ->addFilter(new NotFilter(NotFilter::CONNECTION_AND, [new EqualsFilter('id'$crossSelling->getProductId())]))
  63.             ->setLimit(CompareProductPageLoader::MAX_COMPARE_PRODUCT_ITEMS);
  64.     }
  65.     public function handleCrossSellingLoadedEvent(ProductCrossSellingsLoadedEvent $event)
  66.     {
  67.         $crossSellings $event->getCrossSellings();
  68.         $context $event->getContext();
  69.         $salesChannelContext =  $event->getSalesChannelContext();
  70.         /** @var CrossSellingElement $crossSellingElement */
  71.         foreach ($crossSellings as $crossSellingElement) {
  72.             $crossSelling $crossSellingElement->getCrossSelling();
  73.             /** @var CrossSellingComparableEntity $crossSellingComparable */
  74.             $crossSellingComparable $crossSelling->getExtension('crossSellingComparable');
  75.             if (!$crossSellingComparable || !$crossSellingComparable->isComparable()) {
  76.                 continue;
  77.             }
  78.             $featureProductId $crossSelling->getProductId();
  79.             /** @var SalesChannelProductEntity $product */
  80.             foreach ($crossSellingElement->getProducts() as $product) {
  81.                 if ($product->getParentId() === $featureProductId) {
  82.                     // if there's at least a variant that in the compare list, remove container product from compare list
  83.                     $featureProductId null;
  84.                     break;
  85.                 }
  86.             }
  87.             $products = new ProductCollection();
  88.             if ($featureProductId) {
  89.                 $featureProduct $this->getFeaturedProduct($featureProductId$salesChannelContext);
  90.                 $products->add($featureProduct);
  91.             }
  92.             $compareProducts $crossSellingElement->getProducts();
  93.             $products->merge($compareProducts);
  94.             $products ProductListingResult::createFrom($products);
  95.             $productWithComparableData $this->compareProductPageLoader->loadProductCompareData($products$salesChannelContext);
  96.             $crossSellingElement->setProducts(new ProductCollection($productWithComparableData));
  97.             $properties $this->compareProductPageLoader->loadProperties($products);
  98.             $crossSelling->addExtension('compareProperties'$properties);
  99.         }
  100.     }
  101.     private function getFeaturedProduct(string $productIdSalesChannelContext $context): SalesChannelProductEntity
  102.     {
  103.         $products $this->productGateway->get([$productId], $context);
  104.         /** @var SalesChannelProductEntity $salesChannelProduct */
  105.         $salesChannelProduct $products->get($productId);
  106.         return $salesChannelProduct;
  107.     }
  108. }