<?php declare(strict_types=1);
namespace Zeobv\CartRecovery\Storefront\Subscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Core\Checkout\Order\OrderEntity;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Zeobv\CartRecovery\Service\CartRecoveryService;
use Shopware\Core\Checkout\Cart\Cart;
class CheckoutSubscriber implements EventSubscriberInterface
{
/**
* @var CartRecoveryService
*/
protected $cartRecoveryService;
/**
* CheckoutSubscriber constructor.
*
* @param CartRecoveryService $cartRecoveryService
*/
public function __construct(
CartRecoveryService $cartRecoveryService
)
{
$this->cartRecoveryService = $cartRecoveryService;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
CheckoutFinishPageLoadedEvent::class => 'onFinishPageLoaded',
CheckoutConfirmPageLoadedEvent::class => 'onConfirmPageLoaded'
];
}
/**
* @param CheckoutFinishPageLoadedEvent $event
*/
public function onFinishPageLoaded(CheckoutFinishPageLoadedEvent $event)
{
$order = $event->getPage()->getOrder();
if ($event->getPage()->isPaymentFailed() || $this->paymentFailedForOrder($order)) {
$this->cartRecoveryService->recoverCartFromOrder($order, $event->getSalesChannelContext());
} else {
$this->cartRecoveryService->cleanUpCartWaitingForRecoveryForOrder($order, $event->getSalesChannelContext());
}
}
public function onConfirmPageLoaded(CheckoutConfirmPageLoadedEvent $event)
{
$event->getPage()->addExtension('ZeobvCartRecovery', new ArrayStruct([
'freshLoadToken' => md5(random_bytes(3))
]));
}
/**
* @param OrderEntity $order
*
* @return bool
*/
protected function paymentFailedForOrder(OrderEntity $order)
{
$latestTransactionStateName = $order->getTransactions()->last()->getStateMachineState()->getTechnicalName();
return in_array($latestTransactionStateName, [
'cancelled',
'denied'
]);
}
}