<?php declare(strict_types=1);
namespace Nimbits\NimbitsPriceOnRequestNext\Subscriber;
use Nimbits\NimbitsPriceOnRequestNext\Service\PriceOnRequestService;
use Nimbits\NimbitsPriceOnRequestNext\Setting\Service\SettingService;
use Shopware\Core\Checkout\Cart\SalesChannel\CartService;
use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelEntityLoadedEvent;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Pagelet\Footer\FooterPageletLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\KernelEvents;
//use Symfony\Component\DependencyInjection\ContainerBuilder;
class StorefrontSubscriber implements EventSubscriberInterface
{
private SettingService $settingsService;
private CartService $cartService;
private $productRepository;
private $productDetailRoute;
private PriceOnRequestService $priceOnRequestService;
private SalesChannelRepositoryInterface $salesChannelProductRepository;
public function __construct(
SettingService $settingsService,
CartService $cartService,
EntityRepositoryInterface $productRepository,
AbstractProductDetailRoute $productDetailRoute,
PriceOnRequestService $priceOnRequestService,
SalesChannelRepositoryInterface $salesChannelProductRepository
)
{
$this->settingsService = $settingsService;
$this->cartService = $cartService;
$this->productRepository = $productRepository;
$this->productDetailRoute = $productDetailRoute;
$this->priceOnRequestService = $priceOnRequestService;
$this->salesChannelProductRepository = $salesChannelProductRepository;
}
public static function getSubscribedEvents(): array
{
// Return the events to listen to as array like this: <event to listen to> => <method to execute>
return [
KernelEvents::CONTROLLER_ARGUMENTS => 'beforeController',
ProductPageLoadedEvent::class => 'onProductPageLoaded',
'sales_channel.product.loaded' => 'productsLoaded',
OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPageLoaded',
CheckoutCartPageLoadedEvent::class => 'onCheckoutCartPageLoaded',
CheckoutConfirmPageLoadedEvent::class => 'onCheckoutPageLoaded',
FooterPageletLoadedEvent::class => 'onFooterLoaded'
];
}
public function beforeController(ControllerArgumentsEvent $event)
{
if ($event->getRequest()->getPathInfo() == '/checkout/product/add-by-number') {
/** @var $salesChannelContext SalesChannelContext */
$salesChannelContext = $event->getArguments()[1];
$product = $this->salesChannelProductRepository->search(
(new Criteria())
->addFilter(new EqualsFilter('productNumber', $event->getRequest()->get('number'))),
$salesChannelContext
);
if ($product->count() > 0) {
if ($this->priceOnRequestService->checkForProductCheckoutDisabled($product->first(), $salesChannelContext->getCurrentCustomerGroup()->getName())) {
$event->setController(function (Request $request, SalesChannelContext $salesChannelContext) {
return new RedirectResponse($request->getUriForPath('/checkout/cart?nb_por_nbpn=1'));
});
}
}
}
}
public function onProductPageLoaded(ProductPageLoadedEvent $event)
{
$config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
$product = $event->getPage()->getProduct();
$productId = $event->getPage()->getProduct()->getId();
$event->getPage()->getProduct()->addExtension('nimbitsPriceOnRequestSettings', $config);
$salesChannelContext = $event->getSalesChannelContext();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
$priceOnRequestService = $this->priceOnRequestService;
$priceOnRequestService->setSalesChannelId($salesChannelId);
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$event->getPage()->getProduct()->addExtension('nimbits_por', $porRuleset);
$customer = $salesChannelContext->getCustomer();
if ($customer != null) {
$event->getPage()->addExtension('nimbits_por_customer', $customer);
}
}
public function productsLoaded(SalesChannelEntityLoadedEvent $event): void
{
$config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
$salesChannelContext = $event->getSalesChannelContext();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$priceOnRequestService = $this->priceOnRequestService;
$priceOnRequestService->setSalesChannelId($salesChannelId);
$products = [];
foreach ($event->getEntities() as $product) {
$products[] = $product;
$cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$product->addExtension('nimbits_por', $porRuleset);
}
}
public function onOffcanvasCartPageLoaded(OffcanvasCartPageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
$config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
$priceOnRequestService = $this->priceOnRequestService;
$priceOnRequestService->setSalesChannelId($salesChannelId);
$event->getPage()->addExtension('nimbitsPriceOnRequestSettings', $config);
$currentCart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
$lineitems = $currentCart->getLineItems();
//iterate cart and apply price on request rules to each item and the cart
$products = [];
$productNumbers = [];
foreach ($lineitems as $item) {
$payload = $item->getPayload();
if (!isset($payload["productNumber"])) {
continue;
}
//xtract children's productNumbers if any
foreach ($item->getChildren() as $child) {
$payloadChild = $child->getPayload();
if (!isset($payloadChild["productNumber"])) {
continue;
}
$productNumbers[] = $payloadChild["productNumber"];
}
$productNumbers[] = $payload["productNumber"];
}
$prods = $this->salesChannelProductRepository->search(
(new Criteria())
->addFilter(new EqualsAnyFilter('productNumber', $productNumbers)),
$salesChannelContext
);
$prods = $prods->getElements();
//$product = $this->productDetailRoute->load($prods[$akeys[0]]->getId(), $event->getRequest(),$salesChannelContext, $criteria)->getProduct();
foreach ($prods as $p) {
$products[$p->getProductNumber()] = $p;
}
foreach ($lineitems as $item) {
$payload = $item->getPayload();
$rulesets = [];
if (!isset($payload["productNumber"])) {
continue;
}
foreach ($item->getChildren() as $child) {
$payloadChild = $child->getPayload();
if (!isset($payloadChild["productNumber"])) {
continue;
}
if (isset($products[$payloadChild["productNumber"]])) {
$product = $products[$payloadChild["productNumber"]];
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$rulesets[] = $porRuleset;
}
}
if (isset($products[$payload["productNumber"]])) {
$product = $products[$payload["productNumber"]];
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$rulesets[] = $porRuleset;
}
$porRuleset = $priceOnRequestService->sortRulesets($rulesets);
$item->addExtension('nimbits_por', $porRuleset);
}
$checkoutdisabled = $priceOnRequestService->checkForCheckoutDisabled($products, $cg);
$event->getPage()->addExtension('nimbits_por', $checkoutdisabled);
}
public function onCheckoutPageLoaded(CheckoutConfirmPageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$customer = $salesChannelContext->getCustomer();
if ($customer != null) {
$event->getPage()->addExtension('nimbits_por_customer', $customer);
}
}
public function onCheckoutCartPageLoaded(CheckoutCartPageLoadedEvent $event)
{
$salesChannelContext = $event->getSalesChannelContext();
$salesChannelId = $event->getSalesChannelContext()->getSalesChannel()->getId();
$cg = $event->getSalesChannelContext()->getCurrentCustomerGroup()->getName();
$config = $this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId());
$priceOnRequestService = $this->priceOnRequestService;
$priceOnRequestService->setSalesChannelId($salesChannelId);
$currentCart = $this->cartService->getCart($salesChannelContext->getToken(), $salesChannelContext);
$lineitems = $currentCart->getLineItems();
//iterate cart and apply price on request rules to each item and the cart
$products = [];
$productNumbers = [];
foreach ($lineitems as $item) {
$payload = $item->getPayload();
if (!isset($payload["productNumber"])) {
continue;
}
//xtract children's productNumbers if any
foreach ($item->getChildren() as $child) {
$payloadChild = $child->getPayload();
if (!isset($payloadChild["productNumber"])) {
continue;
}
$productNumbers[] = $payloadChild["productNumber"];
}
$productNumbers[] = $payload["productNumber"];
}
$prods = $this->salesChannelProductRepository->search(
(new Criteria())
->addFilter(new EqualsAnyFilter('productNumber', $productNumbers)),
$salesChannelContext
);
$prods = $prods->getElements();
//$product = $this->productDetailRoute->load($prods[$akeys[0]]->getId(), $event->getRequest(),$salesChannelContext, $criteria)->getProduct();
foreach ($prods as $p) {
$products[$p->getProductNumber()] = $p;
}
//iterate cart and apply price on request ruleset to each item and the cart
foreach ($lineitems as $item) {
$payload = $item->getPayload();
$rulesets = [];
if (!isset($payload["productNumber"])) {
continue;
}
foreach ($item->getChildren() as $child) {
$payloadChild = $child->getPayload();
if (!isset($payloadChild["productNumber"])) {
continue;
}
if (isset($products[$payloadChild["productNumber"]])) {
$product = $products[$payloadChild["productNumber"]];
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$rulesets[] = $porRuleset;
}
}
if (isset($products[$payload["productNumber"]])) {
$product = $products[$payload["productNumber"]];
$porRuleset = $priceOnRequestService->getPriceOnRequestRules($product, $cg);
$rulesets[] = $porRuleset;
}
$porRuleset = $priceOnRequestService->sortRulesets($rulesets);
$item->addExtension('nimbits_por', $porRuleset);
}
$checkoutdisabled = $priceOnRequestService->checkForCheckoutDisabled($products, $cg);
$checkoutdisabled->dontAddByProductNumber = ($event->getRequest()->get('nb_por_nbpn', 0) == 1);
$event->getPage()->addExtension('nimbits_por', $checkoutdisabled);
}
public function onFooterLoaded(FooterPageletLoadedEvent $event)
{
$event->getPagelet()->addExtension('nimbitsPriceOnRequestSettings',
$this->settingsService->getSettingsAsStruct($event->getSalesChannelContext()->getSalesChannel()->getId())
);
}
}