Completed
Push — master ( fb3acb...928588 )
by Christian
02:51 queued 10s
created

Configuration   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 505
Duplicated Lines 4.36 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 97.18%

Importance

Changes 0
Metric Value
wmc 25
lcom 1
cbo 4
dl 22
loc 505
ccs 414
cts 426
cp 0.9718
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B getConfigTreeBuilder() 11 146 4
B addViewSection() 11 85 3
A addBodyListenerSection() 0 40 2
A addFormatListenerSection() 0 53 3
A addVersioningSection() 0 49 3
B addExceptionSection() 0 110 6
A testExceptionExists() 0 6 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
/*
4
 * This file is part of the FOSRestBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\RestBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
use Symfony\Component\Config\Definition\ConfigurationInterface;
17
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
18
use Symfony\Component\HttpFoundation\Response;
19
use Symfony\Component\OptionsResolver\OptionsResolver;
20
use Symfony\Component\Serializer\Encoder\XmlEncoder;
21
22
/**
23
 * This class contains the configuration information for the bundle.
24
 *
25
 * This information is solely responsible for how the different configuration
26
 * sections are normalized, and merged.
27
 *
28
 * @author Lukas Kahwe Smith <[email protected]>
29
 *
30
 * @internal
31
 */
32
final class Configuration implements ConfigurationInterface
33
{
34
    private $debug;
35
36 72
    public function __construct(bool $debug)
37
    {
38 72
        $this->debug = $debug;
39 72
    }
40
41 71
    public function getConfigTreeBuilder(): TreeBuilder
42
    {
43 71
        $treeBuilder = new TreeBuilder('fos_rest');
44
45 71
        $rootNode = $treeBuilder->getRootNode();
46
47
        $rootNode
48 71
            ->children()
49 71
                ->scalarNode('disable_csrf_role')->defaultNull()->end()
50 71
                ->arrayNode('access_denied_listener')
51 71
                    ->canBeEnabled()
52 71
                    ->beforeNormalization()
53 View Code Duplication
                        ->ifArray()->then(function ($v) {
54
                            if (!empty($v) && empty($v['formats'])) {
55
                                unset($v['enabled']);
56
                                $v = ['enabled' => true, 'formats' => $v];
57
                            }
58
59
                            return $v;
60 71
                        })
61 71
                    ->end()
62 71
                    ->fixXmlConfig('format', 'formats')
63 71
                    ->children()
64 71
                        ->scalarNode('service')->defaultNull()->end()
65 71
                        ->arrayNode('formats')
66 71
                            ->useAttributeAsKey('name')
67 71
                            ->prototype('boolean')->end()
68 71
                        ->end()
69 71
                    ->end()
70 71
                ->end()
71 71
                ->scalarNode('unauthorized_challenge')->defaultNull()->end()
72 71
                ->arrayNode('param_fetcher_listener')
73 71
                    ->beforeNormalization()
74 71
                        ->ifString()
75 View Code Duplication
                        ->then(function ($v) {
76 1
                            return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v];
77 71
                        })
78 71
                    ->end()
79 71
                    ->canBeEnabled()
80 71
                    ->children()
81 71
                        ->booleanNode('force')->defaultFalse()->end()
82 71
                        ->scalarNode('service')->defaultNull()->end()
83 71
                    ->end()
84 71
                ->end()
85 71
                ->scalarNode('cache_dir')->cannotBeEmpty()->defaultValue('%kernel.cache_dir%/fos_rest')->end()
86 71
                ->arrayNode('allowed_methods_listener')
87 71
                    ->canBeEnabled()
88 71
                    ->children()
89 71
                        ->scalarNode('service')->defaultNull()->end()
90 71
                    ->end()
91 71
                ->end()
92 71
                ->booleanNode('routing_loader')
93 71
                    ->defaultValue(false)
94 71
                    ->validate()
95 71
                        ->ifTrue()
96 71
                        ->thenInvalid('only "false" is supported')
97 71
                    ->end()
98 71
                ->end()
99 71
                ->arrayNode('body_converter')
100 71
                    ->canBeEnabled()
101 71
                    ->children()
102 71
                        ->scalarNode('validate')
103 71
                            ->defaultFalse()
104 71
                            ->beforeNormalization()
105 71
                                ->ifTrue()
106
                                ->then(function ($value) {
107 1
                                    if (!class_exists(OptionsResolver::class)) {
108
                                        throw new InvalidConfigurationException("'body_converter.validate: true' requires OptionsResolver component installation ( composer require symfony/options-resolver )");
109
                                    }
110
111 1
                                    return $value;
112 71
                                })
113 71
                            ->end()
114 71
                        ->end()
115 71
                        ->scalarNode('validation_errors_argument')->defaultValue('validationErrors')->end()
116 71
                    ->end()
117 71
                ->end()
118 71
                ->arrayNode('service')
119 71
                    ->addDefaultsIfNotSet()
120 71
                    ->children()
121 71
                        ->scalarNode('router')->defaultValue('router')->end()
122 71
                        ->scalarNode('templating')
123 71
                            ->defaultNull()
124 71
                            ->validate()
125 71
                                ->ifString()
126 71
                                ->thenInvalid('only null is supported')
127 71
                            ->end()
128 71
                        ->end()
129 71
                        ->scalarNode('serializer')->defaultNull()->end()
130 71
                        ->scalarNode('view_handler')->defaultValue('fos_rest.view_handler.default')->end()
131 71
                        ->scalarNode('inflector')
132 71
                            ->defaultNull()
133 71
                            ->validate()
134 71
                                ->ifString()
135 71
                                ->thenInvalid('only null is supported')
136 71
                            ->end()
137 71
                        ->end()
138 71
                        ->scalarNode('validator')->defaultValue('validator')->end()
139 71
                    ->end()
140 71
                ->end()
141 71
                ->arrayNode('serializer')
142 71
                    ->addDefaultsIfNotSet()
143 71
                    ->children()
144 71
                        ->scalarNode('version')->defaultNull()->end()
145 71
                        ->arrayNode('groups')
146 71
                            ->prototype('scalar')->end()
147 71
                        ->end()
148 71
                        ->booleanNode('serialize_null')->defaultFalse()->end()
149 71
                    ->end()
150 71
                ->end()
151 71
                ->arrayNode('zone')
152 71
                    ->cannotBeOverwritten()
153 71
                    ->prototype('array')
154 71
                    ->fixXmlConfig('ip')
155 71
                    ->children()
156 71
                        ->scalarNode('path')
157 71
                            ->defaultNull()
158 71
                            ->info('use the urldecoded format')
159 71
                            ->example('^/path to resource/')
160 71
                        ->end()
161 71
                        ->scalarNode('host')->defaultNull()->end()
162 71
                        ->arrayNode('methods')
163
                            ->beforeNormalization()->ifString()->then(function ($v) {
164
                                return preg_split('/\s*,\s*/', $v);
165 71
                            })->end()
166 71
                            ->prototype('scalar')->end()
167 71
                        ->end()
168 71
                        ->arrayNode('ips')
169
                            ->beforeNormalization()->ifString()->then(function ($v) {
170 1
                                return array($v);
171 71
                            })->end()
172 71
                            ->prototype('scalar')->end()
173 71
                        ->end()
174 71
                    ->end()
175 71
                ->end()
176 71
            ->end()
177 71
        ->end();
178
179 71
        $this->addViewSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
180 71
        $this->addExceptionSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
181 71
        $this->addBodyListenerSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
182 71
        $this->addFormatListenerSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
183 71
        $this->addVersioningSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
184
185 71
        return $treeBuilder;
186
    }
187
188 71
    private function addViewSection(ArrayNodeDefinition $rootNode): void
189
    {
190
        $rootNode
191 71
            ->children()
192 71
                ->arrayNode('view')
193 71
                    ->fixXmlConfig('format', 'formats')
194 71
                    ->fixXmlConfig('mime_type', 'mime_types')
195 71
                    ->fixXmlConfig('force_redirect', 'force_redirects')
196 71
                    ->addDefaultsIfNotSet()
197 71
                    ->children()
198 71
                        ->scalarNode('default_engine')
199 71
                            ->defaultNull()
200 71
                            ->validate()
201 71
                                ->ifString()
202 71
                                ->thenInvalid('only null is supported')
203 71
                            ->end()
204 71
                        ->end()
205 71
                        ->arrayNode('force_redirects')
206 71
                            ->useAttributeAsKey('name')
207 71
                            ->defaultValue([])
208 71
                            ->validate()
209
                                ->ifTrue(function ($v) { return [] !== $v; })
210 71
                                ->thenInvalid('only the empty array is supported')
211 71
                            ->end()
212 71
                            ->prototype('boolean')->end()
213 71
                        ->end()
214 71
                        ->arrayNode('mime_types')
215 71
                            ->canBeEnabled()
216 71
                            ->beforeNormalization()
217 View Code Duplication
                                ->ifArray()->then(function ($v) {
218 1
                                    if (!empty($v) && empty($v['formats'])) {
219 1
                                        unset($v['enabled']);
220 1
                                        $v = ['enabled' => true, 'formats' => $v];
221
                                    }
222
223 1
                                    return $v;
224 71
                                })
225 71
                            ->end()
226 71
                            ->fixXmlConfig('format', 'formats')
227 71
                            ->children()
228 71
                                ->scalarNode('service')->defaultNull()->end()
229 71
                                ->arrayNode('formats')
230 71
                                    ->useAttributeAsKey('name')
231 71
                                    ->prototype('array')
232 71
                                        ->beforeNormalization()
233 71
                                            ->ifString()
234
                                            ->then(function ($v) { return array($v); })
235 71
                                        ->end()
236 71
                                        ->prototype('scalar')->end()
237 71
                                    ->end()
238 71
                                ->end()
239 71
                            ->end()
240 71
                        ->end()
241 71
                        ->arrayNode('formats')
242 71
                            ->useAttributeAsKey('name')
243 71
                            ->defaultValue(['json' => true, 'xml' => true])
244 71
                            ->prototype('boolean')->end()
245 71
                        ->end()
246 71
                        ->arrayNode('view_response_listener')
247 71
                            ->beforeNormalization()
248 71
                                ->ifString()
249 View Code Duplication
                                ->then(function ($v) {
250 6
                                    return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v];
251 71
                                })
252 71
                            ->end()
253 71
                            ->canBeEnabled()
254 71
                            ->children()
255 71
                                ->booleanNode('force')->defaultFalse()->end()
256 71
                                ->scalarNode('service')->defaultNull()->end()
257 71
                            ->end()
258 71
                        ->end()
259 71
                        ->scalarNode('failed_validation')->defaultValue(Response::HTTP_BAD_REQUEST)->end()
260 71
                        ->scalarNode('empty_content')->defaultValue(Response::HTTP_NO_CONTENT)->end()
261 71
                        ->booleanNode('serialize_null')->defaultFalse()->end()
262 71
                        ->arrayNode('jsonp_handler')
263 71
                            ->canBeUnset()
264 71
                            ->children()
265 71
                                ->scalarNode('callback_param')->defaultValue('callback')->end()
266 71
                                ->scalarNode('mime_type')->defaultValue('application/javascript+jsonp')->end()
267 71
                            ->end()
268 71
                        ->end()
269 71
                    ->end()
270 71
                ->end()
271 71
            ->end();
272 71
    }
273
274 71
    private function addBodyListenerSection(ArrayNodeDefinition $rootNode): void
275
    {
276 71
        $decodersDefaultValue = ['json' => 'fos_rest.decoder.json'];
277 71
        if (class_exists(XmlEncoder::class)) {
278 71
            $decodersDefaultValue['xml'] = 'fos_rest.decoder.xml';
279
        }
280
        $rootNode
281 71
            ->children()
282 71
                ->arrayNode('body_listener')
283 71
                    ->fixXmlConfig('decoder', 'decoders')
284 71
                    ->addDefaultsIfNotSet()
285 71
                    ->canBeUnset()
286 71
                    ->canBeDisabled()
287 71
                    ->children()
288 71
                        ->scalarNode('service')->defaultNull()->end()
289 71
                        ->scalarNode('default_format')->defaultNull()->end()
290 71
                        ->booleanNode('throw_exception_on_unsupported_content_type')
291 71
                            ->defaultFalse()
292 71
                        ->end()
293 71
                        ->arrayNode('decoders')
294 71
                            ->useAttributeAsKey('name')
295 71
                            ->defaultValue($decodersDefaultValue)
296 71
                            ->prototype('scalar')->end()
297 71
                        ->end()
298 71
                        ->arrayNode('array_normalizer')
299 71
                            ->addDefaultsIfNotSet()
300 71
                            ->beforeNormalization()
301
                                ->ifString()->then(function ($v) {
302 1
                                    return ['service' => $v];
303 71
                                })
304 71
                            ->end()
305 71
                            ->children()
306 71
                                ->scalarNode('service')->defaultNull()->end()
307 71
                                ->booleanNode('forms')->defaultFalse()->end()
308 71
                            ->end()
309 71
                        ->end()
310 71
                    ->end()
311 71
                ->end()
312 71
            ->end();
313 71
    }
314
315 71
    private function addFormatListenerSection(ArrayNodeDefinition $rootNode): void
316
    {
317
        $rootNode
318 71
            ->children()
319 71
                ->arrayNode('format_listener')
320 71
                    ->fixXmlConfig('rule', 'rules')
321 71
                    ->addDefaultsIfNotSet()
322 71
                    ->canBeUnset()
323 71
                    ->beforeNormalization()
324
                        ->ifTrue(function ($v) {
325
                            // check if we got an assoc array in rules
326 6
                            return isset($v['rules'])
327 6
                                && is_array($v['rules'])
328 6
                                && array_keys($v['rules']) !== range(0, count($v['rules']) - 1);
329 71
                        })
330
                        ->then(function ($v) {
331 1
                            $v['rules'] = [$v['rules']];
332
333 1
                            return $v;
334 71
                        })
335 71
                    ->end()
336 71
                    ->canBeEnabled()
337 71
                    ->children()
338 71
                        ->scalarNode('service')->defaultNull()->end()
339 71
                        ->arrayNode('rules')
340 71
                            ->performNoDeepMerging()
341 71
                            ->prototype('array')
342 71
                                ->fixXmlConfig('priority', 'priorities')
343 71
                                ->fixXmlConfig('attribute', 'attributes')
344 71
                                ->children()
345 71
                                    ->scalarNode('path')->defaultNull()->info('URL path info')->end()
346 71
                                    ->scalarNode('host')->defaultNull()->info('URL host name')->end()
347 71
                                    ->variableNode('methods')->defaultNull()->info('Method for URL')->end()
348 71
                                    ->arrayNode('attributes')
349 71
                                        ->useAttributeAsKey('name')
350 71
                                        ->prototype('variable')->end()
351 71
                                    ->end()
352 71
                                    ->booleanNode('stop')->defaultFalse()->end()
353 71
                                    ->booleanNode('prefer_extension')->defaultTrue()->end()
354 71
                                    ->scalarNode('fallback_format')->defaultValue('html')->end()
355 71
                                    ->arrayNode('priorities')
356
                                        ->beforeNormalization()->ifString()->then(function ($v) {
357
                                            return preg_split('/\s*,\s*/', $v);
358 71
                                        })->end()
359 71
                                        ->prototype('scalar')->end()
360 71
                                    ->end()
361 71
                                ->end()
362 71
                            ->end()
363 71
                        ->end()
364 71
                    ->end()
365 71
                ->end()
366 71
            ->end();
367 71
    }
368
369 71
    private function addVersioningSection(ArrayNodeDefinition $rootNode): void
370
    {
371
        $rootNode
372 71
        ->children()
373 71
            ->arrayNode('versioning')
374 71
                ->canBeEnabled()
375 71
                ->children()
376 71
                    ->scalarNode('default_version')->defaultNull()->end()
377 71
                    ->arrayNode('resolvers')
378 71
                        ->addDefaultsIfNotSet()
379 71
                        ->children()
380 71
                            ->arrayNode('query')
381 71
                                ->canBeDisabled()
382 71
                                ->children()
383 71
                                    ->scalarNode('parameter_name')->defaultValue('version')->end()
384 71
                                ->end()
385 71
                            ->end()
386 71
                            ->arrayNode('custom_header')
387 71
                                ->canBeDisabled()
388 71
                                ->children()
389 71
                                    ->scalarNode('header_name')->defaultValue('X-Accept-Version')->end()
390 71
                                ->end()
391 71
                            ->end()
392 71
                            ->arrayNode('media_type')
393 71
                                ->canBeDisabled()
394 71
                                ->children()
395 71
                                    ->scalarNode('regex')->defaultValue('/(v|version)=(?P<version>[0-9\.]+)/')->end()
396 71
                                ->end()
397 71
                            ->end()
398 71
                        ->end()
399 71
                    ->end()
400 71
                    ->arrayNode('guessing_order')
401 71
                        ->defaultValue(['query', 'custom_header', 'media_type'])
402 71
                        ->validate()
403
                            ->ifTrue(function ($v) {
404
                                foreach ($v as $resolver) {
405
                                    if (!in_array($resolver, ['query', 'custom_header', 'media_type'])) {
406
                                        return true;
407
                                    }
408
                                }
409 71
                            })
410 71
                            ->thenInvalid('Versioning guessing order can only contain "query", "custom_header", "media_type".')
411 71
                        ->end()
412 71
                        ->prototype('scalar')->end()
413 71
                    ->end()
414 71
                ->end()
415 71
            ->end()
416 71
        ->end();
417 71
    }
418
419 71
    private function addExceptionSection(ArrayNodeDefinition $rootNode): void
420
    {
421
        $rootNode
422 71
            ->children()
423 71
                ->arrayNode('exception')
424 71
                    ->fixXmlConfig('code', 'codes')
425 71
                    ->fixXmlConfig('message', 'messages')
426 71
                    ->addDefaultsIfNotSet()
427 71
                    ->canBeEnabled()
428 71
                    ->children()
429 71
                        ->booleanNode('map_exception_codes')
430 71
                            ->defaultFalse()
431 71
                            ->info('Enables an event listener that maps exception codes to response status codes based on the map configured with the "fos_rest.exception.codes" option.')
432 71
                        ->end()
433 71
                        ->booleanNode('exception_listener')
434
                            ->defaultValue(function () {
435 9
                                @trigger_error('Enabling the "fos_rest.exception.exception_listener" option is deprecated since FOSRestBundle 2.8.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
436
437 9
                                return true;
438 71
                            })
439 71
                            ->beforeNormalization()
440 71
                                ->ifTrue()
441
                                ->then(function ($v) {
442
                                    @trigger_error('Enabling the "fos_rest.exception.exception_listener" option is deprecated since FOSRestBundle 2.8.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
443
444
                                    return $v;
445 71
                                })
446 71
                            ->end()
447 71
                        ->end()
448 71
                        ->scalarNode('exception_controller')
449 71
                            ->defaultNull()
450 71
                            ->setDeprecated('The "%path%.%node%" option is deprecated since FOSRestBundle 2.8.')
451 71
                        ->end()
452 71
                        ->booleanNode('serialize_exceptions')
453
                            ->defaultValue(function () {
454 3
                                @trigger_error('Enabling the "fos_rest.exception.serialize_exceptions" option is deprecated since FOSRestBundle 2.8.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
455
456 3
                                return true;
457 71
                            })
458 71
                            ->beforeNormalization()
459 71
                                ->ifTrue()
460
                                ->then(function ($v) {
461 8
                                    @trigger_error('Enabling the "fos_rest.exception.serialize_exceptions" option is deprecated since FOSRestBundle 2.8.', E_USER_DEPRECATED);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
462
463 8
                                    return $v;
464 71
                                })
465 71
                            ->end()
466 71
                        ->end()
467 71
                        ->enumNode('flatten_exception_format')
468 71
                            ->defaultValue('legacy')
469 71
                            ->values(['legacy', 'rfc7807'])
470 71
                        ->end()
471 71
                        ->scalarNode('service')
472 71
                            ->defaultNull()
473 71
                            ->setDeprecated('The "%path%.%node%" option is deprecated since FOSRestBundle 2.8.')
474 71
                        ->end()
475 71
                        ->arrayNode('codes')
476 71
                            ->useAttributeAsKey('name')
477 71
                            ->beforeNormalization()
478 71
                                ->ifArray()
479
                                ->then(function (array $items) {
480 13
                                    foreach ($items as &$item) {
481 13
                                        if (is_int($item)) {
482 3
                                            continue;
483
                                        }
484
485 10
                                        if (!defined(sprintf('%s::%s', Response::class, $item))) {
486 9
                                            throw new InvalidConfigurationException(sprintf('Invalid HTTP code in fos_rest.exception.codes, see %s for all valid codes.', Response::class));
487
                                        }
488
489 1
                                        $item = constant(sprintf('%s::%s', Response::class, $item));
490
                                    }
491
492 4
                                    return $items;
493 71
                                })
494 71
                            ->end()
495 71
                            ->prototype('integer')->end()
496
497 71
                            ->validate()
498 71
                            ->ifArray()
499
                                ->then(function (array $items) {
500 4
                                    foreach ($items as $class => $code) {
501 4
                                        $this->testExceptionExists($class);
502
                                    }
503
504 3
                                    return $items;
505 71
                                })
506 71
                            ->end()
507 71
                        ->end()
508 71
                        ->arrayNode('messages')
509 71
                            ->useAttributeAsKey('name')
510 71
                            ->prototype('boolean')->end()
511 71
                            ->validate()
512 71
                                ->ifArray()
513
                                ->then(function (array $items) {
514 12
                                    foreach ($items as $class => $nomatter) {
515 12
                                        $this->testExceptionExists($class);
516
                                    }
517
518 11
                                    return $items;
519 71
                                })
520 71
                            ->end()
521 71
                        ->end()
522 71
                        ->booleanNode('debug')
523 71
                            ->defaultValue($this->debug)
524 71
                        ->end()
525 71
                    ->end()
526 71
                ->end()
527 71
            ->end();
528 71
    }
529
530 16
    private function testExceptionExists(string $exception): void
531
    {
532 16
        if (!is_subclass_of($exception, \Exception::class) && !is_a($exception, \Exception::class, true)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Exception::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
533 2
            throw new InvalidConfigurationException(sprintf('FOSRestBundle exception mapper: Could not load class "%s" or the class does not extend from "%s". Most probably this is a configuration problem.', $exception, \Exception::class));
534
        }
535 14
    }
536
}
537