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