Completed
Push — master ( 212f0a...214901 )
by Lukas Kahwe
23s queued 10s
created

src/DependencyInjection/Configuration.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 35
    public function __construct($debug)
30
    {
31 35
        $this->debug = $debug;
32 35
    }
33
34
    /**
35
     * Generates the configuration tree.
36
     *
37
     * @return TreeBuilder
38
     */
39 35
    public function getConfigTreeBuilder()
40
    {
41 35
        $treeBuilder = new TreeBuilder('fos_elastica');
42
43 35
        if (method_exists($treeBuilder, 'getRootNode')) {
44 35
            $rootNode = $treeBuilder->getRootNode();
45
        } else {
46
            // BC layer for symfony/config 4.1 and older
47
            $rootNode = $treeBuilder->root('fos_elastica');
48
        }
49
50 35
        $this->addClientsSection($rootNode);
51 35
        $this->addIndexesSection($rootNode);
52 35
        $this->addIndexTemplatesSection($rootNode);
53
54
        $rootNode
55 35
            ->children()
56 35
                ->scalarNode('default_client')
57 35
                    ->info('Defaults to the first client defined')
58 35
                ->end()
59 35
                ->scalarNode('default_index')
60 35
                    ->info('Defaults to the first index defined')
61 35
                ->end()
62 35
                ->scalarNode('default_manager')->defaultValue('orm')->end()
63 35
                ->arrayNode('serializer')
64 35
                    ->treatNullLike([])
65 35
                    ->children()
66 35
                        ->scalarNode('callback_class')->defaultValue('FOS\ElasticaBundle\Serializer\Callback')->end()
67 35
                        ->scalarNode('serializer')->defaultValue('serializer')->end()
68 35
                    ->end()
69 35
                ->end()
70 35
            ->end()
71
        ;
72
73 35
        return $treeBuilder;
74
    }
75
76
    /**
77
     * Returns the array node used for "dynamic_templates".
78
     */
79 35
    private function getDynamicTemplateNode()
80
    {
81 35
        $node = $this->createTreeBuilderNode('dynamic_templates');
82
83
        $node
84 35
            ->prototype('array')
85 35
                ->prototype('array')
86 35
                    ->children()
87 35
                        ->scalarNode('match')->end()
88 35
                        ->scalarNode('unmatch')->end()
89 35
                        ->scalarNode('match_mapping_type')->end()
90 35
                        ->scalarNode('path_match')->end()
91 35
                        ->scalarNode('path_unmatch')->end()
92 35
                        ->scalarNode('match_pattern')->end()
93 35
                        ->arrayNode('mapping')
94 35
                            ->prototype('variable')
95 35
                                ->treatNullLike([])
96 35
                            ->end()
97 35
                        ->end()
98 35
                    ->end()
99 35
                ->end()
100 35
            ->end()
101
        ;
102
103 35
        return $node;
104
    }
105
106
    /**
107
     * Returns the array node used for "types".
108
     */
109 35
    private function getTypesNode()
110
    {
111 35
        $node = $this->createTreeBuilderNode('types');
112
113
        $node
114 35
            ->useAttributeAsKey('name')
115 35
            ->prototype('array')
116 35
                ->treatNullLike([])
117 35
                ->beforeNormalization()
118 35
                ->ifNull()
119 35
                    ->thenEmptyArray()
120 35
                ->end()
121
                // Support multiple dynamic_template formats to match the old bundle style
122
                // and the way ElasticSearch expects them
123 35
                ->beforeNormalization()
124 35
                ->ifTrue(function ($v) {
125 25
                    return isset($v['dynamic_templates']);
126 35
                })
127 35
                ->then(function ($v) {
128 5
                    $dt = [];
129 5
                    foreach ($v['dynamic_templates'] as $key => $type) {
130 5
                        if (is_int($key)) {
131 5
                            $dt[] = $type;
132
                        } else {
133 5
                            $dt[][$key] = $type;
134
                        }
135
                    }
136
137 5
                    $v['dynamic_templates'] = $dt;
138
139 5
                    return $v;
140 35
                })
141 35
                ->end()
142 35
                ->children()
143 35
                    ->booleanNode('date_detection')->end()
144 35
                    ->arrayNode('dynamic_date_formats')->prototype('scalar')->end()->end()
145 35
                    ->scalarNode('analyzer')->end()
146 35
                    ->booleanNode('numeric_detection')->end()
147 35
                    ->scalarNode('dynamic')->end()
148 35
                    ->variableNode('indexable_callback')->end()
149 35
                    ->append($this->getPersistenceNode())
150 35
                    ->append($this->getSerializerNode())
151 35
                ->end()
152 35
                ->append($this->getIdNode())
153 35
                ->append($this->getPropertiesNode())
154 35
                ->append($this->getDynamicTemplateNode())
155 35
                ->append($this->getSourceNode())
156 35
                ->append($this->getRoutingNode())
157 35
                ->append($this->getParentNode())
158 35
                ->append($this->getAllNode())
159 35
            ->end()
160
        ;
161
162 35
        return $node;
163
    }
164
165
    /**
166
     * Returns the array node used for "properties".
167
     */
168 35
    private function getPropertiesNode()
169
    {
170 35
        $node = $this->createTreeBuilderNode('properties');
171
172
        $node
0 ignored issues
show
The method useAttributeAsKey() does not exist on Symfony\Component\Config...\Builder\NodeDefinition. Did you maybe mean attribute()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
173 35
            ->useAttributeAsKey('name')
174 35
            ->prototype('variable')
175 35
                ->treatNullLike([]);
176
177 35
        return $node;
178
    }
179
180
    /**
181
     * Returns the array node used for "_id".
182
     */
183 35
    private function getIdNode()
184
    {
185 35
        $node = $this->createTreeBuilderNode('_id');
186
187
        $node
188 35
            ->children()
189 35
            ->scalarNode('path')->end()
190 35
            ->end()
191
        ;
192
193 35
        return $node;
194
    }
195
196
    /**
197
     * Returns the array node used for "_source".
198
     */
199 35
    private function getSourceNode()
200
    {
201 35
        $node = $this->createTreeBuilderNode('_source');
202
203
        $node
204 35
            ->children()
205 35
                ->arrayNode('excludes')
206 35
                    ->useAttributeAsKey('name')
207 35
                    ->prototype('scalar')->end()
208 35
                ->end()
209 35
                ->arrayNode('includes')
210 35
                    ->useAttributeAsKey('name')
211 35
                    ->prototype('scalar')->end()
212 35
                ->end()
213 35
                ->scalarNode('compress')->end()
214 35
                ->scalarNode('compress_threshold')->end()
215 35
                ->scalarNode('enabled')->defaultTrue()->end()
216 35
            ->end()
217
        ;
218
219 35
        return $node;
220
    }
221
222
    /**
223
     * Returns the array node used for "_routing".
224
     */
225 35
    private function getRoutingNode()
226
    {
227 35
        $node = $this->createTreeBuilderNode('_routing');
228
229
        $node
230 35
            ->children()
231 35
                ->scalarNode('required')->end()
232 35
                ->scalarNode('path')->end()
233 35
            ->end()
234
        ;
235
236 35
        return $node;
237
    }
238
239
    /**
240
     * Returns the array node used for "_parent".
241
     */
242 35
    private function getParentNode()
243
    {
244 35
        $node = $this->createTreeBuilderNode('_parent');
245
246
        $node
247 35
            ->children()
248 35
                ->scalarNode('type')->end()
249 35
                ->scalarNode('property')->defaultValue(null)->end()
250 35
                ->scalarNode('identifier')->defaultValue('id')->end()
251 35
            ->end()
252
        ;
253
254 35
        return $node;
255
    }
256
257
    /**
258
     * Returns the array node used for "_all".
259
     */
260 35
    private function getAllNode()
261
    {
262 35
        $node = $this->createTreeBuilderNode('_all');
263
264
        $node
265 35
            ->children()
266 35
            ->scalarNode('enabled')->defaultValue(true)->end()
267 35
            ->scalarNode('analyzer')->end()
268 35
            ->end()
269
        ;
270
271 35
        return $node;
272
    }
273
274
    /**
275
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
276
     */
277 35
    private function getPersistenceNode()
278
    {
279 35
        $node = $this->createTreeBuilderNode('persistence');
280
281
        $node
282 35
            ->validate()
283 35
                ->ifTrue(function ($v) {
284 17
                    return isset($v['driver']) && 'orm' !== $v['driver'] && !empty($v['elastica_to_model_transformer']['hints']);
285 35
                })
286 35
                    ->thenInvalid('Hints are only supported by the "orm" driver')
287 35
            ->end()
288 35
            ->children()
289 35
                ->scalarNode('driver')
290 35
                    ->defaultValue('orm')
291 35
                    ->validate()
292 35
                    ->ifNotInArray(self::SUPPORTED_DRIVERS)
293 35
                        ->thenInvalid('The driver %s is not supported. Please choose one of '.json_encode(self::SUPPORTED_DRIVERS))
294 35
                    ->end()
295 35
                ->end()
296 35
                ->scalarNode('model')->defaultValue(null)->end()
297 35
                ->scalarNode('repository')->end()
298 35
                ->scalarNode('identifier')->defaultValue('id')->end()
299 35
                ->arrayNode('provider')
300 35
                    ->addDefaultsIfNotSet()
301 35
                    ->children()
302 35
                        ->scalarNode('batch_size')->defaultValue(100)->end()
303 35
                        ->scalarNode('clear_object_manager')->defaultTrue()->end()
304 35
                        ->scalarNode('debug_logging')
305 35
                            ->defaultValue($this->debug)
306 35
                            ->treatNullLike(true)
307 35
                        ->end()
308 35
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
309 35
                        ->scalarNode('service')->end()
310 35
                    ->end()
311 35
                ->end()
312 35
                ->arrayNode('listener')
313 35
                    ->addDefaultsIfNotSet()
314 35
                    ->children()
315 35
                        ->booleanNode('enabled')->defaultTrue()->end()
316 35
                        ->scalarNode('insert')->defaultTrue()->end()
317 35
                        ->scalarNode('update')->defaultTrue()->end()
318 35
                        ->scalarNode('delete')->defaultTrue()->end()
319 35
                        ->scalarNode('flush')->defaultTrue()->end()
320 35
                        ->booleanNode('defer')->defaultFalse()->end()
321 35
                        ->scalarNode('logger')
322 35
                            ->defaultFalse()
323 35
                            ->treatNullLike('fos_elastica.logger')
324 35
                            ->treatTrueLike('fos_elastica.logger')
325 35
                        ->end()
326 35
                        ->scalarNode('service')->end()
327 35
                    ->end()
328 35
                ->end()
329 35
                ->arrayNode('finder')
330 35
                    ->addDefaultsIfNotSet()
331 35
                    ->children()
332 35
                        ->scalarNode('service')->end()
333 35
                    ->end()
334 35
                ->end()
335 35
                ->arrayNode('elastica_to_model_transformer')
336 35
                    ->addDefaultsIfNotSet()
337 35
                    ->children()
338 35
                        ->arrayNode('hints')
339 35
                            ->prototype('array')
340 35
                                ->children()
341 35
                                    ->scalarNode('name')->end()
342 35
                                    ->scalarNode('value')->end()
343 35
                                ->end()
344 35
                            ->end()
345 35
                        ->end()
346 35
                        ->booleanNode('hydrate')->defaultTrue()->end()
347 35
                        ->booleanNode('ignore_missing')
348 35
                            ->defaultFalse()
349 35
                            ->info('Silently ignore results returned from Elasticsearch without corresponding persistent object.')
350 35
                        ->end()
351 35
                        ->scalarNode('query_builder_method')->defaultValue('createQueryBuilder')->end()
352 35
                        ->scalarNode('service')->end()
353 35
                    ->end()
354 35
                ->end()
355 35
                ->arrayNode('model_to_elastica_transformer')
356 35
                    ->addDefaultsIfNotSet()
357 35
                    ->children()
358 35
                        ->scalarNode('service')->end()
359 35
                    ->end()
360 35
                ->end()
361 35
                ->arrayNode('persister')
362 35
                    ->addDefaultsIfNotSet()
363 35
                    ->children()
364 35
                        ->enumNode('refresh')
365 35
                            ->treatTrueLike('true')
366 35
                            ->treatFalseLike('false')
367 35
                            ->values(['true', 'wait_for', 'false'])
368 35
                        ->end()
369 35
                        ->scalarNode('service')->end()
370 35
                    ->end()
371 35
                ->end()
372 35
            ->end();
373
374 35
        return $node;
375
    }
376
377
    /**
378
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
379
     */
380 35
    private function getSerializerNode()
381
    {
382 35
        $node = $this->createTreeBuilderNode('serializer');
383
384
        $node
385 35
            ->addDefaultsIfNotSet()
386 35
            ->children()
387 35
                ->arrayNode('groups')
388 35
                    ->treatNullLike([])
389 35
                    ->prototype('scalar')->end()
390 35
                ->end()
391 35
                ->scalarNode('version')->end()
392 35
                ->booleanNode('serialize_null')
393 35
                    ->defaultFalse()
394 35
                ->end()
395 35
            ->end();
396
397 35
        return $node;
398
    }
399
400
    /**
401
     * Adds the configuration for the "clients" key.
402
     */
403 35
    private function addClientsSection(ArrayNodeDefinition $rootNode)
404
    {
405
        $rootNode
406 35
            ->fixXmlConfig('client')
407 35
            ->children()
408 35
                ->arrayNode('clients')
409 35
                    ->useAttributeAsKey('id')
410 35
                    ->prototype('array')
411 35
                        ->performNoDeepMerging()
412
                        // Elastica names its properties with camel case, support both
413 35
                        ->beforeNormalization()
414 35
                        ->ifTrue(function ($v) {
415 33
                            return isset($v['connection_strategy']);
416 35
                        })
417 35
                        ->then(function ($v) {
418 5
                            $v['connectionStrategy'] = $v['connection_strategy'];
419 5
                            unset($v['connection_strategy']);
420
421 5
                            return $v;
422 35
                        })
423 35
                        ->end()
424
                        // If there is no connections array key defined, assume a single connection.
425 35
                        ->beforeNormalization()
426 35
                        ->ifTrue(function ($v) {
427 33
                            return is_array($v) && !array_key_exists('connections', $v);
428 35
                        })
429 35
                        ->then(function ($v) {
430
                            return [
431 33
                                'connections' => [$v],
432
                            ];
433 35
                        })
434 35
                        ->end()
435 35
                        ->children()
436 35
                            ->arrayNode('connections')
437 35
                                ->requiresAtLeastOneElement()
438 35
                                ->prototype('array')
439 35
                                    ->fixXmlConfig('header')
440 35
                                    ->children()
441 35
                                        ->scalarNode('url')
442 35
                                            ->validate()
443 35
                                                ->ifTrue(function ($url) {
444 19
                                                    return $url && '/' !== substr($url, -1);
445 35
                                                })
446 35
                                                ->then(function ($url) {
447 19
                                                    return $url.'/';
448 35
                                                })
449 35
                                            ->end()
450 35
                                        ->end()
451 35
                                        ->scalarNode('username')->end()
452 35
                                        ->scalarNode('password')->end()
453 35
                                        ->scalarNode('host')->end()
454 35
                                        ->scalarNode('port')->end()
455 35
                                        ->scalarNode('proxy')->end()
456 35
                                        ->arrayNode('http_error_codes')
457 35
                                            ->beforeNormalization()
458
                                                ->ifTrue(function ($v) { return !is_array($v); })
459
                                                ->then(function ($v) { return array($v); })
460 35
                                            ->end()
461 35
                                            ->requiresAtLeastOneElement()
462 35
                                            ->defaultValue([400, 403, 404])
463 35
                                            ->prototype('scalar')->end()
464 35
                                        ->end()
465 35
                                        ->scalarNode('aws_access_key_id')->end()
466 35
                                        ->scalarNode('aws_secret_access_key')->end()
467 35
                                        ->scalarNode('aws_region')->end()
468 35
                                        ->scalarNode('aws_session_token')->end()
469 35
                                        ->booleanNode('ssl')->defaultValue(false)->end()
470 35
                                        ->scalarNode('logger')
471 35
                                            ->defaultValue($this->debug ? 'fos_elastica.logger' : false)
472 35
                                            ->treatNullLike('fos_elastica.logger')
473 35
                                            ->treatTrueLike('fos_elastica.logger')
474 35
                                        ->end()
475 35
                                        ->booleanNode('compression')->defaultValue(false)->end()
476 35
                                        ->arrayNode('headers')
477 35
                                            ->normalizeKeys(false)
478 35
                                            ->useAttributeAsKey('name')
479 35
                                            ->prototype('scalar')->end()
480 35
                                        ->end()
481 35
                                        ->arrayNode('curl')
482 35
                                            ->useAttributeAsKey(CURLOPT_SSL_VERIFYPEER)
483 35
                                            ->prototype('boolean')->end()
484 35
                                        ->end()
485 35
                                        ->scalarNode('transport')->end()
486 35
                                        ->scalarNode('timeout')->end()
487 35
                                        ->scalarNode('connectTimeout')->end()
488 35
                                        ->scalarNode('retryOnConflict')
489 35
                                            ->defaultValue(0)
490 35
                                        ->end()
491 35
                                        ->booleanNode('persistent')->defaultValue(true)->end()
492 35
                                    ->end()
493 35
                                ->end()
494 35
                            ->end()
495 35
                            ->scalarNode('timeout')->end()
496 35
                            ->scalarNode('connectTimeout')->end()
497 35
                            ->scalarNode('headers')->end()
498 35
                            ->scalarNode('connectionStrategy')->defaultValue('Simple')->end()
499 35
                        ->end()
500 35
                    ->end()
501 35
                ->end()
502 35
            ->end()
503
        ;
504 35
    }
505
506
    /**
507
     * Adds the configuration for the "indexes" key.
508
     */
509 35
    private function addIndexesSection(ArrayNodeDefinition $rootNode)
510
    {
511
        $rootNode
512 35
            ->fixXmlConfig('index')
513 35
            ->children()
514 35
                ->arrayNode('indexes')
515 35
                    ->useAttributeAsKey('name')
516 35
                    ->prototype('array')
517 35
                        ->children()
518 35
                            ->scalarNode('index_name')
519 35
                                ->info('Defaults to the name of the index, but can be modified if the index name is different in ElasticSearch')
520 35
                            ->end()
521 35
                            ->booleanNode('use_alias')->defaultValue(false)->end()
522 35
                            ->scalarNode('client')->end()
523 35
                            ->scalarNode('finder')
524 35
                                ->treatNullLike(true)
525 35
                                ->defaultFalse()
526 35
                            ->end()
527 35
                            ->arrayNode('type_prototype')
528 35
                                ->children()
529 35
                                    ->scalarNode('analyzer')->end()
530 35
                                    ->append($this->getPersistenceNode())
531 35
                                    ->append($this->getSerializerNode())
532 35
                                ->end()
533 35
                            ->end()
534 35
                            ->variableNode('settings')->defaultValue([])->end()
535 35
                        ->end()
536 35
                        ->append($this->getTypesNode())
537 35
                    ->end()
538 35
                ->end()
539 35
            ->end()
540
        ;
541 35
    }
542
543
    /**
544
     * @return ArrayNodeDefinition|\Symfony\Component\Config\Definition\Builder\NodeDefinition
545
     */
546 35
    private function createTreeBuilderNode($name)
547
    {
548 35
        $builder = new TreeBuilder($name);
549
550 35
        if (method_exists($builder, 'getRootNode')) {
551 35
            $node = $builder->getRootNode();
552
        } else {
553
            // BC layer for symfony/config 4.1 and older
554
            $node = $builder->root($name);
555
        }
556
557 35
        return $node;
558
    }
559
560
    /**
561
     * Adds the configuration for the "index_templates" key.
562
     *
563
     * @param ArrayNodeDefinition $rootNode
564
     *
565
     * @return void
566
     */
567 35
    private function addIndexTemplatesSection(ArrayNodeDefinition $rootNode)
568
    {
569
        $rootNode
570 35
            ->fixXmlConfig('index_template')
571 35
            ->children()
572 35
                ->arrayNode('index_templates')
573 35
                    ->useAttributeAsKey('name')
574 35
                    ->prototype('array')
575 35
                        ->children()
576 35
                            ->scalarNode('template_name')
577 35
                                ->info('Defaults to the name of the index template, but can be modified if the index name is different in ElasticSearch')
578 35
                            ->end()
579 35
                            ->scalarNode('template')->isRequired()->end()
580 35
                            ->scalarNode('client')->end()
581 35
                            ->variableNode('settings')->defaultValue([])->end()
582 35
                        ->end()
583 35
                        ->append($this->getTypesNode())
584 35
                    ->end()
585 35
                ->end()
586 35
            ->end()
587
        ;
588 35
    }
589
}
590