Completed
Push — 2.x ( 046d38...36b044 )
by Christian
03:55 queued 12s
created

Configuration::addViewSection()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 96

Duplication

Lines 11
Ratio 11.46 %

Code Coverage

Tests 82
CRAP Score 3.0001

Importance

Changes 0
Metric Value
dl 11
loc 96
ccs 82
cts 84
cp 0.9762
rs 8.0872
c 0
b 0
f 0
cc 3
nc 1
nop 1
crap 3.0001

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
/*
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
    /**
35
     * Default debug mode value.
36
     *
37
     * @var bool
38
     */
39
    private $debug;
40
41 83
    public function __construct(bool $debug)
42
    {
43 83
        $this->debug = $debug;
44 83
    }
45
46 82
    public function getConfigTreeBuilder(): TreeBuilder
47
    {
48 82
        $treeBuilder = new TreeBuilder('fos_rest');
49
50 82
        if (method_exists($treeBuilder, 'getRootNode')) {
51 82
            $rootNode = $treeBuilder->getRootNode();
52
        } else {
53
            $rootNode = $treeBuilder->root('fos_rest');
0 ignored issues
show
Deprecated Code introduced by
The method Symfony\Component\Config...der\TreeBuilder::root() has been deprecated with message: since Symfony 4.3, pass the root name to the constructor instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
54
        }
55
56
        $rootNode
57 82
            ->children()
58 82
                ->scalarNode('disable_csrf_role')->defaultNull()->end()
59 82
                ->arrayNode('access_denied_listener')
60 82
                    ->canBeEnabled()
61 82
                    ->beforeNormalization()
62 View Code Duplication
                        ->ifArray()->then(function ($v) {
63
                            if (!empty($v) && empty($v['formats'])) {
64
                                unset($v['enabled']);
65
                                $v = ['enabled' => true, 'formats' => $v];
66
                            }
67
68
                            return $v;
69 82
                        })
70 82
                    ->end()
71 82
                    ->fixXmlConfig('format', 'formats')
72 82
                    ->children()
73 82
                        ->scalarNode('service')->defaultNull()->end()
74 82
                        ->arrayNode('formats')
75 82
                            ->useAttributeAsKey('name')
76 82
                            ->prototype('boolean')->end()
77 82
                        ->end()
78 82
                    ->end()
79 82
                ->end()
80 82
                ->scalarNode('unauthorized_challenge')->defaultNull()->end()
81 82
                ->arrayNode('param_fetcher_listener')
82 82
                    ->beforeNormalization()
83 82
                        ->ifString()
84 View Code Duplication
                        ->then(function ($v) {
85 1
                            return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v];
86 82
                        })
87 82
                    ->end()
88 82
                    ->canBeEnabled()
89 82
                    ->children()
90 82
                        ->booleanNode('force')->defaultFalse()->end()
91 82
                        ->scalarNode('service')->defaultNull()->end()
92 82
                    ->end()
93 82
                ->end()
94 82
                ->scalarNode('cache_dir')->cannotBeEmpty()->defaultValue('%kernel.cache_dir%/fos_rest')->end()
95 82
                ->arrayNode('allowed_methods_listener')
96 82
                    ->canBeEnabled()
97 82
                    ->children()
98 82
                        ->scalarNode('service')->defaultNull()->end()
99 82
                    ->end()
100 82
                ->end()
101 82
                ->arrayNode('routing_loader')
102 82
                    ->addDefaultsIfNotSet()
103 82
                    ->beforeNormalization()
104
                        ->ifTrue(function ($v) { return isset($v['enabled']) && false !== $v['enabled']; })
105
                        ->then(function ($v) {
106
                            @trigger_error('Enabling the route generation feature 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...
107
108
                            return $v;
109 82
                        })
110 82
                    ->end()
111 82
                    ->beforeNormalization()
112
                        ->ifTrue(function ($v) { return is_bool($v); })
113
                        ->then(function ($v) {
114
                            return [
115 65
                                'enabled' => $v,
116
                            ];
117 82
                        })
118 82
                    ->end()
119 82
                    ->children()
120 82
                        ->booleanNode('enabled')
121
                            ->defaultValue(function () {
122 6
                                @trigger_error('Enabling the route generation feature 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...
123
124 6
                                return true;
125 82
                            })
126 82
                        ->end()
127 82
                        ->scalarNode('default_format')->defaultNull()->end()
128 82
                        ->scalarNode('prefix_methods')->defaultTrue()->end()
129 82
                        ->scalarNode('include_format')->defaultTrue()->end()
130 82
                    ->end()
131 82
                ->end()
132 82
                ->arrayNode('body_converter')
133 82
                    ->canBeEnabled()
134 82
                    ->children()
135 82
                        ->scalarNode('validate')
136 82
                            ->defaultFalse()
137 82
                            ->beforeNormalization()
138 82
                                ->ifTrue()
139
                                ->then(function ($value) {
140 3
                                    if (!class_exists(OptionsResolver::class)) {
141
                                        throw new InvalidConfigurationException("'body_converter.validate: true' requires OptionsResolver component installation ( composer require symfony/options-resolver )");
142
                                    }
143
144 3
                                    return $value;
145 82
                                })
146 82
                            ->end()
147 82
                        ->end()
148 82
                        ->scalarNode('validation_errors_argument')->defaultValue('validationErrors')->end()
149 82
                    ->end()
150 82
                ->end()
151 82
                ->arrayNode('service')
152 82
                    ->addDefaultsIfNotSet()
153 82
                    ->children()
154 82
                        ->scalarNode('router')->defaultValue('router')->setDeprecated('The "%path%.%node%" configuration key has been deprecated in FOSRestBundle 2.8.')->end()
155 82
                        ->scalarNode('templating')
156
                            ->defaultValue(static function () {
157 5
                                @trigger_error('Not setting the "fos_rest.service.templating" configuration option to "null" 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...
158
159 5
                                return 'templating';
160 82
                            })
161 82
                            ->validate()
162
                                ->ifTrue(static function ($v) { return $v; })
163
                                ->then(static function ($v) {
164
                                    @trigger_error('Not setting the "fos_rest.service.templating" configuration option to "null" 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...
165
166
                                    return $v;
167 82
                                })
168 82
                            ->end()
169 82
                        ->end()
170 82
                        ->scalarNode('serializer')->defaultNull()->end()
171 82
                        ->scalarNode('view_handler')->defaultValue('fos_rest.view_handler.default')->end()
172 82
                        ->scalarNode('inflector')
173
                            ->defaultValue(static function () {
174
                                @trigger_error('Not setting the "fos_rest.service.inflector" configuration option to "null" 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...
175
176
                                return 'fos_rest.inflector.doctrine';
177 82
                            })
178 82
                            ->defaultValue('fos_rest.inflector.doctrine')
179 82
                        ->end()
180 82
                        ->scalarNode('validator')->defaultValue('validator')->end()
181 82
                    ->end()
182 82
                ->end()
183 82
                ->arrayNode('serializer')
184 82
                    ->addDefaultsIfNotSet()
185 82
                    ->children()
186 82
                        ->scalarNode('version')->defaultNull()->end()
187 82
                        ->arrayNode('groups')
188 82
                            ->prototype('scalar')->end()
189 82
                        ->end()
190 82
                        ->booleanNode('serialize_null')->defaultFalse()->end()
191 82
                    ->end()
192 82
                ->end()
193 82
                ->arrayNode('zone')
194 82
                    ->cannotBeOverwritten()
195 82
                    ->prototype('array')
196 82
                    ->fixXmlConfig('ip')
197 82
                    ->children()
198 82
                        ->scalarNode('path')
199 82
                            ->defaultNull()
200 82
                            ->info('use the urldecoded format')
201 82
                            ->example('^/path to resource/')
202 82
                        ->end()
203 82
                        ->scalarNode('host')->defaultNull()->end()
204 82
                        ->arrayNode('methods')
205
                            ->beforeNormalization()->ifString()->then(function ($v) {
206
                                return preg_split('/\s*,\s*/', $v);
207 82
                            })->end()
208 82
                            ->prototype('scalar')->end()
209 82
                        ->end()
210 82
                        ->arrayNode('ips')
211
                            ->beforeNormalization()->ifString()->then(function ($v) {
212 1
                                return array($v);
213 82
                            })->end()
214 82
                            ->prototype('scalar')->end()
215 82
                        ->end()
216 82
                    ->end()
217 82
                ->end()
218 82
            ->end()
219 82
        ->end();
220
221 82
        $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...
222 82
        $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...
223 82
        $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...
224 82
        $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...
225 82
        $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...
226
227 82
        return $treeBuilder;
228
    }
229
230 82
    private function addViewSection(ArrayNodeDefinition $rootNode)
231
    {
232
        $rootNode
233 82
            ->children()
234 82
                ->arrayNode('view')
235 82
                    ->fixXmlConfig('format', 'formats')
236 82
                    ->fixXmlConfig('mime_type', 'mime_types')
237 82
                    ->fixXmlConfig('templating_format', 'templating_formats')
238 82
                    ->fixXmlConfig('force_redirect', 'force_redirects')
239 82
                    ->addDefaultsIfNotSet()
240 82
                    ->children()
241 82
                        ->scalarNode('default_engine')
242
                            ->defaultValue(static function () {
243 5
                                @trigger_error('Not setting the "fos_rest.view.default_engine" configuration option to "null" 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...
244
245 5
                                return 'twig';
246 82
                            })
247 82
                            ->validate()
248
                                ->ifTrue(static function ($v) { return $v; })
249
                                ->then(static function ($v) {
250
                                    @trigger_error('Not setting the "fos_rest.view.default_engine" configuration option to "null" 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...
251
252
                                    return $v;
253 82
                                })
254 82
                            ->end()
255 82
                        ->end()
256 82
                        ->arrayNode('force_redirects')
257 82
                            ->useAttributeAsKey('name')
258 82
                            ->defaultValue(['html' => true])
259 82
                            ->prototype('boolean')->end()
260 82
                        ->end()
261 82
                        ->arrayNode('mime_types')
262 82
                            ->canBeEnabled()
263 82
                            ->beforeNormalization()
264 View Code Duplication
                                ->ifArray()->then(function ($v) {
265 1
                                    if (!empty($v) && empty($v['formats'])) {
266 1
                                        unset($v['enabled']);
267 1
                                        $v = ['enabled' => true, 'formats' => $v];
268
                                    }
269
270 1
                                    return $v;
271 82
                                })
272 82
                            ->end()
273 82
                            ->fixXmlConfig('format', 'formats')
274 82
                            ->children()
275 82
                                ->scalarNode('service')->defaultNull()->end()
276 82
                                ->arrayNode('formats')
277 82
                                    ->useAttributeAsKey('name')
278 82
                                    ->prototype('array')
279 82
                                        ->beforeNormalization()
280 82
                                            ->ifString()
281
                                            ->then(function ($v) { return array($v); })
282 82
                                        ->end()
283 82
                                        ->prototype('scalar')->end()
284 82
                                    ->end()
285 82
                                ->end()
286 82
                            ->end()
287 82
                        ->end()
288 82
                        ->arrayNode('formats')
289 82
                            ->useAttributeAsKey('name')
290 82
                            ->defaultValue(['json' => true, 'xml' => true])
291 82
                            ->prototype('boolean')->end()
292 82
                        ->end()
293 82
                        ->arrayNode('templating_formats')
294 82
                            ->setDeprecated('The "%path%.%node%" configuration key has been deprecated in FOSRestBundle 2.8.')
295 82
                            ->useAttributeAsKey('name')
296 82
                            ->defaultValue(['html' => true])
297 82
                            ->prototype('boolean')->end()
298 82
                        ->end()
299 82
                        ->arrayNode('view_response_listener')
300 82
                            ->beforeNormalization()
301 82
                                ->ifString()
302 View Code Duplication
                                ->then(function ($v) {
303 9
                                    return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v];
304 82
                                })
305 82
                            ->end()
306 82
                            ->canBeEnabled()
307 82
                            ->children()
308 82
                                ->booleanNode('force')->defaultFalse()->end()
309 82
                                ->scalarNode('service')->defaultNull()->end()
310 82
                            ->end()
311 82
                        ->end()
312 82
                        ->scalarNode('failed_validation')->defaultValue(Response::HTTP_BAD_REQUEST)->end()
313 82
                        ->scalarNode('empty_content')->defaultValue(Response::HTTP_NO_CONTENT)->end()
314 82
                        ->booleanNode('serialize_null')->defaultFalse()->end()
315 82
                        ->arrayNode('jsonp_handler')
316 82
                            ->canBeUnset()
317 82
                            ->children()
318 82
                                ->scalarNode('callback_param')->defaultValue('callback')->end()
319 82
                                ->scalarNode('mime_type')->defaultValue('application/javascript+jsonp')->end()
320 82
                            ->end()
321 82
                        ->end()
322 82
                    ->end()
323 82
                ->end()
324 82
            ->end();
325 82
    }
326
327 82
    private function addBodyListenerSection(ArrayNodeDefinition $rootNode)
328
    {
329 82
        $decodersDefaultValue = ['json' => 'fos_rest.decoder.json'];
330 82
        if (class_exists(XmlEncoder::class)) {
331 82
            $decodersDefaultValue['xml'] = 'fos_rest.decoder.xml';
332
        }
333
        $rootNode
334 82
            ->children()
335 82
                ->arrayNode('body_listener')
336 82
                    ->fixXmlConfig('decoder', 'decoders')
337 82
                    ->addDefaultsIfNotSet()
338 82
                    ->canBeUnset()
339 82
                    ->treatFalseLike(['enabled' => false])
340 82
                    ->treatTrueLike(['enabled' => true])
341 82
                    ->treatNullLike(['enabled' => true])
342 82
                    ->children()
343 82
                        ->booleanNode('enabled')
344
                            ->defaultValue(function () {
345 6
                                @trigger_error('The body_listener config has been enabled by default and will be disabled by default in FOSRestBundle 3.0. Please enable or disable it explicitly.', 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...
346
347 6
                                return true;
348 82
                            })
349 82
                        ->end()
350 82
                        ->scalarNode('service')->defaultNull()->end()
351 82
                        ->scalarNode('default_format')->defaultNull()->end()
352 82
                        ->booleanNode('throw_exception_on_unsupported_content_type')
353 82
                            ->defaultFalse()
354 82
                        ->end()
355 82
                        ->arrayNode('decoders')
356 82
                            ->useAttributeAsKey('name')
357 82
                            ->defaultValue($decodersDefaultValue)
358 82
                            ->prototype('scalar')->end()
359 82
                        ->end()
360 82
                        ->arrayNode('array_normalizer')
361 82
                            ->addDefaultsIfNotSet()
362 82
                            ->beforeNormalization()
363
                                ->ifString()->then(function ($v) {
364 1
                                    return ['service' => $v];
365 82
                                })
366 82
                            ->end()
367 82
                            ->children()
368 82
                                ->scalarNode('service')->defaultNull()->end()
369 82
                                ->booleanNode('forms')->defaultFalse()->end()
370 82
                            ->end()
371 82
                        ->end()
372 82
                    ->end()
373 82
                ->end()
374 82
            ->end();
375 82
    }
376
377 82
    private function addFormatListenerSection(ArrayNodeDefinition $rootNode)
378
    {
379
        $rootNode
380 82
            ->children()
381 82
                ->arrayNode('format_listener')
382 82
                    ->fixXmlConfig('rule', 'rules')
383 82
                    ->addDefaultsIfNotSet()
384 82
                    ->canBeUnset()
385 82
                    ->beforeNormalization()
386
                        ->ifTrue(function ($v) {
387
                            // check if we got an assoc array in rules
388 9
                            return isset($v['rules'])
389 9
                                && is_array($v['rules'])
390 9
                                && array_keys($v['rules']) !== range(0, count($v['rules']) - 1);
391 82
                        })
392
                        ->then(function ($v) {
393 1
                            $v['rules'] = [$v['rules']];
394
395 1
                            return $v;
396 82
                        })
397 82
                    ->end()
398 82
                    ->canBeEnabled()
399 82
                    ->children()
400 82
                        ->scalarNode('service')->defaultNull()->end()
401 82
                        ->arrayNode('rules')
402 82
                            ->performNoDeepMerging()
403 82
                            ->prototype('array')
404 82
                                ->fixXmlConfig('priority', 'priorities')
405 82
                                ->fixXmlConfig('attribute', 'attributes')
406 82
                                ->children()
407 82
                                    ->scalarNode('path')->defaultNull()->info('URL path info')->end()
408 82
                                    ->scalarNode('host')->defaultNull()->info('URL host name')->end()
409 82
                                    ->variableNode('methods')->defaultNull()->info('Method for URL')->end()
410 82
                                    ->arrayNode('attributes')
411 82
                                        ->useAttributeAsKey('name')
412 82
                                        ->prototype('variable')->end()
413 82
                                    ->end()
414 82
                                    ->booleanNode('stop')->defaultFalse()->end()
415 82
                                    ->booleanNode('prefer_extension')->defaultTrue()->end()
416 82
                                    ->scalarNode('fallback_format')->defaultValue('html')->end()
417 82
                                    ->arrayNode('priorities')
418
                                        ->beforeNormalization()->ifString()->then(function ($v) {
419
                                            return preg_split('/\s*,\s*/', $v);
420 82
                                        })->end()
421 82
                                        ->prototype('scalar')->end()
422 82
                                    ->end()
423 82
                                ->end()
424 82
                            ->end()
425 82
                        ->end()
426 82
                    ->end()
427 82
                ->end()
428 82
            ->end();
429 82
    }
430
431 82
    private function addVersioningSection(ArrayNodeDefinition $rootNode)
432
    {
433
        $rootNode
434 82
        ->children()
435 82
            ->arrayNode('versioning')
436 82
                ->canBeEnabled()
437 82
                ->children()
438 82
                    ->scalarNode('default_version')->defaultNull()->end()
439 82
                    ->arrayNode('resolvers')
440 82
                        ->addDefaultsIfNotSet()
441 82
                        ->children()
442 82
                            ->arrayNode('query')
443 82
                                ->canBeDisabled()
444 82
                                ->children()
445 82
                                    ->scalarNode('parameter_name')->defaultValue('version')->end()
446 82
                                ->end()
447 82
                            ->end()
448 82
                            ->arrayNode('custom_header')
449 82
                                ->canBeDisabled()
450 82
                                ->children()
451 82
                                    ->scalarNode('header_name')->defaultValue('X-Accept-Version')->end()
452 82
                                ->end()
453 82
                            ->end()
454 82
                            ->arrayNode('media_type')
455 82
                                ->canBeDisabled()
456 82
                                ->children()
457 82
                                    ->scalarNode('regex')->defaultValue('/(v|version)=(?P<version>[0-9\.]+)/')->end()
458 82
                                ->end()
459 82
                            ->end()
460 82
                        ->end()
461 82
                    ->end()
462 82
                    ->arrayNode('guessing_order')
463 82
                        ->defaultValue(['query', 'custom_header', 'media_type'])
464 82
                        ->validate()
465
                            ->ifTrue(function ($v) {
466
                                foreach ($v as $resolver) {
467
                                    if (!in_array($resolver, ['query', 'custom_header', 'media_type'])) {
468
                                        return true;
469
                                    }
470
                                }
471 82
                            })
472 82
                            ->thenInvalid('Versioning guessing order can only contain "query", "custom_header", "media_type".')
473 82
                        ->end()
474 82
                        ->prototype('scalar')->end()
475 82
                    ->end()
476 82
                ->end()
477 82
            ->end()
478 82
        ->end();
479 82
    }
480
481 82
    private function addExceptionSection(ArrayNodeDefinition $rootNode)
482
    {
483
        $rootNode
484 82
            ->children()
485 82
                ->arrayNode('exception')
486 82
                    ->fixXmlConfig('code', 'codes')
487 82
                    ->fixXmlConfig('message', 'messages')
488 82
                    ->addDefaultsIfNotSet()
489 82
                    ->canBeEnabled()
490 82
                    ->children()
491 82
                        ->booleanNode('map_exception_codes')
492 82
                            ->defaultFalse()
493 82
                            ->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.')
494 82
                        ->end()
495 82
                        ->booleanNode('exception_listener')
496
                            ->defaultValue(function () {
497 14
                                @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...
498
499 14
                                return true;
500 82
                            })
501 82
                            ->beforeNormalization()
502 82
                                ->ifTrue()
503
                                ->then(function ($v) {
504
                                    @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...
505
506
                                    return $v;
507 82
                                })
508 82
                            ->end()
509 82
                        ->end()
510 82
                        ->scalarNode('exception_controller')
511 82
                            ->defaultNull()
512 82
                            ->setDeprecated('The "%path%.%node%" option is deprecated since FOSRestBundle 2.8.')
513 82
                        ->end()
514 82
                        ->booleanNode('serialize_exceptions')
515
                            ->defaultValue(function () {
516 9
                                @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...
517
518 9
                                return true;
519 82
                            })
520 82
                            ->beforeNormalization()
521 82
                                ->ifTrue()
522
                                ->then(function ($v) {
523 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...
524
525 8
                                    return $v;
526 82
                                })
527 82
                            ->end()
528 82
                        ->end()
529 82
                        ->enumNode('flatten_exception_format')
530 82
                            ->defaultValue('legacy')
531 82
                            ->values(['legacy', 'rfc7807'])
532 82
                        ->end()
533 82
                        ->scalarNode('service')
534 82
                            ->defaultNull()
535 82
                            ->setDeprecated('The "%path%.%node%" option is deprecated since FOSRestBundle 2.8.')
536 82
                        ->end()
537 82
                        ->booleanNode('serializer_error_renderer')->defaultValue(false)->end()
538 82
                        ->arrayNode('codes')
539 82
                            ->useAttributeAsKey('name')
540 82
                            ->beforeNormalization()
541 82
                                ->ifArray()
542
                                ->then(function (array $items) {
543 13
                                    foreach ($items as &$item) {
544 13
                                        if (is_int($item)) {
545 3
                                            continue;
546
                                        }
547
548 10
                                        if (!defined(sprintf('%s::%s', Response::class, $item))) {
549 9
                                            throw new InvalidConfigurationException(sprintf('Invalid HTTP code in fos_rest.exception.codes, see %s for all valid codes.', Response::class));
550
                                        }
551
552 1
                                        $item = constant(sprintf('%s::%s', Response::class, $item));
553
                                    }
554
555 4
                                    return $items;
556 82
                                })
557 82
                            ->end()
558 82
                            ->prototype('integer')->end()
559
560 82
                            ->validate()
561 82
                            ->ifArray()
562
                                ->then(function (array $items) {
563 4
                                    foreach ($items as $class => $code) {
564 4
                                        $this->testExceptionExists($class);
565
                                    }
566
567 3
                                    return $items;
568 82
                                })
569 82
                            ->end()
570 82
                        ->end()
571 82
                        ->arrayNode('messages')
572 82
                            ->useAttributeAsKey('name')
573 82
                            ->prototype('boolean')->end()
574 82
                            ->validate()
575 82
                                ->ifArray()
576
                                ->then(function (array $items) {
577 12
                                    foreach ($items as $class => $nomatter) {
578 12
                                        $this->testExceptionExists($class);
579
                                    }
580
581 11
                                    return $items;
582 82
                                })
583 82
                            ->end()
584 82
                        ->end()
585 82
                        ->booleanNode('debug')
586 82
                            ->defaultValue($this->debug)
587 82
                        ->end()
588 82
                    ->end()
589 82
                ->end()
590 82
            ->end();
591 82
    }
592
593 16
    private function testExceptionExists(string $throwable)
594
    {
595 16
        if (!is_subclass_of($throwable, \Throwable::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Throwable::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
596 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.', $throwable, \Throwable::class));
597
        }
598 14
    }
599
}
600