Configuration::createGroupsNode()   B
last analyzed

Complexity

Conditions 6
Paths 2

Size

Total Lines 345

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 298
CRAP Score 6.0012

Importance

Changes 0
Metric Value
dl 0
loc 345
ccs 298
cts 308
cp 0.9675
rs 7.3777
c 0
b 0
f 0
cc 6
nc 2
nop 0
crap 6.0012

How to fix   Long Method   

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\Bundle\MigrationsBundle\DoctrineMigrationsBundle;
6
use Symfony\Component\Config\Definition\BaseNode;
7
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
8
use Symfony\Component\Config\Definition\ConfigurationInterface;
9
10
/**
11
 * This class contains the configuration information for the bundle.
12
 *
13
 * This information is solely responsible for how the different configuration
14
 * sections are normalized, and merged.
15
 *
16
 * @author Lukas Kahwe Smith <[email protected]>
17
 */
18
class Configuration implements ConfigurationInterface
19
{
20
    /**
21
     * Generates the configuration tree.
22
     *
23
     * @return TreeBuilder
24
     */
25 49
    public function getConfigTreeBuilder()
26
    {
27 49
        $treeBuilder = new TreeBuilder('liip_monitor');
28
29
        // Keep compatibility with symfony/config < 4.2
30 49
        if (\method_exists($treeBuilder, 'getRootNode')) {
31 49
            $rootNode = $treeBuilder->getRootNode();
32
        } else {
33
            $rootNode = $treeBuilder->root('liip_monitor');
0 ignored issues
show
Bug introduced by
The method root() does not seem to exist on object<Symfony\Component...on\Builder\TreeBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
34
        }
35
36
        $rootNode
37 49
            ->beforeNormalization()
38
                ->always(function ($v) {
39 49
                    if (empty($v['default_group'])) {
40 49
                        $v['default_group'] = 'default';
41
                    }
42
43 49
                    if (isset($v['checks']) && is_array($v['checks']) && !isset($v['checks']['groups'])) {
44 40
                        $checks = $v['checks'];
45 40
                        unset($v['checks']);
46
47 40
                        $v['checks']['groups'][$v['default_group']] = $checks;
48
                    }
49
50 49
                    return $v;
51 49
                })
52 49
            ->end()
53 49
            ->children()
54 49
                ->booleanNode('enable_controller')->defaultFalse()->end()
55 49
                ->scalarNode('view_template')->defaultNull()->end()
56 49
                ->integerNode('failure_status_code')
57 49
                    ->min(100)->max(598)
58 49
                    ->defaultValue(502)
59 49
                ->end()
60 49
                ->arrayNode('mailer')
61 49
                    ->canBeEnabled()
62 49
                    ->children()
63 49
                        ->arrayNode('recipient')
64 49
                            ->isRequired()->requiresAtLeastOneElement()
65 49
                            ->prototype('scalar')->end()
66 49
                            ->beforeNormalization()
67 49
                                ->ifString()
68
                                ->then(function ($v) { return [$v]; })
69 49
                            ->end()
70 49
                        ->end()
71 49
                        ->scalarNode('sender')->isRequired()->cannotBeEmpty()->end()
72 49
                        ->scalarNode('subject')->isRequired()->cannotBeEmpty()->end()
73 49
                        ->booleanNode('send_on_warning')->defaultTrue()->end()
74 49
                    ->end()
75 49
                ->end()
76 49
                ->scalarNode('default_group')->defaultValue('default')->end()
77 49
                ->arrayNode('checks')
78 49
                    ->canBeUnset()
79 49
                    ->children()
80 49
                        ->append($this->createGroupsNode())
81 49
                    ->end()
82 49
                ->end()
83 49
            ->end()
84 49
        ->end();
85
86 49
        return $treeBuilder;
87
    }
88
89 49
    private function createGroupsNode()
90
    {
91 49
        $builder = new TreeBuilder('groups');
92
93
        // Keep compatibility with symfony/config < 4.2
94 49
        if (\method_exists($builder, 'getRootNode')) {
95 49
            $node = $builder->getRootNode();
96
        } else {
97
            $node = $builder->root('groups');
0 ignored issues
show
Bug introduced by
The method root() does not seem to exist on object<Symfony\Component...on\Builder\TreeBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
98
        }
99
        $node
100 49
            ->requiresAtLeastOneElement()
101 49
            ->info('Grouping checks')
102 49
            ->useAttributeAsKey('name')
103 49
            ->prototype('array')
104 49
                ->children()
105 49
                    ->arrayNode('php_extensions')
106 49
                        ->info('Validate that a named extension or a collection of extensions is available')
107 49
                        ->example('session.use_only_cookies: false')
108 49
                        ->prototype('scalar')->end()
109 49
                    ->end()
110 49
                    ->arrayNode('php_flags')
111 49
                        ->info('Pairs of a PHP setting and an expected value')
112 49
                        ->example('session.use_only_cookies: false')
113 49
                        ->useAttributeAsKey('setting')
114 49
                        ->prototype('scalar')->defaultValue(true)->end()
115 49
                    ->end()
116 49
                    ->arrayNode('php_version')
117 49
                        ->info('Pairs of a version and a comparison operator')
118 49
                        ->example('5.4.15: >=')
119 49
                        ->useAttributeAsKey('version')
120 49
                        ->prototype('scalar')->end()
121 49
                    ->end()
122 49
                    ->variableNode('process_running')
123 49
                        ->info('Process name/pid or an array of process names/pids')
124 49
                        ->example('[apache, foo]')
125 49
                    ->end()
126 49
                    ->arrayNode('readable_directory')
127 49
                        ->info('Validate that a given path (or a collection of paths) is a dir and is readable')
128 49
                        ->example('["%kernel.cache_dir%"]')
129 49
                        ->prototype('scalar')->end()
130 49
                    ->end()
131 49
                    ->arrayNode('writable_directory')
132 49
                        ->info('Validate that a given path (or a collection of paths) is a dir and is writable')
133 49
                        ->example('["%kernel.cache_dir%"]')
134 49
                        ->prototype('scalar')->end()
135 49
                    ->end()
136 49
                    ->arrayNode('class_exists')
137 49
                        ->info('Validate that a class or a collection of classes is available')
138 49
                        ->example('["Lua", "My\Fancy\Class"]')
139 49
                        ->prototype('scalar')->end()
140 49
                    ->end()
141 49
                    ->scalarNode('cpu_performance')
142 49
                        ->info('Benchmark CPU performance and return failure if it is below the given ratio')
143 49
                        ->example('1.0 # This is the power of an EC2 micro instance')
144 49
                    ->end()
145 49
                    ->arrayNode('disk_usage')
146 49
                        ->info('Checks to see if the disk usage is below warning/critical percent thresholds')
147 49
                        ->children()
148 49
                            ->integerNode('warning')->defaultValue(70)->end()
149 49
                            ->integerNode('critical')->defaultValue(90)->end()
150 49
                            ->scalarNode('path')->defaultValue('%kernel.cache_dir%')->end()
151 49
                        ->end()
152 49
                    ->end()
153 49
                    ->arrayNode('symfony_requirements')
154 49
                        ->info('Checks Symfony2 requirements file')
155 49
                        ->children()
156 49
                            ->scalarNode('file')->defaultValue('%kernel.root_dir%/SymfonyRequirements.php')->end()
157 49
                        ->end()
158 49
                    ->end()
159 49
                    ->arrayNode('opcache_memory')
160 49
                        ->info('Checks to see if the OpCache memory usage is below warning/critical thresholds')
161 49
                        ->children()
162 49
                            ->integerNode('warning')->defaultValue(70)->end()
163 49
                            ->integerNode('critical')->defaultValue(90)->end()
164 49
                        ->end()
165 49
                    ->end()
166 49
                    ->arrayNode('apc_memory')
167 49
                        ->info('Checks to see if the APC memory usage is below warning/critical thresholds')
168 49
                        ->children()
169 49
                            ->integerNode('warning')->defaultValue(70)->end()
170 49
                            ->integerNode('critical')->defaultValue(90)->end()
171 49
                        ->end()
172 49
                    ->end()
173 49
                    ->arrayNode('apc_fragmentation')
174 49
                        ->info('Checks to see if the APC fragmentation is below warning/critical thresholds')
175 49
                        ->children()
176 49
                            ->integerNode('warning')->defaultValue(70)->end()
177 49
                            ->integerNode('critical')->defaultValue(90)->end()
178 49
                        ->end()
179 49
                    ->end()
180 49
                    ->variableNode('doctrine_dbal')
181 49
                        ->defaultNull()
182 49
                        ->info('Connection name or an array of connection names')
183 49
                        ->example('[default, crm]')
184 49
                    ->end()
185 49
                    ->variableNode('doctrine_mongodb')
186 49
                        ->defaultNull()
187 49
                        ->info('Connection name or an array of connection names')
188 49
                        ->example('[default, crm]')
189 49
                    ->end()
190 49
                    ->arrayNode('doctrine_migrations')
191 49
                        ->useAttributeAsKey('name')
192 49
                        ->info('Checks to see if migrations from specified configuration file are applied')
193 49
                        ->prototype('array')
194 49
                            ->children()
195 49
                                ->scalarNode('configuration_file')
196 49
                                    ->info('Absolute path to doctrine migrations configuration')
197 49
                                ->end()
198 49
                                ->scalarNode('connection')
199 49
                                    ->isRequired()
200 49
                                    ->cannotBeEmpty()
201 49
                                    ->info('Connection name from doctrine DBAL configuration')
202 49
                                ->end()
203 49
                            ->end()
204 49
                            ->beforeNormalization()
205 49
                                ->ifString()
206
                                ->then(function ($value) {
207
                                    if (is_string($value)) {
208
                                        $value = ['connection' => $value];
209
                                    }
210
211
                                    return $value;
212 49
                                })
213 49
                            ->end()
214 49
                            ->validate()
215 49
                                ->ifArray()
216
                                ->then(static function (array $value): array {
217
                                    $isError = !isset($value['configuration_file'])
218
                                        && !class_exists(DoctrineMigrationsBundle::class);
219
220
                                    if ($isError) {
221
                                        throw new \InvalidArgumentException('You should explicitly define "configuration_file" parameter or install doctrine/doctrine-migrations-bundle to use empty parameter.');
222
                                    }
223
224
                                    return $value;
225 49
                                })
226 49
                            ->end()
227 49
                        ->end()
228 49
                        ->beforeNormalization()
229 49
                            ->ifString()
230
                            ->then(static function (string $value): array {
231
                                return ['default' => $value];
232 49
                            })
233 49
                        ->end()
234 49
                        ->example(
235
                            [
236
                                'application_migrations' => [
237 49
                                    'configuration_file' => '%kernel.root_dir%/Resources/config/migrations.yml',
238
                                    'connection' => 'default',
239
                                ],
240
                                'migrations_with_doctrine_bundle' => [
241
                                    'connection' => 'default',
242
                                ],
243
                                'migrations_with_doctrine_bundle_v2' => 'default',
244
                            ]
245
                        )
246 49
                    ->end()
247 49
                    ->arrayNode('memcache')
248 49
                        ->info('Check if MemCache extension is loaded and given server is reachable')
249 49
                        ->useAttributeAsKey('name')
250 49
                        ->prototype('array')
251 49
                            ->children()
252 49
                                ->scalarNode('host')->defaultValue('localhost')->end()
253 49
                                ->integerNode('port')->defaultValue(11211)->end()
254 49
                            ->end()
255 49
                        ->end()
256 49
                    ->end()
257 49
                    ->arrayNode('memcached')
258 49
                        ->info('Check if MemCached extension is loaded and given server is reachable')
259 49
                        ->useAttributeAsKey('name')
260 49
                        ->prototype('array')
261 49
                            ->children()
262 49
                                ->scalarNode('host')->defaultValue('localhost')->end()
263 49
                                ->integerNode('port')->defaultValue(11211)->end()
264 49
                            ->end()
265 49
                        ->end()
266 49
                    ->end()
267 49
                    ->arrayNode('redis')
268 49
                        ->info('Validate that a Redis service is running')
269 49
                        ->useAttributeAsKey('name')
270 49
                        ->beforeNormalization()
271 49
                            ->ifString()
272
                            ->then(function ($v) { return ['dsn' => $v]; })
273 49
                        ->end()
274 49
                        ->prototype('array')
275 49
                            ->children()
276 49
                                ->scalarNode('host')->defaultValue('localhost')->end()
277 49
                                ->integerNode('port')->defaultValue(6379)->end()
278 49
                                ->scalarNode('password')->defaultNull()->end()
279 49
                                ->scalarNode('dsn')->defaultNull()->end()
280 49
                            ->end()
281 49
                        ->end()
282 49
                    ->end()
283 49
                    ->arrayNode('http_service')
284 49
                        ->info('Attempt connection to given HTTP host and (optionally) check status code and page content')
285 49
                        ->useAttributeAsKey('name')
286 49
                        ->prototype('array')
287 49
                            ->children()
288 49
                                ->scalarNode('host')->defaultValue('localhost')->end()
289 49
                                ->integerNode('port')->defaultValue(80)->end()
290 49
                                ->scalarNode('path')->defaultValue('/')->end()
291 49
                                ->integerNode('status_code')->defaultValue(200)->end()
292 49
                                ->scalarNode('content')->defaultNull()->end()
293 49
                            ->end()
294 49
                        ->end()
295 49
                    ->end()
296 49
                    ->arrayNode('guzzle_http_service')
297 49
                        ->info('Attempt connection using Guzzle to given HTTP host and (optionally) check status code and page content')
298 49
                        ->useAttributeAsKey('name')
299 49
                        ->prototype('array')
300 49
                            ->children()
301 49
                                ->scalarNode('url')->defaultValue('localhost')->end()
302 49
                                ->variableNode('headers')->defaultValue([])->end()
303 49
                                ->variableNode('options')->defaultValue([])->end()
304 49
                                ->integerNode('status_code')->defaultValue(200)->end()
305 49
                                ->scalarNode('content')->defaultNull()->end()
306 49
                                ->scalarNode('method')->defaultValue('GET')->end()
307 49
                                ->scalarNode('body')->defaultNull()->end()
308 49
                            ->end()
309 49
                        ->end()
310 49
                    ->end()
311 49
                    ->arrayNode('rabbit_mq')
312 49
                        ->info('Validate that a RabbitMQ service is running')
313 49
                        ->useAttributeAsKey('name')
314 49
                        ->beforeNormalization()
315 49
                            ->ifString()
316
                            ->then(function ($v) { return ['dsn' => $v]; })
317 49
                        ->end()
318 49
                        ->prototype('array')
319 49
                            ->children()
320 49
                                ->scalarNode('host')->defaultValue('localhost')->end()
321 49
                                ->integerNode('port')->defaultValue(5672)->end()
322 49
                                ->scalarNode('user')->defaultValue('guest')->end()
323 49
                                ->scalarNode('password')->defaultValue('guest')->end()
324 49
                                ->scalarNode('vhost')->defaultValue('/')->end()
325 49
                                ->scalarNode('dsn')->defaultNull()->end()
326 49
                            ->end()
327 49
                        ->end()
328 49
                    ->end()
329 49
                    ->booleanNode('symfony_version')
330 49
                        ->info('Checks the version of this app against the latest stable release')
331 49
                    ->end()
332 49
                    ->arrayNode('custom_error_pages')
333 49
                        ->info('Checks if error pages have been customized for given error codes')
334 49
                        ->children()
335 49
                            ->arrayNode('error_codes')
336 49
                                ->example('[404, 503]')
337 49
                                ->info('The status codes that should be customized')
338 49
                                ->isRequired()
339 49
                                ->requiresAtLeastOneElement()
340 49
                                ->prototype('scalar')->end()
341 49
                            ->end()
342 49
                            ->scalarNode('path')
343 49
                                ->info('The directory where your custom error page twig templates are located. Keep as "%kernel.project_dir%" to use default location.')
344 49
                                ->defaultValue('%kernel.project_dir%')
345 49
                            ->end()
346 49
                            ->scalarNode('controller')
347 49
                                ->defaultNull()
348 49
                                ->setDeprecated(...self::getCustomErrorPagesControllerDeprecationMessage())
349 49
                            ->end()
350 49
                        ->end()
351 49
                    ->end()
352 49
                    ->arrayNode('security_advisory')
353 49
                        ->info('Checks installed composer dependencies against the SensioLabs Security Advisory database')
354 49
                        ->children()
355 49
                            ->scalarNode('lock_file')->defaultValue('%kernel.project_dir%/composer.lock')->end()
356 49
                        ->end()
357 49
                    ->end()
358 49
                    ->arrayNode('stream_wrapper_exists')
359 49
                        ->info('Validate that a stream wrapper or collection of stream wrappers exists')
360 49
                        ->example('[\'zlib\', \'bzip2\', \'zip\']')
361 49
                        ->prototype('scalar')->end()
362 49
                    ->end()
363 49
                    ->arrayNode('file_ini')
364 49
                        ->info('Find and validate INI files')
365 49
                        ->example('[\'path/to/my.ini\']')
366 49
                        ->prototype('scalar')->end()
367 49
                    ->end()
368 49
                    ->arrayNode('file_json')
369 49
                        ->info('Find and validate JSON files')
370 49
                        ->example('[\'path/to/my.json\']')
371 49
                        ->prototype('scalar')->end()
372 49
                    ->end()
373 49
                    ->arrayNode('file_xml')
374 49
                        ->info('Find and validate XML files')
375 49
                        ->example('[\'path/to/my.xml\']')
376 49
                        ->prototype('scalar')->end()
377 49
                    ->end()
378 49
                    ->arrayNode('file_yaml')
379 49
                        ->info('Find and validate YAML files')
380 49
                        ->example('[\'path/to/my.yml\']')
381 49
                        ->prototype('scalar')->end()
382 49
                    ->end()
383 49
                    ->arrayNode('pdo_connections')
384 49
                        ->info('PDO connections to check for connection')
385 49
                        ->useAttributeAsKey('name')
386 49
                        ->prototype('array')
387 49
                            ->children()
388 49
                                ->scalarNode('dsn')->defaultNull()->end()
389 49
                                ->scalarNode('username')->defaultNull()->end()
390 49
                                ->scalarNode('password')->defaultNull()->end()
391 49
                                ->integerNode('timeout')->defaultValue(1)->end()
392 49
                            ->end()
393 49
                        ->end()
394 49
                    ->end()
395 49
                    ->arrayNode('expressions')
396 49
                        ->useAttributeAsKey('alias')
397 49
                        ->info('Checks that fail/warn when given expression is false (expressions are evaluated with symfony/expression-language)')
398 49
                        ->example([
399
                            'opcache' => [
400 49
                                'label' => 'OPcache',
401
                                'warning_expression' => "ini('opcache.revalidate_freq') > 0",
402
                                'critical_expression' => "ini('opcache.enable')",
403
                                'warning_message' => 'OPcache not optimized for production',
404
                                'critical_message' => 'OPcache not enabled',
405
                            ],
406
                        ])
407 49
                        ->prototype('array')
408 49
                            ->addDefaultsIfNotSet()
409 49
                            ->validate()
410
                                ->ifTrue(function ($value) {
411 2
                                    return !$value['warning_expression'] && !$value['critical_expression'];
412 49
                                })
413 49
                                ->thenInvalid('A warning_expression or a critical_expression must be set.')
414 49
                            ->end()
415 49
                            ->children()
416 49
                                ->scalarNode('label')->isRequired()->end()
417 49
                                ->scalarNode('warning_expression')
418 49
                                ->defaultNull()
419 49
                                ->example('ini(\'apc.stat\') == 0')
420 49
                            ->end()
421 49
                            ->scalarNode('critical_expression')
422 49
                            ->defaultNull()
423 49
                            ->example('ini(\'short_open_tag\') == 1')
424 49
                        ->end()
425 49
                        ->scalarNode('warning_message')->defaultNull()->end()
426 49
                        ->scalarNode('critical_message')->defaultNull()->end()
427 49
                    ->end()
428 49
                ->end()
429 49
            ->end()
430
        ;
431
432 49
        return $node;
433
    }
434
435
    /**
436
     * Returns the correct deprecation param's as an array for setDeprecated.
437
     *
438
     * Symfony/Config v5.1 introduces a deprecation notice when calling
439
     * setDeprecation() with less than 3 args and the getDeprecation method was
440
     * introduced at the same time. By checking if getDeprecation() exists,
441
     * we can determine the correct param count to use when calling setDeprecated.
442
     */
443 49
    private static function getCustomErrorPagesControllerDeprecationMessage()
444
    {
445 49
        $message = 'The custom error page controller option is no longer used; the corresponding config parameter was deprecated in 2.13 and will be dropped in 3.0.';
446
447 49
        if (method_exists(BaseNode::class, 'getDeprecation')) {
448
            return [
449 49
                'liip/monitor-bundle',
450 49
                '2.13',
451 49
                $message,
452
            ];
453
        }
454
455
        return [$message];
456
    }
457
}
458