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

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