Completed
Pull Request — master (#1343)
by Dmitry
05:26
created

Configuration::addIndexTemplatesSection()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.568
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 1
nc 1
nop 1
crap 2
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
        $this->addIndexTemplatesSection($rootNode);
47
48 30
        $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
            ->end()
65
        ;
66 30
67
        return $treeBuilder;
68
    }
69
70
    /**
71
     * Returns the array node used for "dynamic_templates".
72 30
     */
73
    public function getDynamicTemplateNode()
74 30
    {
75 30
        $builder = new TreeBuilder();
76
        $node = $builder->root('dynamic_templates');
77
78 30
        $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
            ->end()
96
        ;
97 30
98
        return $node;
99
    }
100
101
    /**
102
     * Returns the array node used for "types".
103 30
     */
104
    protected function getTypesNode()
105 30
    {
106 30
        $builder = new TreeBuilder();
107
        $node = $builder->root('types');
108
109 30
        $node
110 30
            ->useAttributeAsKey('name')
111 30
            ->prototype('array')
112 30
                ->treatNullLike([])
113 30
                ->beforeNormalization()
114 30
                ->ifNull()
115 30
                    ->thenEmptyArray()
116
                ->end()
117
                // Support multiple dynamic_template formats to match the old bundle style
118 30
                // and the way ElasticSearch expects them
119 30
                ->beforeNormalization()
120 21
                ->ifTrue(function ($v) {
121 30
                    return isset($v['dynamic_templates']);
122 30
                })
123 3
                ->then(function ($v) {
124 3
                    $dt = [];
125 3
                    foreach ($v['dynamic_templates'] as $key => $type) {
126 3
                        if (is_int($key)) {
127
                            $dt[] = $type;
128 3
                        } else {
129
                            $dt[][$key] = $type;
130
                        }
131
                    }
132 3
133
                    $v['dynamic_templates'] = $dt;
134 3
135 30
                    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
            ->end()
156
        ;
157 30
158
        return $node;
159
    }
160
161
    /**
162
     * Returns the array node used for "properties".
163 30
     */
164
    protected function getPropertiesNode()
165 30
    {
166 30
        $builder = new TreeBuilder();
167
        $node = $builder->root('properties');
168
169 30
        $node
170 30
            ->useAttributeAsKey('name')
171 30
            ->prototype('variable')
172
                ->treatNullLike([]);
173 30
174
        return $node;
175
    }
176
177
    /**
178
     * Returns the array node used for "_id".
179 30
     */
180 View Code Duplication
    protected function getIdNode()
181 30
    {
182 30
        $builder = new TreeBuilder();
183
        $node = $builder->root('_id');
184
185 30
        $node
186 30
            ->children()
187 30
            ->scalarNode('path')->end()
188
            ->end()
189
        ;
190 30
191
        return $node;
192
    }
193
194
    /**
195
     * Returns the array node used for "_source".
196 30
     */
197
    protected function getSourceNode()
198 30
    {
199 30
        $builder = new TreeBuilder();
200
        $node = $builder->root('_source');
201
202 30
        $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
            ->end()
216
        ;
217 30
218
        return $node;
219
    }
220
221
    /**
222
     * Returns the array node used for "_routing".
223 30
     */
224 View Code Duplication
    protected function getRoutingNode()
225 30
    {
226 30
        $builder = new TreeBuilder();
227
        $node = $builder->root('_routing');
228
229 30
        $node
230 30
            ->children()
231 30
                ->scalarNode('required')->end()
232 30
                ->scalarNode('path')->end()
233
            ->end()
234
        ;
235 30
236
        return $node;
237
    }
238
239
    /**
240
     * Returns the array node used for "_parent".
241 30
     */
242
    protected function getParentNode()
243 30
    {
244 30
        $builder = new TreeBuilder();
245
        $node = $builder->root('_parent');
246
247 30
        $node
248 30
            ->children()
249 30
                ->scalarNode('type')->end()
250 30
                ->scalarNode('property')->defaultValue(null)->end()
251 30
                ->scalarNode('identifier')->defaultValue('id')->end()
252
            ->end()
253
        ;
254 30
255
        return $node;
256
    }
257
258
    /**
259
     * Returns the array node used for "_all".
260 30
     */
261
    protected function getAllNode()
262 30
    {
263 30
        $builder = new TreeBuilder();
264
        $node = $builder->root('_all');
265
266 30
        $node
267 30
            ->children()
268 30
            ->scalarNode('enabled')->defaultValue(true)->end()
269 30
            ->scalarNode('analyzer')->end()
270
            ->end()
271
        ;
272 30
273
        return $node;
274
    }
275
276
    /**
277
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
278 30
     */
279
    protected function getPersistenceNode()
280 30
    {
281 30
        $builder = new TreeBuilder();
282
        $node = $builder->root('persistence');
283
284 30
        $node
285 30
            ->validate()
286 17
                ->ifTrue(function ($v) {
287 30
                    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
            ->end();
376 30
377
        return $node;
378
    }
379
380
    /**
381
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
382 30
     */
383
    protected function getSerializerNode()
384 30
    {
385 30
        $builder = new TreeBuilder();
386
        $node = $builder->root('serializer');
387
388 30
        $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
            ->end();
400 30
401
        return $node;
402
    }
403
404
    /**
405
     * Adds the configuration for the "clients" key.
406 30
     */
407
    private function addClientsSection(ArrayNodeDefinition $rootNode)
408
    {
409 30
        $rootNode
410 30
            ->fixXmlConfig('client')
411 30
            ->children()
412 30
                ->arrayNode('clients')
413 30
                    ->useAttributeAsKey('id')
414 30
                    ->prototype('array')
415
                        ->performNoDeepMerging()
416 30
                        // Elastica names its properties with camel case, support both
417 30
                        ->beforeNormalization()
418 29
                        ->ifTrue(function ($v) {
419 30
                            return isset($v['connection_strategy']);
420 30
                        })
421 3
                        ->then(function ($v) {
422 3
                            $v['connectionStrategy'] = $v['connection_strategy'];
423
                            unset($v['connection_strategy']);
424 3
425 30
                            return $v;
426 30
                        })
427
                        ->end()
428 30
                        // If there is no connections array key defined, assume a single connection.
429 30
                        ->beforeNormalization()
430 29
                        ->ifTrue(function ($v) {
431 30
                            return is_array($v) && !array_key_exists('connections', $v);
432 30
                        })
433
                        ->then(function ($v) {
434 29
                            return [
435
                                'connections' => [$v],
436 30
                            ];
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 17
                                                ->ifTrue(function ($url) {
448 30
                                                    return $url && '/' !== substr($url, -1);
449 30
                                                })
450 17
                                                ->then(function ($url) {
451 30
                                                    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
            ->end()
497 30
        ;
498
    }
499
500
    /**
501
     * Adds the configuration for the "indexes" key.
502 30
     */
503
    private function addIndexesSection(ArrayNodeDefinition $rootNode)
504
    {
505 30
        $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
            ->end()
534 30
        ;
535
    }
536
537
    /**
538
     * Adds the configuration for the "index_templates" key.
539
     *
540
     * @param ArrayNodeDefinition $rootNode
541
     *
542
     * @return void
543
     */
544
    private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode)
545
    {
546
        $rootNode
547
            ->fixXmlConfig('index_template')
548
            ->children()
549
                ->arrayNode('index_templates')
550
                    ->useAttributeAsKey('name')
551
                    ->prototype('array')
552
                        ->children()
553
                            ->scalarNode('template_name')
554
                                ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch')
555
                            ->end()
556
                            ->scalarNode('template')->isRequired()->end()
557
                            ->scalarNode('client')->end()
558
                            ->variableNode('settings')->defaultValue([])->end()
559
                        ->end()
560
                        ->append($this->getTypesNode())
561
                    ->end()
562
                ->end()
563
            ->end()
564
        ;
565
    }
566
}
567