<?php declare(strict_types=1);
namespace LoyxxSeminar\Subscriber;
use LoyxxSeminar\Core\Checkout\Cart\Participant\ParticipantCollection;
use LoyxxSeminar\Core\Checkout\Cart\Participant\ParticipantService;
use LoyxxSeminar\LoyxxSeminar;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemQuantityChangedEvent;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemRemovedEvent;
use Shopware\Core\Checkout\Cart\Event\LineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\LineItemQuantityChangedEvent;
use Shopware\Core\Checkout\Cart\Event\LineItemRemovedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LineItemEventSubscriber implements EventSubscriberInterface
{
/**
* @var ParticipantService
*/
protected $participantService;
/**
* @var SalesChannelRepositoryInterface
*/
private $productRepository;
public function __construct(
ParticipantService $participantService,
SalesChannelRepositoryInterface $productRepository
) {
$this->participantService = $participantService;
$this->productRepository = $productRepository;
}
public static function getSubscribedEvents(): array
{
return [
BeforeLineItemAddedEvent::class => 'onLineItemAdded',
BeforeLineItemQuantityChangedEvent::class => 'onLineItemQuantityChanged',
BeforeLineItemRemovedEvent::class => 'onLineItemRemoved'
];
}
public function onLineItemAdded(BeforeLineItemAddedEvent $event)
{
$lineItem = $event->getLineItem();
if ($lineItem->getType() === LineItem::PRODUCT_LINE_ITEM_TYPE){ // do not process participant service for other product types
$criteria = new Criteria([$lineItem->getReferencedId()]);
$criteria->setLimit(1);
/** @var SalesChannelProductEntity $product */
$product = $this->productRepository->search($criteria, $event->getSalesChannelContext())->getEntities()->first();
if ($product){
$customFields = $product->getCustomFields();
if (isset($customFields[LoyxxSeminar::PRODUCT_CUSTOM_FIELD_SEMINAR]) &&
$customFields[LoyxxSeminar::PRODUCT_CUSTOM_FIELD_SEMINAR]) {
// Check if line item already exists for product
// this happens when same product is added to cart twice
// line item passed to event will be new, but we need to use existing line item if available
// quantity of new line item passed will be 1 but actual quantity is in existing line item
$lineItem = $event->getCart()->getLineItems()->get($lineItem->getId()) ?? $lineItem;
$this->participantService->syncParticipantsAndLineItemQuantity(
$event->getCart(),
$lineItem,
$event->getSalesChannelContext()
);
}
}
}
}
public function onLineItemQuantityChanged(BeforeLineItemQuantityChangedEvent $event)
{
$lineItem = $event->getLineItem();
if ($lineItem->hasExtension(ParticipantCollection::PARTICIPANT_EXTENSION_NAME)) {
$this->participantService->syncParticipantsAndLineItemQuantity(
$event->getCart(),
$lineItem,
$event->getSalesChannelContext()
);
}
}
public function onLineItemRemoved(BeforeLineItemRemovedEvent $event)
{
$lineItem = $event->getLineItem();
if ($lineItem->hasExtension(ParticipantCollection::PARTICIPANT_EXTENSION_NAME)) {
$lineItem->removeExtension(ParticipantCollection::PARTICIPANT_EXTENSION_NAME);
}
}
}