Completed
Push — master ( ce3f18...1319dc )
by Christian
05:54
created

Configuration   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 363
Duplicated Lines 3.86 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 98.73%

Importance

Changes 6
Bugs 1 Features 1
Metric Value
wmc 16
c 6
b 1
f 1
lcom 1
cbo 4
dl 14
loc 363
ccs 312
cts 316
cp 0.9873
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B getConfigTreeBuilder() 7 116 3
A addViewSection() 7 73 3
B addBodyListenerSection() 0 34 1
B addFormatListenerSection() 0 51 4
A addVersioningSection() 0 49 3
B addExceptionSection() 0 27 2

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