Completed
Pull Request — master (#1343)
by Dmitry
06:34
created

Configuration::addIndexTemplatesSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 19
cts 19
cp 1
rs 9.568
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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
    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 34
    public function __construct($debug)
30
    {
31 34
        $this->debug = $debug;
32 34
    }
33
34
    /**
35
     * Generates the configuration tree.
36
     *
37
     * @return TreeBuilder
38
     */
39 34
    public function getConfigTreeBuilder()
40
    {
41 34
        $treeBuilder = new TreeBuilder('fos_elastica');
0 ignored issues
show
Unused Code introduced by
The call to TreeBuilder::__construct() has too many arguments starting with 'fos_elastica'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
42
43 34
        if (method_exists($treeBuilder, 'getRootNode')) {
44 34
            $rootNode = $treeBuilder->getRootNode();
0 ignored issues
show
Bug introduced by
The method getRootNode() does not seem to exist on object<Symfony\Component...on\Builder\TreeBuilder>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
45
        } else {
46
            // BC layer for symfony/config 4.1 and older
47
            $rootNode = $treeBuilder->root('fos_elastica');
48
        }
49
50 34
        $this->addClientsSection($rootNode);
51 34
        $this->addIndexesSection($rootNode);
52 34
        $this->addIndexTemplatesSection($rootNode);
53
54
        $rootNode
55 34
            ->children()
56 34
                ->scalarNode('default_client')
57 34
                    ->info('Defaults to the first client defined')
58 34
                ->end()
59 34
                ->scalarNode('default_index')
60 34
                    ->info('Defaults to the first index defined')
61 34
                ->end()
62 34
                ->scalarNode('default_manager')->defaultValue('orm')->end()
63 34
                ->arrayNode('serializer')
64 34
                    ->treatNullLike([])
65 34
                    ->children()
66 34
                        ->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
67 34
                        ->scalarNode('serializer')->defaultValue('serializer')->end()
68 34
                    ->end()
69 34
                ->end()
70 34
            ->end()
71
        ;
72
73 34
        return $treeBuilder;
74
    }
75
76
    /**
77
     * Returns the array node used for "dynamic_templates".
78
     */
79 34
    public function getDynamicTemplateNode()
80
    {
81 34
        $builder = new TreeBuilder();
82 34
        $node = $builder->root('dynamic_templates');
83
84
        $node
85 34
            ->prototype('array')
86 34
                ->prototype('array')
87 34
                    ->children()
88 34
                        ->scalarNode('match')->end()
89 34
                        ->scalarNode('unmatch')->end()
90 34
                        ->scalarNode('match_mapping_type')->end()
91 34
                        ->scalarNode('path_match')->end()
92 34
                        ->scalarNode('path_unmatch')->end()
93 34
                        ->scalarNode('match_pattern')->end()
94 34
                        ->arrayNode('mapping')
95 34
                            ->prototype('variable')
96 34
                                ->treatNullLike([])
97 34
                            ->end()
98 34
                        ->end()
99 34
                    ->end()
100 34
                ->end()
101 34
            ->end()
102
        ;
103
104 34
        return $node;
105
    }
106
107
    /**
108
     * Returns the array node used for "types".
109
     */
110 34
    protected function getTypesNode()
111
    {
112 34
        $builder = new TreeBuilder();
113 34
        $node = $builder->root('types');
114
115
        $node
116 34
            ->useAttributeAsKey('name')
117 34
            ->prototype('array')
118 34
                ->treatNullLike([])
119 34
                ->beforeNormalization()
120 34
                ->ifNull()
121 34
                    ->thenEmptyArray()
122 34
                ->end()
123
                // Support multiple dynamic_template formats to match the old bundle style
124
                // and the way ElasticSearch expects them
125 34
                ->beforeNormalization()
126 34
                ->ifTrue(function ($v) {
127 25
                    return isset($v['dynamic_templates']);
128 34
                })
129 34
                ->then(function ($v) {
130 5
                    $dt = [];
131 5
                    foreach ($v['dynamic_templates'] as $key => $type) {
132 5
                        if (is_int($key)) {
133 5
                            $dt[] = $type;
134
                        } else {
135 5
                            $dt[][$key] = $type;
136
                        }
137
                    }
138
139 5
                    $v['dynamic_templates'] = $dt;
140
141 5
                    return $v;
142 34
                })
143 34
                ->end()
144 34
                ->children()
145 34
                    ->booleanNode('date_detection')->end()
146 34
                    ->arrayNode('dynamic_date_formats')->prototype('scalar')->end()->end()
147 34
                    ->scalarNode('analyzer')->end()
148 34
                    ->booleanNode('numeric_detection')->end()
149 34
                    ->scalarNode('dynamic')->end()
150 34
                    ->variableNode('indexable_callback')->end()
151 34
                    ->append($this->getPersistenceNode())
152 34
                    ->append($this->getSerializerNode())
153 34
                ->end()
154 34
                ->append($this->getIdNode())
155 34
                ->append($this->getPropertiesNode())
156 34
                ->append($this->getDynamicTemplateNode())
157 34
                ->append($this->getSourceNode())
158 34
                ->append($this->getRoutingNode())
159 34
                ->append($this->getParentNode())
160 34
                ->append($this->getAllNode())
161 34
            ->end()
162
        ;
163
164 34
        return $node;
165
    }
166
167
    /**
168
     * Returns the array node used for "properties".
169
     */
170 34
    protected function getPropertiesNode()
171
    {
172 34
        $builder = new TreeBuilder();
173 34
        $node = $builder->root('properties');
174
175
        $node
176 34
            ->useAttributeAsKey('name')
177 34
            ->prototype('variable')
178 34
                ->treatNullLike([]);
179
180 34
        return $node;
181
    }
182
183
    /**
184
     * Returns the array node used for "_id".
185
     */
186 34 View Code Duplication
    protected function getIdNode()
187
    {
188 34
        $builder = new TreeBuilder();
189 34
        $node = $builder->root('_id');
190
191
        $node
192 34
            ->children()
193 34
            ->scalarNode('path')->end()
194 34
            ->end()
195
        ;
196
197 34
        return $node;
198
    }
199
200
    /**
201
     * Returns the array node used for "_source".
202
     */
203 34
    protected function getSourceNode()
204
    {
205 34
        $builder = new TreeBuilder();
206 34
        $node = $builder->root('_source');
207
208
        $node
209 34
            ->children()
210 34
                ->arrayNode('excludes')
211 34
                    ->useAttributeAsKey('name')
212 34
                    ->prototype('scalar')->end()
213 34
                ->end()
214 34
                ->arrayNode('includes')
215 34
                    ->useAttributeAsKey('name')
216 34
                    ->prototype('scalar')->end()
217 34
                ->end()
218 34
                ->scalarNode('compress')->end()
219 34
                ->scalarNode('compress_threshold')->end()
220 34
                ->scalarNode('enabled')->defaultTrue()->end()
221 34
            ->end()
222
        ;
223
224 34
        return $node;
225
    }
226
227
    /**
228
     * Returns the array node used for "_routing".
229
     */
230 34 View Code Duplication
    protected function getRoutingNode()
231
    {
232 34
        $builder = new TreeBuilder();
233 34
        $node = $builder->root('_routing');
234
235
        $node
236 34
            ->children()
237 34
                ->scalarNode('required')->end()
238 34
                ->scalarNode('path')->end()
239 34
            ->end()
240
        ;
241
242 34
        return $node;
243
    }
244
245
    /**
246
     * Returns the array node used for "_parent".
247
     */
248 34
    protected function getParentNode()
249
    {
250 34
        $builder = new TreeBuilder();
251 34
        $node = $builder->root('_parent');
252
253
        $node
254 34
            ->children()
255 34
                ->scalarNode('type')->end()
256 34
                ->scalarNode('property')->defaultValue(null)->end()
257 34
                ->scalarNode('identifier')->defaultValue('id')->end()
258 34
            ->end()
259
        ;
260
261 34
        return $node;
262
    }
263
264
    /**
265
     * Returns the array node used for "_all".
266
     */
267 34
    protected function getAllNode()
268
    {
269 34
        $builder = new TreeBuilder();
270 34
        $node = $builder->root('_all');
271
272
        $node
273 34
            ->children()
274 34
            ->scalarNode('enabled')->defaultValue(true)->end()
275 34
            ->scalarNode('analyzer')->end()
276 34
            ->end()
277
        ;
278
279 34
        return $node;
280
    }
281
282
    /**
283
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
284
     */
285 34
    protected function getPersistenceNode()
286
    {
287 34
        $builder = new TreeBuilder();
288 34
        $node = $builder->root('persistence');
289
290
        $node
291 34
            ->validate()
292 34
                ->ifTrue(function ($v) {
293 17
                    return isset($v['driver']) && 'orm' !== $v['driver'] && !empty($v['elastica_to_model_transformer']['hints']);
294 34
                })
295 34
                    ->thenInvalid('Hints are only supported by the "orm" driver')
296 34
            ->end()
297 34
            ->children()
298 34
                ->scalarNode('driver')
299 34
                    ->defaultValue('orm')
300 34
                    ->validate()
301 34
                    ->ifNotInArray(self::SUPPORTED_DRIVERS)
302 34
                        ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode(self::SUPPORTED_DRIVERS))
303 34
                    ->end()
304 34
                ->end()
305 34
                ->scalarNode('model')->defaultValue(null)->end()
306 34
                ->scalarNode('repository')->end()
307 34
                ->scalarNode('identifier')->defaultValue('id')->end()
308 34
                ->arrayNode('provider')
309 34
                    ->addDefaultsIfNotSet()
310 34
                    ->children()
311 34
                        ->scalarNode('batch_size')->defaultValue(100)->end()
312 34
                        ->scalarNode('clear_object_manager')->defaultTrue()->end()
313 34
                        ->scalarNode('debug_logging')
314 34
                            ->defaultValue($this->debug)
315 34
                            ->treatNullLike(true)
316 34
                        ->end()
317 34
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
318 34
                        ->scalarNode('service')->end()
319 34
                    ->end()
320 34
                ->end()
321 34
                ->arrayNode('listener')
322 34
                    ->addDefaultsIfNotSet()
323 34
                    ->children()
324 34
                        ->booleanNode('enabled')->defaultTrue()->end()
325 34
                        ->scalarNode('insert')->defaultTrue()->end()
326 34
                        ->scalarNode('update')->defaultTrue()->end()
327 34
                        ->scalarNode('delete')->defaultTrue()->end()
328 34
                        ->scalarNode('flush')->defaultTrue()->end()
329 34
                        ->booleanNode('defer')->defaultFalse()->end()
330 34
                        ->scalarNode('logger')
331 34
                            ->defaultFalse()
332 34
                            ->treatNullLike('fos_elastica.logger')
333 34
                            ->treatTrueLike('fos_elastica.logger')
334 34
                        ->end()
335 34
                        ->scalarNode('service')->end()
336 34
                    ->end()
337 34
                ->end()
338 34
                ->arrayNode('finder')
339 34
                    ->addDefaultsIfNotSet()
340 34
                    ->children()
341 34
                        ->scalarNode('service')->end()
342 34
                    ->end()
343 34
                ->end()
344 34
                ->arrayNode('elastica_to_model_transformer')
345 34
                    ->addDefaultsIfNotSet()
346 34
                    ->children()
347 34
                        ->arrayNode('hints')
348 34
                            ->prototype('array')
349 34
                                ->children()
350 34
                                    ->scalarNode('name')->end()
351 34
                                    ->scalarNode('value')->end()
352 34
                                ->end()
353 34
                            ->end()
354 34
                        ->end()
355 34
                        ->booleanNode('hydrate')->defaultTrue()->end()
356 34
                        ->booleanNode('ignore_missing')
357 34
                            ->defaultFalse()
358 34
                            ->info('Silently ignore results returned from Elasticsearch without corresponding persistent object.')
359 34
                        ->end()
360 34
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
361 34
                        ->scalarNode('service')->end()
362 34
                    ->end()
363 34
                ->end()
364 34
                ->arrayNode('model_to_elastica_transformer')
365 34
                    ->addDefaultsIfNotSet()
366 34
                    ->children()
367 34
                        ->scalarNode('service')->end()
368 34
                    ->end()
369 34
                ->end()
370 34
                ->arrayNode('persister')
371 34
                    ->addDefaultsIfNotSet()
372 34
                    ->children()
373 34
                        ->enumNode('refresh')
374 34
                            ->treatTrueLike('true')
375 34
                            ->treatFalseLike('false')
376 34
                            ->values(['true', 'wait_for', 'false'])
377 34
                        ->end()
378 34
                        ->scalarNode('service')->end()
379 34
                    ->end()
380 34
                ->end()
381 34
            ->end();
382
383 34
        return $node;
384
    }
385
386
    /**
387
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
388
     */
389 34
    protected function getSerializerNode()
390
    {
391 34
        $builder = new TreeBuilder();
392 34
        $node = $builder->root('serializer');
393
394
        $node
395 34
            ->addDefaultsIfNotSet()
396 34
            ->children()
397 34
                ->arrayNode('groups')
398 34
                    ->treatNullLike([])
399 34
                    ->prototype('scalar')->end()
400 34
                ->end()
401 34
                ->scalarNode('version')->end()
402 34
                ->booleanNode('serialize_null')
403 34
                    ->defaultFalse()
404 34
                ->end()
405 34
            ->end();
406
407 34
        return $node;
408
    }
409
410
    /**
411
     * Adds the configuration for the "clients" key.
412
     */
413 34
    private function addClientsSection(ArrayNodeDefinition $rootNode)
414
    {
415
        $rootNode
416 34
            ->fixXmlConfig('client')
417 34
            ->children()
418 34
                ->arrayNode('clients')
419 34
                    ->useAttributeAsKey('id')
420 34
                    ->prototype('array')
421 34
                        ->performNoDeepMerging()
422
                        // Elastica names its properties with camel case, support both
423 34
                        ->beforeNormalization()
424 34
                        ->ifTrue(function ($v) {
425 32
                            return isset($v['connection_strategy']);
426 34
                        })
427 34
                        ->then(function ($v) {
428 5
                            $v['connectionStrategy'] = $v['connection_strategy'];
429 5
                            unset($v['connection_strategy']);
430
431 5
                            return $v;
432 34
                        })
433 34
                        ->end()
434
                        // If there is no connections array key defined, assume a single connection.
435 34
                        ->beforeNormalization()
436 34
                        ->ifTrue(function ($v) {
437 32
                            return is_array($v) && !array_key_exists('connections', $v);
438 34
                        })
439 34
                        ->then(function ($v) {
440
                            return [
441 32
                                'connections' => [$v],
442
                            ];
443 34
                        })
444 34
                        ->end()
445 34
                        ->children()
446 34
                            ->arrayNode('connections')
447 34
                                ->requiresAtLeastOneElement()
448 34
                                ->prototype('array')
449 34
                                    ->fixXmlConfig('header')
450 34
                                    ->children()
451 34
                                        ->scalarNode('url')
452 34
                                            ->validate()
453 34
                                                ->ifTrue(function ($url) {
454 19
                                                    return $url && '/' !== substr($url, -1);
455 34
                                                })
456 34
                                                ->then(function ($url) {
457 19
                                                    return $url.'/';
458 34
                                                })
459 34
                                            ->end()
460 34
                                        ->end()
461 34
                                        ->scalarNode('username')->end()
462 34
                                        ->scalarNode('password')->end()
463 34
                                        ->scalarNode('host')->end()
464 34
                                        ->scalarNode('port')->end()
465 34
                                        ->scalarNode('proxy')->end()
466 34
                                        ->scalarNode('aws_access_key_id')->end()
467 34
                                        ->scalarNode('aws_secret_access_key')->end()
468 34
                                        ->scalarNode('aws_region')->end()
469 34
                                        ->scalarNode('aws_session_token')->end()
470 34
                                        ->booleanNode('ssl')->defaultValue(false)->end()
471 34
                                        ->scalarNode('logger')
472 34
                                            ->defaultValue($this->debug ? 'fos_elastica.logger' : false)
473 34
                                            ->treatNullLike('fos_elastica.logger')
474 34
                                            ->treatTrueLike('fos_elastica.logger')
475 34
                                        ->end()
476 34
                                        ->booleanNode('compression')->defaultValue(false)->end()
477 34
                                        ->arrayNode('headers')
478 34
                                            ->normalizeKeys(false)
479 34
                                            ->useAttributeAsKey('name')
480 34
                                            ->prototype('scalar')->end()
481 34
                                        ->end()
482 34
                                        ->arrayNode('curl')
483 34
                                            ->useAttributeAsKey(CURLOPT_SSL_VERIFYPEER)
484 34
                                            ->prototype('boolean')->end()
485 34
                                        ->end()
486 34
                                        ->scalarNode('transport')->end()
487 34
                                        ->scalarNode('timeout')->end()
488 34
                                        ->scalarNode('connectTimeout')->end()
489 34
                                        ->scalarNode('retryOnConflict')
490 34
                                            ->defaultValue(0)
491 34
                                        ->end()
492 34
                                    ->end()
493 34
                                ->end()
494 34
                            ->end()
495 34
                            ->scalarNode('timeout')->end()
496 34
                            ->scalarNode('connectTimeout')->end()
497 34
                            ->scalarNode('headers')->end()
498 34
                            ->scalarNode('connectionStrategy')->defaultValue('Simple')->end()
499 34
                        ->end()
500 34
                    ->end()
501 34
                ->end()
502 34
            ->end()
503
        ;
504 34
    }
505
506
    /**
507
     * Adds the configuration for the "indexes" key.
508
     */
509 34
    private function addIndexesSection(ArrayNodeDefinition $rootNode)
510
    {
511
        $rootNode
512 34
            ->fixXmlConfig('index')
513 34
            ->children()
514 34
                ->arrayNode('indexes')
515 34
                    ->useAttributeAsKey('name')
516 34
                    ->prototype('array')
517 34
                        ->children()
518 34
                            ->scalarNode('index_name')
519 34
                                ->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
520 34
                            ->end()
521 34
                            ->booleanNode('use_alias')->defaultValue(false)->end()
522 34
                            ->scalarNode('client')->end()
523 34
                            ->scalarNode('finder')
524 34
                                ->treatNullLike(true)
525 34
                                ->defaultFalse()
526 34
                            ->end()
527 34
                            ->arrayNode('type_prototype')
528 34
                                ->children()
529 34
                                    ->scalarNode('analyzer')->end()
530 34
                                    ->append($this->getPersistenceNode())
531 34
                                    ->append($this->getSerializerNode())
532 34
                                ->end()
533 34
                            ->end()
534 34
                            ->variableNode('settings')->defaultValue([])->end()
535 34
                        ->end()
536 34
                        ->append($this->getTypesNode())
537 34
                    ->end()
538 34
                ->end()
539 34
            ->end()
540
        ;
541 34
    }
542
543
    /**
544
     * Adds the configuration for the "index_templates" key.
545
     *
546
     * @param ArrayNodeDefinition $rootNode
547
     *
548
     * @return void
549
     */
550 34
    private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode)
551
    {
552
        $rootNode
553 34
            ->fixXmlConfig('index_template')
554 34
            ->children()
555 34
                ->arrayNode('index_templates')
556 34
                    ->useAttributeAsKey('name')
557 34
                    ->prototype('array')
558 34
                        ->children()
559 34
                            ->scalarNode('template_name')
560 34
                                ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch')
561 34
                            ->end()
562 34
                            ->scalarNode('template')->isRequired()->end()
563 34
                            ->scalarNode('client')->end()
564 34
                            ->variableNode('settings')->defaultValue([])->end()
565 34
                        ->end()
566 34
                        ->append($this->getTypesNode())
567 34
                    ->end()
568 34
                ->end()
569 34
            ->end()
570
        ;
571 34
    }
572
}
573