vendor/shopware/core/Checkout/Order/Listener/OrderStateChangeEventListener.php line 182

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Checkout\Order\Listener;
  3. use Shopware\Core\Checkout\Cart\Exception\OrderDeliveryNotFoundException;
  4. use Shopware\Core\Checkout\Cart\Exception\OrderNotFoundException;
  5. use Shopware\Core\Checkout\Cart\Exception\OrderTransactionNotFoundException;
  6. use Shopware\Core\Checkout\Cart\Order\OrderConverter;
  7. use Shopware\Core\Checkout\Order\Aggregate\OrderDelivery\OrderDeliveryEntity;
  8. use Shopware\Core\Checkout\Order\Event\OrderStateChangeCriteriaEvent;
  9. use Shopware\Core\Checkout\Order\Event\OrderStateMachineStateChangeEvent;
  10. use Shopware\Core\Checkout\Order\OrderEntity;
  11. use Shopware\Core\Framework\Context;
  12. use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
  13. use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
  14. use Shopware\Core\Framework\Event\BusinessEventCollector;
  15. use Shopware\Core\Framework\Event\BusinessEventCollectorEvent;
  16. use Shopware\Core\System\StateMachine\Aggregation\StateMachineState\StateMachineStateEntity;
  17. use Shopware\Core\System\StateMachine\Event\StateMachineStateChangeEvent;
  18. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  19. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  20. class OrderStateChangeEventListener implements EventSubscriberInterface
  21. {
  22.     /**
  23.      * @var EntityRepositoryInterface
  24.      */
  25.     private $stateRepository;
  26.     /**
  27.      * @var EntityRepositoryInterface
  28.      */
  29.     private $orderRepository;
  30.     /**
  31.      * @var EntityRepositoryInterface
  32.      */
  33.     private $transactionRepository;
  34.     /**
  35.      * @var EntityRepositoryInterface
  36.      */
  37.     private $deliveryRepository;
  38.     /**
  39.      * @var EventDispatcherInterface
  40.      */
  41.     private $eventDispatcher;
  42.     /**
  43.      * @var OrderConverter
  44.      */
  45.     private $orderConverter;
  46.     /**
  47.      * @var BusinessEventCollector
  48.      */
  49.     private $businessEventCollector;
  50.     public function __construct(
  51.         EntityRepositoryInterface $orderRepository,
  52.         EntityRepositoryInterface $transactionRepository,
  53.         EntityRepositoryInterface $deliveryRepository,
  54.         EventDispatcherInterface $eventDispatcher,
  55.         OrderConverter $orderConverter,
  56.         BusinessEventCollector $businessEventCollector,
  57.         EntityRepositoryInterface $stateRepository
  58.     ) {
  59.         $this->orderRepository $orderRepository;
  60.         $this->transactionRepository $transactionRepository;
  61.         $this->deliveryRepository $deliveryRepository;
  62.         $this->eventDispatcher $eventDispatcher;
  63.         $this->orderConverter $orderConverter;
  64.         $this->stateRepository $stateRepository;
  65.         $this->businessEventCollector $businessEventCollector;
  66.     }
  67.     public static function getSubscribedEvents(): array
  68.     {
  69.         return [
  70.             'state_machine.order.state_changed' => 'onOrderStateChange',
  71.             'state_machine.order_delivery.state_changed' => 'onOrderDeliveryStateChange',
  72.             'state_machine.order_transaction.state_changed' => 'onOrderTransactionStateChange',
  73.             BusinessEventCollectorEvent::NAME => 'onAddStateEvents',
  74.         ];
  75.     }
  76.     /**
  77.      * @throws OrderDeliveryNotFoundException
  78.      * @throws OrderNotFoundException
  79.      */
  80.     public function onOrderDeliveryStateChange(StateMachineStateChangeEvent $event): void
  81.     {
  82.         $orderDeliveryId $event->getTransition()->getEntityId();
  83.         $criteria = new Criteria([$orderDeliveryId]);
  84.         $criteria->addAssociation('order.orderCustomer');
  85.         $criteria->addAssociation('order.transactions');
  86.         /** @var OrderDeliveryEntity|null $orderDelivery */
  87.         $orderDelivery $this->deliveryRepository
  88.             ->search($criteria$event->getContext())
  89.             ->first();
  90.         if ($orderDelivery === null) {
  91.             throw new OrderDeliveryNotFoundException($orderDeliveryId);
  92.         }
  93.         if ($orderDelivery->getOrder() === null) {
  94.             throw new OrderNotFoundException($orderDeliveryId);
  95.         }
  96.         $context $this->getContext($orderDelivery->getOrder(), $event->getContext());
  97.         $order $this->getOrder($orderDelivery->getOrderId(), $context);
  98.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  99.     }
  100.     /**
  101.      * @throws OrderNotFoundException
  102.      * @throws OrderTransactionNotFoundException
  103.      */
  104.     public function onOrderTransactionStateChange(StateMachineStateChangeEvent $event): void
  105.     {
  106.         $orderTransactionId $event->getTransition()->getEntityId();
  107.         $criteria = new Criteria([$orderTransactionId]);
  108.         $criteria->addAssociation('paymentMethod');
  109.         $criteria->addAssociation('order.orderCustomer');
  110.         $criteria->addAssociation('order.transactions');
  111.         $orderTransaction $this->transactionRepository
  112.             ->search($criteria$event->getContext())
  113.             ->first();
  114.         if ($orderTransaction === null) {
  115.             throw new OrderTransactionNotFoundException($orderTransactionId);
  116.         }
  117.         if ($orderTransaction->getPaymentMethod() === null) {
  118.             throw new OrderTransactionNotFoundException($orderTransactionId);
  119.         }
  120.         if ($orderTransaction->getOrder() === null) {
  121.             throw new OrderNotFoundException($orderTransactionId);
  122.         }
  123.         $context $this->getContext($orderTransaction->getOrder(), $event->getContext());
  124.         $order $this->getOrder($orderTransaction->getOrderId(), $context);
  125.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  126.     }
  127.     /**
  128.      * @throws OrderNotFoundException
  129.      */
  130.     public function onOrderStateChange(StateMachineStateChangeEvent $event): void
  131.     {
  132.         $orderId $event->getTransition()->getEntityId();
  133.         $criteria = new Criteria([$orderId]);
  134.         $criteria->addAssociation('orderCustomer');
  135.         $criteria->addAssociation('transactions');
  136.         $order $this->orderRepository
  137.             ->search($criteria$event->getContext())
  138.             ->first();
  139.         if ($order === null) {
  140.             throw new OrderNotFoundException($orderId);
  141.         }
  142.         $context $this->getContext($order$event->getContext());
  143.         $order $this->getOrder($orderId$context);
  144.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  145.     }
  146.     public function onAddStateEvents(BusinessEventCollectorEvent $event): void
  147.     {
  148.         $context $event->getContext();
  149.         $collection $event->getCollection();
  150.         $criteria = new Criteria();
  151.         $criteria->addAssociation('stateMachine');
  152.         $states $this->stateRepository->search($criteria$context);
  153.         $sides = [
  154.             StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_ENTER,
  155.             StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_LEAVE,
  156.         ];
  157.         /** @var StateMachineStateEntity $state */
  158.         foreach ($states as $state) {
  159.             foreach ($sides as $side) {
  160.                 $machine $state->getStateMachine();
  161.                 if (!$machine) {
  162.                     continue;
  163.                 }
  164.                 $name implode('.', [
  165.                     $side,
  166.                     $machine->getTechnicalName(),
  167.                     $state->getTechnicalName(),
  168.                 ]);
  169.                 $definition $this->businessEventCollector->define(OrderStateMachineStateChangeEvent::class, $name);
  170.                 if (!$definition) {
  171.                     continue;
  172.                 }
  173.                 $collection->set($name$definition);
  174.             }
  175.         }
  176.     }
  177.     /**
  178.      * @throws OrderNotFoundException
  179.      */
  180.     private function dispatchEvent(string $stateEventNameOrderEntity $orderContext $context): void
  181.     {
  182.         $this->eventDispatcher->dispatch(
  183.             new OrderStateMachineStateChangeEvent($stateEventName$order$context),
  184.             $stateEventName
  185.         );
  186.     }
  187.     private function getContext(OrderEntity $orderContext $context): Context
  188.     {
  189.         $context = clone $context;
  190.         $salesChannelContext $this->orderConverter->assembleSalesChannelContext($order$context);
  191.         if ($order->getRuleIds() !== null) {
  192.             $salesChannelContext->setRuleIds($order->getRuleIds());
  193.         }
  194.         return $salesChannelContext->getContext();
  195.     }
  196.     /**
  197.      * @throws OrderNotFoundException
  198.      */
  199.     private function getOrder(string $orderIdContext $context): OrderEntity
  200.     {
  201.         $orderCriteria $this->getOrderCriteria($orderId);
  202.         $order $this->orderRepository
  203.             ->search($orderCriteria$context)
  204.             ->first();
  205.         if (!$order instanceof OrderEntity) {
  206.             throw new OrderNotFoundException($orderId);
  207.         }
  208.         return $order;
  209.     }
  210.     private function getOrderCriteria(string $orderId): Criteria
  211.     {
  212.         $criteria = new Criteria([$orderId]);
  213.         $criteria->addAssociation('orderCustomer.salutation');
  214.         $criteria->addAssociation('orderCustomer.customer');
  215.         $criteria->addAssociation('stateMachineState');
  216.         $criteria->addAssociation('deliveries.shippingMethod');
  217.         $criteria->addAssociation('deliveries.shippingOrderAddress.country');
  218.         $criteria->addAssociation('salesChannel');
  219.         $criteria->addAssociation('language.locale');
  220.         $criteria->addAssociation('transactions.paymentMethod');
  221.         $criteria->addAssociation('lineItems');
  222.         $criteria->addAssociation('currency');
  223.         $criteria->addAssociation('addresses.country');
  224.         $event = new OrderStateChangeCriteriaEvent($orderId$criteria);
  225.         $this->eventDispatcher->dispatch($event);
  226.         return $criteria;
  227.     }
  228. }