Completed
Pull Request — master (#1358)
by Guilh
07:06
created

Configuration::getConfigTreeBuilder()   B

Complexity

Conditions 3
Paths 1

Size

Total Lines 115
Code Lines 108

Duplication

Lines 7
Ratio 6.09 %

Code Coverage

Tests 101
CRAP Score 3.0002

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 7
loc 115
ccs 101
cts 104
cp 0.9712
rs 8.2857
cc 3
eloc 108
nc 1
nop 0
crap 3.0002

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\HttpFoundation\Response;
18
19
/**
20
 * This class contains the configuration information for the bundle.
21
 *
22
 * This information is solely responsible for how the different configuration
23
 * sections are normalized, and merged.
24
 *
25
 * @author Lukas Kahwe Smith <[email protected]>
26
 *
27
 * @internal
28
 */
29
final class Configuration implements ConfigurationInterface
30
{
31
    /**
32
     * Generates the configuration tree.
33
     *
34
     * @return TreeBuilder
35
     */
36 46
    public function getConfigTreeBuilder()
37
    {
38 46
        $treeBuilder = new TreeBuilder();
39 46
        $rootNode = $treeBuilder->root('fos_rest', 'array');
40
41
        $rootNode
42 46
            ->children()
43 46
                ->scalarNode('disable_csrf_role')->defaultNull()->end()
44 46
                ->arrayNode('access_denied_listener')
45 46
                    ->canBeEnabled()
46 46
                    ->beforeNormalization()
47 View Code Duplication
                        ->ifArray()->then(function ($v) { if (!empty($v) && empty($v['formats'])) {
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...
48
     unset($v['enabled']);
49
     $v = ['enabled' => true, 'formats' => $v];
50
 }
51
52 46
return $v; })
53 46
                    ->end()
54 46
                    ->fixXmlConfig('format', 'formats')
55 46
                    ->children()
56 46
                        ->scalarNode('service')->defaultNull()->end()
57 46
                        ->arrayNode('formats')
58 46
                            ->useAttributeAsKey('name')
59 46
                            ->prototype('boolean')->end()
60 46
                        ->end()
61 46
                    ->end()
62 46
                ->end()
63 46
                ->scalarNode('unauthorized_challenge')->defaultNull()->end()
64 46
                ->arrayNode('param_fetcher_listener')
65 46
                    ->beforeNormalization()
66 46
                        ->ifString()
67 View Code Duplication
                        ->then(function ($v) { return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v]; })
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...
68 46
                    ->end()
69 46
                    ->canBeEnabled()
70 46
                    ->children()
71 46
                        ->booleanNode('enabled')->defaultFalse()->end()
72 46
                        ->booleanNode('force')->defaultFalse()->end()
73 46
                        ->scalarNode('service')->defaultNull()->end()
74 46
                    ->end()
75 46
                ->end()
76 46
                ->scalarNode('cache_dir')->cannotBeEmpty()->defaultValue('%kernel.cache_dir%/fos_rest')->end()
77 46
                ->arrayNode('allowed_methods_listener')
78 46
                    ->canBeEnabled()
79 46
                    ->children()
80 46
                        ->scalarNode('service')->defaultNull()->end()
81 46
                    ->end()
82 46
                ->end()
83 46
                ->arrayNode('routing_loader')
84 46
                    ->addDefaultsIfNotSet()
85 46
                    ->children()
86 46
                        ->scalarNode('default_format')->defaultNull()->end()
87 46
                        ->scalarNode('include_format')->defaultTrue()->end()
88 46
                    ->end()
89 46
                ->end()
90 46
                ->arrayNode('body_converter')
91 46
                    ->addDefaultsIfNotSet()
92 46
                    ->children()
93 46
                        ->scalarNode('enabled')->defaultFalse()->end()
94 46
                        ->scalarNode('validate')->defaultFalse()->end()
95 46
                        ->scalarNode('validation_errors_argument')->defaultValue('validationErrors')->end()
96 46
                    ->end()
97 46
                ->end()
98 46
                ->arrayNode('service')
99 46
                    ->addDefaultsIfNotSet()
100 46
                    ->children()
101 46
                        ->scalarNode('router')->defaultValue('router')->end()
102 46
                        ->scalarNode('templating')->defaultValue('templating')->end()
103 46
                        ->scalarNode('serializer')->defaultNull()->end()
104 46
                        ->scalarNode('view_handler')->defaultValue('fos_rest.view_handler.default')->end()
105 46
                        ->scalarNode('inflector')->defaultValue('fos_rest.inflector.doctrine')->end()
106 46
                        ->scalarNode('validator')->defaultValue('validator')->end()
107 46
                    ->end()
108 46
                ->end()
109 46
                ->arrayNode('serializer')
110 46
                    ->addDefaultsIfNotSet()
111 46
                    ->children()
112 46
                        ->scalarNode('version')->defaultNull()->end()
113 46
                        ->arrayNode('groups')
114 46
                            ->prototype('scalar')->end()
115 46
                        ->end()
116 46
                        ->booleanNode('serialize_null')->defaultFalse()->end()
117 46
                    ->end()
118 46
                ->end()
119 46
                ->arrayNode('zone')
120 46
                    ->cannotBeOverwritten()
121 46
                    ->prototype('array')
122 46
                    ->fixXmlConfig('ip')
123 46
                    ->children()
124 46
                        ->scalarNode('path')
125 46
                            ->defaultNull()
126 46
                            ->info('use the urldecoded format')
127 46
                            ->example('^/path to resource/')
128 46
                        ->end()
129 46
                        ->scalarNode('host')->defaultNull()->end()
130 46
                        ->arrayNode('methods')
131
                            ->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); })->end()
132 46
                            ->prototype('scalar')->end()
133 46
                        ->end()
134 46
                        ->arrayNode('ips')
135
                            ->beforeNormalization()->ifString()->then(function ($v) { return array($v); })->end()
136 46
                            ->prototype('scalar')->end()
137 46
                        ->end()
138 46
                    ->end()
139 46
                ->end()
140 46
            ->end()
141 46
        ->end();
142
143 46
        $this->addViewSection($rootNode);
144 46
        $this->addExceptionSection($rootNode);
145 46
        $this->addBodyListenerSection($rootNode);
146 46
        $this->addFormatListenerSection($rootNode);
147 46
        $this->addVersioningSection($rootNode);
148
149 46
        return $treeBuilder;
150
    }
151
152 46
    private function addViewSection(ArrayNodeDefinition $rootNode)
153
    {
154
        $rootNode
155 46
            ->children()
156 46
                ->arrayNode('view')
157 46
                    ->fixXmlConfig('format', 'formats')
158 46
                    ->fixXmlConfig('mime_type', 'mime_types')
159 46
                    ->fixXmlConfig('templating_format', 'templating_formats')
160 46
                    ->fixXmlConfig('force_redirect', 'force_redirects')
161 46
                    ->addDefaultsIfNotSet()
162 46
                    ->children()
163 46
                        ->scalarNode('default_engine')->defaultValue('twig')->end()
164 46
                        ->arrayNode('force_redirects')
165 46
                            ->useAttributeAsKey('name')
166 46
                            ->defaultValue(['html' => true])
167 46
                            ->prototype('boolean')->end()
168 46
                        ->end()
169 46
                        ->arrayNode('mime_types')
170 46
                            ->canBeEnabled()
171 46
                            ->beforeNormalization()
172 View Code Duplication
                                ->ifArray()->then(function ($v) {
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...
173 1
                                    if (!empty($v) && empty($v['formats'])) {
174 1
                                        unset($v['enabled']);
175 1
                                        $v = ['enabled' => true, 'formats' => $v];
176 1
                                    }
177
178 1
                                    return $v;
179 46
                                })
180 46
                            ->end()
181 46
                            ->fixXmlConfig('format', 'formats')
182 46
                            ->children()
183 46
                                ->scalarNode('service')->defaultNull()->end()
184 46
                                ->arrayNode('formats')
185 46
                                    ->useAttributeAsKey('name')
186 46
                                    ->prototype('variable')->end()
187 46
                                ->end()
188 46
                            ->end()
189 46
                        ->end()
190 46
                        ->arrayNode('formats')
191 46
                            ->useAttributeAsKey('name')
192 46
                            ->defaultValue(['json' => true, 'xml' => true])
193 46
                            ->prototype('boolean')->end()
194 46
                        ->end()
195 46
                        ->arrayNode('templating_formats')
196 46
                            ->useAttributeAsKey('name')
197 46
                            ->defaultValue(['html' => true])
198 46
                            ->prototype('boolean')->end()
199 46
                        ->end()
200 46
                        ->arrayNode('view_response_listener')
201 46
                            ->beforeNormalization()
202 46
                                ->ifString()
203 View Code Duplication
                                ->then(function ($v) { return ['enabled' => in_array($v, ['force', 'true']), 'force' => 'force' === $v]; })
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...
204 46
                            ->end()
205 46
                            ->canBeEnabled()
206 46
                            ->children()
207 46
                                ->booleanNode('enabled')->defaultFalse()->end()
208 46
                                ->booleanNode('force')->defaultFalse()->end()
209 46
                                ->scalarNode('service')->defaultNull()->end()
210 46
                            ->end()
211 46
                        ->end()
212 46
                        ->scalarNode('failed_validation')->defaultValue(Response::HTTP_BAD_REQUEST)->end()
213 46
                        ->scalarNode('empty_content')->defaultValue(Response::HTTP_NO_CONTENT)->end()
214 46
                        ->booleanNode('serialize_null')->defaultFalse()->end()
215 46
                        ->arrayNode('jsonp_handler')
216 46
                            ->canBeUnset()
217 46
                            ->children()
218 46
                                ->scalarNode('callback_param')->defaultValue('callback')->end()
219 46
                                ->scalarNode('mime_type')->defaultValue('application/javascript+jsonp')->end()
220 46
                            ->end()
221 46
                        ->end()
222 46
                    ->end()
223 46
                ->end()
224 46
            ->end();
225 46
    }
226
227 46
    private function addBodyListenerSection(ArrayNodeDefinition $rootNode)
228
    {
229
        $rootNode
230 46
            ->children()
231 46
                ->arrayNode('body_listener')
232 46
                    ->fixXmlConfig('decoder', 'decoders')
233 46
                    ->addDefaultsIfNotSet()
234 46
                    ->canBeUnset()
235 46
                    ->canBeDisabled()
236 46
                    ->children()
237 46
                        ->scalarNode('service')->defaultNull()->end()
238 46
                        ->scalarNode('default_format')->defaultNull()->end()
239 46
                        ->booleanNode('throw_exception_on_unsupported_content_type')
240 46
                            ->defaultFalse()
241 46
                        ->end()
242 46
                        ->arrayNode('decoders')
243 46
                            ->useAttributeAsKey('name')
244 46
                            ->defaultValue(['json' => 'fos_rest.decoder.json', 'xml' => 'fos_rest.decoder.xml'])
245 46
                            ->prototype('scalar')->end()
246 46
                        ->end()
247 46
                        ->arrayNode('array_normalizer')
248 46
                            ->addDefaultsIfNotSet()
249 46
                            ->beforeNormalization()
250
                                ->ifString()->then(function ($v) { return ['service' => $v]; })
251 46
                            ->end()
252 46
                            ->children()
253 46
                                ->scalarNode('service')->defaultNull()->end()
254 46
                                ->booleanNode('forms')->defaultFalse()->end()
255 46
                            ->end()
256 46
                        ->end()
257 46
                    ->end()
258 46
                ->end()
259 46
            ->end();
260 46
    }
261
262 46
    private function addFormatListenerSection(ArrayNodeDefinition $rootNode)
263
    {
264
        $rootNode
265 46
            ->children()
266 46
                ->arrayNode('format_listener')
267 46
                    ->fixXmlConfig('rule', 'rules')
268 46
                    ->addDefaultsIfNotSet()
269 46
                    ->canBeUnset()
270 46
                    ->beforeNormalization()
271
                        ->ifTrue(function ($v) {
272
                            // check if we got an assoc array in rules
273 7
                            return isset($v['rules'])
274 7
                                && is_array($v['rules'])
275 7
                                && array_keys($v['rules']) !== range(0, count($v['rules']) - 1);
276 46
                        })
277
                        ->then(function ($v) {
278 1
                            $v['rules'] = [$v['rules']];
279
280 1
                            return $v;
281 46
                        })
282 46
                    ->end()
283 46
                    ->canBeEnabled()
284 46
                    ->validate()
285
                        ->ifTrue(function ($v) { return empty($v['rules']) && !empty($v['media_type']['enabled']); })
286 46
                        ->thenInvalid('To enable the "media_type" setting, a "rules" setting must also needs to be defined for the "format_listener"')
287 46
                    ->end()
288 46
                    ->children()
289 46
                        ->scalarNode('service')->defaultNull()->end()
290 46
                        ->arrayNode('rules')
291 46
                            ->cannotBeOverwritten()
292 46
                            ->prototype('array')
293 46
                                ->fixXmlConfig('priority', 'priorities')
294 46
                                ->fixXmlConfig('attribute', 'attributes')
295 46
                                ->children()
296 46
                                    ->scalarNode('path')->defaultNull()->info('URL path info')->end()
297 46
                                    ->scalarNode('host')->defaultNull()->info('URL host name')->end()
298 46
                                    ->variableNode('methods')->defaultNull()->info('Method for URL')->end()
299 46
                                    ->arrayNode('attributes')
300 46
                                        ->useAttributeAsKey('name')
301 46
                                        ->prototype('variable')->end()
302 46
                                    ->end()
303 46
                                    ->booleanNode('stop')->defaultFalse()->end()
304 46
                                    ->booleanNode('prefer_extension')->defaultTrue()->end()
305 46
                                    ->scalarNode('fallback_format')->defaultValue('html')->end()
306 46
                                    ->arrayNode('priorities')
307
                                        ->beforeNormalization()->ifString()->then(function ($v) { return preg_split('/\s*,\s*/', $v); })->end()
308 46
                                        ->prototype('scalar')->end()
309 46
                                    ->end()
310 46
                                ->end()
311 46
                            ->end()
312 46
                        ->end()
313 46
                    ->end()
314 46
                ->end()
315 46
            ->end();
316 46
    }
317
318 46
    private function addVersioningSection(ArrayNodeDefinition $rootNode)
319
    {
320
        $rootNode
321 46
        ->children()
322 46
            ->arrayNode('versioning')
323 46
                ->canBeEnabled()
324 46
                ->children()
325 46
                    ->scalarNode('default_version')->defaultNull()->end()
326 46
                    ->arrayNode('resolvers')
327 46
                        ->addDefaultsIfNotSet()
328 46
                        ->children()
329 46
                            ->arrayNode('query')
330 46
                                ->canBeDisabled()
331 46
                                ->children()
332 46
                                    ->scalarNode('parameter_name')->defaultValue('version')->end()
333 46
                                ->end()
334 46
                            ->end()
335 46
                            ->arrayNode('custom_header')
336 46
                                ->canBeDisabled()
337 46
                                ->children()
338 46
                                    ->scalarNode('header_name')->defaultValue('X-Accept-Version')->end()
339 46
                                ->end()
340 46
                            ->end()
341 46
                            ->arrayNode('media_type')
342 46
                                ->canBeDisabled()
343 46
                                ->children()
344 46
                                    ->scalarNode('regex')->defaultValue('/(v|version)=(?P<version>[0-9\.]+)/')->end()
345 46
                                ->end()
346 46
                            ->end()
347 46
                        ->end()
348 46
                    ->end()
349 46
                    ->arrayNode('guessing_order')
350 46
                        ->defaultValue(['query', 'custom_header', 'media_type'])
351 46
                        ->validate()
352
                            ->ifTrue(function ($v) {
353 1
                                foreach ($v as $resolver) {
354 1
                                    if (!in_array($resolver, ['query', 'custom_header', 'media_type'])) {
355
                                        return true;
356
                                    }
357 1
                                }
358 46
                            })
359 46
                            ->thenInvalid('Versioning guessing order can only contain "query", "custom_header", "media_type".')
360 46
                        ->end()
361 46
                        ->prototype('scalar')->end()
362 46
                    ->end()
363 46
                ->end()
364 46
            ->end()
365 46
        ->end();
366 46
    }
367
368 46
    private function addExceptionSection(ArrayNodeDefinition $rootNode)
369
    {
370
        $rootNode
371 46
            ->children()
372 46
                ->arrayNode('exception')
373 46
                    ->fixXmlConfig('code', 'codes')
374 46
                    ->fixXmlConfig('message', 'messages')
375 46
                    ->addDefaultsIfNotSet()
376 46
                    ->canBeEnabled()
377 46
                    ->children()
378 46
                        ->scalarNode('exception_controller')->defaultNull()->end()
379 46
                        ->arrayNode('codes')
380 46
                            ->useAttributeAsKey('name')
381 46
                            ->validate()
382
                                ->ifTrue(function ($v) { return 0 !== count(array_filter($v, function ($i) { return !defined('Symfony\Component\HttpFoundation\Response::'.$i) && !is_int($i); })); })
383 46
                                ->thenInvalid('Invalid HTTP code in fos_rest.exception.codes, see Symfony\Component\HttpFoundation\Response for all valid codes.')
384 46
                            ->end()
385 46
                            ->prototype('scalar')->end()
386 46
                        ->end()
387 46
                        ->arrayNode('messages')
388 46
                            ->useAttributeAsKey('name')
389 46
                            ->prototype('boolean')->end()
390 46
                        ->end()
391 46
                    ->end()
392 46
                ->end()
393 46
            ->end();
394 46
    }
395
}
396