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

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\SalesChannel\CartService;
  6. use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
  7. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  8. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  9. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
  10. use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
  11. use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
  12. use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
  13. use Shopware\Core\System\SalesChannel\SalesChannelContext;
  14. use Shopware\Core\System\SystemConfig\SystemConfigService;
  15. use Shopware\Storefront\Event\StorefrontRenderEvent;
  16. use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
  17. use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
  18. use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
  19. use Shopware\Storefront\Page\GenericPageLoadedEvent;
  20. use Shopware\Storefront\Page\PageLoadedEvent;
  21. use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
  22. use Shopware\Storefront\Pagelet\Footer\FooterPageletLoadedEvent;
  23. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  24. use Symfony\Component\HttpFoundation\RedirectResponse;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
  27. use Symfony\Component\HttpKernel\KernelEvents;
  28. //use Symfony\Component\DependencyInjection\ContainerBuilder;
  29. class StorefrontSubscriber implements EventSubscriberInterface
  30. {
  31.     private SettingService $settingsService;
  32.     private CartService $cartService;
  33.     private $productRepository;
  34.     private $productDetailRoute;
  35.     private PriceOnRequestService $priceOnRequestService;
  36.     private SalesChannelRepositoryInterface $salesChannelProductRepository;
  37.     private SystemConfigService $systemConfigService;
  38.     private SalesChannelRepositoryInterface $countryRepository;
  39.     public function __construct(
  40.         SettingService                  $settingsService,
  41.         CartService                     $cartService,
  42.         EntityRepositoryInterface       $productRepository,
  43.         AbstractProductDetailRoute      $productDetailRoute,
  44.         PriceOnRequestService           $priceOnRequestService,
  45.         SalesChannelRepositoryInterface $salesChannelProductRepository,
  46.         SystemConfigService             $systemConfigService,
  47.         SalesChannelRepositoryInterface $countryRepository
  48.     )
  49.     {
  50.         $this->settingsService = $settingsService;
  51.         $this->cartService = $cartService;
  52.         $this->productRepository = $productRepository;
  53.         $this->productDetailRoute = $productDetailRoute;
  54.         $this->priceOnRequestService = $priceOnRequestService;
  55.         $this->salesChannelProductRepository = $salesChannelProductRepository;
  56.         $this->systemConfigService = $systemConfigService;
  57.         $this->countryRepository = $countryRepository;
  58.     }
  59.     public static function getSubscribedEvents(): array
  60.     {
  61.         // Return the events to listen to as array like this:  <event to listen to> => <method to execute>
  62.         return [
  63.             KernelEvents::CONTROLLER_ARGUMENTS => 'beforeController',
  64.             ProductPageLoadedEvent::class => 'onProductPageLoaded',
  65.             'sales_channel.product.loaded' => 'productsLoaded',
  66.             OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPageLoaded',
  67.             CheckoutCartPageLoadedEvent::class => 'onCheckoutCartPageLoaded',
  68.             CheckoutConfirmPageLoadedEvent::class => 'onCheckoutPageLoaded',
  69.             FooterPageletLoadedEvent::class => 'onFooterLoaded',
  70.             StorefrontRenderEvent::class => 'onStorefrontRender'
  71.         ];
  72.     }
  73.     public function beforeController(ControllerArgumentsEvent $event)
  74.     {
  75.         if ($event->getRequest()->getPathInfo() == '/checkout/product/add-by-number') {
  76.             /** @var $salesChannelContext SalesChannelContext */
  77.             $salesChannelContext = $event->getArguments()[1];
  78.             $product = $this->salesChannelProductRepository->search(
  79.                 (new Criteria())
  80.                     ->addFilter(new EqualsFilter('productNumber', $event->getRequest()->get('number'))),
  81.                 $salesChannelContext
  82.             );
  83.             if ($product->count() > 0) {
  84.                 if ($this->priceOnRequestService->checkForProductCheckoutDisabled($product->first(), $salesChannelContext->getCurrentCustomerGroup()->getName())) {
  85.                     $event->setController(function (Request $request, SalesChannelContext $salesChannelContext) {
  86.                         return new RedirectResponse($request->getUriForPath('/checkout/cart?nb_por_nbpn=1'));
  87.                     });
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     public function onProductPageLoaded(ProductPageLoadedEvent $event)
  93.     {
  94.         $config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
  95.         $product = $event->getPage()->getProduct();
  96.         $productId = $event->getPage()->getProduct()->getId();
  97.         $event->getPage()->getProduct()->addExtension('nimbitsPriceOnRequestSettings', $config);
  98.         $salesChannelContext = $event->getSalesChannelContext();
  99.         $salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
  100.         $cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
  101.         $priceOnRequestService = $this->priceOnRequestService;
  102.         $priceOnRequestService->setSalesChannelId($salesChannelId);
  103.         $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  104.         $event->getPage()->getProduct()->addExtension('nimbits_por', $porRuleset);
  105.         $customer = $salesChannelContext->getCustomer();
  106.         if ($customer != null) {
  107.             $event->getPage()->addExtension('nimbits_por_customer', $customer);
  108.         }
  109.     }
  110.     public function productsLoaded(SalesChannelEntityLoadedEvent $event): void
  111.     {
  112.         $config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
  113.         $salesChannelContext = $event->getSalesChannelContext();
  114.         $salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
  115.         $priceOnRequestService = $this->priceOnRequestService;
  116.         $priceOnRequestService->setSalesChannelId($salesChannelId);
  117.         $products = [];
  118.         foreach ($event->getEntities() as $product) {
  119.             $products[] = $product;
  120.             $cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
  121.             $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  122.             $product->addExtension('nimbits_por', $porRuleset);
  123.         }
  124.     }
  125.     public function onOffcanvasCartPageLoaded(OffcanvasCartPageLoadedEvent $event)
  126.     {
  127.         $salesChannelContext = $event->getSalesChannelContext();
  128.         $salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
  129.         $cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
  130.         $config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
  131.         $priceOnRequestService = $this->priceOnRequestService;
  132.         $priceOnRequestService->setSalesChannelId($salesChannelId);
  133.         $event->getPage()->addExtension('nimbitsPriceOnRequestSettings', $config);
  134.         $currentCart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  135.         $lineitems = $currentCart->getLineItems();
  136.         //iterate cart and apply price on request rules to each item and the cart
  137.         $products = [];
  138.         $productNumbers = [];
  139.         foreach ($lineitems as $item) {
  140.             $payload = $item->getPayload();
  141.             if (!isset($payload["productNumber"])) {
  142.                 continue;
  143.             }
  144.             //xtract children's productNumbers if any
  145.             foreach ($item->getChildren() as $child) {
  146.                 $payloadChild = $child->getPayload();
  147.                 if (!isset($payloadChild["productNumber"])) {
  148.                     continue;
  149.                 }
  150.                 $productNumbers[] = $payloadChild["productNumber"];
  151.             }
  152.             $productNumbers[] = $payload["productNumber"];
  153.         }
  154.         $prods = $this->salesChannelProductRepository->search(
  155.             (new Criteria())
  156.                 ->addFilter(new EqualsAnyFilter('productNumber', $productNumbers)),
  157.             $salesChannelContext
  158.         );
  159.         $prods = $prods->getElements();
  160.         //$product = $this->productDetailRoute->load($prods[$akeys[0]]->getId(), $event->getRequest(),$salesChannelContext, $criteria)->getProduct();
  161.         foreach ($prods as $p) {
  162.             $products[$p->getProductNumber()] = $p;
  163.         }
  164.         foreach ($lineitems as $item) {
  165.             $payload = $item->getPayload();
  166.             $rulesets = [];
  167.             if (!isset($payload["productNumber"])) {
  168.                 continue;
  169.             }
  170.             foreach ($item->getChildren() as $child) {
  171.                 $payloadChild = $child->getPayload();
  172.                 if (!isset($payloadChild["productNumber"])) {
  173.                     continue;
  174.                 }
  175.                 if (isset($products[$payloadChild["productNumber"]])) {
  176.                     $product = $products[$payloadChild["productNumber"]];
  177.                     $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  178.                     $rulesets[] = $porRuleset;
  179.                 }
  180.             }
  181.             if (isset($products[$payload["productNumber"]])) {
  182.                 $product = $products[$payload["productNumber"]];
  183.                 $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  184.                 $rulesets[] = $porRuleset;
  185.             }
  186.             $porRuleset = $priceOnRequestService->sortRulesets($rulesets);
  187.             $item->addExtension('nimbits_por', $porRuleset);
  188.         }
  189.         $checkoutdisabled = $priceOnRequestService->checkForCheckoutDisabled($products, $cg);
  190.         $event->getPage()->addExtension('nimbits_por', $checkoutdisabled);
  191.     }
  192.     public function onCheckoutPageLoaded(CheckoutConfirmPageLoadedEvent $event)
  193.     {
  194.         $salesChannelContext = $event->getSalesChannelContext();
  195.         $criteria = new Criteria();
  196.         $criteria->addFilter(new EqualsFilter('active', true));
  197.         $countries = $this->countryRepository->search($criteria, $salesChannelContext);
  198.         $customer = $salesChannelContext->getCustomer();
  199.         if ($customer != null) {
  200.             $event->getPage()->addExtension('nimbits_por_customer', $customer);
  201.             $event->getPage()->assign(['countries' => $countries]);
  202.         }
  203.     }
  204.     public function onCheckoutCartPageLoaded(CheckoutCartPageLoadedEvent $event)
  205.     {
  206.         $salesChannelContext = $event->getSalesChannelContext();
  207.         $salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
  208.         $cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
  209.         $config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
  210.         $priceOnRequestService = $this->priceOnRequestService;
  211.         $priceOnRequestService->setSalesChannelId($salesChannelId);
  212.         $currentCart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
  213.         $lineitems = $currentCart->getLineItems();
  214.         //iterate cart and apply price on request rules to each item and the cart
  215.         $products = [];
  216.         $productNumbers = [];
  217.         foreach ($lineitems as $item) {
  218.             $payload = $item->getPayload();
  219.             if (!isset($payload["productNumber"])) {
  220.                 continue;
  221.             }
  222.             //xtract children's productNumbers if any
  223.             foreach ($item->getChildren() as $child) {
  224.                 $payloadChild = $child->getPayload();
  225.                 if (!isset($payloadChild["productNumber"])) {
  226.                     continue;
  227.                 }
  228.                 $productNumbers[] = $payloadChild["productNumber"];
  229.             }
  230.             $productNumbers[] = $payload["productNumber"];
  231.         }
  232.         $prods = $this->salesChannelProductRepository->search(
  233.             (new Criteria())
  234.                 ->addFilter(new EqualsAnyFilter('productNumber', $productNumbers)),
  235.             $salesChannelContext
  236.         );
  237.         $prods = $prods->getElements();
  238.         //$product = $this->productDetailRoute->load($prods[$akeys[0]]->getId(), $event->getRequest(),$salesChannelContext, $criteria)->getProduct();
  239.         foreach ($prods as $p) {
  240.             $products[$p->getProductNumber()] = $p;
  241.         }
  242.         //iterate cart and apply price on request ruleset to each item and the cart
  243.         foreach ($lineitems as $item) {
  244.             $payload = $item->getPayload();
  245.             $rulesets = [];
  246.             if (!isset($payload["productNumber"])) {
  247.                 continue;
  248.             }
  249.             foreach ($item->getChildren() as $child) {
  250.                 $payloadChild = $child->getPayload();
  251.                 if (!isset($payloadChild["productNumber"])) {
  252.                     continue;
  253.                 }
  254.                 if (isset($products[$payloadChild["productNumber"]])) {
  255.                     $product = $products[$payloadChild["productNumber"]];
  256.                     $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  257.                     $rulesets[] = $porRuleset;
  258.                 }
  259.             }
  260.             if (isset($products[$payload["productNumber"]])) {
  261.                 $product = $products[$payload["productNumber"]];
  262.                 $porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
  263.                 $rulesets[] = $porRuleset;
  264.             }
  265.             $porRuleset = $priceOnRequestService->sortRulesets($rulesets);
  266.             $item->addExtension('nimbits_por', $porRuleset);
  267.         }
  268.         $checkoutdisabled = $priceOnRequestService->checkForCheckoutDisabled($products, $cg);
  269.         $checkoutdisabled->dontAddByProductNumber = ($event->getRequest()->get('nb_por_nbpn', 0) == 1);
  270.         $event->getPage()->addExtension('nimbits_por', $checkoutdisabled);
  271.     }
  272.     public function onFooterLoaded(FooterPageletLoadedEvent $event)
  273.     {
  274.         $event->getPagelet()->addExtension('nimbitsPriceOnRequestSettings',
  275.             $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId())
  276.         );
  277.     }
  278.     public function onStorefrontRender(StorefrontRenderEvent $event)
  279.     {
  280.         $event->setParameter('requestsOverview', $this->getConfig('NimbitsPriceOnRequestNext.config.nbporcustomeroverview', $event));
  281.     }
  282.     public function getConfig($key, $event)
  283.     {
  284.         return $this->systemConfigService->get($key, $event->getSalesChannelContext()->getSalesChannelId());
  285.     }
  286. }