Completed
Push — master ( 1d9788...8a00e7 )
by Ross
03:13 queued 01:37
created

CommandHandlerPass::process()   C

Complexity

Conditions 8
Paths 21

Size

Total Lines 48
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 38
CRAP Score 8

Importance

Changes 0
Metric Value
dl 0
loc 48
ccs 38
cts 38
cp 1
rs 5.9322
c 0
b 0
f 0
cc 8
eloc 28
nc 21
nop 1
crap 8
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 18
    public function process(ContainerBuilder $container)
25
    {
26 18
        $tacticianConfig = $container->getExtensionConfig('tactician');
27 18
        $defaultBusId = $tacticianConfig['default_bus'];
28 18
        $busIds = array_keys($tacticianConfig['commandbus']);
29 18
        $busIdToHandlerMapping = [];
30
31 18
        foreach ($container->findTaggedServiceIds('tactician.handler') as $id => $tags) {
32
33 18
            foreach ($tags as $attributes) {
34 18
                if (!isset($attributes['command'])) {
35 3
                    throw new \Exception('The tactician.handler tag must always have a command attribute');
36
                }
37
38 15
                if (array_key_exists('bus', $attributes)) {
39 12
                    $this->abortIfInvalidBusId($attributes['bus'], $busIds);
40 6
                }
41
42 12
                $busIdsDefined = array_key_exists('bus', $attributes) ? [$attributes['bus']] : $busIds;
43 12
                foreach ($busIdsDefined as $busId) {
44 12
                    $busIdToHandlerMapping[$busId][$attributes['command']] = $id;
45 8
                }
46 8
            }
47 8
        }
48
49 12
        foreach ($busIdToHandlerMapping as $busId => $handlerMapping) {
50 12
            $locatorServiceId = 'tactician.commandbus.'.$busId.'.handler.locator';
51 12
            $container->setDefinition(
52 8
                $locatorServiceId,
53 12
                $this->buildLocatorDefinition($handlerMapping)
54 8
            );
55
56 12
            $container->setDefinition(
57 12
                'tactician.commandbus.'.$busId.'.middleware.command_handler',
58 12
                $this->buildCommandHandlerDefinition($busId, $locatorServiceId, $tacticianConfig)
59 8
            );
60 8
        }
61
62 12
        $container->setAlias(
63 12
            'tactician.handler.locator.symfony',
64 12
            'tactician.commandbus.'.$defaultBusId.'.handler.locator'
65 8
        );
66
67 12
        $container->setAlias(
68 12
            'tactician.middleware.command_handler',
69 12
            'tactician.commandbus.'.$defaultBusId.'.middleware.command_handler'
70 8
        );
71 12
    }
72
73
    /**
74
     * @param string $id
75
     * @param array $busIds
76
     * @throws Exception
77
     */
78 12
    protected function abortIfInvalidBusId($id, array $busIds)
79
    {
80 12
        if (!in_array($id, $busIds)) {
81 3
            throw new \Exception('Invalid bus id "'.$id.'". Valid buses are: '.implode(', ', $busIds));
82
        }
83 9
    }
84
85
    /**
86
     * @param array $handlerMapping
87
     * @return Definition
88
     */
89 12
    protected function buildLocatorDefinition(array $handlerMapping)
90
    {
91 12
        return new Definition(
92 12
            ContainerBasedHandlerLocator::class,
93
            [
94 12
                new Reference('service_container'),
95 12
                $handlerMapping,
96
            ]
97 8
        );
98
    }
99
100
    /**
101
     * @param string $busId
102
     * @param string $locatorServiceId
103
     * @param array $config
104
     * @return Definition
105
     */
106 12
    protected function buildCommandHandlerDefinition($busId, $locatorServiceId, array $config)
107
    {
108 12
        return new Definition(
109 12
            CommandHandlerMiddleware::class,
110
            [
111 12
                new Reference('tactician.handler.command_name_extractor.class_name'),
112 12
                new Reference($locatorServiceId),
113 12
                new Reference($this->methodInflectorOfBus($busId, $config))
114 8
            ]
115 8
        );
116
    }
117
118 12
    private function methodInflectorOfBus($busId, array $config)
119
    {
120 12
        if (array_key_exists('method_inflector', $config['commandbus'][$busId])) {
121 3
            return $config['commandbus'][$busId]['method_inflector'];
122
        }
123
124 9
        return $config['method_inflector'];
125
    }
126
}
127