EventEmitter::setContainer()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
namespace Wandu\Event;
3
4
use Psr\Container\ContainerInterface;
5
use Wandu\Event\Contracts\EventEmitter as EventEmitterContract;
6
use Wandu\Event\Contracts\Listener;
7
use Wandu\Event\Contracts\ViaQueue;
8
use Wandu\Event\Listener\CallableListener;
9
use Wandu\Event\Listener\WorkerListener;
10
use Wandu\Q\Worker;
11
12
class EventEmitter implements EventEmitterContract 
13
{
14
    /** @var array */
15
    protected $listeners = [];
16
17
    /** @var \Psr\Container\ContainerInterface */
18
    protected $container;
19
    
20
    /** @var \Wandu\Q\Worker */
21
    protected $worker;
22
23 21
    public function __construct(array $listeners = [])
24
    {
25 21
        $this->listeners = $listeners;
26 21
    }
27
28
    /**
29
     * @param \Psr\Container\ContainerInterface $container
30
     */
31 19
    public function setContainer(ContainerInterface $container)
32
    {
33 19
        $this->container = $container;
34 19
    }
35
36
    /**
37
     * @param \Wandu\Q\Worker $worker
38
     */
39
    public function setWorker(Worker $worker)
40
    {
41
        $this->worker = $worker;
42
    }
43
    
44
    /**
45
     * @param string $event
46
     * @param string|\Closure $listener
47
     * @return void
48
     */
49 7
    public function on(string $event, $listener)
50
    {
51 7
        if (!array_key_exists($event, $this->listeners)) {
52 7
            $this->listeners[$event] = [];
53
        }
54 7
        if (!in_array($listener, $this->listeners[$event])) {
55 7
            $this->listeners[$event][] = $listener;
56
        }
57 7
    }
58
59
    /**
60
     * @param string $event
61
     * @param string|\Closure|\Wandu\Event\Contracts\Listener $listener
62
     * @return void
63
     */
64
    public function off(string $event, $listener = null)
65
    {
66
        if (!array_key_exists($event, $this->listeners)) return;
67
        if ($listener) {
68
            $key = array_search($listener, $this->listeners[$event]);
69
            if ($key !== false) {
70
                array_splice($this->listeners[$event], $key, 1);
71
            }
72
            if (count($this->listeners[$event]) === 0) unset($this->listeners[$event]);
73
        } else {
74
            unset($this->listeners[$event]);
75
        }
76
    }
77
78
    /**
79
     * @param string|object $event
80
     * @param array ...$arguments
81
     * @return void
82
     */
83 21
    public function trigger($event, ...$arguments)
84
    {
85 21
        $eventViaQueue = false;
86 21
        if (is_object($event)) {
87 20
            if ($event instanceof ViaQueue) {
88
                $eventViaQueue = true;
89
            }
90 20
            $eventName = get_class($event);
91 20
            $arguments = [$event];
92
        } else {
93 1
            $eventName = $event;
94
        }
95
96
        /** @var \Wandu\Event\Contracts\Listener $listener */
97 21
        foreach ($this->getListeners($eventName) as $listener) {
98 7
            if ($eventViaQueue && !$listener instanceof WorkerListener) {
99
                $listener = new WorkerListener($this->worker, get_class($listener));
100
            }
101 7
            $listener->call($arguments);
102
        }
103 21
    }
104
105
    /**
106
     * @param $event
107
     * @return \Generator|void
108
     */
109 21
    protected function getListeners($event)
110
    {
111 21
        if (!isset($this->listeners[$event])) return;
112 7
        foreach ($this->listeners[$event] as $listener) {
113 7
            if ($listener instanceof Listener) {
114
                yield $listener;
115 7
            } elseif (is_callable($listener)) {
116 5
                yield new CallableListener($listener);
117 2
            } elseif ($this->container && $this->container->has($listener)) {
118 2
                $listenerInstance = $this->container->get($listener);
119 2
                if ($listenerInstance instanceof Listener) {
120 2
                    if ($listenerInstance instanceof ViaQueue) {
121
                        yield new WorkerListener($this->worker, $listener);
122
                    } else {
123 7
                        yield $listenerInstance;
124
                    }
125
                }
126
            }
127
        }
128 7
    }
129
}
130