Passed
Push — master ( 25c27d...1ff91c )
by Alexander
16:07 queued 09:28
created

EventConfigurator::isCallable()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 3
nc 3
nop 1
dl 0
loc 7
ccs 0
cts 6
cp 0
c 1
b 0
f 1
cc 3
crap 12
rs 10
1
<?php
2
3
namespace Yiisoft\Yii\Console\Config;
4
5
use Psr\Container\ContainerInterface;
6
use Yiisoft\EventDispatcher\Provider\AbstractProviderConfigurator;
0 ignored issues
show
Bug introduced by
The type Yiisoft\EventDispatcher\...actProviderConfigurator was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Yiisoft\EventDispatcher\Provider\Provider;
0 ignored issues
show
Bug introduced by
The type Yiisoft\EventDispatcher\Provider\Provider was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
8
use Yiisoft\Injector\Injector;
0 ignored issues
show
Bug introduced by
The type Yiisoft\Injector\Injector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
9
10
class EventConfigurator extends AbstractProviderConfigurator
11
{
12
    private Provider $listenerProvider;
13
14
    private ContainerInterface $container;
15
16
    public function __construct(Provider $listenerProvider, ContainerInterface $container)
17
    {
18
        $this->listenerProvider = $listenerProvider;
19
        $this->container = $container;
20
    }
21
22
    public function registerListeners(array $eventsListeners): void
23
    {
24
        foreach ($eventsListeners as $eventName => $listeners) {
25
            if (!is_string($eventName)) {
26
                throw new \RuntimeException('Incorrect event listener format. Format with event name must be used.');
27
            }
28
29
            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
            foreach ($listeners as $callable) {
34
                if (!$this->isCallable($callable)) {
35
                    $type = gettype($listeners);
36
                    throw new \RuntimeException("Listener must be a callable. $type given.");
37
                }
38
                if (is_array($callable) && !is_object($callable[0])) {
39
                    $callable = [$this->container->get($callable[0]), $callable[1]];
40
                }
41
42
                $this->listenerProvider
43
                    ->attach(
44
                        fn ($event) => (new Injector($this->container))->invoke($callable, [$event]),
45
                        $eventName
46
                    );
47
            }
48
        }
49
    }
50
51
    private function isCallable($definition): bool
52
    {
53
        if (is_callable($definition)) {
54
            return true;
55
        }
56
57
        return count($definition) === 2 && in_array($definition[1], get_class_methods($definition[0]) ?? [], true);
58
    }
59
}
60