Completed
Push — master ( 829252...7960a5 )
by Ross
08:40
created

CommandHandlerPass::guardInvalidMiddlewares()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.0261

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 6
cts 7
cp 0.8571
rs 9.6666
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 2
crap 3.0261
1
<?php
2
namespace League\Tactician\Bundle\DependencyInjection\Compiler;
3
4
use League\Tactician\Bundle\Handler\ContainerBasedHandlerLocator;
5
use League\Tactician\Handler\CommandHandlerMiddleware;
6
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
8
use Symfony\Component\DependencyInjection\Definition;
9
use Symfony\Component\DependencyInjection\Reference;
10
11
/**
12
 * This compiler pass maps Handler DI tags to specific commands
13
 */
14
class CommandHandlerPass implements CompilerPassInterface
15
{
16
    /**
17
     * You can modify the container here before it is dumped to PHP code.
18
     *
19
     * @param ContainerBuilder $container
20
     *
21
     * @throws \Exception
22
     * @api
23
     */
24 33
    public function process(ContainerBuilder $container)
25
    {
26 33
        $defaultBusId = $container->getParameter('tactician.commandbus.default');
27 33
        $busIds = $container->getParameter('tactician.commandbus.ids');
28 33
        $busIdToHandlerMapping = [];
29
30 33
        foreach ($container->findTaggedServiceIds('tactician.handler') as $id => $tags) {
31
32 30
            foreach ($tags as $attributes) {
33 30
                if (!isset($attributes['command'])) {
34 3
                    throw new \Exception('The tactician.handler tag must always have a command attribute');
35
                }
36
37 27
                if (array_key_exists('bus', $attributes)) {
38 18
                    $this->abortIfInvalidBusId($attributes['bus'], $busIds);
39 12
                }
40
41 21
                $busIdsDefined = array_key_exists('bus', $attributes) ? [$attributes['bus']] : $busIds;
42 21
                foreach ($busIdsDefined as $busId) {
43 21
                    $busIdToHandlerMapping[$busId][$attributes['command']] = $id;
44 21
                }
45 21
            }
46 24
        }
47
48 24
        $container->setAlias(
49 24
            'tactician.handler.locator.symfony',
50 24
            'tactician.commandbus.'.$defaultBusId.'.handler.locator'
51 24
        );
52
53 24
        $container->setAlias(
54 24
            'tactician.middleware.command_handler',
55 24
            'tactician.commandbus.'.$defaultBusId.'.middleware.command_handler'
56 24
        );
57
58 24
        foreach ($busIds as $busId) {
59 24
            $locatorServiceId = 'tactician.commandbus.'.$busId.'.handler.locator';
60 24
            $methodInflectorId = $container->getParameter(sprintf('tactician.method_inflector.%s', $busId));
61 24
            $container->setDefinition(
62 24
                $locatorServiceId,
63 24
                $this->buildLocatorDefinition(
64
                    // Build an empty locator if no command defined. To be sure extension still working
65 24
                    array_key_exists($busId, $busIdToHandlerMapping) ? $busIdToHandlerMapping[$busId] : []
66 24
                )
67 24
            );
68
69 24
            $container->setDefinition(
70 24
                'tactician.commandbus.'.$busId.'.middleware.command_handler',
71 24
                new Definition(
72 24
                    CommandHandlerMiddleware::class,
73
                    [
74 24
                        new Reference('tactician.handler.command_name_extractor.class_name'),
75 24
                        new Reference($locatorServiceId),
76 24
                        new Reference($methodInflectorId)
77 24
                    ]
78 24
                )
79 24
            );
80 24
            $this->guardInvalidMiddlewares($container, $busId);
81 24
        }
82 24
    }
83
84
    /**
85
     * @param string $id
86
     * @param array $busIds
87
     * @throws Exception
88
     */
89 18
    protected function abortIfInvalidBusId($id, array $busIds)
90
    {
91 18
        if (!in_array($id, $busIds)) {
92 6
            throw new \Exception('Invalid bus id "'.$id.'". Valid buses are: '.implode(', ', $busIds));
93
        }
94 12
    }
95
96
    /**
97
     * @param array $handlerMapping
98
     * @return Definition
99
     */
100 24
    protected function buildLocatorDefinition(array $handlerMapping)
101
    {
102 24
        return new Definition(
103 24
            ContainerBasedHandlerLocator::class,
104
            [
105 24
                new Reference('service_container'),
106 24
                $handlerMapping,
107
            ]
108 24
        );
109
    }
110
111 24
    private function guardInvalidMiddlewares(ContainerBuilder $container, $busId)
112
    {
113 24
        $busDefinition = $container->getDefinition('tactician.commandbus.'.$busId);
114 24
        foreach ($busDefinition->getArgument(0) as $middlewareReference) {
115 15
            if (false === $container->has($middlewareReference)) {
116
                throw UnknownMiddleware::withId((string) $middlewareReference);
117
            }
118 24
        }
119 24
    }
120
}
121