<?php declare(strict_types=1);
namespace DreiscSet\Subscriber\Events;
use DreiscSet\Core\Content\DreiscSetProductExtension\DreiscSetProductExtensionEntity;
use DreiscSet\Core\Content\Product\SalesChannelProductRepository;
use DreiscSet\Core\Set\AbstractSetLoaderService;
use DreiscSet\Core\Set\SetLoaderService;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Content\Product\Cart\ProductNotFoundError;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class BeforeLineItemAddedEventSubscriber implements EventSubscriberInterface
{
/**
* @var SalesChannelProductRepository
*/
protected $salesChannelProductRepository;
/**
* @var AbstractSetLoaderService
*/
protected $setLoaderService;
/**
* @param SalesChannelProductRepository $salesChannelProductRepository
* @param AbstractSetLoaderService $setLoaderService
*/
public function __construct(SalesChannelProductRepository $salesChannelProductRepository, AbstractSetLoaderService $setLoaderService)
{
$this->salesChannelProductRepository = $salesChannelProductRepository;
$this->setLoaderService = $setLoaderService;
}
public static function getSubscribedEvents(): array
{
return [
BeforeLineItemAddedEvent::class => 'onBeforeLineItemAddedEvent'
];
}
/**
* @param BeforeLineItemAddedEvent $beforeLineItemAddedEvent
* @return void
*/
public function onBeforeLineItemAddedEvent(BeforeLineItemAddedEvent $beforeLineItemAddedEvent): void
{
$lineItem = $beforeLineItemAddedEvent->getLineItem();
/** Abort, if it's not type product */
if (LineItem::PRODUCT_LINE_ITEM_TYPE !== $lineItem->getType()) {
return;
}
/** Load extended product data to check whether it is a set item that can only be purchased as a set. */
$productId = $lineItem->getReferencedId();
$salesChannelContext = $beforeLineItemAddedEvent->getSalesChannelContext();
$criteria = new Criteria();
$salesChannelProductEntity = $this->salesChannelProductRepository->get(
$productId,
$criteria,
$salesChannelContext
);
/** Abort, if the entity is null */
if (null === $salesChannelProductEntity) {
return;
}
/** Fetch the product extension dreiscSetProductExtension */
/** @var DreiscSetProductExtensionEntity $dreiscSetProductExtension */
$dreiscSetProductExtension = $salesChannelProductEntity->getExtension('dreiscSetProductExtension');
/** Abort, if no dreisc set id is set for this product */
if (null === $dreiscSetProductExtension || null === $dreiscSetProductExtension->getDreiscSetId()) {
return;
}
$dreiscSetEntity = $this->setLoaderService->getDreiscSetEntity($dreiscSetProductExtension->getDreiscSetId(), $salesChannelContext);
if ($dreiscSetEntity->getProductSetOnly()) {
/** This product can only be purchased as a set, so we stop the adding process at this point */
$beforeLineItemAddedEvent->getCart()->remove($lineItem->getId());
$beforeLineItemAddedEvent->getCart()->getErrors()->add(new ProductNotFoundError($productId));
}
}
}