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