Completed
Push — check-assets-enabled ( 77fc5e...7ea9c2 )
by Lukas Kahwe
02:12 queued 54s
created

LiipMonitorExtension::setParameters()   C

Complexity

Conditions 33
Paths 83

Size

Total Lines 68
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 68
rs 5.5197
cc 33
eloc 49
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\Exception\LogicException;
14
use Symfony\Component\DependencyInjection\Loader;
15
use Symfony\Component\DependencyInjection\Reference;
16
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
17
18
class LiipMonitorExtension extends Extension
19
{
20
    /**
21
     * Loads the services based on your application configuration.
22
     *
23
     * @param array            $configs
24
     * @param ContainerBuilder $container
25
     */
26
    public function load(array $configs, ContainerBuilder $container)
27
    {
28
        $loader = new Loader\XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
29
        $loader->load('runner.xml');
30
        $loader->load('helper.xml');
31
        $loader->load('commands.xml');
32
33
        $configuration = new Configuration();
34
        $config = $this->processConfiguration($configuration, $configs);
35
36
        if (null === $config['view_template']) {
37
            $config['view_template'] = __DIR__.'/../Resources/views/health/index.html.php';
38
        }
39
40
        if ($config['enable_controller']) {
41
            $container->setParameter(sprintf('%s.view_template', $this->getAlias()), $config['view_template']);
42
            $loader->load('controller.xml');
43
        }
44
45
        if ($config['mailer']['enabled']) {
46
            $loader->load('swift_mailer.xml');
47
48
            foreach ($config['mailer'] as $key => $value) {
49
                $container->setParameter(sprintf('%s.mailer.%s', $this->getAlias(), $key), $value);
50
            }
51
        }
52
53
        $container->setParameter(sprintf('%s.default_group', $this->getAlias()), $config['default_group']);
54
55
        // symfony3 does not define templating.helper.assets unless php templating is included
56
        if ($container->has('templating.helper.assets')) {
57
            $pathHelper = $container->getDefinition('liip_monitor.helper');
58
            $pathHelper->replaceArgument(0, 'templating.helper.assets');
59
        }
60
61
        // symfony3 does not define templating.helper.router unless php templating is included
62
        if ($container->has('templating.helper.router')) {
63
            $pathHelper = $container->getDefinition('liip_monitor.helper');
64
            $pathHelper->replaceArgument(1, 'templating.helper.router');
65
        }
66
67
        if (empty($config['checks'])) {
68
            return;
69
        }
70
71
        $checksLoaded = array();
72
        $containerParams = array();
73
        foreach ($config['checks']['groups'] as $group => $checks) {
74
            if (empty($checks)) {
75
                continue;
76
            }
77
78
            foreach ($checks as $check => $values) {
79
                if (empty($values)) {
80
                    continue;
81
                }
82
83
                $containerParams['groups'][$group][$check] = $values;
84
                $this->setParameters($container, $check, $group, $values);
85
86
                if (!in_array($check, $checksLoaded)) {
87
                    $loader->load('checks/'.$check.'.xml');
88
                    $checksLoaded[] = $check;
89
                }
90
            }
91
        }
92
93
        $container->setParameter(sprintf('%s.checks', $this->getAlias()), $containerParams);
94
        $this->configureDoctrineMigrationsCheck($container, $containerParams);
95
    }
96
97
    /**
98
     * @param ContainerBuilder $container
99
     * @param string           $checkName
100
     * @param string           $group
101
     * @param array            $values
102
     */
103
    private function setParameters(ContainerBuilder $container, $checkName, $group, $values)
104
    {
105
        $prefix = sprintf('%s.check.%s', $this->getAlias(), $checkName);
106
        switch ($checkName) {
107
            case 'class_exists':
108
            case 'cpu_performance':
109
            case 'php_extensions':
110
            case 'php_version':
111
            case 'php_flags':
112
            case 'readable_directory':
113
            case 'writable_directory':
114
            case 'process_running':
115
            case 'doctrine_dbal':
116
            case 'doctrine_mongodb':
117
            case 'http_service':
118
            case 'guzzle_http_service':
119
            case 'memcache':
120
            case 'redis':
121
            case 'rabbit_mq':
122
            case 'stream_wrapper_exists':
123
            case 'file_ini':
124
            case 'file_json':
125
            case 'file_xml':
126
            case 'file_yaml':
127
            case 'expressions':
128
                $container->setParameter($prefix.'.'.$group, $values);
129
                continue;
130
131
            case 'symfony_version':
132
                continue;
133
134
            case 'opcache_memory':
135
                if (!class_exists('ZendDiagnostics\Check\OpCacheMemory')) {
136
                    throw new \InvalidArgumentException('Please require at least "v1.0.4" of "ZendDiagnostics"');
137
                }
138
                continue;
139
140
            case 'doctrine_migrations':
141
                if (!class_exists('ZendDiagnostics\Check\DoctrineMigration')) {
142
                    throw new \InvalidArgumentException('Please require at least "v1.0.6" of "ZendDiagnostics"');
143
                }
144
145
                if (!class_exists('Doctrine\Bundle\MigrationsBundle\Command\DoctrineCommand')) {
146
                    throw new \InvalidArgumentException('Please require at least "v1.0.0" of "DoctrineMigrationsBundle"');
147
                }
148
149
                if (!class_exists('Doctrine\DBAL\Migrations\Configuration\Configuration')) {
150
                    throw new \InvalidArgumentException('Please require at least "v1.1.0" of "Doctrine Migrations Library"');
151
                }
152
153
                $container->setParameter($prefix.'.'.$group, $values);
154
                continue;
155
156
            case 'pdo_connections':
157
                if (!class_exists('ZendDiagnostics\Check\PDOCheck')) {
158
                    throw new \InvalidArgumentException('Please require at least "v1.0.5" of "ZendDiagnostics"');
159
                }
160
                $container->setParameter($prefix.'.'.$group, $values);
161
                continue;
162
163
        }
164
165
        if (is_array($values)) {
166
            foreach ($values as $key => $value) {
167
                $container->setParameter($prefix.'.'.$key.'.'.$group, $value);
168
            }
169
        }
170
    }
171
172
    /**
173
     * Set up doctrine migration configuration services
174
     *
175
     * @param ContainerBuilder $container The container
176
     * @param array            $params    Container params
177
     *
178
     * @return void
179
     */
180
    private function configureDoctrineMigrationsCheck(ContainerBuilder $container, array $params)
181
    {
182
        if (!$container->hasDefinition('liip_monitor.check.doctrine_migrations') || !isset($params['groups'])) {
183
            return;
184
        }
185
186
        foreach ($params['groups'] as $groupName => $groupChecks) {
187
            if (!isset($groupChecks['doctrine_migrations'])) {
188
                continue;
189
            }
190
191
            $services = [];
192
            foreach ($groupChecks['doctrine_migrations'] as $key => $config) {
193
                $serviceConfiguration =
194
                    $this->createMigrationConfigurationService($container, $config['configuration_file'], $config[ 'connection' ]);
195
196
                $serviceId = sprintf('liip_monitor.check.doctrine_migrations.configuration.%s.%s', $groupName, $key);
197
                $container->setDefinition($serviceId, $serviceConfiguration);
198
199
                $services[$key] = $serviceId;
200
            }
201
202
            $parameter = sprintf('%s.check.%s.%s', $this->getAlias(), 'doctrine_migrations', $groupName);
203
            $container->setParameter($parameter, $services);
204
        }
205
    }
206
207
    /**
208
     * Return key-value array with migration version as key and class as a value defined in config file
209
     *
210
     * @param AbstractFileConfiguration $config Current configuration
211
     * @param Connection                $connection Fake connections
212
     *
213
     * @return array[]
214
     */
215
    private function getPredefinedMigrations(AbstractFileConfiguration $config, Connection $connection)
216
    {
217
        $result = array();
218
219
        $diff = new MigrationConfiguration($connection);
220
        $diff->setMigrationsNamespace($config->getMigrationsNamespace());
221
        $diff->setMigrationsDirectory($config->getMigrationsDirectory());
222
        foreach ($config->getMigrations() as $version) {
223
            $result[$version->getVersion()] = get_class($version->getMigration());
224
        }
225
226
        foreach ($diff->getAvailableVersions() as $version) {
227
            unset($result[$version]);
228
        }
229
230
        return $result;
231
    }
232
233
    /**
234
     * Creates migration configuration service definition
235
     *
236
     * @param ContainerBuilder $container      DI Container
237
     * @param string           $filename       File name with migration configuration
238
     * @param string           $connectionName Connection name for container service
239
     *
240
     * @return DefinitionDecorator|ChildDefinition
241
     */
242
    private function createMigrationConfigurationService(ContainerBuilder $container, $filename, $connectionName)
243
    {
244
        /** @var AbstractFileConfiguration $configuration */
245
        $connection    = new Connection([], new Driver()); // needed for correct migration loading
246
        $configuration = $this->createTemporaryConfiguration($container, $connection, $filename);
247
248
        $configurationServiceName = 'liip_monitor.check.doctrine_migrations.abstract_configuration';
249
        $serviceConfiguration = class_exists('Symfony\Component\DependencyInjection\ChildDefinition')
250
            ? new ChildDefinition($configurationServiceName)
251
            : new DefinitionDecorator($configurationServiceName)
252
        ;
253
254
        $serviceConfiguration->replaceArgument(
255
            0,
256
            new Reference(sprintf('doctrine.dbal.%s_connection', $connectionName))
257
        );
258
259
        if ($configuration->getMigrationsNamespace()) {
260
            $serviceConfiguration->addMethodCall(
261
                'setMigrationsNamespace',
262
                [ $configuration->getMigrationsNamespace() ]
263
            );
264
        }
265
266
        if ($configuration->getMigrationsTableName()) {
267
            $serviceConfiguration->addMethodCall(
268
                'setMigrationsTableName',
269
                [ $configuration->getMigrationsTableName() ]
270
            );
271
        }
272
273
        if ($configuration->getMigrationsColumnName()) {
274
            $serviceConfiguration->addMethodCall(
275
                'setMigrationsColumnName',
276
                [ $configuration->getMigrationsColumnName() ]
277
            );
278
        }
279
280
        if ($configuration->getName()) {
281
            $serviceConfiguration->addMethodCall('setName', [ $configuration->getName() ]);
282
        }
283
284
        if ($configuration->getMigrationsDirectory()) {
285
            $directory        = $configuration->getMigrationsDirectory();
286
            $pathPlaceholders = array('kernel.root_dir', 'kernel.cache_dir', 'kernel.logs_dir');
287
            foreach ($pathPlaceholders as $parameter) {
288
                $kernelDir = realpath($container->getParameter($parameter));
289
                if (strpos(realpath($directory), $kernelDir) === 0) {
290
                    $directory = str_replace($kernelDir, "%{$parameter}%", $directory);
291
                    break;
292
                }
293
            }
294
295
296
            $serviceConfiguration->addMethodCall(
297
                'setMigrationsDirectory',
298
                [ $directory ]
299
            );
300
        }
301
302
        /** @var AbstractFileConfiguration $diff */
303
        $versions = $this->getPredefinedMigrations($configuration, $connection);
304
        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...
305
            $serviceConfiguration->addMethodCall('registerMigrations', [ $versions ]);
306
        }
307
308
        $serviceConfiguration->addMethodCall('configure', []);
309
310
        if ($configuration->areMigrationsOrganizedByYear()) {
311
            $serviceConfiguration->addMethodCall('setMigrationsAreOrganizedByYear', [ true ]);
312
313
            return $serviceConfiguration;
314
        } elseif ($configuration->areMigrationsOrganizedByYearAndMonth()) {
315
            $serviceConfiguration->addMethodCall('setMigrationsAreOrganizedByYearAndMonth', [ true ]);
316
317
            return $serviceConfiguration;
318
        }
319
320
        return $serviceConfiguration;
321
    }
322
323
    /**
324
     * Creates in-memory migration configuration for setting up container service
325
     *
326
     * @param ContainerBuilder $container  The container
327
     * @param Connection       $connection Fake connection
328
     * @param string           $filename   Migrations configuration file
329
     *
330
     * @return AbstractFileConfiguration
331
     */
332
    private function createTemporaryConfiguration(ContainerBuilder $container, Connection $connection, $filename)
333
    {
334
        // -------
335
        // This part must be in sync with Doctrine\DBAL\Migrations\Tools\Console\Helper\ConfigurationHelper::loadConfig
336
        $map = [
337
            'xml'  => '\XmlConfiguration',
338
            'yaml' => '\YamlConfiguration',
339
            'yml'  => '\YamlConfiguration',
340
            'php'  => '\ArrayConfiguration',
341
            'json' => '\JsonConfiguration',
342
        ];
343
        // --------
344
345
        $filename = $container->getParameterBag()->resolveValue($filename);
346
        $info     = pathinfo($filename);
347
        // check we can support this file type
348
        if (empty($map[ $info[ 'extension' ] ])) {
349
            throw new \InvalidArgumentException('Given config file type is not supported');
350
        }
351
352
        $class = 'Doctrine\DBAL\Migrations\Configuration';
353
        $class .= $map[ $info[ 'extension' ] ];
354
        // -------
355
356
        /** @var AbstractFileConfiguration $configuration */
357
        $configuration = new $class($connection);
358
        $configuration->load($filename);
359
        $configuration->validate();
360
361
        return $configuration;
362
    }
363
}
364