<?php
namespace Boldr\Shop\ShopBundle\EventSubscriber;
use Boldr\Shop\ShopBundle\Event\{ OrderStateUpdatedEvent, PaymentStatusUpdatedEvent };
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Boldr\Shop\ShopBundle\Entity\Payment;
use Boldr\Shop\ShopBundle\EmailFactory;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
class OrderEventSubscriber implements EventSubscriberInterface
{
private EntityManagerInterface $em;
private MailerInterface $mailer;
private RequestStack $requestStack;
private EmailFactory $emailFactory;
private EventDispatcherInterface $eventDispatcher;
public function __construct(
RequestStack $requestStack,
EntityManagerInterface $em,
MailerInterface $mailer,
EmailFactory $emailFactory,
EventDispatcherInterface $eventDispatcher
)
{
$this->emailFactory = $emailFactory;
$this->em = $em;
$this->mailer = $mailer;
$this->requestStack = $requestStack;
$this->eventDispatcher = $eventDispatcher;
}
public static function getSubscribedEvents(): array
{
return [
OrderStateUpdatedEvent::class => [
['onOrderStateUpdated', 10]
],
];
}
public function onOrderStateUpdated(OrderStateUpdatedEvent $event)
{
$order = $event->getOrder();
if ($event->getNewState() === 'cart')
{
$payments = $this->em->getRepository(Payment::class)->createQueryBuilder('p')
->leftJoin('p.invoice', 'i')
->leftJoin('i.items', 'ii')
->andWhere('ii.order = :order')
->andWhere('p.status = '. Payment::STATUS_PENDING)
->setParameter('order', $order)
->getQuery()
->getResult()
;
foreach ($payments as $payment)
{
try
{
$payment->setStatus(Payment::STATUS_CANCELLED);
$this->em->flush();
$event = new PaymentStatusUpdatedEvent($payment, Payment::STATUS_PENDING, Payment::STATUS_CANCELLED);
$this->eventDispatcher->dispatch($event);
}
catch (\Exception $ex)
{
// ignore silently
}
}
}
elseif ($event->getNewState() === 'confirmed')
{
$invoices = [];
foreach ($order->getInvoices() as $invoice)
{
if (!$invoice->isDraft() && !$invoice->isProForma() && !$invoice->isSentToCustomer())
{
$invoices[] = $invoice;
$invoice->setSentToCustomer(true);
}
}
try
{
$email = $this->emailFactory->createConfirmationEmail($order, $invoices);
$this->mailer->send($email);
}
catch (\Exception $ex)
{
// could not send, ignore silently
}
try
{
$email = $this->emailFactory->createShopOrderEmail($order);
$this->mailer->send($email);
}
catch (\Exception $ex)
{
// could not send, ignore silently
}
// Save sent to customer
$this->em->flush();
}
}
}