custom/plugins/NimbitsPriceOnRequestNext/src/Subscriber/StorefrontSubscriber.php line 91

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Nimbits\NimbitsPriceOnRequestNext\Subscriber;
  3. use Nimbits\NimbitsPriceOnRequestNext\Service\PriceOnRequestService;
  4. use Nimbits\NimbitsPriceOnRequestNext\Setting\Service\SettingService;
  5. use Shopware\Core\Checkout\Cart\Cart;
  6. use Shopware\Core\Checkout\Cart\CartBehavior;
  7. use Shopware\Core\Checkout\Cart\LineItem\LineItem;
  8. use Shopware\Core\Checkout\Cart\Rule\LineItemScope;
  9. use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
  10. use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
  11. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  12. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  14. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  15. use Shopware\Core\Framework\Struct\StructCollection;
  16. use Shopware\Core\Framework\Uuid\Uuid;
  17. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  18. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  19. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  20. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  21. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  22. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  23. use Shopware\Storefront\Page\Checkout\Register\CheckoutRegisterPageLoadedEvent;
  24. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  25. use Shopware\Storefront\Pagelet\Footer\FooterPageletLoadedEvent;
  26. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  27. use Symfony\Component\HttpFoundation\RedirectResponse;
  28. use Symfony\Component\HttpFoundation\Request;
  29. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  30. use Symfony\Component\HttpKernel\KernelEvents;
  31. use Shopware\Storefront\Page\PageLoadedEvent;
  32. use Shopware\Core\Checkout\Cart\RuleLoader;
  33. use Shopware\Core\Checkout\Cart\CartRuleLoader;
  34. use Shopware\Core\Checkout\Cart\AbstractRuleLoader;
  35. use Shopware\Core\Checkout\Cart\CachedRuleLoader;
  36. use Shopware\Core\Framework\Rule\Rule;
  37. //use Symfony\Component\DependencyInjection\ContainerBuilder;
  38. class StorefrontSubscriber implements EventSubscriberInterface
  39. {
  40.     private SettingService $settingsService;
  41.     private CartService $cartService;
  42.     private $productRepository;
  43.     private $productDetailRoute;
  44.     private PriceOnRequestService $priceOnRequestService;
  45.     private SalesChannelRepositoryInterface $salesChannelProductRepository;
  46.     private CartRuleLoader $cartRuleLoader;
  47.     private CachedRuleLoader $cachedRuleLoader;
  48.     public function __construct(
  49.         SettingService                  $settingsService,
  50.         CartService                     $cartService,
  51.         EntityRepositoryInterface       $productRepository,
  52.         AbstractProductDetailRoute      $productDetailRoute,
  53.         PriceOnRequestService           $priceOnRequestService,
  54.         SalesChannelRepositoryInterface $salesChannelProductRepository,
  55.         CartRuleLoader                  $cartRuleLoader,
  56.         CachedRuleLoader                $cachedRuleLoader
  57.     )
  58.     {
  59.         $this->settingsService $settingsService;
  60.         $this->cartService $cartService;
  61.         $this->productRepository $productRepository;
  62.         $this->productDetailRoute $productDetailRoute;
  63.         $this->priceOnRequestService $priceOnRequestService;
  64.         $this->salesChannelProductRepository $salesChannelProductRepository;
  65.         $this->cartRuleLoader $cartRuleLoader;
  66.         $this->cachedRuleLoader $cachedRuleLoader;
  67.     }
  68.     public static function getSubscribedEvents(): array
  69.     {
  70.         // Return the events to listen to as array like this:  <event to listen to> => <method to execute>
  71.         return [
  72.             KernelEvents::CONTROLLER_ARGUMENTS => 'beforeController',
  73.             //ProductPageLoadedEvent::class => 'onProductPageLoaded',
  74.             'sales_channel.product.loaded' => 'productsLoaded'//TODO
  75.             OffcanvasCartPageLoadedEvent::class => 'onCheckoutPageLoaded'//TODO ALl poroducts
  76.             CheckoutCartPageLoadedEvent::class => 'onCheckoutPageLoaded'//TODO ALl poroducts
  77.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutPageLoaded'//TODO ALl poroducts
  78.             CheckoutRegisterPageLoadedEvent::class => 'onCheckoutPageLoaded'//TODO ALl poroducts
  79.             FooterPageletLoadedEvent::class => 'onFooterLoaded'
  80.         ];
  81.     }
  82.     public function beforeController(ControllerArgumentsEvent $event)
  83.     {
  84.         if ($event->getRequest()->getPathInfo() == '/checkout/product/add-by-number' && isset($event->getArguments()[1])) {
  85.             /** @var $salesChannelContext SalesChannelContext */
  86.             $salesChannelContext $event->getArguments()[1];
  87.             $product $this->salesChannelProductRepository->search(
  88.                 (new Criteria())
  89.                     ->addFilter(new EqualsFilter('productNumber'$event->getRequest()->get('number'))),
  90.                 $salesChannelContext
  91.             );
  92.             if ($product->count() > 0) {
  93.                 $productId $product->first()->getId();
  94.                 $productPorRuleset $this->priceOnRequestService->getProductRuleSet($salesChannelContext$this->priceOnRequestService->createMockLineItem($product->first()));
  95.                 //if the product is not addable to cart
  96.                 if ($productPorRuleset->getVars()["por_add_to_cart_not_visible"]) {
  97.                     $event->setController(function (Request $requestSalesChannelContext $salesChannelContext) {
  98.                         return new RedirectResponse($request->getUriForPath('/checkout/cart?nb_por_nbpn=1'));
  99.                     });
  100.                 }
  101.             }
  102.         }
  103.     }
  104.     public function onProductPageLoaded(ProductPageLoadedEvent $event)
  105.     {
  106.         //evaluate products
  107.         $salesChannelContext $event->getSalesChannelContext();
  108.         $productId $event->getPage()->getProduct()->getId();
  109.         $productPorRuleset $this->priceOnRequestService->getProductRuleSet($salesChannelContext$this->priceOnRequestService->createMockLineItem($event->getPage()->getProduct()));
  110.         $event->getPage()->getProduct()->addExtension('nimbits_por_product_ruleset'$productPorRuleset);
  111.     }
  112.     public function productsLoaded(SalesChannelEntityLoadedEvent $event): void
  113.     {
  114.         //evaluate products
  115.         $salesChannelContext $event->getSalesChannelContext();
  116.         foreach ($event->getEntities() as $product) {
  117.             $productPorRuleset $this->priceOnRequestService->getProductRuleSet($salesChannelContext$this->priceOnRequestService->createMockLineItem($product));
  118.             $product->addExtension('nimbits_por_product_ruleset'$productPorRuleset);
  119.         }
  120.     }
  121.     public function getUnitsForProductByLineitem($item$salesChannelContext)
  122.     {
  123.         if (isset($item->getPayload()["productNumber"])) {
  124.             $productNumber $item->getPayload()["productNumber"];
  125.             $product $this->salesChannelProductRepository->search(
  126.                 (new Criteria())
  127.                     ->addFilter(new EqualsFilter('productNumber'$productNumber)),
  128.                 $salesChannelContext
  129.             );
  130.             if(empty($product)){
  131.                 return ["packUnit" => """packUnitPlural" => ""];
  132.             }
  133.             $pu "";
  134.             $pup "";
  135.             if($product->first() && $product->first()->getTranslated())
  136.             {
  137.                 $pu $product->first()->getTranslated()["packUnit"] ?? "";
  138.                 $pup $product->first()->getTranslated()["packUnitPlural"] ?? "";
  139.             }
  140.             if(empty($pu) && $product->first()){
  141.                 $pu =  $product->first()->packUnit;
  142.                 $pup $product->first()->packUnitPlural;
  143.             }
  144.             return ["packUnit" => $pu"packUnitPlural" => $pup];
  145.         }
  146.         else{
  147.             return ["packUnit" => """packUnitPlural" => ""];
  148.         }
  149.     }
  150.     public function onCheckoutPageLoaded(PageLoadedEvent $event)
  151.     {
  152.         //evaluate products
  153.         $salesChannelContext $event->getSalesChannelContext();
  154.         $currentCart $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  155.         $lineItems $currentCart->getLineItems();
  156.         $priceOnRequestCartRuleset $this->priceOnRequestService->getCartRuleSet($salesChannelContext);
  157.         $cartHasNoPrice false;
  158.         $cartNotPurchasable $priceOnRequestCartRuleset["cart_is_not_purchaseable"];
  159.         foreach ($lineItems as $item) {
  160.             $productPorRuleset $this->priceOnRequestService->getProductRuleSet($salesChannelContext$item);
  161.             foreach($item->getChildren() AS $child){
  162.                 $childPorRuleset $this->priceOnRequestService->getProductRuleSet($salesChannelContext$child);
  163.                 $productPorRuleset->por_dont_show_price $productPorRuleset["por_dont_show_price"] || $childPorRuleset["por_dont_show_price"];
  164.                 $productPorRuleset->por_product_not_purchasable $productPorRuleset["por_product_not_purchasable"]
  165.                     || $childPorRuleset["por_product_not_purchasable"]
  166.                     || $productPorRuleset["por_dont_show_price"];
  167.             }
  168.             foreach($item->getChildren() AS $child){
  169.                 $child->addExtension('nimbits_por_product_ruleset'$productPorRuleset);
  170.             }
  171.             $cartHasNoPrice $cartHasNoPrice || $productPorRuleset["por_dont_show_price"];
  172.             $cartNotPurchasable $cartNotPurchasable || $productPorRuleset["por_product_not_purchasable"] || $productPorRuleset["por_dont_show_price"];
  173.             $item->addExtension('nimbits_por_product_ruleset'$productPorRuleset);
  174.             //add unit set
  175.             $item->addExtension('nimbits_por_product_units', (new StructCollection())->assign($this->getUnitsForProductByLineitem($item$salesChannelContext)));
  176.         }
  177.         $priceOnRequestCartRuleset->assign(["cart_has_no_price" => $cartHasNoPrice]);
  178.         //cart is also not purchasable if no price can be determined
  179.         $priceOnRequestCartRuleset->assign(["cart_is_not_purchaseable" => $cartNotPurchasable]);
  180.         $event->getPage()->addExtension('nimbits_por_cart_ruleset'$priceOnRequestCartRuleset);
  181.         //handling for add by productnumber error
  182.         $dontAddByProductNumber = ($event->getRequest()->get('nb_por_nbpn'0) == 1);
  183.         $showerror = ["showerror" => $dontAddByProductNumber];
  184.         $errorStruct = (new StructCollection())->assign($showerror);
  185.         $event->getPage()->addExtension('nimbits_por_cart_producnumber_add_error'$errorStruct);
  186.     }
  187.     public function onFooterLoaded(FooterPageletLoadedEvent $event)
  188.     {
  189.         $event->getPagelet()->addExtension('nimbitsPriceOnRequestSettings',
  190.             $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId())
  191.         );
  192.     }
  193. }