Completed
Push — master ( bca297...c408c0 )
by Asmir
05:23
created

Configuration::addHandlersSection()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 24
ccs 21
cts 21
cp 1
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 21
nc 1
nop 1
crap 1
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 48
    public function __construct($debug = false)
35
    {
36 48
        $this->debug = $debug;
37 48
    }
38
39 48
    public function getConfigTreeBuilder()
40 1
    {
41 48
        $tb = new TreeBuilder();
42
43
        $root = $tb
44 48
            ->root('jms_serializer', 'array')
45 48
                ->children()
46 48
                    ->booleanNode('enable_short_alias')->defaultTrue()->end()
47 48
        ;
48
49 48
        $this->addHandlersSection($root);
50 48
        $this->addSubscribersSection($root);
51 48
        $this->addObjectConstructorsSection($root);
52 48
        $this->addSerializersSection($root);
53 48
        $this->addMetadataSection($root);
54 48
        $this->addVisitorsSection($root);
55 48
        $this->addContextSection($root);
56
57 48
        return $tb;
58
    }
59
60 48
    private function addHandlersSection(NodeBuilder $builder)
61
    {
62
        $builder
63 48
            ->arrayNode('handlers')
64 48
                ->addDefaultsIfNotSet()
65 48
                ->children()
66 48
                    ->arrayNode('datetime')
67 48
                        ->addDefaultsIfNotSet()
68 48
                        ->children()
69 48
                            ->scalarNode('default_format')->defaultValue(\DateTime::ISO8601)->end()
70 48
                            ->scalarNode('default_timezone')->defaultValue(date_default_timezone_get())->end()
71 48
                            ->scalarNode('cdata')->defaultTrue()->end()
72 48
                        ->end()
73 48
                    ->end()
74 48
                    ->arrayNode('array_collection')
75 48
                        ->addDefaultsIfNotSet()
76 48
                        ->children()
77 48
                            ->booleanNode('initialize_excluded')->defaultTrue()->end()
78 48
                        ->end()
79 48
                    ->end()
80 48
                ->end()
81 48
            ->end()
82
        ;
83 48
    }
84
85 48
    private function addSubscribersSection(NodeBuilder $builder)
86
    {
87
        $builder
88 48
            ->arrayNode('subscribers')
89 48
                ->addDefaultsIfNotSet()
90 48
                    ->children()
91 48
                        ->arrayNode('doctrine_proxy')
92 48
                        ->addDefaultsIfNotSet()
93 48
                        ->children()
94 48
                            ->booleanNode('initialize_excluded')->defaultTrue()->end()
95 48
                            ->booleanNode('initialize_virtual_types')->defaultTrue()->end()
96 48
                        ->end()
97 48
                    ->end()
98 48
                ->end()
99 48
            ->end()
100
        ;
101 48
    }
102
103 48
    private function addObjectConstructorsSection(NodeBuilder $builder)
104
    {
105
        $builder
106 48
            ->arrayNode('object_constructors')
107 48
                ->addDefaultsIfNotSet()
108 48
                    ->children()
109 48
                        ->arrayNode('doctrine')
110 48
                        ->addDefaultsIfNotSet()
111 48
                        ->children()
112 48
                            ->enumNode('fallback_strategy')
113 48
                                ->defaultValue("null")
114 48
                                ->values(["null", "exception", "fallback"])
115 48
                            ->end()
116 48
                        ->end()
117 48
                    ->end()
118 48
                ->end()
119 48
            ->end()
120
        ;
121 48
    }
122
123 48
    private function addSerializersSection(NodeBuilder $builder)
124
    {
125
        $builder
126 48
            ->arrayNode('property_naming')
127 48
                ->addDefaultsIfNotSet()
128 48
                ->beforeNormalization()
129 48
                    ->ifString()
130
                    ->then(function ($id) {
131 1
                        return array('id' => $id);
132 48
                    })
133 48
                ->end()
134 48
                ->children()
135 48
                    ->scalarNode('id')->cannotBeEmpty()->end()
136 48
                    ->scalarNode('separator')->defaultValue('_')->end()
137 48
                    ->booleanNode('lower_case')->defaultTrue()->end()
138 48
                    ->booleanNode('enable_cache')->defaultTrue()->end()
139 48
                ->end()
140 48
            ->end()
141 48
            ->arrayNode('expression_evaluator')
142 48
                ->addDefaultsIfNotSet()
143 48
                ->beforeNormalization()
144 48
                    ->ifString()
145
                    ->then(function ($id) {
146 1
                        return array('id' => $id);
147 48
                    })
148 48
                ->end()
149 48
                ->children()
150 48
                    ->scalarNode('id')
151
                        ->defaultValue(function () {
152 44
                            if (interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
153 44
                                return 'jms_serializer.expression_evaluator';
154
                            }
155
                            return null;
156 48
                        })
157 48
                        ->validate()
158
                            ->always(function($v) {
159 3
                                if (!empty($v) && !interface_exists('Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface')) {
160
                                    throw new InvalidArgumentException('You need at least symfony/expression language v2.6 or v3.0 to use the expression evaluator features');
161
                                }
162 3
                                return $v;
163 48
                            })
164 48
                        ->end()
165 48
                ->end()
166 48
            ->end()
167
        ;
168 48
    }
169
170 48
    private function addMetadataSection(NodeBuilder $builder)
171
    {
172
        $builder
173 48
            ->arrayNode('metadata')
174 48
                ->addDefaultsIfNotSet()
175 48
                ->fixXmlConfig('directory', 'directories')
176 48
                ->children()
177 48
                    ->scalarNode('cache')->defaultValue('file')->end()
178 48
                    ->booleanNode('debug')->defaultValue($this->debug)->end()
179 48
                    ->arrayNode('file_cache')
180 48
                        ->addDefaultsIfNotSet()
181 48
                        ->children()
182 48
                            ->scalarNode('dir')->defaultValue('%kernel.cache_dir%/jms_serializer')->end()
183 48
                        ->end()
184 48
                    ->end()
185 48
                    ->booleanNode('auto_detection')->defaultTrue()->end()
186 48
                    ->booleanNode('infer_types_from_doctrine_metadata')
187 48
                        ->info('Infers type information from Doctrine metadata if no explicit type has been defined for a property.')
188 48
                        ->defaultTrue()
189 48
                    ->end()
190 48
                    ->arrayNode('directories')
191 48
                        ->prototype('array')
192 48
                            ->children()
193 48
                                ->scalarNode('path')->isRequired()->end()
194 48
                                ->scalarNode('namespace_prefix')->defaultValue('')->end()
195 48
                            ->end()
196 48
                        ->end()
197 48
                    ->end()
198 48
                ->end()
199 48
            ->end()
200
        ;
201 48
    }
202
203 48
    private function addVisitorsSection(NodeBuilder $builder)
204
    {
205 1
        $builder
206 48
            ->arrayNode('visitors')
207 48
                ->addDefaultsIfNotSet()
208 48
                ->children()
209 48
                    ->arrayNode('json')
210 48
                        ->addDefaultsIfNotSet()
211 48
                        ->children()
212 48
                            ->scalarNode('options')
213 48
                                ->defaultValue(0)
214 48
                                ->beforeNormalization()
215
                                    ->ifArray()->then(function($v) {
216 1
                                        $options = 0;
217 1
                                        foreach ($v as $option) {
218 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...
219
                                                $options |= (int) $option;
220 1
                                            } elseif (defined($option)) {
221 1
                                                $options |= constant($option);
222 1
                                            } else {
223
                                                throw new InvalidArgumentException('Expected either an integer representing one of the JSON_ constants, or a string of the constant itself.');
224
                                            }
225 1
                                        }
226
227 1
                                        return $options;
228 48
                                    })
229 48
                                ->end()
230 48
                                ->beforeNormalization()
231
                                    ->ifString()->then(function($v) {
232 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...
233
                                            $value = (int) $v;
234 1
                                        } elseif (defined($v)) {
235 1
                                            $value = constant($v);
236 1
                                        } else {
237
                                            throw new InvalidArgumentException('Expected either an integer representing one of the JSON_ constants, or a string of the constant itself.');
238
                                        }
239
240 1
                                        return $value;
241 48
                                    })
242 48
                                ->end()
243 48
                                ->validate()
244
                                    ->always(function($v) {
245 3
                                        if (!is_int($v)) {
246
                                            throw new InvalidArgumentException('Expected either integer value or a array of the JSON_ constants.');
247
                                        }
248
249 3
                                        return $v;
250 48
                                    })
251 48
                                ->end()
252 48
                            ->end()
253 48
                        ->end()
254 48
                    ->end()
255 48
                    ->arrayNode('xml')
256 48
                        ->fixXmlConfig('whitelisted-doctype', 'doctype_whitelist')
257 48
                        ->addDefaultsIfNotSet()
258 48
                        ->children()
259 48
                            ->arrayNode('doctype_whitelist')
260 48
                                ->prototype('scalar')->end()
261 48
                            ->end()
262 48
                            ->booleanNode('format_output')
263 48
                                ->defaultTrue()
264 48
                            ->end()
265 48
                        ->end()
266 48
                    ->end()
267 48
                ->end()
268 48
            ->end()
269
        ;
270 48
    }
271
272 48
    private function addContextSection(NodeBuilder $builder)
273
    {
274
        $root = $builder
275 48
                    ->arrayNode('default_context')
276 48
                    ->addDefaultsIfNotSet();
277
278 48
        $this->createContextNode($root->children(), 'serialization');
279 48
        $this->createContextNode($root->children(), 'deserialization');
280 48
    }
281
282 48
    private function createContextNode(NodeBuilder $builder, $name)
283
    {
284
        $builder
285 48
            ->arrayNode($name)
286 48
                ->addDefaultsIfNotSet()
287 48
                ->beforeNormalization()
288 48
                    ->ifString()
289
                    ->then(function ($id) {
290 1
                        return array('id' => $id);
291 48
                    })
292 48
                ->end()
293
                ->validate()->always(function ($v) {
294 6
                    if (!empty($v['id'])) {
295 2
                        return array('id' => $v['id']);
296
                    }
297 4
                    return $v;
298 48
                })->end()
299 48
                ->children()
300 48
                    ->scalarNode('id')->cannotBeEmpty()->end()
301 48
                    ->scalarNode('serialize_null')
302 48
                        ->validate()->always(function ($v) {
303
                            if (!in_array($v, array(true, false, NULL), true)){
304
                                throw new InvalidTypeException("Expected boolean or NULL for the serialize_null option");
305
                            }
306
                            return $v;
307 48
                        })
308 48
                        ->ifNull()->thenUnset()
309 48
                        ->end()
310 48
                        ->info('Flag if null values should be serialized')
311 48
                    ->end()
312 48
                    ->scalarNode('enable_max_depth_checks')
313 48
                        ->info('Flag to enable the max-depth exclusion strategy')
314 48
                    ->end()
315 48
                    ->arrayNode('attributes')
316 48
                        ->fixXmlConfig('attribute')
317 48
                        ->useAttributeAsKey('key')
318 48
                        ->prototype('scalar')->end()
319 48
                        ->info('Arbitrary key-value data for context')
320 48
                    ->end()
321 48
                    ->arrayNode('groups')
322 48
                        ->fixXmlConfig('group')
323 48
                        ->prototype('scalar')->end()
324 48
                        ->info('Default serialization groups')
325 48
                    ->end()
326 48
                    ->scalarNode('version')
327 48
                        ->validate()->ifNull()->thenUnset()->end()
328 48
                        ->info('Application version to use in exclusion strategies')
329 48
                    ->end()
330 48
                ->end()
331 48
            ->end();
332 48
    }
333
}
334