<?php declare(strict_types=1);
namespace DreiscSet\Subscriber\ProductEvents;
use DreiscSet\Core\Content\DreiscSetProductExtension\DreiscSetProductExtensionEntity;
use DreiscSet\Core\Content\Product\SalesChannelProductRepository;
use DreiscSet\Core\Set\AbstractSetLoaderService;
use DreiscSet\Core\SetOrder\AbstractSetOrderService;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ProductPageLoadedSubscriber implements EventSubscriberInterface
{
/**
* @var AbstractSetLoaderService
*/
protected $setLoaderService;
/**
* @var AbstractSetOrderService
*/
protected $setOrderService;
/**
* @var SalesChannelProductRepository
*/
protected $salesChannelProductRepository;
/**
* @param AbstractSetLoaderService $setLoaderService
* @param AbstractSetOrderService $setOrderService
* @param SalesChannelProductRepository $salesChannelProductRepository
*/
public function __construct(AbstractSetLoaderService $setLoaderService, AbstractSetOrderService $setOrderService, SalesChannelProductRepository $salesChannelProductRepository)
{
$this->setLoaderService = $setLoaderService;
$this->setOrderService = $setOrderService;
$this->salesChannelProductRepository = $salesChannelProductRepository;
}
/**
* @return array|void
*/
public static function getSubscribedEvents()
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded'
];
}
public function onProductPageLoaded(ProductPageLoadedEvent $productPageLoadedEvent)
{
$productEntity = $productPageLoadedEvent->getPage()->getProduct();
$salesChannelContext = $productPageLoadedEvent->getSalesChannelContext();
$dreiscSetOrderId = $productPageLoadedEvent->getRequest()->get('dreiscSetOrderId');
$showSetParameterIsSetOrSetOrderIdWasLoad = !empty($productPageLoadedEvent->getRequest()->get('showSet')) || !empty($dreiscSetOrderId);
/** Fetch the product extension dreiscSetProductExtension */
/** @var DreiscSetProductExtensionEntity $dreiscSetProductExtension */
$dreiscSetProductExtension = $productEntity->getExtension('dreiscSetProductExtension');
/** Load the parent in case of variant */
if (null === $dreiscSetProductExtension && null !== $productEntity->getParentId()) {
$parentProductEntity = $this->salesChannelProductRepository->get(
$productEntity->getParentId(),
new Criteria(),
$productPageLoadedEvent->getSalesChannelContext()
);
$dreiscSetProductExtension = $parentProductEntity->getExtension('dreiscSetProductExtension');
}
/** Abort, if it is not a set product */
if (null === $dreiscSetProductExtension) {
return;
}
/** Abort, if closeout and stock is empty */
if ($productEntity->getStock() <= 0 && $productEntity->getIsCloseout()) {
return;
}
/** Abort, if dreisc set id is null */
if (null === $dreiscSetProductExtension->getDreiscSetId()) {
return;
}
/** Load the set order */
$setOrderCartStruct = $this->setOrderService->loadSetOrder(
$dreiscSetProductExtension->getDreiscSetId(),
$salesChannelContext,
$dreiscSetOrderId,
$productEntity->getId(),
true
);
if (null === $setOrderCartStruct) {
return;
}
/** Load the set configuration struct */
$setStruct = $this->setLoaderService->loadSet($setOrderCartStruct->getDreiscSetId(), $salesChannelContext);
/** Abortion if the product cannot only be bought as a set and the set GET parameter is not set. */
if (!$setStruct->isProductSetOnly() && false === $showSetParameterIsSetOrSetOrderIdWasLoad) {
$productEntity->addExtension(
'dreiscSetIsAvailable',
new ArrayStruct([
'showBuyProductInSetButton' => true
])
);
/** Abort */
return;
}
/** Assign the set configuration struct */
$productEntity->addExtension(
'dreiscSetStruct',
$setStruct
);
/** Load and assign the set order struct */
$productEntity->addExtension(
'dreiscSetOrderCartStruct',
$setOrderCartStruct
);
}
}