Completed
Pull Request — master (#1569)
by
unknown
14:06
created

Configuration::getTypesNode()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 39
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 54
ccs 39
cts 39
cp 1
rs 9.0036
c 0
b 0
f 0
cc 3
nc 1
nop 0
crap 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\DependencyInjection;
13
14
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
16
use Symfony\Component\Config\Definition\ConfigurationInterface;
17
18
class Configuration implements ConfigurationInterface
19
{
20
    private const SUPPORTED_DRIVERS = ['orm', 'mongodb', 'phpcr'];
21
22
    /**
23
     * If the kernel is running in debug mode.
24
     *
25
     * @var bool
26
     */
27
    private $debug;
28
29 35
    public function __construct($debug)
30
    {
31 35
        $this->debug = $debug;
32 35
    }
33
34
    /**
35
     * Generates the configuration tree.
36
     *
37
     * @return TreeBuilder
38
     */
39 35
    public function getConfigTreeBuilder()
40
    {
41 35
        $treeBuilder = new TreeBuilder('fos_elastica');
42
        $rootNode = $treeBuilder->getRootNode();
43 35
44 35
        $this->addClientsSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
45
        $this->addIndexesSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
46
        $this->addIndexTemplatesSection($rootNode);
0 ignored issues
show
Compatibility introduced by
$rootNode of type object<Symfony\Component...Builder\NodeDefinition> is not a sub-type of object<Symfony\Component...er\ArrayNodeDefinition>. It seems like you assume a child class of the class Symfony\Component\Config...\Builder\NodeDefinition to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
47
48
        $rootNode
49
            ->children()
50 35
                ->scalarNode('default_client')
51 35
                    ->info('Defaults to the first client defined')
52 35
                ->end()
53
                ->scalarNode('default_index')
54
                    ->info('Defaults to the first index defined')
55 35
                ->end()
56 35
                ->scalarNode('default_manager')->defaultValue('orm')->end()
57 35
                ->arrayNode('serializer')
58 35
                    ->treatNullLike([])
59 35
                    ->children()
60 35
                        ->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
61 35
                        ->scalarNode('serializer')->defaultValue('serializer')->end()
62 35
                    ->end()
63 35
                ->end()
64 35
            ->end()
65 35
        ;
66 35
67 35
        return $treeBuilder;
68 35
    }
69 35
70 35
    /**
71
     * Returns the array node used for "dynamic_templates".
72
     */
73 35
    private function getDynamicTemplateNode()
74
    {
75
        $node = $this->createTreeBuilderNode('dynamic_templates');
76
77
        $node
78
            ->prototype('array')
79 35
                ->prototype('array')
80
                    ->children()
81 35
                        ->scalarNode('match')->end()
82
                        ->scalarNode('unmatch')->end()
83
                        ->scalarNode('match_mapping_type')->end()
84 35
                        ->scalarNode('path_match')->end()
85 35
                        ->scalarNode('path_unmatch')->end()
86 35
                        ->scalarNode('match_pattern')->end()
87 35
                        ->arrayNode('mapping')
88 35
                            ->prototype('variable')
89 35
                                ->treatNullLike([])
90 35
                            ->end()
91 35
                        ->end()
92 35
                    ->end()
93 35
                ->end()
94 35
            ->end()
95 35
        ;
96 35
97 35
        return $node;
98 35
    }
99 35
100 35
    /**
101
     * Returns the array node used for "types".
102
     */
103 35
    private function getTypesNode()
104
    {
105
        $node = $this->createTreeBuilderNode('types');
106
107
        $node
0 ignored issues
show
Bug introduced by
The method useAttributeAsKey() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. Did you maybe mean attribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
108
            ->useAttributeAsKey('name')
109 35
            ->prototype('array')
110
                ->treatNullLike([])
111 35
                ->beforeNormalization()
112
                ->ifNull()
113
                    ->thenEmptyArray()
114 35
                ->end()
115 35
                // Support multiple dynamic_template formats to match the old bundle style
116 35
                // and the way ElasticSearch expects them
117 35
                ->beforeNormalization()
118 35
                ->ifTrue(function ($v) {
119 35
                    return isset($v['dynamic_templates']);
120 35
                })
121
                ->then(function ($v) {
122
                    $dt = [];
123 35
                    foreach ($v['dynamic_templates'] as $key => $type) {
124 35
                        if (is_int($key)) {
125 25
                            $dt[] = $type;
126 35
                        } else {
127 35
                            $dt[][$key] = $type;
128 5
                        }
129 5
                    }
130 5
131 5
                    $v['dynamic_templates'] = $dt;
132
133 5
                    return $v;
134
                })
135
                ->end()
136
                ->children()
137 5
                    ->booleanNode('date_detection')->end()
138
                    ->arrayNode('dynamic_date_formats')->prototype('scalar')->end()->end()
139 5
                    ->scalarNode('analyzer')->end()
140 35
                    ->booleanNode('numeric_detection')->end()
141 35
                    ->scalarNode('dynamic')->end()
142 35
                    ->variableNode('indexable_callback')->end()
143 35
                    ->append($this->getPersistenceNode())
144 35
                    ->append($this->getSerializerNode())
145 35
                ->end()
146 35
                ->append($this->getIdNode())
147 35
                ->append($this->getPropertiesNode())
148 35
                ->append($this->getDynamicTemplateNode())
149 35
                ->append($this->getSourceNode())
150 35
                ->append($this->getRoutingNode())
151 35
                ->append($this->getAllNode())
152 35
            ->end()
153 35
        ;
154 35
155 35
        return $node;
156 35
    }
157 35
158 35
    /**
159 35
     * Returns the array node used for "properties".
160
     */
161
    private function getPropertiesNode()
162 35
    {
163
        $node = $this->createTreeBuilderNode('properties');
164
165
        $node
0 ignored issues
show
Bug introduced by
The method useAttributeAsKey() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. Did you maybe mean attribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
166
            ->useAttributeAsKey('name')
167
            ->prototype('variable')
168 35
                ->treatNullLike([]);
169
170 35
        return $node;
171
    }
172
173 35
    /**
174 35
     * Returns the array node used for "_id".
175 35
     */
176
    private function getIdNode()
177 35
    {
178
        $node = $this->createTreeBuilderNode('_id');
179
180
        $node
181
            ->children()
182
            ->scalarNode('path')->end()
183 35
            ->end()
184
        ;
185 35
186
        return $node;
187
    }
188 35
189 35
    /**
190 35
     * Returns the array node used for "_source".
191
     */
192
    private function getSourceNode()
193 35
    {
194
        $node = $this->createTreeBuilderNode('_source');
195
196
        $node
197
            ->children()
198
                ->arrayNode('excludes')
199 35
                    ->useAttributeAsKey('name')
200
                    ->prototype('scalar')->end()
201 35
                ->end()
202
                ->arrayNode('includes')
203
                    ->useAttributeAsKey('name')
204 35
                    ->prototype('scalar')->end()
205 35
                ->end()
206 35
                ->scalarNode('compress')->end()
207 35
                ->scalarNode('compress_threshold')->end()
208 35
                ->scalarNode('enabled')->defaultTrue()->end()
209 35
            ->end()
210 35
        ;
211 35
212 35
        return $node;
213 35
    }
214 35
215 35
    /**
216 35
     * Returns the array node used for "_routing".
217
     */
218
    private function getRoutingNode()
219 35
    {
220
        $node = $this->createTreeBuilderNode('_routing');
221
222
        $node
223
            ->children()
224
                ->scalarNode('required')->end()
225 35
                ->scalarNode('path')->end()
226
            ->end()
227 35
        ;
228
229
        return $node;
230 35
    }
231 35
232 35
    /**
233 35
     * Returns the array node used for "_all".
234
     */
235
    private function getAllNode()
236 35
    {
237
        $node = $this->createTreeBuilderNode('_all');
238
239
        $node
240
            ->children()
241
            ->scalarNode('enabled')->defaultValue(true)->end()
242 35
            ->scalarNode('analyzer')->end()
243
            ->end()
244 35
        ;
245
246
        return $node;
247 35
    }
248 35
249 35
    /**
250 35
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
251 35
     */
252
    private function getPersistenceNode()
253
    {
254 35
        $node = $this->createTreeBuilderNode('persistence');
255
256
        $node
257
            ->validate()
258
                ->ifTrue(function ($v) {
259
                    return isset($v['driver']) && 'orm' !== $v['driver'] && !empty($v['elastica_to_model_transformer']['hints']);
260 35
                })
261
                    ->thenInvalid('Hints are only supported by the "orm" driver')
262 35
            ->end()
263
            ->children()
264
                ->scalarNode('driver')
265 35
                    ->defaultValue('orm')
266 35
                    ->validate()
267 35
                    ->ifNotInArray(self::SUPPORTED_DRIVERS)
268 35
                        ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode(self::SUPPORTED_DRIVERS))
269
                    ->end()
270
                ->end()
271 35
                ->scalarNode('model')->defaultValue(null)->end()
272
                ->scalarNode('repository')->end()
273
                ->scalarNode('identifier')->defaultValue('id')->end()
274
                ->arrayNode('provider')
275
                    ->addDefaultsIfNotSet()
276
                    ->children()
277 35
                        ->scalarNode('batch_size')->defaultValue(100)->end()
278
                        ->scalarNode('clear_object_manager')->defaultTrue()->end()
279 35
                        ->scalarNode('debug_logging')
280
                            ->defaultValue($this->debug)
281
                            ->treatNullLike(true)
282 35
                        ->end()
283 35
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
284 17
                        ->scalarNode('service')->end()
285 35
                    ->end()
286 35
                ->end()
287 35
                ->arrayNode('listener')
288 35
                    ->addDefaultsIfNotSet()
289 35
                    ->children()
290 35
                        ->booleanNode('enabled')->defaultTrue()->end()
291 35
                        ->scalarNode('insert')->defaultTrue()->end()
292 35
                        ->scalarNode('update')->defaultTrue()->end()
293 35
                        ->scalarNode('delete')->defaultTrue()->end()
294 35
                        ->scalarNode('flush')->defaultTrue()->end()
295 35
                        ->booleanNode('defer')->defaultFalse()->end()
296 35
                        ->scalarNode('logger')
297 35
                            ->defaultFalse()
298 35
                            ->treatNullLike('fos_elastica.logger')
299 35
                            ->treatTrueLike('fos_elastica.logger')
300 35
                        ->end()
301 35
                        ->scalarNode('service')->end()
302 35
                    ->end()
303 35
                ->end()
304 35
                ->arrayNode('finder')
305 35
                    ->addDefaultsIfNotSet()
306 35
                    ->children()
307 35
                        ->scalarNode('service')->end()
308 35
                    ->end()
309 35
                ->end()
310 35
                ->arrayNode('elastica_to_model_transformer')
311 35
                    ->addDefaultsIfNotSet()
312 35
                    ->children()
313 35
                        ->arrayNode('hints')
314 35
                            ->prototype('array')
315 35
                                ->children()
316 35
                                    ->scalarNode('name')->end()
317 35
                                    ->scalarNode('value')->end()
318 35
                                ->end()
319 35
                            ->end()
320 35
                        ->end()
321 35
                        ->booleanNode('hydrate')->defaultTrue()->end()
322 35
                        ->booleanNode('ignore_missing')
323 35
                            ->defaultFalse()
324 35
                            ->info('Silently ignore results returned from Elasticsearch without corresponding persistent object.')
325 35
                        ->end()
326 35
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
327 35
                        ->scalarNode('service')->end()
328 35
                    ->end()
329 35
                ->end()
330 35
                ->arrayNode('model_to_elastica_transformer')
331 35
                    ->addDefaultsIfNotSet()
332 35
                    ->children()
333 35
                        ->scalarNode('service')->end()
334 35
                    ->end()
335 35
                ->end()
336 35
                ->arrayNode('persister')
337 35
                    ->addDefaultsIfNotSet()
338 35
                    ->children()
339 35
                        ->enumNode('refresh')
340 35
                            ->treatTrueLike('true')
341 35
                            ->treatFalseLike('false')
342 35
                            ->values(['true', 'wait_for', 'false'])
343 35
                        ->end()
344 35
                        ->scalarNode('service')->end()
345 35
                    ->end()
346 35
                ->end()
347 35
            ->end();
348 35
349 35
        return $node;
350 35
    }
351 35
352 35
    /**
353 35
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
354 35
     */
355 35
    private function getSerializerNode()
356 35
    {
357 35
        $node = $this->createTreeBuilderNode('serializer');
358 35
359 35
        $node
360 35
            ->addDefaultsIfNotSet()
361 35
            ->children()
362 35
                ->arrayNode('groups')
363 35
                    ->treatNullLike([])
364 35
                    ->prototype('scalar')->end()
365 35
                ->end()
366 35
                ->scalarNode('version')->end()
367 35
                ->booleanNode('serialize_null')
368 35
                    ->defaultFalse()
369 35
                ->end()
370 35
            ->end();
371 35
372 35
        return $node;
373
    }
374 35
375
    /**
376
     * Adds the configuration for the "clients" key.
377
     */
378
    private function addClientsSection(ArrayNodeDefinition $rootNode)
379
    {
380 35
        $rootNode
381
            ->fixXmlConfig('client')
382 35
            ->children()
383
                ->arrayNode('clients')
384
                    ->useAttributeAsKey('id')
385 35
                    ->prototype('array')
386 35
                        ->performNoDeepMerging()
387 35
                        // Elastica names its properties with camel case, support both
388 35
                        ->beforeNormalization()
389 35
                        ->ifTrue(function ($v) {
390 35
                            return isset($v['connection_strategy']);
391 35
                        })
392 35
                        ->then(function ($v) {
393 35
                            $v['connectionStrategy'] = $v['connection_strategy'];
394 35
                            unset($v['connection_strategy']);
395 35
396
                            return $v;
397 35
                        })
398
                        ->end()
399
                        // If there is no connections array key defined, assume a single connection.
400
                        ->beforeNormalization()
401
                        ->ifTrue(function ($v) {
402
                            return is_array($v) && !array_key_exists('connections', $v);
403 35
                        })
404
                        ->then(function ($v) {
405
                            return [
406 35
                                'connections' => [$v],
407 35
                            ];
408 35
                        })
409 35
                        ->end()
410 35
                        ->children()
411 35
                            ->arrayNode('connections')
412
                                ->requiresAtLeastOneElement()
413 35
                                ->prototype('array')
414 35
                                    ->fixXmlConfig('header')
415 33
                                    ->children()
416 35
                                        ->scalarNode('url')
417 35
                                            ->validate()
418 5
                                                ->ifTrue(function ($url) {
419 5
                                                    return $url && '/' !== substr($url, -1);
420
                                                })
421 5
                                                ->then(function ($url) {
422 35
                                                    return $url.'/';
423 35
                                                })
424
                                            ->end()
425 35
                                        ->end()
426 35
                                        ->scalarNode('username')->end()
427 33
                                        ->scalarNode('password')->end()
428 35
                                        ->scalarNode('host')->end()
429 35
                                        ->scalarNode('port')->end()
430
                                        ->scalarNode('proxy')->end()
431 33
                                        ->arrayNode('http_error_codes')
432
                                            ->beforeNormalization()
433 35
                                                ->ifTrue(function ($v) { return !is_array($v); })
434 35
                                                ->then(function ($v) { return array($v); })
435 35
                                            ->end()
436 35
                                            ->requiresAtLeastOneElement()
437 35
                                            ->defaultValue([400, 403, 404])
438 35
                                            ->prototype('scalar')->end()
439 35
                                        ->end()
440 35
                                        ->scalarNode('aws_access_key_id')->end()
441 35
                                        ->scalarNode('aws_secret_access_key')->end()
442 35
                                        ->scalarNode('aws_region')->end()
443 35
                                        ->scalarNode('aws_session_token')->end()
444 19
                                        ->booleanNode('ssl')->defaultValue(false)->end()
445 35
                                        ->scalarNode('logger')
446 35
                                            ->defaultValue($this->debug ? 'fos_elastica.logger' : false)
447 19
                                            ->treatNullLike('fos_elastica.logger')
448 35
                                            ->treatTrueLike('fos_elastica.logger')
449 35
                                        ->end()
450 35
                                        ->booleanNode('compression')->defaultValue(false)->end()
451 35
                                        ->arrayNode('headers')
452 35
                                            ->normalizeKeys(false)
453 35
                                            ->useAttributeAsKey('name')
454 35
                                            ->prototype('scalar')->end()
455 35
                                        ->end()
456 35
                                        ->arrayNode('curl')
457 35
                                            ->useAttributeAsKey(CURLOPT_SSL_VERIFYPEER)
458
                                            ->prototype('boolean')->end()
459
                                        ->end()
460 35
                                        ->scalarNode('transport')->end()
461 35
                                        ->scalarNode('timeout')->end()
462 35
                                        ->scalarNode('connectTimeout')->end()
463 35
                                        ->scalarNode('retryOnConflict')
464 35
                                            ->defaultValue(0)
465 35
                                        ->end()
466 35
                                        ->booleanNode('persistent')->defaultValue(true)->end()
467 35
                                    ->end()
468 35
                                ->end()
469 35
                            ->end()
470 35
                            ->scalarNode('timeout')->end()
471 35
                            ->scalarNode('connectTimeout')->end()
472 35
                            ->scalarNode('headers')->end()
473 35
                            ->scalarNode('connectionStrategy')->defaultValue('Simple')->end()
474 35
                        ->end()
475 35
                    ->end()
476 35
                ->end()
477 35
            ->end()
478 35
        ;
479 35
    }
480 35
481 35
    /**
482 35
     * Adds the configuration for the "indexes" key.
483 35
     */
484 35
    private function addIndexesSection(ArrayNodeDefinition $rootNode)
485 35
    {
486 35
        $rootNode
487 35
            ->fixXmlConfig('index')
488 35
            ->children()
489 35
                ->arrayNode('indexes')
490 35
                    ->useAttributeAsKey('name')
491 35
                    ->prototype('array')
492 35
                        ->children()
493 35
                            ->scalarNode('index_name')
494 35
                                ->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
495 35
                            ->end()
496 35
                            ->booleanNode('use_alias')->defaultValue(false)->end()
497 35
                            ->scalarNode('client')->end()
498 35
                            ->scalarNode('finder')
499 35
                                ->treatNullLike(true)
500 35
                                ->defaultFalse()
501 35
                            ->end()
502 35
                            ->arrayNode('type_prototype')
503
                                ->children()
504 35
                                    ->scalarNode('analyzer')->end()
505
                                    ->append($this->getPersistenceNode())
506
                                    ->append($this->getSerializerNode())
507
                                ->end()
508
                            ->end()
509 35
                            ->variableNode('settings')->defaultValue([])->end()
510
                        ->end()
511
                        ->append($this->getTypesNode())
512 35
                    ->end()
513 35
                ->end()
514 35
            ->end()
515 35
        ;
516 35
    }
517 35
518 35
    /**
519 35
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
520 35
     */
521 35
    private function createTreeBuilderNode($name)
522 35
    {
523 35
        return (new TreeBuilder($name))->getRootNode();
524 35
    }
525 35
526 35
    /**
527 35
     * Adds the configuration for the "index_templates" key.
528 35
     *
529 35
     * @param ArrayNodeDefinition $rootNode
530 35
     *
531 35
     * @return void
532 35
     */
533 35
    private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode)
534 35
    {
535 35
        $rootNode
536 35
            ->fixXmlConfig('index_template')
537 35
            ->children()
538 35
                ->arrayNode('index_templates')
539 35
                    ->useAttributeAsKey('name')
540
                    ->prototype('array')
541 35
                        ->children()
542
                            ->scalarNode('template_name')
543
                                ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch')
544
                            ->end()
545
                            ->scalarNode('template')->isRequired()->end()
546 35
                            ->scalarNode('client')->end()
547
                            ->variableNode('settings')->defaultValue([])->end()
548 35
                        ->end()
549
                        ->append($this->getTypesNode())
550 35
                    ->end()
551 35
                ->end()
552
            ->end()
553
        ;
554
    }
555
}
556