Completed
Pull Request — master (#20)
by
unknown
04:24
created

CommandHandlerPass::getDefaultBusId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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