Completed
Pull Request — master (#250)
by
unknown
20:15
created

Configuration::createGroupsNode()   F

Complexity

Conditions 40
Paths 2

Size

Total Lines 660

Duplication

Lines 69
Ratio 10.45 %

Code Coverage

Tests 298
CRAP Score 40.0284

Importance

Changes 0
Metric Value
dl 69
loc 660
rs 3.3333
c 0
b 0
f 0
ccs 298
cts 306
cp 0.9739
cc 40
nc 2
nop 0
crap 40.0284

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 InvalidArgumentException;
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 49
     */
25
    public function getConfigTreeBuilder()
26 49
    {
27
        $treeBuilder = new TreeBuilder('liip_monitor');
28
29 49
        // Keep compatibility with symfony/config < 4.2
30 49
        if (\method_exists($treeBuilder, 'getRootNode')) {
31
            $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 49
        $rootNode
37
            ->beforeNormalization()
38 49
                ->always(function ($v) {
39 49
                    if (empty($v['default_group'])) {
40
                        $v['default_group'] = 'default';
41
                    }
42 49
43 40
                    if (isset($v['checks']) && is_array($v['checks']) && !isset($v['checks']['groups'])) {
44 40
                        $checks = $v['checks'];
45
                        unset($v['checks']);
46 40
47
                        $v['checks']['groups'][$v['default_group']] = $checks;
48
                    }
49 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
                                ->ifString()
68 49
                                ->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
        ->end();
85 49
86
        return $treeBuilder;
87
    }
88 49
89
    private function createGroupsNode()
90 49
    {
91
        $builder = new TreeBuilder('groups');
92
93 49
        // Keep compatibility with symfony/config < 4.2
94 49
        if (\method_exists($builder, 'getRootNode')) {
95
            $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 49
        $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('[apc, xdebug]')
108 49
                        ->prototype('variable')
109 49
                            ->beforeNormalization()
110 49
                                ->ifString()
111 49
                                ->then(function ($value) { return ['name' => $value]; })
112 49
                            ->end()
113 49
                            ->validate()
114 49
                                ->ifArray()
115 49
                                ->then(function ($value) {
116 49
                                    if (!isset($value['name'])) {
117 49
                                        throw new InvalidArgumentException('You should define an extension name');
118 49
                                    }
119 49
120 49
                                    return $value;
121 49
                                })
122 49
                            ->end()
123 49
                        ->end()
124 49
                    ->end()
125 49
                    ->arrayNode('php_flags')
126 49
                        ->info('Pairs of a PHP setting and an expected value')
127 49
                        ->example('session.use_only_cookies: false')
128 49
                        ->useAttributeAsKey('setting')
129 49
                        ->beforeNormalization()
130 49
                            ->always()
131 49
                            ->then(function ($flags) {
132 49
                                foreach ($flags as $flagName => $flagValue) {
133 49
                                    if (is_scalar($flagValue)) {
134 49
                                        $flags[$flagName] = [
135 49
                                            'value' => $flagValue,
136 49
                                        ];
137 49
                                    }
138 49
                                }
139 49
140 49
                                return $flags;
141 49
                            })
142 49
                        ->end()
143 49
                        ->prototype('variable')
144 49
                            ->validate()
145 49
                                ->ifArray()
146 49
                                ->then(function ($value) {
147 49
                                    if (!isset($value['value'])) {
148 49
                                        throw new InvalidArgumentException('You should define a value of php flag');
149 49
                                    }
150 49
151 49
                                    return $value;
152 49
                                })
153 49
                            ->end()
154 49
                        ->end()
155 49
                    ->end()
156 49
                    ->arrayNode('php_version')
157 49
                        ->info('Pairs of a version and a comparison operator')
158 49
                        ->example('5.4.15: >=')
159 49
                        ->useAttributeAsKey('version')
160 49
                        ->beforeNormalization()
161 49
                            ->always()
162 49
                            ->then(function ($versions) {
163 49
                                foreach ($versions as $version => $value) {
164 49
                                    if (is_scalar($value)) {
165 49
                                        $versions[$version] = [
166 49
                                            'operator' => $value,
167 49
                                        ];
168 49
                                    }
169 49
                                }
170 49
171 49
                                return $versions;
172 49
                            })
173 49
                        ->end()
174 49
                        ->prototype('variable')
175 49
                            ->validate()
176 49
                                ->ifArray()
177 49
                                ->then(function ($value) {
178 49
                                    if (!isset($value['operator'])) {
179 49
                                        throw new InvalidArgumentException('You should define a comparison operator');
180 49
                                    }
181 49
182 49
                                    return $value;
183 49
                                })
184 49
                            ->end()
185 49
                        ->end()
186 49
                    ->end()
187 49
                    ->variableNode('process_running')
188 49
                        ->info('Process name/pid or an array of process names/pids')
189 49
                        ->example('[apache, foo]')
190 49
                        ->beforeNormalization()
191 49
                            ->always()
192 49 View Code Duplication
                            ->then(function ($value) {
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...
193 49
                                if (is_array($value)) {
194 49
                                    foreach ($value as $key => $process) {
195 49
                                        if (is_scalar($process)) {
196 49
                                            $value[$key] = [
197 49
                                                'name' => $process,
198 49
                                            ];
199 49
                                        }
200 49
                                    }
201 49
                                } else {
202 49
                                    $value = [
203 49
                                        ['name' => $value],
204 49
                                    ];
205
                                }
206
207
                                return $value;
208
                            })
209
                        ->end()
210
                        ->validate()
211 49
                            ->always()
212 49
                            ->then(function ($value) {
213 49
                                foreach ($value as $process) {
214
                                    if (!isset($process['name'])) {
215
                                        throw new InvalidArgumentException('You should define a process name');
216
                                    }
217
                                }
218
219
                                return $value;
220 49
                            })
221 49
                        ->end()
222 49
                    ->end()
223 49
                    ->arrayNode('readable_directory')
224
                        ->info('Validate that a given path (or a collection of paths) is a dir and is readable')
225
                        ->example('["%kernel.cache_dir%"]')
226 49
                        ->prototype('variable')
227
                            ->beforeNormalization()
228
                                ->ifString()
229
                                ->then(function ($value) { return ['path' => $value]; })
230
                            ->end()
231
                            ->validate()
232
                                ->ifArray()
233
                                ->then(function ($value) {
234
                                    if (!isset($value['path'])) {
235 49
                                        throw new InvalidArgumentException('You should define a directory path');
236 49
                                    }
237 49
238 49
                                    return $value;
239 49
                                })
240 49
                            ->end()
241 49
                        ->end()
242 49
                    ->end()
243 49
                    ->arrayNode('writable_directory')
244 49
                        ->info('Validate that a given path (or a collection of paths) is a dir and is writable')
245 49
                        ->example('["%kernel.cache_dir%"]')
246 49
                        ->prototype('variable')
247 49
                            ->beforeNormalization()
248 49
                                ->ifString()
249 49
                                ->then(function ($value) { return ['path' => $value]; })
250 49
                            ->end()
251 49
                            ->validate()
252 49
                                ->ifArray()
253 49
                                ->then(function ($value) {
254 49
                                    if (!isset($value['path'])) {
255 49
                                        throw new InvalidArgumentException('You should define a directory path');
256 49
                                    }
257 49
258 49
                                    return $value;
259 49
                                })
260 49
                            ->end()
261
                        ->end()
262 49
                    ->end()
263 49
                    ->arrayNode('class_exists')
264 49
                        ->info('Validate that a class or a collection of classes is available')
265 49
                        ->example('["Lua", "My\Fancy\Class"]')
266 49
                        ->prototype('variable')
267 49
                            ->beforeNormalization()
268 49
                                ->ifString()
269 49
                                ->then(function ($value) { return ['name' => $value]; })
270 49
                            ->end()
271 49
                            ->validate()
272 49
                                ->ifArray()
273 49
                                ->then(function ($value) {
274 49
                                    if (!isset($value['name'])) {
275 49
                                        throw new InvalidArgumentException('You should define a class name');
276 49
                                    }
277 49
278 49
                                    return $value;
279 49
                                })
280 49
                            ->end()
281 49
                        ->end()
282 49
                    ->end()
283 49
                    ->variableNode('cpu_performance')
284 49
                        ->info('Benchmark CPU performance and return failure if it is below the given ratio')
285 49
                        ->example('1.0 # This is the power of an EC2 micro instance')
286 49
                        ->beforeNormalization()
287 49
                            ->always()
288 49
                            ->then(function ($value) {
289 49
                                if (!is_array($value)) {
290 49
                                    $value = ['performance' => $value];
291 49
                                }
292 49
293 49
                                return $value;
294 49
                            })
295 49
                        ->end()
296 49
                        ->validate()
297 49
                            ->ifArray()
298 49
                            ->then(function ($value) {
299 49
                                if (!isset($value['performance'])) {
300 49
                                    throw new InvalidArgumentException('You should define performance value');
301 49
                                }
302 49
303 49
                                return $value;
304 49
                            })
305
                        ->end()
306 49
                    ->end()
307 49
                    ->arrayNode('disk_usage')
308 49
                        ->info('Checks to see if the disk usage is below warning/critical percent thresholds')
309 49
                        ->children()
310 49
                            ->integerNode('warning')->defaultValue(70)->end()
311 49
                            ->integerNode('critical')->defaultValue(90)->end()
312 49
                            ->scalarNode('path')->defaultValue('%kernel.cache_dir%')->end()
313 49
                            ->scalarNode('label')->defaultNull()->end()
314 49
                        ->end()
315 49
                    ->end()
316 49
                    ->arrayNode('symfony_requirements')
317 49
                        ->info('Checks Symfony2 requirements file')
318 49
                        ->children()
319 49
                            ->scalarNode('file')->defaultValue('%kernel.root_dir%/SymfonyRequirements.php')->end()
320 49
                            ->scalarNode('label')->defaultNull()->end()
321 49
                        ->end()
322 49
                    ->end()
323 49
                    ->arrayNode('opcache_memory')
324 49
                        ->info('Checks to see if the OpCache memory usage is below warning/critical thresholds')
325 49
                        ->children()
326 49
                            ->integerNode('warning')->defaultValue(70)->end()
327 49
                            ->integerNode('critical')->defaultValue(90)->end()
328 49
                            ->scalarNode('label')->defaultNull()->end()
329 49
                        ->end()
330 49
                    ->end()
331 49
                    ->arrayNode('apc_memory')
332 49
                        ->info('Checks to see if the APC memory usage is below warning/critical thresholds')
333 49
                        ->children()
334 49
                            ->integerNode('warning')->defaultValue(70)->end()
335 49
                            ->integerNode('critical')->defaultValue(90)->end()
336 49
                            ->scalarNode('label')->defaultNull()->end()
337 49
                        ->end()
338 49
                    ->end()
339 49
                    ->arrayNode('apc_fragmentation')
340 49
                        ->info('Checks to see if the APC fragmentation is below warning/critical thresholds')
341 49
                        ->children()
342 49
                            ->integerNode('warning')->defaultValue(70)->end()
343 49
                            ->integerNode('critical')->defaultValue(90)->end()
344 49
                            ->scalarNode('label')->defaultNull()->end()
345 49
                        ->end()
346 49
                    ->end()
347 49
                    ->variableNode('doctrine_dbal')
348 49
                        ->defaultNull()
349 49
                        ->info('Connection name or an array of connection names')
350 49
                        ->example('[default, crm]')
351 49
                        ->beforeNormalization()
352 49
                            ->always()
353 49 View Code Duplication
                            ->then(function ($value) {
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...
354 49
                                if (is_array($value)) {
355 49
                                    foreach ($value as $key => $connection) {
356 49
                                        if (is_scalar($connection)) {
357 49
                                            $value[$key] = [
358 49
                                                'name' => $connection,
359 49
                                            ];
360 49
                                        }
361 49
                                    }
362 49
                                } else {
363 49
                                    $value = [
364 49
                                        ['name' => $value],
365 49
                                    ];
366 49
                                }
367 49
368 49
                                return $value;
369 49
                            })
370 49
                        ->end()
371 49
                        ->validate()
372 49
                            ->ifArray()
373 49 View Code Duplication
                            ->then(function ($value) {
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...
374 49
                                foreach ($value as $connection) {
375 49
                                    if (!isset($connection['name'])) {
376 49
                                        throw new InvalidArgumentException('You should define connection name');
377 49
                                    }
378 49
                                }
379 49
380 49
                                return $value;
381 49
                            })
382 49
                        ->end()
383 49
                    ->end()
384 49
                    ->variableNode('doctrine_mongodb')
385 49
                        ->defaultNull()
386 49
                        ->info('Connection name or an array of connection names')
387 49
                        ->example('[default, crm]')
388
                        ->beforeNormalization()
389 49
                            ->always()
390 View Code Duplication
                            ->then(function ($value) {
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...
391
                                if (is_array($value)) {
392
                                    foreach ($value as $key => $connection) {
393
                                        if (is_scalar($connection)) {
394
                                            $value[$key] = [
395
                                                'name' => $connection,
396 49
                                            ];
397 49
                                        }
398 49
                                    }
399
                                } else {
400 2
                                    $value = [
401 49
                                        ['name' => $value],
402 49
                                    ];
403 49
                                }
404 49
405 49
                                return $value;
406 49
                            })
407 49
                        ->end()
408 49
                        ->validate()
409 49
                            ->ifArray()
410 49 View Code Duplication
                            ->then(function ($value) {
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...
411 49
                                foreach ($value as $connection) {
412 49
                                    if (!isset($connection['name'])) {
413 49
                                        throw new InvalidArgumentException('You should define connection name');
414 49
                                    }
415 49
                                }
416 49
417 49
                                return $value;
418 49
                            })
419
                        ->end()
420
                    ->end()
421 49
                    ->arrayNode('doctrine_migrations')
422
                        ->useAttributeAsKey('name')
423
                        ->info('Checks to see if migrations from specified configuration file are applied')
424
                        ->prototype('array')
425
                            ->children()
426
                                ->scalarNode('configuration_file')
427
                                    ->info('Absolute path to doctrine migrations configuration')
428
                                ->end()
429
                                ->scalarNode('connection')
430
                                    ->isRequired()
431
                                    ->cannotBeEmpty()
432 49
                                    ->info('Connection name from doctrine DBAL configuration')
433
                                ->end()
434 49
                                ->scalarNode('label')->defaultNull()->end()
435
                            ->end()
436 49
                            ->beforeNormalization()
437
                                ->ifString()
438 49
                                ->then(function ($value) {
439 49
                                    if (is_string($value)) {
440 49
                                        $value = ['connection' => $value];
441
                                    }
442
443
                                    return $value;
444
                                })
445
                            ->end()
446
                            ->validate()
447
                                ->always(function ($value) {
448
                                    if (is_array($value) && !isset($value['configuration_file']) && !class_exists('Doctrine\\Bundle\\MigrationsBundle\\Command\\DoctrineCommand')) {
449
                                        throw new InvalidArgumentException('You should explicitly define "configuration_file" parameter or install doctrine/doctrine-migrations-bundle to use empty parameter.');
450
                                    }
451
452
                                    return $value;
453
                                })
454
                            ->end()
455
                        ->end()
456
                        ->example(
457
                            [
458
                                'application_migrations' => [
459
                                    'configuration_file' => '%kernel.root_dir%/Resources/config/migrations.yml',
460
                                    'connection' => 'default',
461
                                ],
462
                                'migrations_with_doctrine_bundle' => [
463
                                    'connection' => 'default',
464
                                ],
465
                                'migrations_with_doctrine_bundle_v2' => 'default',
466
                            ]
467
                        )
468
                    ->end()
469
                    ->arrayNode('memcache')
470
                        ->info('Check if MemCache extension is loaded and given server is reachable')
471
                        ->useAttributeAsKey('name')
472
                        ->prototype('array')
473
                            ->children()
474
                                ->scalarNode('host')->defaultValue('localhost')->end()
475
                                ->integerNode('port')->defaultValue(11211)->end()
476
                                ->scalarNode('label')->defaultNull()->end()
477
                            ->end()
478
                        ->end()
479
                    ->end()
480
                    ->arrayNode('memcached')
481
                        ->info('Check if MemCached extension is loaded and given server is reachable')
482
                        ->useAttributeAsKey('name')
483
                        ->prototype('array')
484
                            ->children()
485
                                ->scalarNode('host')->defaultValue('localhost')->end()
486
                                ->integerNode('port')->defaultValue(11211)->end()
487
                                ->scalarNode('label')->defaultNull()->end()
488
                            ->end()
489
                        ->end()
490
                    ->end()
491
                    ->arrayNode('redis')
492
                        ->info('Validate that a Redis service is running')
493
                        ->useAttributeAsKey('name')
494
                        ->beforeNormalization()
495
                            ->ifString()
496
                            ->then(function ($v) { return ['dsn' => $v]; })
497
                        ->end()
498
                        ->prototype('array')
499
                            ->children()
500
                                ->scalarNode('host')->defaultValue('localhost')->end()
501
                                ->integerNode('port')->defaultValue(6379)->end()
502
                                ->scalarNode('password')->defaultNull()->end()
503
                                ->scalarNode('dsn')->defaultNull()->end()
504
                                ->scalarNode('label')->defaultNull()->end()
505
                            ->end()
506
                        ->end()
507
                    ->end()
508
                    ->arrayNode('http_service')
509
                        ->info('Attempt connection to given HTTP host and (optionally) check status code and page content')
510
                        ->useAttributeAsKey('name')
511
                        ->prototype('array')
512
                            ->children()
513
                                ->scalarNode('host')->defaultValue('localhost')->end()
514
                                ->integerNode('port')->defaultValue(80)->end()
515
                                ->scalarNode('path')->defaultValue('/')->end()
516
                                ->integerNode('status_code')->defaultValue(200)->end()
517
                                ->scalarNode('content')->defaultNull()->end()
518
                                ->scalarNode('label')->defaultNull()->end()
519
                            ->end()
520
                        ->end()
521
                    ->end()
522
                    ->arrayNode('guzzle_http_service')
523
                        ->info('Attempt connection using Guzzle to given HTTP host and (optionally) check status code and page content')
524
                        ->useAttributeAsKey('name')
525
                        ->prototype('array')
526
                            ->children()
527
                                ->scalarNode('url')->defaultValue('localhost')->end()
528
                                ->variableNode('headers')->defaultValue([])->end()
529
                                ->variableNode('options')->defaultValue([])->end()
530
                                ->integerNode('status_code')->defaultValue(200)->end()
531
                                ->scalarNode('content')->defaultNull()->end()
532
                                ->scalarNode('method')->defaultValue('GET')->end()
533
                                ->scalarNode('body')->defaultNull()->end()
534
                                ->scalarNode('label')->defaultNull()->end()
535
                            ->end()
536
                        ->end()
537
                    ->end()
538
                    ->arrayNode('rabbit_mq')
539
                        ->info('Validate that a RabbitMQ service is running')
540
                        ->useAttributeAsKey('name')
541
                        ->beforeNormalization()
542
                            ->ifString()
543
                            ->then(function ($v) { return ['dsn' => $v]; })
544
                        ->end()
545
                        ->prototype('array')
546
                            ->children()
547
                                ->scalarNode('host')->defaultValue('localhost')->end()
548
                                ->integerNode('port')->defaultValue(5672)->end()
549
                                ->scalarNode('user')->defaultValue('guest')->end()
550
                                ->scalarNode('password')->defaultValue('guest')->end()
551
                                ->scalarNode('vhost')->defaultValue('/')->end()
552
                                ->scalarNode('dsn')->defaultNull()->end()
553
                                ->scalarNode('label')->defaultNull()->end()
554
                            ->end()
555
                        ->end()
556
                    ->end()
557
                    ->variableNode('symfony_version')
558
                        ->info('Checks the version of this app against the latest stable release')
559
                        ->beforeNormalization()
560
                            ->always()
561
                            ->then(function ($value) {
562
                                if (!is_array($value)) {
563
                                    $value = [$value];
564
                                }
565
566
                                return $value;
567
                            })
568
                        ->end()
569
                    ->end()
570
                    ->arrayNode('custom_error_pages')
571
                        ->info('Checks if error pages have been customized for given error codes')
572
                        ->children()
573
                            ->arrayNode('error_codes')
574
                                ->example('[404, 503]')
575
                                ->info('The status codes that should be customized')
576
                                ->isRequired()
577
                                ->requiresAtLeastOneElement()
578
                                ->prototype('scalar')->end()
579
                            ->end()
580
                            ->scalarNode('path')
581
                                ->info('The directory where your custom error page twig templates are located. Keep as "%kernel.project_dir%" to use default location.')
582
                                ->defaultValue('%kernel.project_dir%')
583
                            ->end()
584
                            ->scalarNode('controller')
585
                                ->defaultNull()
586
                                ->setDeprecated(...self::getCustomErrorPagesControllerDeprecationMessage())
587
                            ->end()
588
                            ->scalarNode('label')->defaultNull()->end()
589
                        ->end()
590
                    ->end()
591
                    ->arrayNode('security_advisory')
592
                        ->info('Checks installed composer dependencies against the SensioLabs Security Advisory database')
593
                        ->children()
594
                            ->scalarNode('lock_file')->defaultValue('%kernel.project_dir%/composer.lock')->end()
595
                            ->scalarNode('label')->defaultNull()->end()
596
                        ->end()
597
                    ->end()
598
                    ->arrayNode('stream_wrapper_exists')
599
                        ->info('Validate that a stream wrapper or collection of stream wrappers exists')
600
                        ->example('[\'zlib\', \'bzip2\', \'zip\']')
601
                        ->prototype('variable')
602
                            ->beforeNormalization()
603
                                ->ifString()
604
                                ->then(function ($value) { return ['name' => $value]; })
605
                            ->end()
606
                            ->validate()
607
                                ->ifArray()
608
                                ->then(function ($value) {
609
                                    if (!isset($value['name'])) {
610
                                        throw new InvalidArgumentException('You should define a stream wrapper name');
611
                                    }
612
613
                                    return $value;
614
                                })
615
                            ->end()
616
                        ->end()
617
                    ->end()
618
                    ->arrayNode('file_ini')
619
                        ->info('Find and validate INI files')
620
                        ->example('[\'path/to/my.ini\']')
621
                        ->prototype('variable')
622
                            ->beforeNormalization()
623
                                ->ifString()
624
                                ->then(function ($value) { return ['path' => $value]; })
625
                            ->end()
626
                            ->validate()
627
                                ->ifArray()
628
                                ->then(function ($value) {
629
                                    if (!isset($value['path'])) {
630
                                        throw new InvalidArgumentException('You should define a file path');
631
                                    }
632
633
                                    return $value;
634
                                })
635
                            ->end()
636
                        ->end()
637
                    ->end()
638
                    ->arrayNode('file_json')
639
                        ->info('Find and validate JSON files')
640
                        ->example('[\'path/to/my.json\']')
641
                        ->prototype('variable')
642
                            ->beforeNormalization()
643
                                ->ifString()
644
                                ->then(function ($value) { return ['path' => $value]; })
645
                            ->end()
646
                            ->validate()
647
                                ->ifArray()
648
                                ->then(function ($value) {
649
                                    if (!isset($value['path'])) {
650
                                        throw new InvalidArgumentException('You should define a file path');
651
                                    }
652
653
                                    return $value;
654
                                })
655
                            ->end()
656
                        ->end()
657
                    ->end()
658
                    ->arrayNode('file_xml')
659
                        ->info('Find and validate XML files')
660
                        ->example('[\'path/to/my.xml\']')
661
                        ->prototype('variable')
662
                            ->beforeNormalization()
663
                                ->ifString()
664
                                ->then(function ($value) { return ['path' => $value]; })
665
                            ->end()
666
                            ->validate()
667
                                ->ifArray()
668
                                ->then(function ($value) {
669
                                    if (!isset($value['path'])) {
670
                                        throw new InvalidArgumentException('You should define a file path');
671
                                    }
672
673
                                    return $value;
674
                                })
675
                            ->end()
676
                        ->end()
677
                    ->end()
678
                    ->arrayNode('file_yaml')
679
                        ->info('Find and validate YAML files')
680
                        ->example('[\'path/to/my.yml\']')
681
                        ->prototype('variable')
682
                            ->beforeNormalization()
683
                                ->ifString()
684
                                ->then(function ($value) { return ['path' => $value]; })
685
                            ->end()
686
                            ->validate()
687
                                ->ifArray()
688
                                ->then(function ($value) {
689
                                    if (!isset($value['path'])) {
690
                                        throw new InvalidArgumentException('You should define a file path');
691
                                    }
692
693
                                    return $value;
694
                                })
695
                            ->end()
696
                        ->end()
697
                    ->end()
698
                    ->arrayNode('pdo_connections')
699
                        ->info('PDO connections to check for connection')
700
                        ->useAttributeAsKey('name')
701
                        ->prototype('array')
702
                            ->children()
703
                                ->scalarNode('dsn')->defaultNull()->end()
704
                                ->scalarNode('username')->defaultNull()->end()
705
                                ->scalarNode('password')->defaultNull()->end()
706
                                ->integerNode('timeout')->defaultValue(1)->end()
707
                            ->end()
708
                        ->end()
709
                    ->end()
710
                    ->arrayNode('expressions')
711
                        ->useAttributeAsKey('alias')
712
                        ->info('Checks that fail/warn when given expression is false (expressions are evaluated with symfony/expression-language)')
713
                        ->example([
714
                            'opcache' => [
715
                                'label' => 'OPcache',
716
                                'warning_expression' => "ini('opcache.revalidate_freq') > 0",
717
                                'critical_expression' => "ini('opcache.enable')",
718
                                'warning_message' => 'OPcache not optimized for production',
719
                                'critical_message' => 'OPcache not enabled',
720
                            ],
721
                        ])
722
                        ->prototype('array')
723
                            ->addDefaultsIfNotSet()
724
                            ->validate()
725
                                ->ifTrue(function ($value) {
726
                                    return !$value['warning_expression'] && !$value['critical_expression'];
727
                                })
728
                                ->thenInvalid('A warning_expression or a critical_expression must be set.')
729
                            ->end()
730
                            ->children()
731
                                ->scalarNode('label')->isRequired()->end()
732
                                ->scalarNode('warning_expression')
733
                                ->defaultNull()
734
                                ->example('ini(\'apc.stat\') == 0')
735
                            ->end()
736
                            ->scalarNode('critical_expression')
737
                            ->defaultNull()
738
                            ->example('ini(\'short_open_tag\') == 1')
739
                        ->end()
740
                        ->scalarNode('warning_message')->defaultNull()->end()
741
                        ->scalarNode('critical_message')->defaultNull()->end()
742
                    ->end()
743
                ->end()
744
            ->end()
745
        ;
746
747
        return $node;
748
    }
749
750
    /**
751
     * Returns the correct deprecation param's as an array for setDeprecated.
752
     *
753
     * Symfony/Config v5.1 introduces a deprecation notice when calling
754
     * setDeprecation() with less than 3 args and the getDeprecation method was
755
     * introduced at the same time. By checking if getDeprecation() exists,
756
     * we can determine the correct param count to use when calling setDeprecated.
757
     */
758
    private static function getCustomErrorPagesControllerDeprecationMessage()
759
    {
760
        $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.';
761
762
        if (method_exists(BaseNode::class, 'getDeprecation')) {
763
            return [
764
                'liip/monitor-bundle',
765
                '2.13',
766
                $message,
767
            ];
768
        }
769
770
        return [$message];
771
    }
772
}
773