Passed
Pull Request — master (#23)
by Sergei
02:09
created

ListenerConfigurationChecker   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 25
c 1
b 0
f 0
dl 0
loc 68
ccs 27
cts 27
cp 1
rs 10
wmc 13

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A isCallable() 0 9 2
B check() 0 32 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Event;
6
7
use Psr\Container\ContainerExceptionInterface;
8
9
use function get_class;
10
use function gettype;
11
use function is_object;
12
use function is_string;
13
14
final class ListenerConfigurationChecker
15
{
16
    private ListenerFactory $listenerFactory;
17
18 20
    public function __construct(ListenerFactory $listenerFactory)
19
    {
20 20
        $this->listenerFactory = $listenerFactory;
21 20
    }
22
23
    /**
24
     * Checks the given event configuration and throws an exception in some cases:
25
     * - incorrect configuration format
26
     * - incorrect listener format
27
     * - listener is not a callable
28
     * - listener is meant to be a method of an object which can't be instantiated
29
     *
30
     * @param array $configuration An array in format of [eventClassName => [listeners]]
31
     */
32 20
    public function check(array $configuration): void
33
    {
34 20
        foreach ($configuration as $eventName => $listeners) {
35 20
            if (!is_string($eventName) || !class_exists($eventName)) {
36 1
                throw new InvalidEventConfigurationFormatException(
37 1
                    'Incorrect event listener format. Format with event name must be used.'
38
                );
39
            }
40
41 19
            if (!is_iterable($listeners)) {
42 1
                $type = is_object($listeners) ? get_class($listeners) : gettype($listeners);
43
44 1
                throw new InvalidEventConfigurationFormatException(
45 1
                    "Event listeners for $eventName must be an iterable, $type given."
46
                );
47
            }
48
49
            /** @var mixed $listener */
50 18
            foreach ($listeners as $listener) {
51
                try {
52 18
                    if (!$this->isCallable($listener)) {
53 10
                        $type = is_object($listener) ? get_class($listener) : gettype($listener);
54
55 10
                        throw new InvalidListenerConfigurationException(
56 17
                            "Listener must be a callable, $type given."
57
                        );
58
                    }
59 11
                } catch (ContainerExceptionInterface $exception) {
60 1
                    throw new InvalidListenerConfigurationException(
61 1
                        'Could not instantiate event listener or listener class has invalid configuration.',
62 1
                        0,
63
                        $exception
64
                    );
65
                }
66
            }
67
        }
68 7
    }
69
70
    /**
71
     * @param mixed $definition
72
     */
73 18
    private function isCallable($definition): bool
74
    {
75
        try {
76 18
            $this->listenerFactory->create($definition);
77 11
        } catch (InvalidListenerConfigurationException $e) {
78 10
            return false;
79
        }
80
81 7
        return true;
82
    }
83
}
84