platform/src/Core/Content/Flow/Dispatching/FlowDispatcher.php line 50

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