<?php declare(strict_types=1);
namespace Zeobv\AbandonedCart\Core\Subscriber;
use Shopware\Core\Checkout\Order\OrderDefinition;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Core\Checkout\Order\OrderEvents;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Zeobv\AbandonedCart\Service\AbandonedCartService;
class OrderSubscriber implements EventSubscriberInterface
{
protected AbandonedCartService $abandonedCartService;
protected EntityRepositoryInterface $orderRepository;
protected EntityRepositoryInterface $abandonedCartRepository;
/**
* @param AbandonedCartService $abandonedCartService
* @param EntityRepositoryInterface $orderRepository
* @param EntityRepositoryInterface $abandonedCartRepository
*/
public function __construct(
AbandonedCartService $abandonedCartService,
EntityRepositoryInterface $orderRepository,
EntityRepositoryInterface $abandonedCartRepository
)
{
$this->abandonedCartService = $abandonedCartService;
$this->orderRepository = $orderRepository;
$this->abandonedCartRepository = $abandonedCartRepository;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
OrderEvents::ORDER_WRITTEN_EVENT => 'onOrderWritten',
];
}
/**
* @param EntityWrittenEvent $event
*/
public function onOrderWritten(EntityWrittenEvent $event): void
{
foreach ($event->getWriteResults() as $writeResult) {
if ($writeResult->getOperation() !== EntityWriteResult::OPERATION_INSERT
|| $writeResult->getEntityName() !== OrderDefinition::ENTITY_NAME
) {
continue;
}
if (is_array($writeResult->getPrimaryKey())) {
foreach ($writeResult->getPrimaryKey() as $id) {
$this->resolveAbandonedCartForOrderId($id, $event->getContext());
}
} else {
$this->resolveAbandonedCartForOrderId($writeResult->getPrimaryKey(), $event->getContext());
}
}
}
/**
* @param string $orderId
* @param Context $context
*/
protected function resolveAbandonedCartForOrderId(string $orderId, Context $context): void
{
$criteria = new Criteria([$orderId]);
$criteria->addAssociation('orderCustomer');
/** @var OrderEntity|null $order */
$order = $this->orderRepository->search($criteria, $context)->first();
if ($order === null || $order->getOrderCustomer() === null) {
return;
}
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('email', $order->getOrderCustomer()->getEmail()));
$abandonedCart = $this->abandonedCartRepository->search($criteria, $context)->first();
if ($abandonedCart === null) {
return;
}
/* Here we are upsert the data on order table for displaying the recovered orders in dashboard */
if ($abandonedCart->getIsRecovered() == true) {
$writeData = [
'id' => $orderId,
'customFields' => ['ZeobvAbandonedCartMail' => 1],
];
$this->orderRepository->upsert([$writeData], Context::createDefaultContext());
}
$this->abandonedCartService->resolveAbandonedCart($abandonedCart, $context);
}
}