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

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