CompilerPasses   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 59.14%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 3
dl 0
loc 180
ccs 55
cts 93
cp 0.5914
rs 9.6
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 7 1
C removeCommandHandlerDuplicates() 0 32 7
C handleEventSubscriberDuplicates() 0 41 11
C processMessageHandlers() 0 35 8
B replaceSimpleBusPublisher() 0 33 3
A hasDoctrine() 0 5 2
1
<?php
2
3
namespace Happyr\SimpleBusBundle\DependencyInjection\CompilerPass;
4
5
use Happyr\SimpleBusBundle\Message\Publisher\DirectPublisher;
6
use Happyr\SimpleBusBundle\Message\Publisher\RabbitMQPublisher;
7
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
8
use Symfony\Component\DependencyInjection\ContainerBuilder;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
use Symfony\Component\DependencyInjection\Reference;
11
12
/**
13
 * @author Tobias Nyholm
14
 */
15
class CompilerPasses implements CompilerPassInterface
16
{
17 1
    public function process(ContainerBuilder $container)
18
    {
19 1
        $this->removeCommandHandlerDuplicates($container);
20 1
        $this->handleEventSubscriberDuplicates($container);
21 1
        $this->processMessageHandlers($container);
22 1
        $this->replaceSimpleBusPublisher($container);
23 1
    }
24
25
    /**
26
     * If we find to command handler services that are registered on the same command, make sure we remove the one with '.auto' on the end.
27
     *
28
     * @param ContainerBuilder $container
29
     */
30 1
    private function removeCommandHandlerDuplicates(ContainerBuilder $container)
31
    {
32 1
        $taggedServices = array_merge($container->findTaggedServiceIds('command_handler'), $container->findTaggedServiceIds('asynchronous_command_handler'));
33
34 1
        $commands = [];
35
36 1
        foreach ($taggedServices as $id => $tags) {
37 1
            foreach ($tags as $tag) {
38 1
                if (isset($commands[$tag['handles']])) {
39
                    // Find the one that ends with '.auto'
40
                    $removeServiceId = null;
41
42
                    if ('.auto' === substr($id, -5)) {
43
                        $removeServiceId = $id;
44
                    }
45
46
                    if ('.auto' === substr($commands[$tag['handles']], -5)) {
47
                        $removeServiceId = $commands[$tag['handles']];
48
                        $commands[$tag['handles']] = $id;
49
                    }
50
51
                    if (null !== $removeServiceId) {
52
                        // Remove the definition
53
                        $container->removeDefinition($removeServiceId);
54
55
                        continue;
56
                    }
57
                }
58 1
                $commands[$tag['handles']] = $id;
59
            }
60
        }
61 1
    }
62
63
    /**
64
     * @param ContainerBuilder $container
65
     */
66 1
    private function handleEventSubscriberDuplicates(ContainerBuilder $container)
67
    {
68 1
        $taggedServices = array_merge($container->findTaggedServiceIds('event_subscriber'), $container->findTaggedServiceIds('asynchronous_event_subscriber'));
69
70
        // Keys are event class names
71 1
        $events = [];
72
73 1
        foreach ($taggedServices as $id => $tags) {
74 1
            foreach ($tags as $tag) {
75 1
                if (isset($tag['subscribes_to'])) {
76 1
                    $events[$tag['subscribes_to']][] = $id;
77
                }
78
            }
79
        }
80
81 1
        foreach ($events as $eventClass => $subscribersIds) {
82 1
            if (count($subscribersIds) <= 1) {
83 1
                continue;
84
            }
85
86
            // Get services
87
            $subscriberClassNames = [];
88
            foreach ($subscribersIds as $subscribersId) {
89
                $service = $container->getDefinition($subscribersId);
90
                $subscriberClassNames[$service->getClass()][] = $subscribersId;
91
            }
92
93
            foreach ($subscriberClassNames as $className => $services) {
94
                if (count($services) <= 1) {
95
                    continue;
96
                }
97
98
                // IF we have multiple services registed to the same event subscriber, remove the auto added ones.
99
                foreach ($services as $serviceId) {
100
                    if ('.auto' === substr($serviceId, -5)) {
101
                        $container->removeDefinition($serviceId);
102
                    }
103
                }
104
            }
105
        }
106 1
    }
107
108
    /**
109
     * @param ContainerBuilder $container
110
     */
111 1
    private function processMessageHandlers(ContainerBuilder $container)
112
    {
113 1
        $taggedServices = array_merge(
114 1
            $container->findTaggedServiceIds('command_handler'),
115 1
            $container->findTaggedServiceIds('event_subscriber'),
116 1
            $container->findTaggedServiceIds('asynchronous_command_handler'),
117 1
            $container->findTaggedServiceIds('asynchronous_event_subscriber')
118
        );
119 1
        $doctrine = $this->hasDoctrine($container);
120
121 1
        foreach ($taggedServices as $id => $tags) {
122 1
            $def = $container->findDefinition($id);
123 1
            $class = $def->getClass();
124
125 1
            if (method_exists($class, 'setEventRecorder')) {
126
                $def->addMethodCall('setEventRecorder', [new Reference('event_recorder')]);
127
            }
128
129 1
            if (method_exists($class, 'setCommandBus')) {
130
                $def->addMethodCall('setCommandBus', [new Reference('command_bus')]);
131
            }
132
133 1
            if (method_exists($class, 'setEventBus')) {
134
                $def->addMethodCall('setEventBus', [new Reference('event_bus')]);
135
            }
136
137 1
            if ($doctrine && method_exists($class, 'setEntityManager')) {
138
                $def->addMethodCall('setEntityManager', [new Reference('doctrine.orm.entity_manager')]);
139
            }
140
141 1
            if (in_array('Psr\Log\LoggerAwareInterface', class_implements($class))) {
142 1
                $def->addMethodCall('setLogger', [new Reference('logger', ContainerInterface::NULL_ON_INVALID_REFERENCE)]);
143
            }
144
        }
145 1
    }
146
147
    /**
148
     * @param ContainerBuilder $container
149
     */
150 1
    private function replaceSimpleBusPublisher(ContainerBuilder $container)
151
    {
152 1
        if (!$container->has('simple_bus.rabbit_mq_bundle_bridge.event_publisher')) {
153
            return;
154
        }
155
156 1
        if (!$container->getParameter('happyr.simplebus.direct_publisher')) {
157 1
            $container->getDefinition('simple_bus.rabbit_mq_bundle_bridge.event_publisher')
158 1
                ->setClass(RabbitMQPublisher::class)
159 1
                ->setLazy(true);
160 1
            $container->getDefinition('simple_bus.rabbit_mq_bundle_bridge.command_publisher')
161 1
                ->setClass(RabbitMQPublisher::class)
162 1
                ->setLazy(true);
163
        } else {
164
            $container->getDefinition('simple_bus.rabbit_mq_bundle_bridge.event_publisher')
165
                ->setClass(DirectPublisher::class)
166
                ->setLazy(true)
167
                ->setArguments([
168
                    new Reference('happyr.mq2php.consumer_wrapper'),
169
                    new Reference('happyr.mq2php.message_serializer'),
170
                    $container->getParameter('happyr.mq2php.event_queue_name'),
171
                ]);
172
173
            $container->getDefinition('simple_bus.rabbit_mq_bundle_bridge.command_publisher')
174
                ->setClass(DirectPublisher::class)
175
                ->setLazy(true)
176
                ->setArguments([
177
                    new Reference('happyr.mq2php.consumer_wrapper'),
178
                    new Reference('happyr.mq2php.message_serializer'),
179
                    $container->getParameter('happyr.mq2php.command_queue_name'),
180
                ]);
181
        }
182 1
    }
183
184
    /**
185
     * @param ContainerBuilder $container
186
     *
187
     * @return bool
188
     */
189 1
    private function hasDoctrine(ContainerBuilder $container)
190
    {
191 1
        return $container->hasDefinition('doctrine.orm.entity_manager') ||
192 1
            $container->hasAlias('doctrine.orm.entity_manager');
193
    }
194
}
195