Completed
Pull Request — master (#556)
by Evgenij
02:50
created

Configuration::addMetadataSection()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 1

Importance

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