CallableFactory   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 29
c 2
b 1
f 0
dl 0
loc 71
ccs 34
cts 34
cp 1
rs 10
wmc 16

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A create() 0 9 2
C prepare() 0 42 13
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Yii\Event;
6
7
use Psr\Container\ContainerExceptionInterface;
8
use Psr\Container\ContainerInterface;
9
use ReflectionException;
10
use ReflectionMethod;
11
12
use function is_array;
13
use function is_callable;
14
use function is_string;
15
16
/**
17
 * @internal Create real callable listener from configuration.
18
 */
19
final class CallableFactory
20
{
21 47
    public function __construct(
22
        private ContainerInterface $container
23
    ) {
24 47
    }
25
26
    /**
27
     * Create real callable listener from definition.
28
     *
29
     * @param mixed $definition Definition to create listener from.
30
     *
31
     * @throws InvalidListenerConfigurationException Failed to create listener.
32
     * @throws ContainerExceptionInterface Error while retrieving the entry from container.
33
     */
34 39
    public function create(mixed $definition): callable
35
    {
36 39
        $callable = $this->prepare($definition);
37
38 38
        if (is_callable($callable)) {
39 16
            return $callable;
40
        }
41
42 22
        throw new InvalidListenerConfigurationException();
43
    }
44
45
    /**
46
     * @throws ContainerExceptionInterface Error while retrieving the entry from container.
47
     */
48 39
    private function prepare(mixed $definition): mixed
49
    {
50 39
        if (is_string($definition) && $this->container->has($definition)) {
51 4
            return $this->container->get($definition);
52
        }
53
54 36
        if (is_array($definition)
55 36
            && array_keys($definition) === [0, 1]
56 36
            && is_string($definition[0])
57 36
            && is_string($definition[1])
58
        ) {
59 16
            [$className, $methodName] = $definition;
60
61 16
            if (!class_exists($className) && $this->container->has($className)) {
62 5
                return [
63 5
                    $this->container->get($className),
64 5
                    $methodName,
65 5
                ];
66
            }
67
68 12
            if (!class_exists($className)) {
69 2
                return null;
70
            }
71
72
            try {
73 10
                $reflection = new ReflectionMethod($className, $methodName);
74 2
            } catch (ReflectionException) {
75 2
                return null;
76
            }
77 8
            if ($reflection->isStatic()) {
78 3
                return [$className, $methodName];
79
            }
80 6
            if ($this->container->has($className)) {
81 4
                return [
82 4
                    $this->container->get($className),
83 4
                    $methodName,
84 4
                ];
85
            }
86 2
            return null;
87
        }
88
89 21
        return $definition;
90
    }
91
}
92