Passed
Push — master ( 65b0fe...a313b4 )
by Alexander
02:06
created

ConcreteProvider::listenersFor()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
nc 3
nop 1
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 3
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Yiisoft\EventDispatcher\Provider;
4
5
use Psr\EventDispatcher\ListenerProviderInterface;
6
7
use function array_values;
8
use function class_implements;
9
use function class_parents;
10
use function get_class;
11
12
/**
13
 * ConcreteProvider is a listener provider that registers event listeners for interface names specified explicitly
14
 * and gives out a list of handlers for further use with Dispatcher.
15
 *
16
 * ```php
17
 * $provider = new Yiisoft\EventDispatcher\Provider\ConcreteProvider();
18
 * $provider->attach(SomeEvent::class, function () {
19
 *    // handle it
20
 * });
21
 * ```
22
 */
23
final class ConcreteProvider implements ListenerProviderInterface
24
{
25
    /**
26
     * @var callable[]
27
     */
28
    private array $listeners = [];
29
30
    /**
31
     * @param object $event
32
     * @return iterable<callable>
33
     */
34 9
    public function getListenersForEvent(object $event): iterable
35
    {
36 9
        yield from $this->listenersFor(get_class($event));
37 9
        yield from $this->listenersFor(...array_values(class_parents($event)));
38 9
        yield from $this->listenersFor(...array_values(class_implements($event)));
39
    }
40
41
    /**
42
     * Attach an event handler for the given event name
43
     *
44
     * @param string $eventName
45
     * @param callable $listener
46
     */
47 9
    public function attach(string $eventName, callable $listener): void
48
    {
49 9
        $this->listeners[$eventName][] = $listener;
50
    }
51
52
    /**
53
     * Detach all event handlers registered for an interface
54
     *
55
     * @param string $eventName
56
     */
57 1
    public function detach(string $eventName): void
58
    {
59 1
        unset($this->listeners[$eventName]);
60
    }
61
62
    /**
63
     * @param string ...$eventNames
64
     * @return iterable<callable>
65
     */
66 9
    private function listenersFor(string ...$eventNames): iterable
67
    {
68 9
        foreach ($eventNames as $name) {
69 9
            if (isset($this->listeners[$name])) {
70 8
                yield from $this->listeners[$name];
71
            }
72
        }
73
    }
74
}
75