Completed
Push — master ( 20d667...bbf4c7 )
by Lukas Kahwe
9s
created

LiipMonitorExtension::setParameters()   D

Complexity

Conditions 33
Paths 83

Size

Total Lines 68

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 68
rs 4.1666
c 0
b 0
f 0
cc 33
nc 83
nop 4

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Liip\MonitorBundle\DependencyInjection;
4
5
use Doctrine\DBAL\Connection;
6
use Doctrine\DBAL\Driver\PDOSqlite\Driver;
7
use Doctrine\DBAL\Migrations\Configuration\AbstractFileConfiguration;
8
use Doctrine\DBAL\Migrations\Configuration\Configuration as MigrationConfiguration;
9
use Symfony\Component\Config\FileLocator;
10
use Symfony\Component\DependencyInjection\ChildDefinition;
11
use Symfony\Component\DependencyInjection\ContainerBuilder;
12
use Symfony\Component\DependencyInjection\DefinitionDecorator;
13
use Symfony\Component\DependencyInjection\Loader;
14
use Symfony\Component\DependencyInjection\Reference;
15
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
16
17
class LiipMonitorExtension extends Extension
18
{
19
    /**
20
     * Loads the services based on your application configuration.
21
     *
22
     * @param array            $configs
23
     * @param ContainerBuilder $container
24
     */
25
    public function load(array $configs, ContainerBuilder $container)
26
    {
27
        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
28
        $loader->load('runner.xml');
29
        $loader->load('helper.xml');
30
        $loader->load('commands.xml');
31
32
        $configuration = new Configuration();
33
        $config = $this->processConfiguration($configuration, $configs);
34
35
        if (null === $config['view_template']) {
36
            $config['view_template'] = __DIR__.'/../Resources/views/health/index.html.php';
37
        }
38
39
        if ($config['enable_controller']) {
40
            $container->setParameter(sprintf('%s.view_template', $this->getAlias()), $config['view_template']);
41
            $loader->load('controller.xml');
42
        }
43
44
        if ($config['mailer']['enabled']) {
45
            $loader->load('swift_mailer.xml');
46
47
            foreach ($config['mailer'] as $key => $value) {
48
                $container->setParameter(sprintf('%s.mailer.%s', $this->getAlias(), $key), $value);
49
            }
50
        }
51
52
        $container->setParameter(sprintf('%s.default_group', $this->getAlias()), $config['default_group']);
53
54
        // symfony3 does not define templating.helper.assets unless php templating is included
55
        if ($container->has('templating.helper.assets')) {
56
            $pathHelper = $container->getDefinition('liip_monitor.helper');
57
            $pathHelper->replaceArgument(0, 'templating.helper.assets');
58
        }
59
60
        // symfony3 does not define templating.helper.router unless php templating is included
61
        if ($container->has('templating.helper.router')) {
62
            $pathHelper = $container->getDefinition('liip_monitor.helper');
63
            $pathHelper->replaceArgument(1, 'templating.helper.router');
64
        }
65
66
        if (empty($config['checks'])) {
67
            return;
68
        }
69
70
        $checksLoaded = array();
71
        $containerParams = array();
72
        foreach ($config['checks']['groups'] as $group => $checks) {
73
            if (empty($checks)) {
74
                continue;
75
            }
76
77
            foreach ($checks as $check => $values) {
78
                if (empty($values)) {
79
                    continue;
80
                }
81
82
                $containerParams['groups'][$group][$check] = $values;
83
                $this->setParameters($container, $check, $group, $values);
84
85
                if (!in_array($check, $checksLoaded)) {
86
                    $loader->load('checks/'.$check.'.xml');
87
                    $checksLoaded[] = $check;
88
                }
89
            }
90
        }
91
92
        $container->setParameter(sprintf('%s.checks', $this->getAlias()), $containerParams);
93
        $this->configureDoctrineMigrationsCheck($container, $containerParams);
94
    }
95
96
    /**
97
     * @param ContainerBuilder $container
98
     * @param string           $checkName
99
     * @param string           $group
100
     * @param array            $values
101
     */
102
    private function setParameters(ContainerBuilder $container, $checkName, $group, $values)
103
    {
104
        $prefix = sprintf('%s.check.%s', $this->getAlias(), $checkName);
105
        switch ($checkName) {
106
            case 'class_exists':
107
            case 'cpu_performance':
108
            case 'php_extensions':
109
            case 'php_version':
110
            case 'php_flags':
111
            case 'readable_directory':
112
            case 'writable_directory':
113
            case 'process_running':
114
            case 'doctrine_dbal':
115
            case 'doctrine_mongodb':
116
            case 'http_service':
117
            case 'guzzle_http_service':
118
            case 'memcache':
119
            case 'redis':
120
            case 'rabbit_mq':
121
            case 'stream_wrapper_exists':
122
            case 'file_ini':
123
            case 'file_json':
124
            case 'file_xml':
125
            case 'file_yaml':
126
            case 'expressions':
127
                $container->setParameter($prefix.'.'.$group, $values);
128
                continue;
129
130
            case 'symfony_version':
131
                continue;
132
133
            case 'opcache_memory':
134
                if (!class_exists('ZendDiagnostics\Check\OpCacheMemory')) {
135
                    throw new \InvalidArgumentException('Please require at least "v1.0.4" of "ZendDiagnostics"');
136
                }
137
                continue;
138
139
            case 'doctrine_migrations':
140
                if (!class_exists('ZendDiagnostics\Check\DoctrineMigration')) {
141
                    throw new \InvalidArgumentException('Please require at least "v1.0.6" of "ZendDiagnostics"');
142
                }
143
144
                if (!class_exists('Doctrine\Bundle\MigrationsBundle\Command\DoctrineCommand')) {
145
                    throw new \InvalidArgumentException('Please require at least "v1.0.0" of "DoctrineMigrationsBundle"');
146
                }
147
148
                if (!class_exists('Doctrine\DBAL\Migrations\Configuration\Configuration')) {
149
                    throw new \InvalidArgumentException('Please require at least "v1.1.0" of "Doctrine Migrations Library"');
150
                }
151
152
                $container->setParameter($prefix.'.'.$group, $values);
153
                continue;
154
155
            case 'pdo_connections':
156
                if (!class_exists('ZendDiagnostics\Check\PDOCheck')) {
157
                    throw new \InvalidArgumentException('Please require at least "v1.0.5" of "ZendDiagnostics"');
158
                }
159
                $container->setParameter($prefix.'.'.$group, $values);
160
                continue;
161
162
        }
163
164
        if (is_array($values)) {
165
            foreach ($values as $key => $value) {
166
                $container->setParameter($prefix.'.'.$key.'.'.$group, $value);
167
            }
168
        }
169
    }
170
171
    /**
172
     * Set up doctrine migration configuration services
173
     *
174
     * @param ContainerBuilder $container The container
175
     * @param array            $params    Container params
176
     *
177
     * @return void
178
     */
179
    private function configureDoctrineMigrationsCheck(ContainerBuilder $container, array $params)
180
    {
181
        if (!$container->hasDefinition('liip_monitor.check.doctrine_migrations') || !isset($params['groups'])) {
182
            return;
183
        }
184
185
        foreach ($params['groups'] as $groupName => $groupChecks) {
186
            if (!isset($groupChecks['doctrine_migrations'])) {
187
                continue;
188
            }
189
190
            $services = [];
191
            foreach ($groupChecks['doctrine_migrations'] as $key => $config) {
192
                $serviceConfiguration =
193
                    $this->createMigrationConfigurationService($container, $config['configuration_file'], $config[ 'connection' ]);
194
195
                $serviceId = sprintf('liip_monitor.check.doctrine_migrations.configuration.%s.%s', $groupName, $key);
196
                $container->setDefinition($serviceId, $serviceConfiguration);
197
198
                $services[$key] = $serviceId;
199
            }
200
201
            $parameter = sprintf('%s.check.%s.%s', $this->getAlias(), 'doctrine_migrations', $groupName);
202
            $container->setParameter($parameter, $services);
203
        }
204
    }
205
206
    /**
207
     * Return key-value array with migration version as key and class as a value defined in config file
208
     *
209
     * @param AbstractFileConfiguration $config Current configuration
210
     * @param Connection                $connection Fake connections
211
     *
212
     * @return array[]
213
     */
214
    private function getPredefinedMigrations(AbstractFileConfiguration $config, Connection $connection)
215
    {
216
        $result = array();
217
218
        $diff = new MigrationConfiguration($connection);
219
        $diff->setMigrationsNamespace($config->getMigrationsNamespace());
220
        $diff->setMigrationsDirectory($config->getMigrationsDirectory());
221
        foreach ($config->getMigrations() as $version) {
222
            $result[$version->getVersion()] = get_class($version->getMigration());
223
        }
224
225
        foreach ($diff->getAvailableVersions() as $version) {
226
            unset($result[$version]);
227
        }
228
229
        return $result;
230
    }
231
232
    /**
233
     * Creates migration configuration service definition
234
     *
235
     * @param ContainerBuilder $container      DI Container
236
     * @param string           $filename       File name with migration configuration
237
     * @param string           $connectionName Connection name for container service
238
     *
239
     * @return DefinitionDecorator|ChildDefinition
240
     */
241
    private function createMigrationConfigurationService(ContainerBuilder $container, $filename, $connectionName)
242
    {
243
        /** @var AbstractFileConfiguration $configuration */
244
        $connection    = new Connection([], new Driver()); // needed for correct migration loading
245
        $configuration = $this->createTemporaryConfiguration($container, $connection, $filename);
246
247
        $configurationServiceName = 'liip_monitor.check.doctrine_migrations.abstract_configuration';
248
        $serviceConfiguration = class_exists('Symfony\Component\DependencyInjection\ChildDefinition')
249
            ? new ChildDefinition($configurationServiceName)
250
            : new DefinitionDecorator($configurationServiceName)
251
        ;
252
253
        $serviceConfiguration->replaceArgument(
254
            0,
255
            new Reference(sprintf('doctrine.dbal.%s_connection', $connectionName))
256
        );
257
258
        if ($configuration->getMigrationsNamespace()) {
259
            $serviceConfiguration->addMethodCall(
260
                'setMigrationsNamespace',
261
                [ $configuration->getMigrationsNamespace() ]
262
            );
263
        }
264
265
        if ($configuration->getMigrationsTableName()) {
266
            $serviceConfiguration->addMethodCall(
267
                'setMigrationsTableName',
268
                [ $configuration->getMigrationsTableName() ]
269
            );
270
        }
271
272
        if ($configuration->getMigrationsColumnName()) {
273
            $serviceConfiguration->addMethodCall(
274
                'setMigrationsColumnName',
275
                [ $configuration->getMigrationsColumnName() ]
276
            );
277
        }
278
279
        if ($configuration->getName()) {
280
            $serviceConfiguration->addMethodCall('setName', [ $configuration->getName() ]);
281
        }
282
283
        if ($configuration->getMigrationsDirectory()) {
284
            $directory        = $configuration->getMigrationsDirectory();
285
            $pathPlaceholders = array('kernel.root_dir', 'kernel.cache_dir', 'kernel.logs_dir');
286
            foreach ($pathPlaceholders as $parameter) {
287
                $kernelDir = realpath($container->getParameter($parameter));
288
                if (strpos(realpath($directory), $kernelDir) === 0) {
289
                    $directory = str_replace($kernelDir, "%{$parameter}%", $directory);
290
                    break;
291
                }
292
            }
293
294
295
            $serviceConfiguration->addMethodCall(
296
                'setMigrationsDirectory',
297
                [ $directory ]
298
            );
299
        }
300
301
        /** @var AbstractFileConfiguration $diff */
302
        $versions = $this->getPredefinedMigrations($configuration, $connection);
303
        if ($versions) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $versions of type array[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
304
            $serviceConfiguration->addMethodCall('registerMigrations', [ $versions ]);
305
        }
306
307
        $serviceConfiguration->addMethodCall('configure', []);
308
309
        if ($configuration->areMigrationsOrganizedByYear()) {
310
            $serviceConfiguration->addMethodCall('setMigrationsAreOrganizedByYear', [ true ]);
311
312
            return $serviceConfiguration;
313
        } elseif ($configuration->areMigrationsOrganizedByYearAndMonth()) {
314
            $serviceConfiguration->addMethodCall('setMigrationsAreOrganizedByYearAndMonth', [ true ]);
315
316
            return $serviceConfiguration;
317
        }
318
319
        return $serviceConfiguration;
320
    }
321
322
    /**
323
     * Creates in-memory migration configuration for setting up container service
324
     *
325
     * @param ContainerBuilder $container  The container
326
     * @param Connection       $connection Fake connection
327
     * @param string           $filename   Migrations configuration file
328
     *
329
     * @return AbstractFileConfiguration
330
     */
331
    private function createTemporaryConfiguration(ContainerBuilder $container, Connection $connection, $filename)
332
    {
333
        // -------
334
        // This part must be in sync with Doctrine\DBAL\Migrations\Tools\Console\Helper\ConfigurationHelper::loadConfig
335
        $map = [
336
            'xml'  => '\XmlConfiguration',
337
            'yaml' => '\YamlConfiguration',
338
            'yml'  => '\YamlConfiguration',
339
            'php'  => '\ArrayConfiguration',
340
            'json' => '\JsonConfiguration',
341
        ];
342
        // --------
343
344
        $filename = $container->getParameterBag()->resolveValue($filename);
345
        $info     = pathinfo($filename);
346
        // check we can support this file type
347
        if (empty($map[ $info[ 'extension' ] ])) {
348
            throw new \InvalidArgumentException('Given config file type is not supported');
349
        }
350
351
        $class = 'Doctrine\DBAL\Migrations\Configuration';
352
        $class .= $map[ $info[ 'extension' ] ];
353
        // -------
354
355
        /** @var AbstractFileConfiguration $configuration */
356
        $configuration = new $class($connection);
357
        $configuration->load($filename);
358
        $configuration->validate();
359
360
        return $configuration;
361
    }
362
}
363