custom/plugins/DvsnProductOption/src/Subscriber/Core/Checkout/Cart/SalesChannel/CartService.php line 93

Open in your IDE?
  1. <?php
  2. /**
  3.  * digitvision
  4.  *
  5.  * @category  digitvision
  6.  * @package   Shopware\Plugins\DvsnProductOption
  7.  * @copyright (c) 2020 digitvision
  8.  */
  9. namespace Dvsn\ProductOption\Subscriber\Core\Checkout\Cart\SalesChannel;
  10. use Dvsn\ProductOption\Core\Content\ProductOption\ProductOptionEntity;
  11. use Dvsn\ProductOption\Service\LineItemFactoryServiceInterface;
  12. use Dvsn\ProductOption\Service\ProductOptionCollectorServiceInterface;
  13. use Shopware\Core\Checkout\Cart\Cart;
  14. use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
  15. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  16. use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
  17. use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
  18. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  19. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  20. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  21. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  22. use Symfony\Component\HttpFoundation\RequestStack;
  23. class CartService implements EventSubscriberInterface
  24. {
  25.     /**
  26.      * ...
  27.      *
  28.      * @var ProductOptionCollectorServiceInterface
  29.      */
  30.     protected $productOptionCollectorService;
  31.     /**
  32.      * ...
  33.      *
  34.      * @var LineItemFactoryServiceInterface
  35.      */
  36.     protected $lineItemFactoryService;
  37.     /**
  38.      * ...
  39.      *
  40.      * @var SalesChannelRepositoryInterface
  41.      */
  42.     protected $salesChannelProductRepository;
  43.     /**
  44.      * ...
  45.      *
  46.      * @var RequestStack
  47.      */
  48.     protected $requestStack;
  49.     /**
  50.      * ...
  51.      *
  52.      * @param ProductOptionCollectorServiceInterface $productOptionCollectorService
  53.      * @param LineItemFactoryServiceInterface $lineItemFactoryService
  54.      * @param SalesChannelRepositoryInterface $salesChannelProductRepository
  55.      * @param RequestStack $requestStack
  56.      */
  57.     public function __construct(
  58.         ProductOptionCollectorServiceInterface $productOptionCollectorService,
  59.         LineItemFactoryServiceInterface $lineItemFactoryService,
  60.         SalesChannelRepositoryInterface $salesChannelProductRepository,
  61.         RequestStack $requestStack
  62.     ) {
  63.         // set params
  64.         $this->productOptionCollectorService $productOptionCollectorService;
  65.         $this->lineItemFactoryService $lineItemFactoryService;
  66.         $this->salesChannelProductRepository $salesChannelProductRepository;
  67.         $this->requestStack $requestStack;
  68.     }
  69.     /**
  70.      * {@inheritDoc}
  71.      */
  72.     public static function getSubscribedEvents(): array
  73.     {
  74.         return [
  75.             BeforeLineItemAddedEvent::class => 'onLineItemAdded'
  76.         ];
  77.     }
  78.     /**
  79.      * ...
  80.      *
  81.      * @param BeforeLineItemAddedEvent $event
  82.      */
  83.     public function onLineItemAdded(BeforeLineItemAddedEvent $event)
  84.     {
  85.         // get parameters
  86.         $salesChannelContext $event->getSalesChannelContext();
  87.         $lineItem $event->getLineItem();
  88.         $cart $event->getCart();
  89.         $alreadyExists $event->isMerged();
  90.         // product already in cart?
  91.         if ($alreadyExists === true) {
  92.             // get every line item for this product
  93.             $lineItems $cart->getLineItems()->filter(function(LineItem $item) use ($lineItem) { return $item->getReferencedId() === $lineItem->getReferencedId(); });
  94.             // loop every product within the cart
  95.             foreach ($lineItems->getElements() as $currentLineItem) {
  96.                 // remove current children
  97.                 $currentLineItem->setChildren(new LineItemCollection());
  98.                 // and add our options
  99.                 $this->addChildren(
  100.                     $currentLineItem,
  101.                     $salesChannelContext,
  102.                     $cart
  103.                 );
  104.             }
  105.             // done here
  106.             return;
  107.         }
  108.         // new product -> add our options
  109.         $this->addChildren(
  110.             $lineItem,
  111.             $salesChannelContext,
  112.             $cart
  113.         );
  114.     }
  115.     /**
  116.      * ...
  117.      *
  118.      * @param LineItem $lineItem
  119.      * @param SalesChannelContext $salesChannelContext
  120.      * @param Cart $cart
  121.      */
  122.     private function addChildren(LineItem $lineItemSalesChannelContext $salesChannelContextCart $cart)
  123.     {
  124.         // get the current request
  125.         $request $this->requestStack->getCurrentRequest();
  126.         // do we even have options?!
  127.         if (!$request->request->has('lineItemsOptions') || !is_array($request->request->get('lineItemsOptions'))) {
  128.             // nothing to do
  129.             return;
  130.         }
  131.         /** @var SalesChannelProductEntity $product */
  132.         $product $this->salesChannelProductRepository->search(
  133.             new Criteria([$lineItem->getReferencedId()]),
  134.             $salesChannelContext
  135.         )->first();
  136.         // get the selected options
  137.         $selected $request->request->get('lineItemsOptions');
  138.         // get the entities
  139.         $options $this->productOptionCollectorService->get(
  140.             $product,
  141.             $salesChannelContext
  142.         )->getElements();
  143.         /** @var ProductOptionEntity $option */
  144.         foreach ($options as $option) {
  145.             // is this one selected?
  146.             if (in_array($option->getId(), $selected)) {
  147.                 // create a line item
  148.                 $child $this->lineItemFactoryService->create(
  149.                     $option,
  150.                     $lineItem,
  151.                     $cart,
  152.                     $salesChannelContext
  153.                 );
  154.                 // add as child
  155.                 $lineItem->addChild(
  156.                     $child
  157.                 );
  158.             }
  159.         }
  160.         // did we add any options?
  161.         if ($lineItem->getChildren()->count() > 0) {
  162.             // set payload for the view
  163.             $lineItem->setPayloadValue('dvsnProductOptionHasOptions'true);
  164.         }
  165.     }
  166. }