Completed
Push — master ( d37f4d...5acbf0 )
by Asmir
10s
created

Configuration   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 325
Duplicated Lines 4.31 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 96.11%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 21
c 1
b 0
f 0
lcom 1
cbo 10
dl 14
loc 325
ccs 247
cts 257
cp 0.9611
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B addHandlersSection() 0 24 1
A addSubscribersSection() 0 17 1
A addObjectConstructorsSection() 0 19 1
B addSerializersSection() 0 46 4
A addMetadataSection() 0 51 1
C addVisitorsSection() 14 68 7
A addContextSection() 0 9 1
A createContextNode() 0 51 3
A getConfigTreeBuilder() 0 19 1

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
 * Copyright 2011 Johannes M. Schmitt <[email protected]>
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
namespace JMS\SerializerBundle\DependencyInjection;
20
21
use JMS\Serializer\Exception\InvalidArgumentException;
22
use Symfony\Component\Config\Definition\Builder\NodeBuilder;
23
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
24
use Symfony\Component\Config\Definition\ConfigurationInterface;
25
use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
26
27
class Configuration implements ConfigurationInterface
28
{
29
    private $debug;
30
31
    /**
32
     * @param boolean $debug
33
     */
34 60
    public function __construct($debug = false)
35
    {
36 60
        $this->debug = $debug;
37 60
    }
38
39 60
    public function getConfigTreeBuilder()
40
    {
41 60
        $tb = new TreeBuilder();
42
43
        $root = $tb
44 60
            ->root('jms_serializer', 'array')
45 60
                ->children()
46 60
        ;
47
48 60
        $this->addHandlersSection($root);
49 60
        $this->addSubscribersSection($root);
50 60
        $this->addObjectConstructorsSection($root);
51 60
        $this->addSerializersSection($root);
52 60
        $this->addMetadataSection($root);
53 60
        $this->addVisitorsSection($root);
54 60
        $this->addContextSection($root);
55
56 60
        return $tb;
57
    }
58
59 60
    private function addHandlersSection(NodeBuilder $builder)
60
    {
61
        $builder
62 60
            ->arrayNode('handlers')
63 60
                ->addDefaultsIfNotSet()
64 60
                ->children()
65 60
                    ->arrayNode('datetime')
66 60
                        ->addDefaultsIfNotSet()
67 60
                        ->children()
68 60
                            ->scalarNode('default_format')->defaultValue(\DateTime::RFC3339)->end()
69 60
                            ->scalarNode('default_timezone')->defaultValue(date_default_timezone_get())->end()
70 60
                            ->scalarNode('cdata')->defaultTrue()->end()
71 60
                        ->end()
72 60
                    ->end()
73 60
                    ->arrayNode('array_collection')
74 60
                        ->addDefaultsIfNotSet()
75 60
                        ->children()
76 60
                            ->booleanNode('initialize_excluded')->defaultFalse()->end()
77 60
                        ->end()
78 60
                    ->end()
79 60
                ->end()
80 60
            ->end()
81
        ;
82 60
    }
83
84 60
    private function addSubscribersSection(NodeBuilder $builder)
85
    {
86
        $builder
87 60
            ->arrayNode('subscribers')
88 60
                ->addDefaultsIfNotSet()
89 60
                    ->children()
90 60
                        ->arrayNode('doctrine_proxy')
91 60
                        ->addDefaultsIfNotSet()
92 60
                        ->children()
93 60
                            ->booleanNode('initialize_excluded')->defaultFalse()->end()
94 60
                            ->booleanNode('initialize_virtual_types')->defaultFalse()->end()
95 60
                        ->end()
96 60
                    ->end()
97 60
                ->end()
98 60
            ->end()
99
        ;
100 60
    }
101
102 60
    private function addObjectConstructorsSection(NodeBuilder $builder)
103
    {
104
        $builder
105 60
            ->arrayNode('object_constructors')
106 60
                ->addDefaultsIfNotSet()
107 60
                    ->children()
108 60
                        ->arrayNode('doctrine')
109 60
                        ->addDefaultsIfNotSet()
110 60
                        ->children()
111 60
                            ->enumNode('fallback_strategy')
112 60
                                ->defaultValue("null")
113 60
                                ->values(["null", "exception", "fallback"])
114 60
                            ->end()
115 60
                        ->end()
116 60
                    ->end()
117 60
                ->end()
118 60
            ->end()
119
        ;
120 60
    }
121
122 60
    private function addSerializersSection(NodeBuilder $builder)
123
    {
124
        $builder
125 60
            ->arrayNode('property_naming')
126 60
                ->addDefaultsIfNotSet()
127 60
                ->beforeNormalization()
128 60
                    ->ifString()
129
                    ->then(function ($id) {
130 1
                        return array('id' => $id);
131 60
                    })
132 60
                ->end()
133 60
                ->children()
134 60
                    ->scalarNode('id')->cannotBeEmpty()->end()
135 60
                    ->scalarNode('separator')->defaultValue('_')->end()
136 60
                    ->booleanNode('lower_case')->defaultTrue()->end()
137 60
                    ->booleanNode('enable_cache')->defaultTrue()->end()
138 60
                ->end()
139 60
            ->end()
140 60
            ->arrayNode('expression_evaluator')
141 60
                ->addDefaultsIfNotSet()
142 60
                ->beforeNormalization()
143 60
                    ->ifString()
144
                    ->then(function ($id) {
145 1
                        return array('id' => $id);
146 60
                    })
147 60
                ->end()
148 60
                ->children()
149 60
                    ->scalarNode('id')
150
                        ->defaultValue(function () {
151 56
                            if (interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
152 56
                                return 'jms_serializer.expression_evaluator';
153
                            }
154
                            return null;
155 60
                        })
156 60
                        ->validate()
157
                            ->always(function($v) {
158 3
                                if (!empty($v) && !interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
159
                                    throw new InvalidArgumentException('You need at least symfony/expression language v2.6 or v3.0 to use the expression evaluator features');
160
                                }
161 3
                                return $v;
162 60
                            })
163 60
                        ->end()
164 60
                ->end()
165 60
            ->end()
166
        ;
167 60
    }
168
169 60
    private function addMetadataSection(NodeBuilder $builder)
170
    {
171
        $builder
172 60
            ->arrayNode('metadata')
173 60
                ->addDefaultsIfNotSet()
174 60
                ->fixXmlConfig('directory', 'directories')
175 60
                ->children()
176
177 60
                    ->arrayNode('warmup')
178 60
                        ->addDefaultsIfNotSet()
179 60
                        ->children()
180 60
                            ->arrayNode('paths')
181 60
                                ->addDefaultsIfNotSet()
182 60
                                ->children()
183 60
                                    ->arrayNode('included')
184 60
                                        ->prototype('scalar')->end()
185 60
                                    ->end()
186 60
                                    ->arrayNode('excluded')
187 60
                                        ->prototype('scalar')->end()
188 60
                                    ->end()
189 60
                                ->end()
190 60
                            ->end()
191 60
                        ->end()
192 60
                    ->end()
193
194 60
                    ->scalarNode('cache')->defaultValue('file')->end()
195 60
                    ->booleanNode('debug')->defaultValue($this->debug)->end()
196 60
                    ->arrayNode('file_cache')
197 60
                        ->addDefaultsIfNotSet()
198 60
                        ->children()
199 60
                            ->scalarNode('dir')->defaultValue('%kernel.cache_dir%/jms_serializer')->end()
200 60
                        ->end()
201 60
                    ->end()
202 60
                    ->booleanNode('auto_detection')->defaultTrue()->end()
203 60
                    ->booleanNode('infer_types_from_doctrine_metadata')
204 60
                        ->info('Infers type information from Doctrine metadata if no explicit type has been defined for a property.')
205 60
                        ->defaultTrue()
206 60
                    ->end()
207 60
                    ->arrayNode('directories')
208 60
                        ->useAttributeAsKey('name')
209 60
                        ->prototype('array')
210 60
                            ->children()
211 60
                                ->scalarNode('path')->isRequired()->end()
212 60
                                ->scalarNode('namespace_prefix')->defaultValue('')->end()
213 60
                            ->end()
214 60
                        ->end()
215 60
                    ->end()
216 60
                ->end()
217 60
            ->end()
218
        ;
219 60
    }
220
221 60
    private function addVisitorsSection(NodeBuilder $builder)
222
    {
223
        $builder
224 60
            ->arrayNode('visitors')
225 60
                ->addDefaultsIfNotSet()
226 60
                ->children()
227 60
                    ->arrayNode('json')
228 60
                        ->addDefaultsIfNotSet()
229 60
                        ->children()
230 60
                            ->scalarNode('options')
231 60
                                ->defaultValue(0)
232 60
                                ->beforeNormalization()
233
                                    ->ifArray()->then(function($v) {
234 1
                                        $options = 0;
235 1
                                        foreach ($v as $option) {
236 1 View Code Duplication
                                            if (is_numeric($option)) {
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...
237
                                                $options |= (int) $option;
238 1
                                            } elseif (defined($option)) {
239 1
                                                $options |= constant($option);
240 1
                                            } else {
241
                                                throw new InvalidArgumentException('Expected either an integer representing one of the JSON_ constants, or a string of the constant itself.');
242
                                            }
243 1
                                        }
244
245 1
                                        return $options;
246 60
                                    })
247 60
                                ->end()
248 60
                                ->beforeNormalization()
249
                                    ->ifString()->then(function($v) {
250 1 View Code Duplication
                                        if (is_numeric($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...
251
                                            $value = (int) $v;
252 1
                                        } elseif (defined($v)) {
253 1
                                            $value = constant($v);
254 1
                                        } else {
255
                                            throw new InvalidArgumentException('Expected either an integer representing one of the JSON_ constants, or a string of the constant itself.');
256
                                        }
257
258 1
                                        return $value;
259 60
                                    })
260 60
                                ->end()
261 60
                                ->validate()
262
                                    ->always(function($v) {
263 3
                                        if (!is_int($v)) {
264
                                            throw new InvalidArgumentException('Expected either integer value or a array of the JSON_ constants.');
265
                                        }
266
267 3
                                        return $v;
268 60
                                    })
269 60
                                ->end()
270 60
                            ->end()
271 60
                        ->end()
272 60
                    ->end()
273 60
                    ->arrayNode('xml')
274 60
                        ->fixXmlConfig('whitelisted-doctype', 'doctype_whitelist')
275 60
                        ->addDefaultsIfNotSet()
276 60
                        ->children()
277 60
                            ->arrayNode('doctype_whitelist')
278 60
                                ->prototype('scalar')->end()
279 60
                            ->end()
280 60
                            ->booleanNode('format_output')
281 60
                                ->defaultTrue()
282 60
                            ->end()
283 60
                        ->end()
284 60
                    ->end()
285 60
                ->end()
286 60
            ->end()
287
        ;
288 60
    }
289
290 60
    private function addContextSection(NodeBuilder $builder)
291
    {
292
        $root = $builder
293 60
                    ->arrayNode('default_context')
294 60
                    ->addDefaultsIfNotSet();
295
296 60
        $this->createContextNode($root->children(), 'serialization');
297 60
        $this->createContextNode($root->children(), 'deserialization');
298 60
    }
299
300 60
    private function createContextNode(NodeBuilder $builder, $name)
301
    {
302
        $builder
303 60
            ->arrayNode($name)
304 60
                ->addDefaultsIfNotSet()
305 60
                ->beforeNormalization()
306 60
                    ->ifString()
307
                    ->then(function ($id) {
308 1
                        return array('id' => $id);
309 60
                    })
310 60
                ->end()
311
                ->validate()->always(function ($v) {
312 6
                    if (!empty($v['id'])) {
313 2
                        return array('id' => $v['id']);
314
                    }
315 4
                    return $v;
316 60
                })->end()
317 60
                ->children()
318 60
                    ->scalarNode('id')->cannotBeEmpty()->end()
319 60
                    ->scalarNode('serialize_null')
320 60
                        ->validate()->always(function ($v) {
321
                            if (!in_array($v, array(true, false, NULL), true)){
322
                                throw new InvalidTypeException("Expected boolean or NULL for the serialize_null option");
323
                            }
324
                            return $v;
325 60
                        })
326 60
                        ->ifNull()->thenUnset()
327 60
                        ->end()
328 60
                        ->info('Flag if null values should be serialized')
329 60
                    ->end()
330 60
                    ->scalarNode('enable_max_depth_checks')
331 60
                        ->info('Flag to enable the max-depth exclusion strategy')
332 60
                    ->end()
333 60
                    ->arrayNode('attributes')
334 60
                        ->fixXmlConfig('attribute')
335 60
                        ->useAttributeAsKey('key')
336 60
                        ->prototype('scalar')->end()
337 60
                        ->info('Arbitrary key-value data for context')
338 60
                    ->end()
339 60
                    ->arrayNode('groups')
340 60
                        ->fixXmlConfig('group')
341 60
                        ->prototype('scalar')->end()
342 60
                        ->info('Default serialization groups')
343 60
                    ->end()
344 60
                    ->scalarNode('version')
345 60
                        ->validate()->ifNull()->thenUnset()->end()
346 60
                        ->info('Application version to use in exclusion strategies')
347 60
                    ->end()
348 60
                ->end()
349 60
            ->end();
350 60
    }
351
}
352