Lines 100.00% 10 / 10
Methods 100.00% 4 / 4
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 dispatch 100.00% 5 / 5 100.00% 1 / 1 4
 getProvider 100.00% 1 / 1 100.00% 1 / 1 1
 invoke 100.00% 3 / 3 100.00% 1 / 1 2
26class EventDispatcher implements EventDispatcherInterface
27{
28    /**
29     * @param ListenerProvider $provider Supplies listeners for an event
30     * @param ContainerInterface $container Resolves class-string listeners
31     */
32    public function __construct(
33        private readonly ListenerProvider $provider,
34        private readonly ContainerInterface $container,
35    ) {
36    }
37
38    /**
39     * Provide all relevant listeners with an event to process.
40     *
41     * @param object $event The event to dispatch
42     * @return object The event, possibly modified by listeners
43     */
44    public function dispatch(object $event): object
45    {
46        foreach ($this->provider->getListenersForEvent($event) as $listener) {
47            if ($event instanceof StoppableEventInterface && $event->isPropagationStopped()) {
48                break;
49            }
50
51            $this->invoke($listener, $event);
52        }
53
54        return $event;
55    }
56
57    /**
58     * Get the listener provider backing this dispatcher.
59     *
60     * @return ListenerProvider The provider supplying listeners
61     */
62    public function getProvider(): ListenerProvider
63    {
64        return $this->provider;
65    }
66
67    /**
68     * Invoke a single listener with the event.
69     *
70     * Class-string listeners are resolved through the container so their
71     * dependencies are injected; the resolved instance is expected to be
72     * invokable.
73     *
74     * @param callable|string $listener The listener to invoke
75     * @param object $event The event to pass
76     * @return void
77     */
78    private function invoke(callable|string $listener, object $event): void
79    {
80        if (is_string($listener)) {
81            $listener = $this->container->get($listener);
82        }
83
84        $listener($event);
85    }
86}