Completed
Pull Request — master (#1343)
by Dmitry
06:23
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();
42 31
        $rootNode = $treeBuilder->root('fos_elastica', 'array');
43
44 31
        $this->addClientsSection($rootNode);
45 31
        $this->addIndexesSection($rootNode);
46 31
        $this->addIndexTemplatesSection($rootNode);
47
48
        $rootNode
49 31
            ->children()
50 31
                ->scalarNode('default_client')
51 31
                    ->info('Defaults to the first client defined')
52 31
                ->end()
53 31
                ->scalarNode('default_index')
54 31
                    ->info('Defaults to the first index defined')
55 31
                ->end()
56 31
                ->scalarNode('default_manager')->defaultValue('orm')->end()
57 31
                ->arrayNode('serializer')
58 31
                    ->treatNullLike([])
59 31
                    ->children()
60 31
                        ->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
61 31
                        ->scalarNode('serializer')->defaultValue('serializer')->end()
62 31
                    ->end()
63 31
                ->end()
64 31
            ->end()
65
        ;
66
67 31
        return $treeBuilder;
68
    }
69
70
    /**
71
     * Returns the array node used for "dynamic_templates".
72
     */
73 31
    public function getDynamicTemplateNode()
74
    {
75 31
        $builder = new TreeBuilder();
76 31
        $node = $builder->root('dynamic_templates');
77
78
        $node
79 31
            ->prototype('array')
80 31
                ->prototype('array')
81 31
                    ->children()
82 31
                        ->scalarNode('match')->end()
83 31
                        ->scalarNode('unmatch')->end()
84 31
                        ->scalarNode('match_mapping_type')->end()
85 31
                        ->scalarNode('path_match')->end()
86 31
                        ->scalarNode('path_unmatch')->end()
87 31
                        ->scalarNode('match_pattern')->end()
88 31
                        ->arrayNode('mapping')
89 31
                            ->prototype('variable')
90 31
                                ->treatNullLike([])
91 31
                            ->end()
92 31
                        ->end()
93 31
                    ->end()
94 31
                ->end()
95 31
            ->end()
96
        ;
97
98 31
        return $node;
99
    }
100
101
    /**
102
     * Returns the array node used for "types".
103
     */
104 31
    protected function getTypesNode()
105
    {
106 31
        $builder = new TreeBuilder();
107 31
        $node = $builder->root('types');
108
109
        $node
110 31
            ->useAttributeAsKey('name')
111 31
            ->prototype('array')
112 31
                ->treatNullLike([])
113 31
                ->beforeNormalization()
114 31
                ->ifNull()
115 31
                    ->thenEmptyArray()
116 31
                ->end()
117
                // Support multiple dynamic_template formats to match the old bundle style
118
                // and the way ElasticSearch expects them
119 31
                ->beforeNormalization()
120 31
                ->ifTrue(function ($v) {
121 22
                    return isset($v['dynamic_templates']);
122 31
                })
123 31
                ->then(function ($v) {
124 4
                    $dt = [];
125 4
                    foreach ($v['dynamic_templates'] as $key => $type) {
126 4
                        if (is_int($key)) {
127 4
                            $dt[] = $type;
128
                        } else {
129 4
                            $dt[][$key] = $type;
130
                        }
131
                    }
132
133 4
                    $v['dynamic_templates'] = $dt;
134
135 4
                    return $v;
136 31
                })
137 31
                ->end()
138 31
                ->children()
139 31
                    ->booleanNode('date_detection')->end()
140 31
                    ->arrayNode('dynamic_date_formats')->prototype('scalar')->end()->end()
141 31
                    ->scalarNode('analyzer')->end()
142 31
                    ->booleanNode('numeric_detection')->end()
143 31
                    ->scalarNode('dynamic')->end()
144 31
                    ->variableNode('indexable_callback')->end()
145 31
                    ->append($this->getPersistenceNode())
146 31
                    ->append($this->getSerializerNode())
147 31
                ->end()
148 31
                ->append($this->getIdNode())
149 31
                ->append($this->getPropertiesNode())
150 31
                ->append($this->getDynamicTemplateNode())
151 31
                ->append($this->getSourceNode())
152 31
                ->append($this->getRoutingNode())
153 31
                ->append($this->getParentNode())
154 31
                ->append($this->getAllNode())
155 31
            ->end()
156
        ;
157
158 31
        return $node;
159
    }
160
161
    /**
162
     * Returns the array node used for "properties".
163
     */
164 31
    protected function getPropertiesNode()
165
    {
166 31
        $builder = new TreeBuilder();
167 31
        $node = $builder->root('properties');
168
169
        $node
170 31
            ->useAttributeAsKey('name')
171 31
            ->prototype('variable')
172 31
                ->treatNullLike([]);
173
174 31
        return $node;
175
    }
176
177
    /**
178
     * Returns the array node used for "_id".
179
     */
180 31 View Code Duplication
    protected function getIdNode()
181
    {
182 31
        $builder = new TreeBuilder();
183 31
        $node = $builder->root('_id');
184
185
        $node
186 31
            ->children()
187 31
            ->scalarNode('path')->end()
188 31
            ->end()
189
        ;
190
191 31
        return $node;
192
    }
193
194
    /**
195
     * Returns the array node used for "_source".
196
     */
197 31
    protected function getSourceNode()
198
    {
199 31
        $builder = new TreeBuilder();
200 31
        $node = $builder->root('_source');
201
202
        $node
203 31
            ->children()
204 31
                ->arrayNode('excludes')
205 31
                    ->useAttributeAsKey('name')
206 31
                    ->prototype('scalar')->end()
207 31
                ->end()
208 31
                ->arrayNode('includes')
209 31
                    ->useAttributeAsKey('name')
210 31
                    ->prototype('scalar')->end()
211 31
                ->end()
212 31
                ->scalarNode('compress')->end()
213 31
                ->scalarNode('compress_threshold')->end()
214 31
                ->scalarNode('enabled')->defaultTrue()->end()
215 31
            ->end()
216
        ;
217
218 31
        return $node;
219
    }
220
221
    /**
222
     * Returns the array node used for "_routing".
223
     */
224 31 View Code Duplication
    protected function getRoutingNode()
225
    {
226 31
        $builder = new TreeBuilder();
227 31
        $node = $builder->root('_routing');
228
229
        $node
230 31
            ->children()
231 31
                ->scalarNode('required')->end()
232 31
                ->scalarNode('path')->end()
233 31
            ->end()
234
        ;
235
236 31
        return $node;
237
    }
238
239
    /**
240
     * Returns the array node used for "_parent".
241
     */
242 31
    protected function getParentNode()
243
    {
244 31
        $builder = new TreeBuilder();
245 31
        $node = $builder->root('_parent');
246
247
        $node
248 31
            ->children()
249 31
                ->scalarNode('type')->end()
250 31
                ->scalarNode('property')->defaultValue(null)->end()
251 31
                ->scalarNode('identifier')->defaultValue('id')->end()
252 31
            ->end()
253
        ;
254
255 31
        return $node;
256
    }
257
258
    /**
259
     * Returns the array node used for "_all".
260
     */
261 31
    protected function getAllNode()
262
    {
263 31
        $builder = new TreeBuilder();
264 31
        $node = $builder->root('_all');
265
266
        $node
267 31
            ->children()
268 31
            ->scalarNode('enabled')->defaultValue(true)->end()
269 31
            ->scalarNode('analyzer')->end()
270 31
            ->end()
271
        ;
272
273 31
        return $node;
274
    }
275
276
    /**
277
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
278
     */
279 31
    protected function getPersistenceNode()
280
    {
281 31
        $builder = new TreeBuilder();
282 31
        $node = $builder->root('persistence');
283
284
        $node
285 31
            ->validate()
286 31
                ->ifTrue(function ($v) {
287 17
                    return isset($v['driver']) && 'orm' !== $v['driver'] && !empty($v['elastica_to_model_transformer']['hints']);
288 31
                })
289 31
                    ->thenInvalid('Hints are only supported by the "orm" driver')
290 31
            ->end()
291 31
            ->children()
292 31
                ->scalarNode('driver')
293 31
                    ->defaultValue('orm')
294 31
                    ->validate()
295 31
                    ->ifNotInArray(self::SUPPORTED_DRIVERS)
296 31
                        ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode(self::SUPPORTED_DRIVERS))
297 31
                    ->end()
298 31
                ->end()
299 31
                ->scalarNode('model')->defaultValue(null)->end()
300 31
                ->scalarNode('repository')->end()
301 31
                ->scalarNode('identifier')->defaultValue('id')->end()
302 31
                ->arrayNode('provider')
303 31
                    ->addDefaultsIfNotSet()
304 31
                    ->children()
305 31
                        ->scalarNode('batch_size')->defaultValue(100)->end()
306 31
                        ->scalarNode('clear_object_manager')->defaultTrue()->end()
307 31
                        ->scalarNode('debug_logging')
308 31
                            ->defaultValue($this->debug)
309 31
                            ->treatNullLike(true)
310 31
                        ->end()
311 31
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
312 31
                        ->scalarNode('service')->end()
313 31
                    ->end()
314 31
                ->end()
315 31
                ->arrayNode('listener')
316 31
                    ->addDefaultsIfNotSet()
317 31
                    ->children()
318 31
                        ->booleanNode('enabled')->defaultTrue()->end()
319 31
                        ->scalarNode('insert')->defaultTrue()->end()
320 31
                        ->scalarNode('update')->defaultTrue()->end()
321 31
                        ->scalarNode('delete')->defaultTrue()->end()
322 31
                        ->scalarNode('flush')->defaultTrue()->end()
323 31
                        ->booleanNode('defer')->defaultFalse()->end()
324 31
                        ->scalarNode('logger')
325 31
                            ->defaultFalse()
326 31
                            ->treatNullLike('fos_elastica.logger')
327 31
                            ->treatTrueLike('fos_elastica.logger')
328 31
                        ->end()
329 31
                        ->scalarNode('service')->end()
330 31
                    ->end()
331 31
                ->end()
332 31
                ->arrayNode('finder')
333 31
                    ->addDefaultsIfNotSet()
334 31
                    ->children()
335 31
                        ->scalarNode('service')->end()
336 31
                    ->end()
337 31
                ->end()
338 31
                ->arrayNode('elastica_to_model_transformer')
339 31
                    ->addDefaultsIfNotSet()
340 31
                    ->children()
341 31
                        ->arrayNode('hints')
342 31
                            ->prototype('array')
343 31
                                ->children()
344 31
                                    ->scalarNode('name')->end()
345 31
                                    ->scalarNode('value')->end()
346 31
                                ->end()
347 31
                            ->end()
348 31
                        ->end()
349 31
                        ->booleanNode('hydrate')->defaultTrue()->end()
350 31
                        ->booleanNode('ignore_missing')
351 31
                            ->defaultFalse()
352 31
                            ->info('Silently ignore results returned from Elasticsearch without corresponding persistent object.')
353 31
                        ->end()
354 31
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
355 31
                        ->scalarNode('service')->end()
356 31
                    ->end()
357 31
                ->end()
358 31
                ->arrayNode('model_to_elastica_transformer')
359 31
                    ->addDefaultsIfNotSet()
360 31
                    ->children()
361 31
                        ->scalarNode('service')->end()
362 31
                    ->end()
363 31
                ->end()
364 31
                ->arrayNode('persister')
365 31
                    ->addDefaultsIfNotSet()
366 31
                    ->children()
367 31
                        ->enumNode('refresh')
368 31
                            ->treatTrueLike('true')
369 31
                            ->treatFalseLike('false')
370 31
                            ->values(['true', 'wait_for', 'false'])
371 31
                        ->end()
372 31
                        ->scalarNode('service')->end()
373 31
                    ->end()
374 31
                ->end()
375 31
            ->end();
376
377 31
        return $node;
378
    }
379
380
    /**
381
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
382
     */
383 31
    protected function getSerializerNode()
384
    {
385 31
        $builder = new TreeBuilder();
386 31
        $node = $builder->root('serializer');
387
388
        $node
0 ignored issues
show
Bug introduced by
The method scalarNode() does not seem to exist on object<Symfony\Component...odeDefinitionInterface>.

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...
389 31
            ->addDefaultsIfNotSet()
390 31
            ->children()
391 31
                ->arrayNode('groups')
392 31
                    ->treatNullLike([])
393 31
                    ->prototype('scalar')->end()
394 31
                ->end()
395 31
                ->scalarNode('version')->end()
396 31
                ->booleanNode('serialize_null')
397 31
                    ->defaultFalse()
398 31
                ->end()
399 31
            ->end();
400
401 31
        return $node;
402
    }
403
404
    /**
405
     * Adds the configuration for the "clients" key.
406
     */
407 31
    private function addClientsSection(ArrayNodeDefinition $rootNode)
408
    {
409
        $rootNode
410 31
            ->fixXmlConfig('client')
411 31
            ->children()
412 31
                ->arrayNode('clients')
413 31
                    ->useAttributeAsKey('id')
414 31
                    ->prototype('array')
415 31
                        ->performNoDeepMerging()
416
                        // Elastica names its properties with camel case, support both
417 31
                        ->beforeNormalization()
418 31
                        ->ifTrue(function ($v) {
419 30
                            return isset($v['connection_strategy']);
420 31
                        })
421 31
                        ->then(function ($v) {
422 4
                            $v['connectionStrategy'] = $v['connection_strategy'];
423 4
                            unset($v['connection_strategy']);
424
425 4
                            return $v;
426 31
                        })
427 31
                        ->end()
428
                        // If there is no connections array key defined, assume a single connection.
429 31
                        ->beforeNormalization()
430 31
                        ->ifTrue(function ($v) {
431 30
                            return is_array($v) && !array_key_exists('connections', $v);
432 31
                        })
433 31
                        ->then(function ($v) {
434
                            return [
435 30
                                'connections' => [$v],
436
                            ];
437 31
                        })
438 31
                        ->end()
439 31
                        ->children()
440 31
                            ->arrayNode('connections')
441 31
                                ->requiresAtLeastOneElement()
442 31
                                ->prototype('array')
443 31
                                    ->fixXmlConfig('header')
444 31
                                    ->children()
445 31
                                        ->scalarNode('url')
446 31
                                            ->validate()
447 31
                                                ->ifTrue(function ($url) {
448 18
                                                    return $url && '/' !== substr($url, -1);
449 31
                                                })
450 31
                                                ->then(function ($url) {
451 18
                                                    return $url.'/';
452 31
                                                })
453 31
                                            ->end()
454 31
                                        ->end()
455 31
                                        ->scalarNode('username')->end()
456 31
                                        ->scalarNode('password')->end()
457 31
                                        ->scalarNode('host')->end()
458 31
                                        ->scalarNode('port')->end()
459 31
                                        ->scalarNode('proxy')->end()
460 31
                                        ->scalarNode('aws_access_key_id')->end()
461 31
                                        ->scalarNode('aws_secret_access_key')->end()
462 31
                                        ->scalarNode('aws_region')->end()
463 31
                                        ->scalarNode('aws_session_token')->end()
464 31
                                        ->booleanNode('ssl')->defaultValue(false)->end()
465 31
                                        ->scalarNode('logger')
466 31
                                            ->defaultValue($this->debug ? 'fos_elastica.logger' : false)
467 31
                                            ->treatNullLike('fos_elastica.logger')
468 31
                                            ->treatTrueLike('fos_elastica.logger')
469 31
                                        ->end()
470 31
                                        ->booleanNode('compression')->defaultValue(false)->end()
471 31
                                        ->arrayNode('headers')
472 31
                                            ->normalizeKeys(false)
473 31
                                            ->useAttributeAsKey('name')
474 31
                                            ->prototype('scalar')->end()
475 31
                                        ->end()
476 31
                                        ->arrayNode('curl')
477 31
                                            ->useAttributeAsKey(CURLOPT_SSL_VERIFYPEER)
478 31
                                            ->prototype('boolean')->end()
479 31
                                        ->end()
480 31
                                        ->scalarNode('transport')->end()
481 31
                                        ->scalarNode('timeout')->end()
482 31
                                        ->scalarNode('connectTimeout')->end()
483 31
                                        ->scalarNode('retryOnConflict')
484 31
                                            ->defaultValue(0)
485 31
                                        ->end()
486 31
                                    ->end()
487 31
                                ->end()
488 31
                            ->end()
489 31
                            ->scalarNode('timeout')->end()
490 31
                            ->scalarNode('connectTimeout')->end()
491 31
                            ->scalarNode('headers')->end()
492 31
                            ->scalarNode('connectionStrategy')->defaultValue('Simple')->end()
493 31
                        ->end()
494 31
                    ->end()
495 31
                ->end()
496 31
            ->end()
497
        ;
498 31
    }
499
500
    /**
501
     * Adds the configuration for the "indexes" key.
502
     */
503 31
    private function addIndexesSection(ArrayNodeDefinition $rootNode)
504
    {
505
        $rootNode
506 31
            ->fixXmlConfig('index')
507 31
            ->children()
508 31
                ->arrayNode('indexes')
509 31
                    ->useAttributeAsKey('name')
510 31
                    ->prototype('array')
511 31
                        ->children()
512 31
                            ->scalarNode('index_name')
513 31
                                ->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
514 31
                            ->end()
515 31
                            ->booleanNode('use_alias')->defaultValue(false)->end()
516 31
                            ->scalarNode('client')->end()
517 31
                            ->scalarNode('finder')
518 31
                                ->treatNullLike(true)
519 31
                                ->defaultFalse()
520 31
                            ->end()
521 31
                            ->arrayNode('type_prototype')
522 31
                                ->children()
523 31
                                    ->scalarNode('analyzer')->end()
524 31
                                    ->append($this->getPersistenceNode())
525 31
                                    ->append($this->getSerializerNode())
526 31
                                ->end()
527 31
                            ->end()
528 31
                            ->variableNode('settings')->defaultValue([])->end()
529 31
                        ->end()
530 31
                        ->append($this->getTypesNode())
531 31
                    ->end()
532 31
                ->end()
533 31
            ->end()
534
        ;
535 31
    }
536
537
    /**
538
     * Adds the configuration for the "index_templates" key.
539
     *
540
     * @param ArrayNodeDefinition $rootNode
541
     *
542
     * @return void
543
     */
544 31
    private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode)
545
    {
546
        $rootNode
547 31
            ->fixXmlConfig('index_template')
548 31
            ->children()
549 31
                ->arrayNode('index_templates')
550 31
                    ->useAttributeAsKey('name')
551 31
                    ->prototype('array')
552 31
                        ->children()
553 31
                            ->scalarNode('template_name')
554 31
                                ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch')
555 31
                            ->end()
556 31
                            ->scalarNode('template')->isRequired()->end()
557 31
                            ->scalarNode('client')->end()
558 31
                            ->variableNode('settings')->defaultValue([])->end()
559 31
                        ->end()
560 31
                        ->append($this->getTypesNode())
561 31
                    ->end()
562 31
                ->end()
563 31
            ->end()
564
        ;
565 31
    }
566
}
567