<?php declare(strict_types=1);
namespace Ott\EmarsysIntegration\Decorator;
use Ott\EmarsysIntegration\Event\EventDataProviderFactory;
use Ott\EmarsysIntegration\Gateway\EmarsysCustomerGateway;
use Ott\EmarsysIntegration\Service\ApiService;
use Ott\EmarsysIntegration\Service\MailEventProvider;
use Ott\EmarsysIntegration\Service\MailTriggerService;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Content\MailTemplate\Subscriber\MailSendSubscriber;
use Shopware\Core\Framework\Event\MailActionInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Contracts\EventDispatcher\Event;
class MailSendSubscriberDecorator implements EventSubscriberInterface
{
private EventSubscriberInterface $parentMailSendSubscriber;
private MailEventProvider $mailEventProvider;
private MailTriggerService $mailTriggerService;
private bool $alreadyTriggeredEvent = false;
private ApiService $apiService;
private EmarsysCustomerGateway $emarsysCustomerGateway;
private EventDataProviderFactory $dataProviderFactory;
private LoggerInterface $logger;
public function __construct(
EventSubscriberInterface $parentMailSendSubscriber,
MailEventProvider $mailEventProvider,
MailTriggerService $mailTriggerService,
ApiService $apiService,
EmarsysCustomerGateway $emarsysCustomerGateway,
EventDataProviderFactory $dataProviderFactory,
LoggerInterface $logger
)
{
$this->parentMailSendSubscriber = $parentMailSendSubscriber;
$this->mailEventProvider = $mailEventProvider;
$this->mailTriggerService = $mailTriggerService;
$this->apiService = $apiService;
$this->emarsysCustomerGateway = $emarsysCustomerGateway;
$this->dataProviderFactory = $dataProviderFactory;
$this->logger = $logger;
}
public static function getSubscribedEvents(): array
{
return [
MailSendSubscriber::ACTION_NAME => 'sendMail',
];
}
public function sendMail(Event $event): void
{
/** @var MailActionInterface $mailActionEvent */
$isOrderPlacedEvent = false;
try {
$mailActionEvent = $event->getEvent();
$isOrderPlacedEvent = CheckoutOrderPlacedEvent::EVENT_NAME === $mailActionEvent->getName();
$salesChannelId = $event->getContext()->getSource()->getSalesChannelId();
$mailEvent = $this->mailEventProvider->getMailEvent(
$mailActionEvent->getName(),
$salesChannelId
);
if ($isOrderPlacedEvent) {
$extension = $mailActionEvent->getContext()->getExtension('cronjob');
if (null === $extension || !$extension->getVars()['shouldSendMail']) {
return;
}
}
} catch (\Exception $e) {
$this->logger->error(
sprintf(
'Something went wrong while fetching MailEvent for %s: %s',
$event->getEvent()->getName(),
$e->getMessage()
)
);
if (!$isOrderPlacedEvent) {
$this->parentMailSendSubscriber->sendMail($event);
}
return;
}
if (null !== $mailEvent) {
try {
$eventData = $this->dataProviderFactory->getEventData($mailActionEvent);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
if (!$isOrderPlacedEvent) {
$this->parentMailSendSubscriber->sendMail($event);
}
return;
}
if (
null !== $eventData
&& !empty($eventData->getData())
&& !empty($eventData->getMail())
&& !$this->alreadyTriggeredEvent
) {
try {
$mailActionEvent->stopPropagation();
if (
null !== $eventData->getCustomerId()
&& !$this->emarsysCustomerGateway->emarsysCustomerExists($eventData->getCustomerId())
) {
$this->apiService->initApiClient($salesChannelId);
$this->apiService->createEmarsysCustomer($eventData->getCustomerId());
} elseif (
null === $eventData->getCustomerId()
&& null !== $eventData->getMail()
) {
$this->apiService->createEmarsysNewsletterCustomer($eventData->getMail());
}
$this->mailTriggerService->sendMail($mailEvent, $eventData, $salesChannelId);
$this->alreadyTriggeredEvent = true;
} catch (\Exception $e) {
$this->logger->error(
sprintf(
'Something went wrong while triggering MailEvent for %s: %s',
$mailActionEvent->getName(),
$e->getMessage()
)
);
if (!$isOrderPlacedEvent) {
$this->parentMailSendSubscriber->sendMail($event);
}
}
} else {
if (!$isOrderPlacedEvent) {
$this->parentMailSendSubscriber->sendMail($event);
}
}
} else {
if (!$isOrderPlacedEvent) {
$this->parentMailSendSubscriber->sendMail($event);
}
}
}
}