Completed
Push — master ( dd40bf...739ea2 )
by Asmir
18:26 queued 13:49
created

Configuration::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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