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

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\SalesChannel\Context\SalesChannelContextRestorer;
  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. class OrderStateChangeEventListener implements EventSubscriberInterface
  26. {
  27.     private EntityRepositoryInterface $stateRepository;
  28.     private EntityRepositoryInterface $orderRepository;
  29.     private EntityRepositoryInterface $transactionRepository;
  30.     private EntityRepositoryInterface $deliveryRepository;
  31.     private EventDispatcherInterface $eventDispatcher;
  32.     private BusinessEventCollector $businessEventCollector;
  33.     private SalesChannelContextRestorer $salesChannelContextRestorer;
  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.         SalesChannelContextRestorer $salesChannelContextRestorer
  45.     ) {
  46.         $this->orderRepository $orderRepository;
  47.         $this->transactionRepository $transactionRepository;
  48.         $this->deliveryRepository $deliveryRepository;
  49.         $this->eventDispatcher $eventDispatcher;
  50.         $this->stateRepository $stateRepository;
  51.         $this->businessEventCollector $businessEventCollector;
  52.         $this->salesChannelContextRestorer $salesChannelContextRestorer;
  53.     }
  54.     public static function getSubscribedEvents(): array
  55.     {
  56.         return [
  57.             'state_machine.order.state_changed' => 'onOrderStateChange',
  58.             'state_machine.order_delivery.state_changed' => 'onOrderDeliveryStateChange',
  59.             'state_machine.order_transaction.state_changed' => 'onOrderTransactionStateChange',
  60.             BusinessEventCollectorEvent::NAME => 'onAddStateEvents',
  61.         ];
  62.     }
  63.     /**
  64.      * @throws OrderDeliveryNotFoundException
  65.      * @throws OrderNotFoundException
  66.      */
  67.     public function onOrderDeliveryStateChange(StateMachineStateChangeEvent $event): void
  68.     {
  69.         $orderDeliveryId $event->getTransition()->getEntityId();
  70.         $criteria = new Criteria([$orderDeliveryId]);
  71.         $criteria->addAssociation('order.orderCustomer');
  72.         $criteria->addAssociation('order.transactions');
  73.         /** @var OrderDeliveryEntity|null $orderDelivery */
  74.         $orderDelivery $this->deliveryRepository
  75.             ->search($criteria$event->getContext())
  76.             ->first();
  77.         if ($orderDelivery === null) {
  78.             if (Feature::isActive('v6.5.0.0')) {
  79.                 throw OrderException::orderDeliveryNotFound($orderDeliveryId);
  80.             }
  81.             throw new OrderDeliveryNotFoundException($orderDeliveryId);
  82.         }
  83.         if ($orderDelivery->getOrder() === null) {
  84.             if (Feature::isActive('v6.5.0.0')) {
  85.                 throw OrderException::orderDeliveryNotFound($orderDeliveryId);
  86.             }
  87.             throw new OrderNotFoundException($orderDeliveryId);
  88.         }
  89.         $context $this->getContext($orderDelivery->getOrderId(), $event->getContext());
  90.         $order $this->getOrder($orderDelivery->getOrderId(), $context);
  91.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  92.     }
  93.     /**
  94.      * @throws OrderNotFoundException
  95.      * @throws OrderTransactionNotFoundException
  96.      */
  97.     public function onOrderTransactionStateChange(StateMachineStateChangeEvent $event): void
  98.     {
  99.         $orderTransactionId $event->getTransition()->getEntityId();
  100.         $criteria = new Criteria([$orderTransactionId]);
  101.         $criteria->addAssociation('paymentMethod');
  102.         $criteria->addAssociation('order.orderCustomer');
  103.         $criteria->addAssociation('order.transactions');
  104.         $orderTransaction $this->transactionRepository
  105.             ->search($criteria$event->getContext())
  106.             ->first();
  107.         if ($orderTransaction === null) {
  108.             if (Feature::isActive('v6.5.0.0')) {
  109.                 throw OrderException::orderTransactionNotFound($orderTransactionId);
  110.             }
  111.             throw new OrderTransactionNotFoundException($orderTransactionId);
  112.         }
  113.         if ($orderTransaction->getPaymentMethod() === null) {
  114.             if (Feature::isActive('v6.5.0.0')) {
  115.                 throw OrderException::orderTransactionNotFound($orderTransactionId);
  116.             }
  117.             throw new OrderTransactionNotFoundException($orderTransactionId);
  118.         }
  119.         if ($orderTransaction->getOrder() === null) {
  120.             if (Feature::isActive('v6.5.0.0')) {
  121.                 throw OrderException::orderTransactionNotFound($orderTransactionId);
  122.             }
  123.             throw new OrderNotFoundException($orderTransactionId);
  124.         }
  125.         $context $this->getContext($orderTransaction->getOrderId(), $event->getContext());
  126.         $order $this->getOrder($orderTransaction->getOrderId(), $context);
  127.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  128.     }
  129.     public function onOrderStateChange(StateMachineStateChangeEvent $event): void
  130.     {
  131.         $orderId $event->getTransition()->getEntityId();
  132.         $context $this->getContext($orderId$event->getContext());
  133.         $order $this->getOrder($orderId$context);
  134.         $this->dispatchEvent($event->getStateEventName(), $order$context);
  135.     }
  136.     public function onAddStateEvents(BusinessEventCollectorEvent $event): void
  137.     {
  138.         $context $event->getContext();
  139.         $collection $event->getCollection();
  140.         $criteria = new Criteria();
  141.         $criteria->addAssociation('stateMachine');
  142.         $states $this->stateRepository->search($criteria$context);
  143.         $sides = [
  144.             StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_ENTER,
  145.             StateMachineStateChangeEvent::STATE_MACHINE_TRANSITION_SIDE_LEAVE,
  146.         ];
  147.         /** @var StateMachineStateEntity $state */
  148.         foreach ($states as $state) {
  149.             foreach ($sides as $side) {
  150.                 $machine $state->getStateMachine();
  151.                 if (!$machine) {
  152.                     continue;
  153.                 }
  154.                 $name implode('.', [
  155.                     $side,
  156.                     $machine->getTechnicalName(),
  157.                     $state->getTechnicalName(),
  158.                 ]);
  159.                 $definition $this->businessEventCollector->define(OrderStateMachineStateChangeEvent::class, $name);
  160.                 if (!$definition) {
  161.                     continue;
  162.                 }
  163.                 $collection->set($name$definition);
  164.             }
  165.         }
  166.     }
  167.     /**
  168.      * @throws OrderNotFoundException
  169.      */
  170.     private function dispatchEvent(string $stateEventNameOrderEntity $orderContext $context): void
  171.     {
  172.         $this->eventDispatcher->dispatch(
  173.             new OrderStateMachineStateChangeEvent($stateEventName$order$context),
  174.             $stateEventName
  175.         );
  176.     }
  177.     private function getContext(string $orderIdContext $context): Context
  178.     {
  179.         $context = clone $context;
  180.         $salesChannelContext $this->salesChannelContextRestorer->restoreByOrder($orderId$context);
  181.         $context->setRuleIds($salesChannelContext->getRuleIds());
  182.         return $salesChannelContext->getContext();
  183.     }
  184.     /**
  185.      * @throws OrderNotFoundException
  186.      */
  187.     private function getOrder(string $orderIdContext $context): OrderEntity
  188.     {
  189.         $orderCriteria $this->getOrderCriteria($orderId);
  190.         $order $this->orderRepository
  191.             ->search($orderCriteria$context)
  192.             ->first();
  193.         if (!$order instanceof OrderEntity) {
  194.             throw new OrderNotFoundException($orderId);
  195.         }
  196.         return $order;
  197.     }
  198.     private function getOrderCriteria(string $orderId): Criteria
  199.     {
  200.         $criteria = new Criteria([$orderId]);
  201.         $criteria->addAssociation('orderCustomer.salutation');
  202.         $criteria->addAssociation('orderCustomer.customer');
  203.         $criteria->addAssociation('stateMachineState');
  204.         $criteria->addAssociation('deliveries.shippingMethod');
  205.         $criteria->addAssociation('deliveries.shippingOrderAddress.country');
  206.         $criteria->addAssociation('deliveries.shippingOrderAddress.countryState');
  207.         $criteria->addAssociation('salesChannel');
  208.         $criteria->addAssociation('language.locale');
  209.         $criteria->addAssociation('transactions.paymentMethod');
  210.         $criteria->addAssociation('lineItems');
  211.         $criteria->addAssociation('currency');
  212.         $criteria->addAssociation('addresses.country');
  213.         $criteria->addAssociation('addresses.countryState');
  214.         $event = new OrderStateChangeCriteriaEvent($orderId$criteria);
  215.         $this->eventDispatcher->dispatch($event);
  216.         return $criteria;
  217.     }
  218. }