Completed
Push — master ( dd8539...4b6ec1 )
by Tobias
04:14
created

HappyrSimpleBusExtension::requireBundle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 0
cts 7
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 2
crap 6
1
<?php
2
3
namespace Happyr\SimpleBusBundle\DependencyInjection;
4
5
use Happyr\SimpleBusBundle\EventListener\ExceptionConverterListener;
6
use Happyr\SimpleBusBundle\EventListener\ExceptionLoggerListener;
7
use Happyr\SimpleBusBundle\Message\AsyncCommandHandler;
8
use Happyr\SimpleBusBundle\Message\AutoRegisteredEventSubscriber;
9
use Happyr\SimpleBusBundle\Message\HandlesMessagesAsync;
10
use Symfony\Component\DependencyInjection\ContainerBuilder;
11
use Symfony\Component\Config\FileLocator;
12
use Symfony\Component\DependencyInjection\Definition;
13
use Symfony\Component\DependencyInjection\Reference;
14
use Symfony\Component\Finder\Finder;
15
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
16
use Symfony\Component\DependencyInjection\Loader;
17
use Symfony\Component\HttpKernel\KernelEvents;
18
19
/**
20
 * This is the class that loads and manages your bundle configuration.
21
 *
22
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
23
 */
24
class HappyrSimpleBusExtension extends Extension
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function load(array $configs, ContainerBuilder $container)
30
    {
31
        $configuration = new Configuration();
32
        $config = $this->processConfiguration($configuration, $configs);
33
34
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
35
        $loader->load('ping.yml');
36
        $this->requireBundle('SimpleBusCommandBusBundle', $container);
37
        $this->requireBundle('SimpleBusEventBusBundle', $container);
38
        $this->requireBundle('SimpleBusAsynchronousBundle', $container);
39
        $this->requireBundle('SimpleBusRabbitMQBundleBridgeBundle', $container);
40
        $this->requireBundle('SimpleBusJMSSerializerBundleBridgeBundle', $container);
41
        $this->requireBundle('HappyrMq2phpBundle', $container);
42
        $this->requireBundle('OldSoundRabbitMqBundle', $container);
43
        $this->requireBundle('JMSSerializerBundle', $container);
44
45
46
        if ($config['auto_register_handlers']['enabled']) {
47
            $handlerPath = $config['auto_register_handlers']['command_handler_path'];
48
            if (empty($handlerPath)) {
49
                $rootDir = $container->getParameter('kernel.root_dir');
50
                $handlerPath = $rootDir.'/../src/App/Message/CommandHandler';
51
            }
52
53
            $commandNamespace = $config['auto_register_handlers']['command_namespace'];
54
            if (empty($commandNamespace)) {
55
                $commandNamespace = 'App\\Message\\Command';
56
            }
57
58
            $handlerNamespace = $config['auto_register_handlers']['command_handler_namespace'];
59
            if (empty($handlerNamespace)) {
60
                $handlerNamespace = 'App\\Message\\CommandHandler';
61
            }
62
63
            $this->autoRegisterCommands($container, $commandNamespace, $handlerNamespace, $handlerPath);
64
        }
65
66
        if ($config['auto_register_event_subscribers']['enabled']) {
67
            $path = $config['auto_register_event_subscribers']['event_subscriber_path'];
68
            if (empty($path)) {
69
                $rootDir = $container->getParameter('kernel.root_dir');
70
                $path = $rootDir.'/../src/App/Message/EventSubscriber';
71
            }
72
73
            $namespace = $config['auto_register_event_subscribers']['event_subscriber_namespace'];
74
            if (empty($namespace)) {
75
                $namespace = 'App\\Message\\EventSubscriber';
76
            }
77
78
            $this->autoRegisterEventSubscribers($container, $namespace, $path);
79
        }
80
    }
81
82
    /**
83
     * @param ContainerBuilder $container
84
     * @param string           $commandNamespace
85
     * @param string           $handlerNamespace
86
     * @param string           $handlerPath
87
     */
88
    protected function autoRegisterCommands(ContainerBuilder $container, $commandNamespace, $handlerNamespace, $handlerPath)
89
    {
90
        // Make sure it ends with slash
91
        $commandNamespace = rtrim($commandNamespace, '\\').'\\';
92
        $handlerNamespace = rtrim($handlerNamespace, '\\').'\\';
93
94
        $finder = new Finder();
95
        $finder->files()->in($handlerPath)->name('*Handler.php');
96
97
        foreach ($finder as $file) {
98
            $handlerClassName = $file->getBasename('.php');
99
            $commandClassName = $file->getBasename('Handler.php');
100
101
            $dynamicContainerId = '';
102
            $dynamicFQN = '';
103
            $path = $file->getRelativePath();
104 View Code Duplication
            if (!empty($path)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
105
                $dynamicFQN = str_replace('/', '\\', $path).'\\';
106
                $dynamicContainerId = str_replace('/', '.', $path).'.';
107
            }
108
109
            $commandFQN = $commandNamespace.$dynamicFQN.$commandClassName;
110
            $handlerFQN = $handlerNamespace.$dynamicFQN.$handlerClassName;
111
112
            $containerId = strtolower(sprintf('command_handler.%s%s.auto', $dynamicContainerId, ltrim(preg_replace('/[A-Z]/', '_$0', $commandClassName), '_')));
113
114
            $def = new Definition($handlerFQN);
115
            $def->setAutowired(true);
116
117
            $tag = 'command_handler';
118
            if (is_subclass_of($handlerFQN, HandlesMessagesAsync::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Happyr\SimpleBusBundle\...lesMessagesAsync::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
119
                $tag = 'asynchronous_command_handler';
120
            }
121
122
            $def->addTag($tag, ['handles' => $commandFQN]);
123
            $container->setDefinition($containerId, $def);
124
        }
125
    }
126
127
    /**
128
     * @param ContainerBuilder $container
129
     * @param string           $subscriberNamespace
130
     * @param string           $subscriberPath
131
     */
132
    protected function autoRegisterEventSubscribers(ContainerBuilder $container, $subscriberNamespace, $subscriberPath)
133
    {
134
        // Make sure it ends with slash
135
        $subscriberNamespace = rtrim($subscriberNamespace, '\\').'\\';
136
137
        $finder = new Finder();
138
        $finder->files()->in($subscriberPath)->name('*.php');
139
140
        foreach ($finder as $file) {
141
            $subscriberClassName = $file->getBasename('.php');
142
143
            $dynamicContainerId = '';
144
            $dynamicFQN = '';
145
            $path = $file->getRelativePath();
146 View Code Duplication
            if (!empty($path)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
                $dynamicFQN = str_replace('/', '\\', $path).'\\';
148
                $dynamicContainerId = str_replace('/', '.', $path).'.';
149
            }
150
151
            $subscriberFQN = $subscriberNamespace.$dynamicFQN.$subscriberClassName;
152
            if (!is_subclass_of($subscriberFQN, AutoRegisteredEventSubscriber::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Happyr\SimpleBusBundle\...dEventSubscriber::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
153
                continue;
154
            }
155
156
            if (!method_exists($subscriberFQN, 'notify')) {
157
                throw new \LogicException(sprintf('An event subscriber that implements AutoRegisteredEventSubscriber must have a function called notify. Please add one in "%s"', $subscriberFQN));
158
            }
159
160
            $containerId = strtolower(sprintf('event_subscriber.%s%s.auto', $dynamicContainerId, ltrim(preg_replace('/[A-Z]/', '_$0', $subscriberClassName), '_')));
161
            $def = new Definition($subscriberFQN);
162
            $def->setAutowired(true);
163
164
            $tag = 'event_subscriber';
165
            if (is_subclass_of($subscriberFQN, HandlesMessagesAsync::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Happyr\SimpleBusBundle\...lesMessagesAsync::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
166
                $tag = 'asynchronous_event_subscriber';
167
            }
168
169
            $def->addTag($tag, ['subscribes_to' => call_user_func($subscriberFQN.'::subscribesTo')]);
170
            $container->setDefinition($containerId, $def);
171
        }
172
    }
173
174
    /**
175
     * Make sure we have activated the required bundles.
176
     *
177
     * @param $bundleName
178
     * @param ContainerBuilder $container
179
     */
180
    private function requireBundle($bundleName, ContainerBuilder $container)
181
    {
182
        $enabledBundles = $container->getParameter('kernel.bundles');
183
        if (!isset($enabledBundles[$bundleName])) {
184
            throw new \LogicException(sprintf('You need to enable "%s" as well', $bundleName));
185
        }
186
    }
187
188
    public function getAlias()
189
    {
190
        return 'happyr_simplebus';
191
    }
192
}
193