custom/plugins/ThemeOkeonline/src/Storefront/Page/Checkout/CheckoutCartPageLoadedEventSubscriber.php line 53

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace ThemeOkeOnline\Storefront\Page\Checkout;
  3. use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
  4. use Shopware\Core\Checkout\Shipping\SalesChannel\AbstractShippingMethodRoute;
  5. use Shopware\Core\Content\Product\ProductCollection;
  6. use Shopware\Core\Content\Product\SalesChannel\CrossSelling\AbstractProductCrossSellingRoute;
  7. use Shopware\Core\Content\Product\SalesChannel\CrossSelling\ProductCrossSellingRouteResponse;
  8. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  12. use Shopware\Core\System\SystemConfig\SystemConfigService;
  13. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  14. use Shopware\Storefront\Page\PageLoadedEvent;
  15. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  16. use Symfony\Component\HttpFoundation\Request;
  17. class CheckoutCartPageLoadedEventSubscriber implements EventSubscriberInterface
  18. {
  19.     /** @var ProductCrossSellingRoute $crossSellLoaderRoute */
  20.     private $crossSellLoaderRoute;
  21.     private AbstractShippingMethodRoute $shippingMethodRoute;
  22.     private EntityRepository $shippingMethodRepository;
  23.     private SystemConfigService $systemConfigService;
  24.     public function __construct(
  25.         AbstractShippingMethodRoute $shippingMethodRoute,
  26.         EntityRepository $shippingMethodRepository,
  27.         AbstractProductCrossSellingRoute $crossSellLoaderRoute,
  28.         SystemConfigService $systemConfigService
  29.     )
  30.     {
  31.         $this->shippingMethodRoute $shippingMethodRoute;
  32.         $this->shippingMethodRepository $shippingMethodRepository;
  33.         $this->crossSellLoaderRoute $crossSellLoaderRoute;
  34.         $this->systemConfigService $systemConfigService;
  35.     }
  36.     public static function getSubscribedEvents(): array
  37.     {
  38.         return [
  39.             CheckoutCartPageLoadedEvent::class => ['addCrossSellProductsToCartPage'],
  40.             CheckoutCartPageLoadedEvent::class => ['addShippingMethodsToPage']
  41.         ];
  42.     }
  43.     public function addShippingMethodsToPage(PageLoadedEvent $event)
  44.     {
  45.         $request = new Request();
  46.         $request->query->set('onlyAvailable''1');
  47.         $salesChannelContext $event->getSalesChannelContext();
  48.         $context $salesChannelContext->getContext();
  49.         $page $event->getPage();
  50.         $salesChannelId $salesChannelContext->getSalesChannel()->id;
  51.         $criteria = new Criteria();
  52.         $criteria->addAssociation('salesChannels');
  53.         $criteria->addAssociation('prices');
  54.         $criteria->addFilter(
  55.             new EqualsFilter('active'true),
  56.             new EqualsFilter('salesChannels.id'$salesChannelId)
  57.         );
  58.         $shippingMethods $this->shippingMethodRoute->load($request$salesChannelContext, new Criteria())->getShippingMethods();
  59.         $page->addExtension(
  60.             'shippingMethods',
  61.             $shippingMethods
  62.         );
  63.     }
  64.     public function addCrossSellProductsToCartPage(CheckoutCartPageLoadedEvent $event)
  65.     {
  66.         $salesChannelContext $event->getSalesChannelContext();
  67.         $page $event->getPage();
  68.         $cart $page->getCart();
  69.         
  70.         // collect all productIds of products in cart
  71.         $productIds $this->getProductIdsFromLineItems($cart->getLineItems());
  72.         $productCollection = new ProductCollection();
  73.         $maxNumProductsInCart $this->systemConfigService->get("ThemeOkeOnline.config.maxNumProductsInCart") ?? 6;
  74.         foreach($productIds as $productId)
  75.         {
  76.             if($productCollection->count() > $maxNumProductsInCart)
  77.                 break;
  78.             // load all CrossSelling products, trough the loader, to handle normal crossselling products, but also the productstream variant
  79.             $crossSellResponse $this->crossSellLoaderRoute->load($productId, new Request(), $salesChannelContext, new Criteria());
  80.             
  81.             // merge all CrossSelling prodicts in one ProductCollection
  82.             $productCollection $this->mergeCrossSellingProductsCollectionFromObject($crossSellResponse$productCollection);
  83.         }
  84.         // add Extension to the page
  85.         if($productCollection->count() > 0)
  86.         {
  87.             $page->addExtension(
  88.                 'crossSellProducts',
  89.                 $productCollection
  90.             );
  91.         }
  92.     }
  93.     private function getProductIdsFromLineItems(LineItemCollection $lineItems): array
  94.     {
  95.         // get both normal products, and cp-products
  96.         return array_merge(
  97.             $this->getProductIdsFromProducts($lineItems),
  98.             $this->getProductIdsFromCustomizedProducts($lineItems)
  99.         );
  100.     }
  101.     private function getProductIdsFromCustomizedProducts(LineItemCollection $lineItems): array
  102.     {
  103.         $ids = array();
  104.         // loop trough the Cp's and get the ReferenceIds from there underlaying products
  105.         $lineItems->filterType('customized-products')->map(function($lineItem) use (&$ids) {
  106.             $ids array_merge($idsarray_values($lineItem->getChildren()->filterType('product')->getReferenceIds()));
  107.         });
  108.         return $ids;
  109.     }
  110.     private function getProductIdsFromProducts(LineItemCollection $lineItems): array
  111.     {
  112.         return $lineItems->filterType('product')->getReferenceIds();   
  113.     }
  114.     private function mergeCrossSellingProductsCollectionFromObject(ProductCrossSellingRouteResponse $crossSellResponseProductCollection $productCollection): ProductCollection
  115.     {
  116.         if($array $crossSellResponse->getResult())
  117.         {
  118.             foreach($array as $crossSellingElement)
  119.             {
  120.                 $productCollection->merge($crossSellingElement->getProducts());
  121.             }
  122.         }
  123.         return $productCollection;
  124.     }
  125. }