vendor/shopware/core/Content/Flow/Dispatching/FlowDispatcher.php line 56

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Content\Flow\Dispatching;
  3. use Psr\EventDispatcher\StoppableEventInterface;
  4. use Psr\Log\LoggerInterface;
  5. use Shopware\Core\Content\Flow\Dispatching\Struct\Flow;
  6. use Shopware\Core\Content\Flow\Exception\ExecuteSequenceException;
  7. use Shopware\Core\Framework\Context;
  8. use Shopware\Core\Framework\Event\BusinessEvent;
  9. use Shopware\Core\Framework\Event\FlowEvent;
  10. use Shopware\Core\Framework\Event\FlowEventAware;
  11. use Shopware\Core\Framework\Event\FlowLogEvent;
  12. use Shopware\Core\Framework\Feature;
  13. use Shopware\Core\Framework\Log\Package;
  14. use Symfony\Component\DependencyInjection\ContainerInterface;
  15. use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
  16. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. /**
  19.  * @internal not intended for decoration or replacement
  20.  */
  21. #[Package('business-ops')]
  22. class FlowDispatcher implements EventDispatcherInterface
  23. {
  24.     private EventDispatcherInterface $dispatcher;
  25.     private ContainerInterface $container;
  26.     private LoggerInterface $logger;
  27.     private FlowFactory $flowFactory;
  28.     public function __construct(EventDispatcherInterface $dispatcherLoggerInterface $loggerFlowFactory $flowFactory)
  29.     {
  30.         $this->dispatcher $dispatcher;
  31.         $this->logger $logger;
  32.         $this->flowFactory $flowFactory;
  33.     }
  34.     public function setContainer(ContainerInterface $container): void
  35.     {
  36.         $this->container $container;
  37.     }
  38.     /**
  39.      * @template TEvent of object
  40.      *
  41.      * @param TEvent $event
  42.      *
  43.      * @return TEvent
  44.      */
  45.     public function dispatch($event, ?string $eventName null): object
  46.     {
  47.         $event $this->dispatcher->dispatch($event$eventName);
  48.         if (!$event instanceof FlowEventAware) {
  49.             return $event;
  50.         }
  51.         if (Feature::isActive('v6.5.0.0')) {
  52.             $flowLogEvent = new FlowLogEvent(FlowLogEvent::NAME$event);
  53.             $this->dispatcher->dispatch($flowLogEvent$flowLogEvent->getName());
  54.         }
  55.         if (Feature::isActive('FEATURE_NEXT_17858')) {
  56.             if ($event instanceof FlowEvent) {
  57.                 return $event;
  58.             }
  59.         } else {
  60.             if ($event instanceof BusinessEvent || $event instanceof FlowEvent) {
  61.                 return $event;
  62.             }
  63.         }
  64.         if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
  65.             return $event;
  66.         }
  67.         if ($event->getContext()->hasState(Context::SKIP_TRIGGER_FLOW)) {
  68.             return $event;
  69.         }
  70.         $storableFlow $this->flowFactory->create($event);
  71.         /** @deprecated tag:v6.5.0 Will be removed */
  72.         if (!Feature::isActive('v6.5.0.0')) {
  73.             $storableFlow->setOriginalEvent($event);
  74.         }
  75.         $this->callFlowExecutor($storableFlow);
  76.         return $event;
  77.     }
  78.     /**
  79.      * @param string   $eventName
  80.      * @param callable $listener
  81.      * @param int      $priority
  82.      */
  83.     public function addListener($eventName$listener$priority 0): void
  84.     {
  85.         $this->dispatcher->addListener($eventName$listener$priority);
  86.     }
  87.     public function addSubscriber(EventSubscriberInterface $subscriber): void
  88.     {
  89.         $this->dispatcher->addSubscriber($subscriber);
  90.     }
  91.     /**
  92.      * @param string   $eventName
  93.      * @param callable $listener
  94.      */
  95.     public function removeListener($eventName$listener): void
  96.     {
  97.         $this->dispatcher->removeListener($eventName$listener);
  98.     }
  99.     public function removeSubscriber(EventSubscriberInterface $subscriber): void
  100.     {
  101.         $this->dispatcher->removeSubscriber($subscriber);
  102.     }
  103.     public function getListeners(?string $eventName null): array
  104.     {
  105.         return $this->dispatcher->getListeners($eventName);
  106.     }
  107.     /**
  108.      * @param string $eventName
  109.      * @param callable $listener
  110.      */
  111.     public function getListenerPriority($eventName$listener): ?int
  112.     {
  113.         return $this->dispatcher->getListenerPriority($eventName$listener);
  114.     }
  115.     public function hasListeners(?string $eventName null): bool
  116.     {
  117.         return $this->dispatcher->hasListeners($eventName);
  118.     }
  119.     private function callFlowExecutor(StorableFlow $event): void
  120.     {
  121.         $flows $this->getFlows($event->getName());
  122.         if (empty($flows)) {
  123.             return;
  124.         }
  125.         /** @var FlowExecutor|null $flowExecutor */
  126.         $flowExecutor $this->container->get(FlowExecutor::class);
  127.         if ($flowExecutor === null) {
  128.             throw new ServiceNotFoundException(FlowExecutor::class);
  129.         }
  130.         foreach ($flows as $flow) {
  131.             try {
  132.                 /** @var Flow $payload */
  133.                 $payload $flow['payload'];
  134.                 $flowExecutor->execute($payload$event);
  135.             } catch (ExecuteSequenceException $e) {
  136.                 $this->logger->error(
  137.                     "Could not execute flow with error message:\n"
  138.                     'Flow name: ' $flow['name'] . "\n"
  139.                     'Flow id: ' $flow['id'] . "\n"
  140.                     'Sequence id: ' $e->getSequenceId() . "\n"
  141.                     $e->getMessage() . "\n"
  142.                     'Error Code: ' $e->getCode() . "\n"
  143.                 );
  144.             } catch (\Throwable $e) {
  145.                 $this->logger->error(
  146.                     "Could not execute flow with error message:\n"
  147.                     'Flow name: ' $flow['name'] . "\n"
  148.                     'Flow id: ' $flow['id'] . "\n"
  149.                     $e->getMessage() . "\n"
  150.                     'Error Code: ' $e->getCode() . "\n"
  151.                 );
  152.             }
  153.         }
  154.     }
  155.     /**
  156.      * @return array<string, mixed>
  157.      */
  158.     private function getFlows(string $eventName): array
  159.     {
  160.         /** @var AbstractFlowLoader|null $flowLoader */
  161.         $flowLoader $this->container->get(FlowLoader::class);
  162.         if ($flowLoader === null) {
  163.             throw new ServiceNotFoundException(FlowExecutor::class);
  164.         }
  165.         $flows $flowLoader->load();
  166.         $result = [];
  167.         if (\array_key_exists($eventName$flows)) {
  168.             $result $flows[$eventName];
  169.         }
  170.         return $result;
  171.     }
  172. }