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

ListenerConfigurationChecker::isCallable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 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 CallableFactory $callableFactory;
17
18 20
    public function __construct(CallableFactory $callableFactory)
19
    {
20 20
        $this->callableFactory = $callableFactory;
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 */
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
     * @throws ContainerExceptionInterface Error while retrieving the entry from container.
74
     */
75 18
    private function isCallable($definition): bool
76
    {
77
        try {
78 18
            $this->callableFactory->create($definition);
79 11
        } catch (InvalidListenerConfigurationException $e) {
80 10
            return false;
81
        }
82
83 7
        return true;
84
    }
85
}
86