Passed
Push — master ( 3b7cd0...1b99f7 )
by Alexander
02:56 queued 53s
created

EventConfigurator::isCallable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 3.1406

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 3
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 7
ccs 3
cts 4
cp 0.75
crap 3.1406
rs 10
1
<?php
2
3
namespace Yiisoft\Yii\Web\Config;
4
5
use Psr\Container\ContainerInterface;
6
use Yiisoft\EventDispatcher\Provider\AbstractProviderConfigurator;
7
use Yiisoft\EventDispatcher\Provider\Provider;
8
use Yiisoft\Injector\Injector;
9
10
class EventConfigurator extends AbstractProviderConfigurator
11
{
12
    private Provider $listenerProvider;
13
14
    private ContainerInterface $container;
15
16 2
    public function __construct(Provider $listenerProvider, ContainerInterface $container)
17
    {
18 2
        $this->listenerProvider = $listenerProvider;
19 2
        $this->container = $container;
20 2
    }
21
22 2
    public function registerListeners(array $eventsListeners): void
23
    {
24 2
        foreach ($eventsListeners as $eventName => $listeners) {
25 2
            if (!is_string($eventName)) {
26
                throw new \RuntimeException('Incorrect event listener format. Format with event name must be used.');
27
            }
28
29 2
            if (!is_array($listeners)) {
30
                $type = $this->isCallable($listeners) ? 'callable' : gettype($listeners);
31
                throw new \RuntimeException("Event listeners for $eventName must be an array, $type given.");
32
            }
33 2
            foreach ($listeners as $callable) {
34 2
                if (!$this->isCallable($callable)) {
35
                    $type = gettype($listeners);
36
                    throw new \RuntimeException("Listener must be a callable. $type given.");
37
                }
38 2
                if (is_array($callable) && !is_object($callable[0])) {
39 1
                    $callable = [$this->container->get($callable[0]), $callable[1]];
40
                }
41
42 2
                $this->listenerProvider
43 2
                    ->attach(
44 2
                        fn ($event) => (new Injector($this->container))->invoke($callable, [$event]),
45
                        $eventName
46
                    );
47
            }
48
        }
49 2
    }
50
51 2
    private function isCallable($definition): bool
52
    {
53 2
        if (is_callable($definition)) {
54 2
            return true;
55
        }
56
57
        return count($definition) === 2 && in_array($definition[1], get_class_methods($definition[0]) ?? [], true);
58
    }
59
}
60