<?php
declare(strict_types=1);
namespace WnsSecurityComplianceSuite\Logging\Subscriber;
use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use WnsSecurityComplianceSuite\Logging\DTO\Log;
use WnsSecurityComplianceSuite\Logging\Provider\SourceInfoProvider;
use WnsSecurityComplianceSuite\Logging\Service\ActionLogger;
final class OrderStateSubscriber implements EventSubscriberInterface
{
private ActionLogger $actionLogger;
private SourceInfoProvider $sourceInfoProvider;
public function __construct(
ActionLogger $actionLogger,
SourceInfoProvider $sourceInfoProvider
) {
$this->actionLogger = $actionLogger;
$this->sourceInfoProvider = $sourceInfoProvider;
}
public static function getSubscribedEvents()
{
return [
'state_machine.order.state_changed' => 'onStateChange',
'state_machine.order_delivery.state_changed' => 'onStateChange',
'state_machine.order_transaction.state_changed' => 'onStateChange',
];
}
public function onStateChange(StateMachineStateChangeEvent $event): void
{
// The specifics don't matter here - the important part is to avoid getting 2 hits per state change
if ($event->getTransitionSide() !== StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_ENTER) {
return;
}
$contextSource = $event->getContext()->getSource();
$source = $this->sourceInfoProvider->getSourceDTO($contextSource);
$log = new Log(
$event->getName(),
$source,
$this->assembleDetail($event),
new \DateTimeImmutable(),
);
$this->actionLogger->log($log, $event->getSalesChannelId());
}
private function assembleDetail(StateMachineStateChangeEvent $event): array
{
return [
'entity' => $event->getTransition()
->getEntityName(),
'entityId' => $event->getTransition()
->getEntityId(),
'transition' => $event->getTransition()
->getTransitionName(),
'previousState' => [
'id' => $event->getPreviousState()
->getId(),
'technicalName' => $event->getPreviousState()
->getTechnicalName(),
'stateMachineId' => $event->getPreviousState()
->getStateMachineId(),
],
'nextState' => [
'id' => $event->getNextState()
->getId(),
'technicalName' => $event->getNextState()
->getTechnicalName(),
'stateMachineId' => $event->getNextState()
->getStateMachineId(),
],
];
}
}