Dispatcher   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 101
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 101
rs 10
c 0
b 0
f 0
wmc 17

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addListener() 0 11 3
A dispatchEvent() 0 6 2
A addSubscriber() 0 12 5
A __construct() 0 11 4
A dispatch() 0 18 3
1
<?php
2
3
/*
4
 * event-symfony-event-dispatcher (https://github.com/phpgears/event-symfony-event-dispatcher).
5
 * Event bus with Symfony Event Dispatcher.
6
 *
7
 * @license MIT
8
 * @link https://github.com/phpgears/event-symfony-event-dispatcher
9
 * @author Julián Gutiérrez <[email protected]>
10
 */
11
12
declare(strict_types=1);
13
14
namespace Gears\Event\Symfony\Dispatcher;
15
16
use Gears\Event\EventHandler;
17
use Symfony\Component\EventDispatcher\EventDispatcher as SymfonyEventDispatcher;
18
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
19
use Symfony\Contracts\EventDispatcher\Event as SymfonyEvent;
20
21
class Dispatcher extends SymfonyEventDispatcher implements EventDispatcher
22
{
23
    /**
24
     * ContainerAwareEventDispatcher constructor.
25
     *
26
     * @param array<string, mixed> $listenersMap
27
     */
28
    public function __construct(array $listenersMap = [])
29
    {
30
        parent::__construct();
31
32
        foreach ($listenersMap as $eventName => $listeners) {
33
            if (!\is_array($listeners)) {
34
                $listeners = [$listeners];
35
            }
36
37
            foreach ($listeners as $listener) {
38
                $this->addListener($eventName, $listener);
39
            }
40
        }
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function addSubscriber(EventSubscriberInterface $subscriber): void
47
    {
48
        foreach ($subscriber::getSubscribedEvents() as $eventName => $params) {
49
            if (!\is_array($params)) {
50
                $params = [$params];
51
            }
52
53
            foreach ($params as $listener) {
54
                if (!\is_array($listener)) {
55
                    $this->addListener($eventName, $listener);
56
                } else {
57
                    $this->addListener($eventName, $listener[0], $listener[1] ?? 0);
58
                }
59
            }
60
        }
61
    }
62
63
    /**
64
     * Adds an event listener that listens on the specified events.
65
     *
66
     * @param string $eventName
67
     * @param mixed  $listener
68
     * @param mixed  $priority
69
     */
70
    public function addListener($eventName, $listener, $priority = 0): void
71
    {
72
        if (!$listener instanceof EventHandler) {
73
            throw new \InvalidArgumentException(\sprintf(
74
                'Event handler must be an instance of "%s", "%s" given',
75
                EventHandler::class,
76
                \is_object($listener) ? \get_class($listener) : \gettype($listener)
77
            ));
78
        }
79
80
        parent::addListener($eventName, $listener, (int) $priority);
81
    }
82
83
    /**
84
     * Dispatches an event to all registered listeners.
85
     *
86
     * @param mixed $eventEnvelope
87
     *
88
     * @return SymfonyEvent
89
     */
90
    public function dispatch($eventEnvelope): SymfonyEvent
91
    {
92
        if ($eventEnvelope === null) {
93
            throw new \InvalidArgumentException('Dispatched event cannot be empty');
94
        }
95
96
        if (!$eventEnvelope instanceof EventEnvelope) {
97
            throw new \InvalidArgumentException(\sprintf(
98
                'Dispatched event must implement "%s", "%s" given',
99
                EventEnvelope::class,
100
                \get_class($eventEnvelope)
101
            ));
102
        }
103
104
        $eventListeners = $this->getListeners($eventEnvelope->getWrappedEvent()->getEventType());
105
        $this->dispatchEvent($eventListeners, $eventEnvelope);
106
107
        return $eventEnvelope;
108
    }
109
110
    /**
111
     * Dispatch event to registered listeners.
112
     *
113
     * @param EventHandler[] $listeners
114
     * @param EventEnvelope  $event
115
     */
116
    private function dispatchEvent(array $listeners, EventEnvelope $event): void
117
    {
118
        $dispatchEvent = $event->getWrappedEvent();
119
120
        foreach ($listeners as $handler) {
121
            $handler->handle($dispatchEvent);
122
        }
123
    }
124
}
125