BuildEventBusStackPass::inject()   B
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 25
ccs 12
cts 12
cp 1
rs 8.8571
c 0
b 0
f 0
cc 3
eloc 15
nc 3
nop 2
crap 3
1
<?php
2
declare(strict_types = 1);
3
4
namespace Innmind\EventBusBundle\DependencyInjection\Compiler;
5
6
use Innmind\EventBusBundle\Exception\LogicException;
7
use Innmind\EventBus\EventBusInterface;
8
use Symfony\Component\DependencyInjection\{
9
    Compiler\CompilerPassInterface,
10
    ContainerBuilder,
11
    Definition,
12
    Reference
13
};
14
15
final class BuildEventBusStackPass implements CompilerPassInterface
16
{
17
    /**
18
     * {@inheritdoc}
19
     */
20 6
    public function process(ContainerBuilder $container)
21
    {
22 6
        if (!$container->hasParameter('innmind_event_bus.stack')) {
23 1
            throw new LogicException;
24
        }
25
26 5
        $stack = $container->getParameter('innmind_event_bus.stack');
27 5
        $services = $this->searchServices($container);
28
29 4
        $container->setAlias(
30 4
            'innmind_event_bus',
31 4
            $services[$stack[0]]
32
        );
33
34 4
        if (count($stack) === 1) {
35 1
            return;
36
        }
37
38 3
        for ($i = 0, $count = count($stack) - 1; $i < $count; $i++) {
39 3
            $alias = $stack[$i];
40 3
            $next = $stack[$i + 1];
41
42 3
            $this->inject(
43 3
                $container->getDefinition($services[$alias]),
44 3
                $services[$next]
45
            );
46
        }
47 2
    }
48
49 5
    private function searchServices(ContainerBuilder $container): array
50
    {
51 5
        $services = $container->findTaggedServiceIds('innmind_event_bus');
52 5
        $map = [];
53
54 5
        foreach ($services as $id => $tags) {
55 5
            foreach ($tags as $tag => $attributes) {
56 5
                if (!isset($attributes['alias'])) {
57 1
                    throw new LogicException;
58
                }
59
60 4
                $map[$attributes['alias']] = $id;
61
            }
62
        }
63
64 4
        return $map;
65
    }
66
67 3
    private function inject(
68
        Definition $definition,
69
        string $next
70
    ) {
71 3
        $class = $definition->getClass();
72 3
        $refl = new \ReflectionMethod($class, '__construct');
73
74 3
        foreach ($refl->getParameters() as $parameter) {
75 3
            if ((string) $parameter->getType() !== EventBusInterface::class) {
76 1
                continue;
77
            }
78
79 3
            $definition->replaceArgument(
80 3
                $parameter->getPosition(),
81 3
                new Reference($next)
82
            );
83
84 3
            return;
85
        }
86
87 1
        throw new LogicException(sprintf(
88 1
            'Missing argument type hinted with EventBusInterface for "%s"',
89
            $class
90
        ));
91
    }
92
}
93