<?phpdeclare(strict_types=1);namespace App\EventSubscriber\ECommerce;use App\Entity\ECommerce\Cart;use App\Entity\ECommerce\CartItem;use App\Event\ECommerce\CartCheckedOutEvent;use App\Event\ECommerce\CartEvent;use App\Event\ECommerce\CartItemAddedEvent;use App\Event\ECommerce\CartLoadedEvent;use App\Event\ECommerce\CartPayedEvent;use App\Event\ECommerce\CartUpdatedEvent;use App\Service\ECommerce\CartCalculator;use App\Service\ECommerce\EmailNotifier;use Symfony\Component\EventDispatcher\EventSubscriberInterface;/** * Class CartSubscriber * * @package App\EventSubscriber\ECommerce */class CartSubscriber implements EventSubscriberInterface{ /** * CartSubscriber constructor. */ public function __construct(private readonly CartCalculator $cartCalculator, private readonly EmailNotifier $notifier) { } public static function getSubscribedEvents(): array { return [ CartUpdatedEvent::class => 'onCartUpdated', CartLoadedEvent::class => 'onCartLoaded', CartItemAddedEvent::class => 'onCartItemAdded', CartPayedEvent::class => 'onCartPayed', CartCheckedOutEvent::class => 'onCartCheckedOut' ]; } public function onCartUpdated(CartEvent $event): void { /** @var Cart $cart */ $cart = $event->getCart(); $this->cartCalculator->reCalc($cart); } public function onCartLoaded(CartEvent $event): void { /** @var Cart $cart */ $cart = $event->getCart(); if ($cart->isCheckedOut()) { return; } $this->cartCalculator->reCalc($cart); /** @var CartItem $item */ foreach ($cart->getItems() as $item) { if ($item->getMinDeliveryDate() > $item->getDeliverDate()) { $item->setDeliverDate($item->getMinDeliveryDate()); } } } /** * @ToDo reevaluate logic */ public function onCartItemAdded(CartEvent $event): void { /** @var Cart $cart */ $cart = $event->getCart(); $oldItems = $cart->getItems()->toArray(); $uniqueItems = []; $duplicatedItems = []; /** @var CartItem $oldItem */ foreach ($oldItems as $oldItem) { $existingItem = array_filter($uniqueItems, fn(CartItem $uniqueItem): bool => $uniqueItem->getDepot()->getId() === $oldItem->getDepot()->getId() && $uniqueItem->getProduct()->getId() === $oldItem->getProduct()->getId()); if ($existingItem === []) { $uniqueItems[] = $oldItem; continue; } $duplicatedItems[] = $oldItem; } $duplicatedItems = array_unique($duplicatedItems, SORT_REGULAR); /** @var CartItem $duplicatedItem */ foreach ($duplicatedItems as $duplicatedItem) { $uniqueItems = array_map(function (CartItem $cartItem) use ($duplicatedItem): CartItem { if ( $cartItem->getProduct()->getId() === $duplicatedItem->getProduct()->getId() && $cartItem->getDepot()->getId() === $duplicatedItem->getDepot()->getId() ) { $newQuantity = $cartItem->getQuantity() + $duplicatedItem->getQuantity(); $cartItem->setQuantity($newQuantity); $this->cartCalculator->calcItem($cartItem); } return $cartItem; }, $uniqueItems); } $cart->setItems($uniqueItems);// $this->cartCalculator->reCalc($cart); } /** * @throws \Exception */ public function onCartCheckedOut(CartEvent $event): void { /** @var Cart $cart */ $cart = $event->getCart(); $cart->setCheckedOutAt(new \DateTime()); $this->notifier->send($cart); } public function onCartPayed(CartEvent $event): void { }}