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