BusBuilder::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace League\Tactician\Bundle\DependencyInjection\Compiler\BusBuilder;
5
6
use League\Tactician\Bundle\Handler\ContainerBasedHandlerLocator;
7
use League\Tactician\CommandBus;
8
use League\Tactician\Container\ContainerLocator;
9
use League\Tactician\Handler\CommandHandlerMiddleware;
10
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
11
use Symfony\Component\DependencyInjection\ContainerBuilder;
12
use Symfony\Component\DependencyInjection\Definition;
13
use Symfony\Component\DependencyInjection\Reference;
14
use Symfony\Component\DependencyInjection\ServiceLocator;
15
16
final class BusBuilder
17
{
18
    /**
19
     * @var string
20
     */
21
    private $busId;
22
23
    /**
24
     * @var string[]
25
     */
26
    private $middlewareIds = [];
27
28
    /**
29
     * @var string
30
     */
31
    private $methodInflectorId;
32
33 111
    public function __construct(string $busId, string $methodInflector, array $middlewareIds)
34
    {
35 111
        $this->busId = $busId;
36 111
        $this->methodInflectorId = $methodInflector;
37 111
        $this->middlewareIds = $middlewareIds;
38 111
    }
39
40 108
    public function id(): string
41
    {
42 108
        return $this->busId;
43
    }
44
45 81
    public function serviceId(): string
46
    {
47 81
        return "tactician.commandbus.$this->busId";
48
    }
49
50 81
    public function locatorServiceId()
51
    {
52 81
        return "tactician.commandbus.{$this->busId}.handler.locator";
53
    }
54
55 81
    public function commandHandlerMiddlewareId(): string
56
    {
57 81
        return "tactician.commandbus.{$this->busId}.middleware.command_handler";
58
    }
59
60 75
    public function registerInContainer(ContainerBuilder $container, array $commandsToAccept)
61
    {
62 75
        $this->registerLocatorService($container, $commandsToAccept);
63
64 75
        $container->setDefinition(
65 75
            $this->commandHandlerMiddlewareId(),
66 75
            new Definition(
67 75
                CommandHandlerMiddleware::class,
68
                [
69 75
                    new Reference('tactician.handler.command_name_extractor.class_name'),
70 75
                    new Reference($this->locatorServiceId()),
71 75
                    new Reference($this->methodInflectorId),
72
                ]
73
            )
74
        );
75
76 75
        $container->setDefinition(
77 75
            $this->serviceId(),
78 75
            new Definition(
79 75
                CommandBus::class,
80
                [
81 75
                    array_map(
82
                        function (string $id) { return new Reference($id); },
83 75
                        $this->middlewareIds
84
                    )
85
                ]
86
            )
87 75
        )->setPublic(true);
88
89 75
        if (method_exists($container, 'registerAliasForArgument')) {
90 50
            $container->registerAliasForArgument($this->serviceId(), CommandBus::class, "{$this->busId}Bus");
91
        }
92 75
    }
93
94 75
    private function registerLocatorService(ContainerBuilder $container, $commandsToAccept)
95
    {
96
        // Leverage symfony/dependency-injection:^3.3 service locators
97 75
        if (class_exists(ServiceLocator::class)) {
98 75
            $definition = new Definition(
99 75
                ContainerLocator::class,
100 75
                [new Reference($this->registerHandlerServiceLocator($container, $commandsToAccept)), $commandsToAccept]
101
            );
102
        } else {
103
            $definition = new Definition(
104
                ContainerBasedHandlerLocator::class,
105
                [new Reference('service_container'), $commandsToAccept]
106
            );
107
        }
108
109 75
        $container->setDefinition($this->locatorServiceId(), $definition);
110 75
    }
111
112 75
    private function registerHandlerServiceLocator(ContainerBuilder $container, array $commandsToAccept): string
113
    {
114 75
        $handlers = [];
115 75
        foreach ($commandsToAccept as $commandName => $handlerId) {
116 36
            $handlers[$handlerId] = new ServiceClosureArgument(new Reference($handlerId));
117
        }
118
119 75
        $handlerServiceLocator = (new Definition(ServiceLocator::class, [$handlers]))
120 75
            ->setPublic(false)
121 75
            ->addTag('container.service_locator');
122
123 75
        $container->setDefinition(
124 75
            $handlerId = "tactician.commandbus.{$this->busId}.handler.service_locator",
125 75
            $handlerServiceLocator
126
        );
127
128 75
        return $handlerId;
129
    }
130
}
131