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

Configuration::addSerializersSection()   B

Complexity

Conditions 4
Paths 1

Size

Total Lines 34
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 26
CRAP Score 4.0008

Importance

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