Completed
Pull Request — master (#1240)
by Maksim
03:38
created

FOSElasticaExtension::loadTypes()   F

Complexity

Conditions 13
Paths 649

Size

Total Lines 85
Code Lines 55

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 36
CRAP Score 13

Importance

Changes 0
Metric Value
dl 0
loc 85
ccs 36
cts 36
cp 1
rs 2.4575
c 0
b 0
f 0
cc 13
eloc 55
nc 649
nop 4
crap 13

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 InvalidArgumentException;
15
use Symfony\Component\Config\FileLocator;
16
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\DefinitionDecorator;
19
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
20
use Symfony\Component\DependencyInjection\Reference;
21
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
22
23
class FOSElasticaExtension extends Extension
24
{
25
    /**
26
     * Definition of elastica clients as configured by this extension.
27
     *
28
     * @var array
29
     */
30
    private $clients = [];
31
32
    /**
33
     * An array of indexes as configured by the extension.
34
     *
35
     * @var array
36
     */
37
    private $indexConfigs = [];
38
39
    /**
40
     * If we've encountered a type mapped to a specific persistence driver, it will be loaded
41
     * here.
42
     *
43
     * @var array
44
     */
45
    private $loadedDrivers = [];
46
47 5
    public function load(array $configs, ContainerBuilder $container)
48
    {
49 5
        $configuration = $this->getConfiguration($configs, $container);
50 5
        $config = $this->processConfiguration($configuration, $configs);
51
52 5
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
53
54 5
        if (empty($config['clients']) || empty($config['indexes'])) {
55
            // No Clients or indexes are defined
56
            return;
57
        }
58
59 5
        foreach (['config', 'index', 'persister', 'provider', 'source', 'transformer', 'event_listener'] as $basename) {
60 5
            $loader->load(sprintf('%s.xml', $basename));
61
        }
62
63 5
        if (empty($config['default_client'])) {
64 5
            $keys = array_keys($config['clients']);
65 5
            $config['default_client'] = reset($keys);
66
        }
67
68 5
        if (empty($config['default_index'])) {
69 5
            $keys = array_keys($config['indexes']);
70 5
            $config['default_index'] = reset($keys);
71
        }
72
73 5
        if (isset($config['serializer'])) {
74 1
            $loader->load('serializer.xml');
75
76 1
            $this->loadSerializer($config['serializer'], $container);
77
        }
78
79 5
        $this->loadClients($config['clients'], $container);
80 5
        $container->setAlias('fos_elastica.client', sprintf('fos_elastica.client.%s', $config['default_client']));
81
82 5
        $this->loadIndexes($config['indexes'], $container);
83 5
        $container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
84
85 5
        $container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs);
86
87 5
        $this->loadIndexManager($container);
88
89 5
        $this->createDefaultManagerAlias($config['default_manager'], $container);
90 5
    }
91
92
    /**
93
     * @param array            $config
94
     * @param ContainerBuilder $container
95
     *
96
     * @return Configuration
97
     */
98 5
    public function getConfiguration(array $config, ContainerBuilder $container)
99
    {
100 5
        return new Configuration($container->getParameter('kernel.debug'));
101
    }
102
103
    /**
104
     * Loads the configured clients.
105
     *
106
     * @param array            $clients   An array of clients configurations
107
     * @param ContainerBuilder $container A ContainerBuilder instance
108
     *
109
     * @return array
110
     */
111 5
    private function loadClients(array $clients, ContainerBuilder $container)
112
    {
113 5
        foreach ($clients as $name => $clientConfig) {
114 5
            $clientId = sprintf('fos_elastica.client.%s', $name);
115
116 5
            $clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
117 5
            $clientDef->replaceArgument(0, $clientConfig);
118
119 5
            $logger = $clientConfig['connections'][0]['logger'];
120 5
            if (false !== $logger) {
121 5
                $clientDef->addMethodCall('setLogger', [new Reference($logger)]);
122
            }
123
124 5
            $clientDef->addTag('fos_elastica.client');
125
126 5
            $container->setDefinition($clientId, $clientDef);
127
128 5
            $this->clients[$name] = [
129 5
                'id' => $clientId,
130 5
                'reference' => new Reference($clientId),
131
            ];
132
        }
133 5
    }
134
135
    /**
136
     * Loads the configured indexes.
137
     *
138
     * @param array            $indexes   An array of indexes configurations
139
     * @param ContainerBuilder $container A ContainerBuilder instance
140
     *
141
     * @throws \InvalidArgumentException
142
     *
143
     * @return array
144
     */
145 5
    private function loadIndexes(array $indexes, ContainerBuilder $container)
146
    {
147 5
        $indexableCallbacks = [];
148
149 5
        foreach ($indexes as $name => $index) {
150 5
            $indexId = sprintf('fos_elastica.index.%s', $name);
151 5
            $indexName = isset($index['index_name']) ? $index['index_name'] : $name;
152
153 5
            $indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
154 5
            $indexDef->setFactory([new Reference('fos_elastica.client'), 'getIndex']);
155 5
            $indexDef->replaceArgument(0, $indexName);
156 5
            $indexDef->addTag('fos_elastica.index', [
157 5
                'name' => $name,
158
            ]);
159
160 5
            if (isset($index['client'])) {
161 2
                $client = $this->getClient($index['client']);
162
163 2
                $indexDef->setFactory([$client, 'getIndex']);
164
            }
165
166 5
            $container->setDefinition($indexId, $indexDef);
167 5
            $reference = new Reference($indexId);
168
169 5
            $this->indexConfigs[$name] = [
170 5
                'elasticsearch_name' => $indexName,
171 5
                'reference' => $reference,
172 5
                'name' => $name,
173 5
                'settings' => $index['settings'],
174 5
                'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : [],
175 5
                'use_alias' => $index['use_alias'],
176
            ];
177
178 5
            if ($index['finder']) {
179
                $this->loadIndexFinder($container, $name, $reference);
180
            }
181
182 5
            $this->loadTypes((array) $index['types'], $container, $this->indexConfigs[$name], $indexableCallbacks);
183
        }
184
185 5
        $indexable = $container->getDefinition('fos_elastica.indexable');
186 5
        $indexable->replaceArgument(0, $indexableCallbacks);
187 5
    }
188
189
    /**
190
     * Loads the configured index finders.
191
     *
192
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
193
     * @param string                                                  $name      The index name
194
     * @param Reference                                               $index     Reference to the related index
195
     *
196
     * @return string
197
     */
198
    private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index)
199
    {
200
        /* Note: transformer services may conflict with "collection.index", if
201
         * an index and type names were "collection" and an index, respectively.
202
         */
203
        $transformerId = sprintf('fos_elastica.elastica_to_model_transformer.collection.%s', $name);
204
        $transformerDef = new DefinitionDecorator('fos_elastica.elastica_to_model_transformer.collection');
205
        $container->setDefinition($transformerId, $transformerDef);
206
207
        $finderId = sprintf('fos_elastica.finder.%s', $name);
208
        $finderDef = new DefinitionDecorator('fos_elastica.finder');
209
        $finderDef->replaceArgument(0, $index);
210
        $finderDef->replaceArgument(1, new Reference($transformerId));
211
212
        $container->setDefinition($finderId, $finderDef);
213
    }
214
215
    /**
216
     * Loads the configured types.
217
     *
218
     * @param array            $types
219
     * @param ContainerBuilder $container
220
     * @param array            $indexConfig
221
     * @param array            $indexableCallbacks
222
     */
223 5
    private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig, array &$indexableCallbacks)
224
    {
225 5
        foreach ($types as $name => $type) {
226 5
            $indexName = $indexConfig['name'];
227
228 5
            $typeId = sprintf('%s.%s', $indexConfig['reference'], $name);
229 5
            $typeDef = new DefinitionDecorator('fos_elastica.type_prototype');
230 5
            $typeDef->setFactory([$indexConfig['reference'], 'getType']);
231 5
            $typeDef->replaceArgument(0, $name);
232
233 5
            $container->setDefinition($typeId, $typeDef);
234
235
            $typeConfig = [
236 5
                'name' => $name,
237
                'mapping' => [], // An array containing anything that gets sent directly to ElasticSearch
238
                'config' => [],
239
            ];
240
241
            foreach ([
242 5
                'dynamic_templates',
243
                'properties',
244
                '_all',
245
                '_id',
246
                '_parent',
247
                '_routing',
248
                '_source',
249
            ] as $field) {
250 5
                if (isset($type[$field])) {
251 5
                    $typeConfig['mapping'][$field] = $type[$field];
252
                }
253
            }
254
255
            foreach ([
256 5
                'persistence',
257
                'serializer',
258
                'analyzer',
259
                'search_analyzer',
260
                'dynamic',
261
                'date_detection',
262
                'dynamic_date_formats',
263
                'numeric_detection',
264
            ] as $field) {
265 5
                $typeConfig['config'][$field] = array_key_exists($field, $type) ?
266 5
                    $type[$field] :
267 5
                    null;
268
            }
269
270 5
            $this->indexConfigs[$indexName]['types'][$name] = $typeConfig;
271
272 5
            if (isset($type['persistence'])) {
273 4
                $this->loadTypePersistenceIntegration($type['persistence'], $container, new Reference($typeId), $indexName, $name);
274
275 4
                $typeConfig['persistence'] = $type['persistence'];
276
            }
277
278 5
            if (isset($type['_parent'])) {
279
                // _parent mapping cannot contain `property` and `identifier`, so removing them after building `persistence`
280 2
                unset($indexConfig['types'][$name]['mapping']['_parent']['property'], $indexConfig['types'][$name]['mapping']['_parent']['identifier']);
281
            }
282
283 5
            if (isset($type['indexable_callback'])) {
284 1
                $indexableCallbacks[sprintf('%s/%s', $indexName, $name)] = $type['indexable_callback'];
285
            }
286
287 5
            if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
288 1
                $typeSerializerId = sprintf('%s.serializer.callback', $typeId);
289 1
                $typeSerializerDef = new DefinitionDecorator('fos_elastica.serializer_callback_prototype');
290
291 1
                if (isset($type['serializer']['groups'])) {
292 1
                    $typeSerializerDef->addMethodCall('setGroups', [$type['serializer']['groups']]);
293
                }
294
295 1
                if (isset($type['serializer']['serialize_null'])) {
296 1
                    $typeSerializerDef->addMethodCall('setSerializeNull', [$type['serializer']['serialize_null']]);
297
                }
298
299 1
                if (isset($type['serializer']['version'])) {
300 1
                    $typeSerializerDef->addMethodCall('setVersion', [$type['serializer']['version']]);
301
                }
302
303 1
                $typeDef->addMethodCall('setSerializer', [[new Reference($typeSerializerId), 'serialize']]);
304 1
                $container->setDefinition($typeSerializerId, $typeSerializerDef);
305
            }
306
        }
307 5
    }
308
309
    /**
310
     * Loads the optional provider and finder for a type.
311
     *
312
     * @param array            $typeConfig
313
     * @param ContainerBuilder $container
314
     * @param Reference        $typeRef
315
     * @param string           $indexName
316
     * @param string           $typeName
317
     */
318 4
    private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Reference $typeRef, $indexName, $typeName)
319
    {
320 4
        if (isset($typeConfig['driver'])) {
321 4
            $this->loadDriver($container, $typeConfig['driver']);
322
        }
323
324 4
        $elasticaToModelTransformerId = $this->loadElasticaToModelTransformer($typeConfig, $container, $indexName, $typeName);
325 4
        $modelToElasticaTransformerId = $this->loadModelToElasticaTransformer($typeConfig, $container, $indexName, $typeName);
326 4
        $objectPersisterId = $this->loadObjectPersister($typeConfig, $typeRef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
327
328 4
        if (isset($typeConfig['provider'])) {
329 4
            $this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
330
        }
331 4
        if (isset($typeConfig['finder'])) {
332 4
            $this->loadTypeFinder($typeConfig, $container, $elasticaToModelTransformerId, $typeRef, $indexName, $typeName);
333
        }
334 4
        if (isset($typeConfig['listener'])) {
335 4
            $this->loadTypeListener($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
336
        }
337 4
    }
338
339
    /**
340
     * Creates and loads an ElasticaToModelTransformer.
341
     *
342
     * @param array            $typeConfig
343
     * @param ContainerBuilder $container
344
     * @param string           $indexName
345
     * @param string           $typeName
346
     *
347
     * @return string
348
     */
349 4
    private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
350
    {
351 4
        if (isset($typeConfig['elastica_to_model_transformer']['service'])) {
352 1
            return $typeConfig['elastica_to_model_transformer']['service'];
353
        }
354
355
        /* Note: transformer services may conflict with "prototype.driver", if
356
         * the index and type names were "prototype" and a driver, respectively.
357
         */
358 3
        $abstractId = sprintf('fos_elastica.elastica_to_model_transformer.prototype.%s', $typeConfig['driver']);
359 3
        $serviceId = sprintf('fos_elastica.elastica_to_model_transformer.%s.%s', $indexName, $typeName);
360 3
        $serviceDef = new DefinitionDecorator($abstractId);
361 3
        $serviceDef->addTag('fos_elastica.elastica_to_model_transformer', ['type' => $typeName, 'index' => $indexName]);
362
363
        // Doctrine has a mandatory service as first argument
364 3
        $argPos = ('propel' === $typeConfig['driver']) ? 0 : 1;
365
366 3
        $serviceDef->replaceArgument($argPos, $typeConfig['model']);
367 3
        $serviceDef->replaceArgument($argPos + 1, array_merge($typeConfig['elastica_to_model_transformer'], [
368 3
            'identifier' => $typeConfig['identifier'],
369
        ]));
370 3
        $container->setDefinition($serviceId, $serviceDef);
371
372 3
        return $serviceId;
373
    }
374
375
    /**
376
     * Creates and loads a ModelToElasticaTransformer for an index/type.
377
     *
378
     * @param array            $typeConfig
379
     * @param ContainerBuilder $container
380
     * @param string           $indexName
381
     * @param string           $typeName
382
     *
383
     * @return string
384
     */
385 4
    private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
386
    {
387 4
        if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
388
            return $typeConfig['model_to_elastica_transformer']['service'];
389
        }
390
391 4
        $abstractId = $container->hasDefinition('fos_elastica.serializer_callback_prototype') ?
392 1
            'fos_elastica.model_to_elastica_identifier_transformer' :
393 4
            'fos_elastica.model_to_elastica_transformer';
394
395 4
        $serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
396 4
        $serviceDef = new DefinitionDecorator($abstractId);
397 4
        $serviceDef->replaceArgument(0, [
398 4
            'identifier' => $typeConfig['identifier'],
399
        ]);
400 4
        $container->setDefinition($serviceId, $serviceDef);
401
402 4
        return $serviceId;
403
    }
404
405
    /**
406
     * Creates and loads an object persister for a type.
407
     *
408
     * @param array            $typeConfig
409
     * @param Reference        $typeRef
410
     * @param ContainerBuilder $container
411
     * @param string           $indexName
412
     * @param string           $typeName
413
     * @param string           $transformerId
414
     *
415
     * @return string
416
     */
417 4
    private function loadObjectPersister(array $typeConfig, Reference $typeRef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
418
    {
419 4
        if (isset($typeConfig['persister']['service'])) {
420 1
            return $typeConfig['persister']['service'];
421
        }
422
423
        $arguments = [
424 3
            $typeRef,
425 3
            new Reference($transformerId),
426 3
            $typeConfig['model'],
427
        ];
428
429 3
        if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
430 1
            $abstractId = 'fos_elastica.object_serializer_persister';
431 1
            $callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['reference'], $typeName);
432 1
            $arguments[] = [new Reference($callbackId), 'serialize'];
433
        } else {
434 2
            $abstractId = 'fos_elastica.object_persister';
435 2
            $mapping = $this->indexConfigs[$indexName]['types'][$typeName]['mapping'];
436 2
            $argument = $mapping['properties'];
437 2
            if (isset($mapping['_parent'])) {
438 1
                $argument['_parent'] = $mapping['_parent'];
439
            }
440 2
            $arguments[] = $argument;
441
        }
442
443 3
        $serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
444 3
        $serviceDef = new DefinitionDecorator($abstractId);
445 3
        foreach ($arguments as $i => $argument) {
446 3
            $serviceDef->replaceArgument($i, $argument);
447
        }
448
449 3
        $serviceDef->addTag('fos_elastica.persister', ['index' => $indexName, 'type' => $typeName]);
450
451 3
        $container->setDefinition($serviceId, $serviceDef);
452
453 3
        return $serviceId;
454
    }
455
456
    /**
457
     * Loads a provider for a type.
458
     *
459
     * @param array            $typeConfig
460
     * @param ContainerBuilder $container
461
     * @param string           $objectPersisterId
462
     * @param string           $indexName
463
     * @param string           $typeName
464
     *
465
     * @return string
466
     */
467 4
    private function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
468
    {
469 4
        if (isset($typeConfig['provider']['service'])) {
470
            return $typeConfig['provider']['service'];
471
        }
472
473
        /* Note: provider services may conflict with "prototype.driver", if the
474
         * index and type names were "prototype" and a driver, respectively.
475
         */
476 4
        $providerId = sprintf('fos_elastica.provider.%s.%s', $indexName, $typeName);
477 4
        $providerDef = new DefinitionDecorator('fos_elastica.provider.prototype.'.$typeConfig['driver']);
478 4
        $providerDef->addTag('fos_elastica.provider', ['index' => $indexName, 'type' => $typeName]);
479 4
        $providerDef->replaceArgument(0, new Reference($objectPersisterId));
480 4
        $providerDef->replaceArgument(2, $typeConfig['model']);
481
        // Propel provider can simply ignore Doctrine-specific options
482 4
        $providerDef->replaceArgument(3, array_merge(array_diff_key($typeConfig['provider'], ['service' => 1]), [
483 4
            'indexName' => $indexName,
484 4
            'typeName' => $typeName,
485
        ]));
486 4
        $container->setDefinition($providerId, $providerDef);
487
488 4
        return $providerId;
489
    }
490
491
    /**
492
     * Loads doctrine listeners to handle indexing of new or updated objects.
493
     *
494
     * @param array            $typeConfig
495
     * @param ContainerBuilder $container
496
     * @param string           $objectPersisterId
497
     * @param string           $indexName
498
     * @param string           $typeName
499
     *
500
     * @return string
501
     */
502 4
    private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
503
    {
504 4
        if (isset($typeConfig['listener']['service'])) {
505
            return $typeConfig['listener']['service'];
506
        }
507
508
        /* Note: listener services may conflict with "prototype.driver", if the
509
         * index and type names were "prototype" and a driver, respectively.
510
         */
511 4
        $abstractListenerId = sprintf('fos_elastica.listener.prototype.%s', $typeConfig['driver']);
512 4
        $listenerId = sprintf('fos_elastica.listener.%s.%s', $indexName, $typeName);
513 4
        $listenerDef = new DefinitionDecorator($abstractListenerId);
514 4
        $listenerDef->replaceArgument(0, new Reference($objectPersisterId));
515 4
        $listenerDef->replaceArgument(3, $typeConfig['listener']['logger'] ?
516
            new Reference($typeConfig['listener']['logger']) :
517 4
            null
518
        );
519
        $listenerConfig = [
520 4
            'identifier' => $typeConfig['identifier'],
521 4
            'indexName' => $indexName,
522 4
            'typeName' => $typeName,
523
        ];
524
525 4
        $tagName = null;
526 4
        switch ($typeConfig['driver']) {
527 4
            case 'orm':
528 4
                $tagName = 'doctrine.event_listener';
529 4
                break;
530
            case 'phpcr':
531
                $tagName = 'doctrine_phpcr.event_listener';
532
                break;
533
            case 'mongodb':
534
                $tagName = 'doctrine_mongodb.odm.event_listener';
535
                break;
536
        }
537
538 4
        if ($typeConfig['listener']['defer']) {
539
            $listenerDef->setPublic(true);
540
            $listenerDef->addTag(
541
                'kernel.event_listener',
542
                ['event' => 'kernel.terminate', 'method' => 'onKernelTerminate']
543
            );
544
            $listenerConfig['defer'] = true;
545
        }
546
547 4
        $listenerDef->replaceArgument(2, $listenerConfig);
548
549 4
        if (null !== $tagName) {
550 4
            foreach ($this->getDoctrineEvents($typeConfig) as $event) {
551 4
                $listenerDef->addTag($tagName, ['event' => $event]);
552
            }
553
        }
554
555 4
        $container->setDefinition($listenerId, $listenerDef);
556
557 4
        return $listenerId;
558
    }
559
560
    /**
561
     * Map Elastica to Doctrine events for the current driver.
562
     */
563 4
    private function getDoctrineEvents(array $typeConfig)
564
    {
565 4
        switch ($typeConfig['driver']) {
566 4
            case 'orm':
567 4
                $eventsClass = '\Doctrine\ORM\Events';
568 4
                break;
569
            case 'phpcr':
570
                $eventsClass = '\Doctrine\ODM\PHPCR\Event';
571
                break;
572
            case 'mongodb':
573
                $eventsClass = '\Doctrine\ODM\MongoDB\Events';
574
                break;
575
            default:
576
                throw new InvalidArgumentException(sprintf('Cannot determine events for driver "%s"', $typeConfig['driver']));
577
        }
578
579 4
        $events = [];
580
        $eventMapping = [
581 4
            'insert' => [constant($eventsClass.'::postPersist')],
582 4
            'update' => [constant($eventsClass.'::postUpdate')],
583 4
            'delete' => [constant($eventsClass.'::preRemove')],
584 4
            'flush' => [constant($eventsClass.'::postFlush')],
585
        ];
586
587 4
        foreach ($eventMapping as $event => $doctrineEvents) {
588 4
            if (isset($typeConfig['listener'][$event]) && $typeConfig['listener'][$event]) {
589 4
                $events = array_merge($events, $doctrineEvents);
590
            }
591
        }
592
593 4
        return $events;
594
    }
595
596
    /**
597
     * Loads a Type specific Finder.
598
     *
599
     * @param array            $typeConfig
600
     * @param ContainerBuilder $container
601
     * @param string           $elasticaToModelId
602
     * @param Reference        $typeRef
603
     * @param string           $indexName
604
     * @param string           $typeName
605
     *
606
     * @return string
607
     */
608 4
    private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Reference $typeRef, $indexName, $typeName)
609
    {
610 4
        if (isset($typeConfig['finder']['service'])) {
611
            $finderId = $typeConfig['finder']['service'];
612
        } else {
613 4
            $finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName);
614 4
            $finderDef = new DefinitionDecorator('fos_elastica.finder');
615 4
            $finderDef->replaceArgument(0, $typeRef);
616 4
            $finderDef->replaceArgument(1, new Reference($elasticaToModelId));
617 4
            $container->setDefinition($finderId, $finderDef);
618
        }
619
620 4
        $indexTypeName = "$indexName/$typeName";
621 4
        $arguments = [$indexTypeName, new Reference($finderId)];
622 4
        if (isset($typeConfig['repository'])) {
623 1
            $arguments[] = $typeConfig['repository'];
624
        }
625
626 4
        $container->getDefinition('fos_elastica.repository_manager')
627 4
            ->addMethodCall('addType', $arguments);
628
629 4
        $managerId = sprintf('fos_elastica.manager.%s', $typeConfig['driver']);
630 4
        $container->getDefinition($managerId)
631 4
            ->addMethodCall('addEntity', [$typeConfig['model'], $indexTypeName]);
632
633 4
        return $finderId;
634
    }
635
636
    /**
637
     * Loads the index manager.
638
     *
639
     * @param ContainerBuilder $container
640
     **/
641
    private function loadIndexManager(ContainerBuilder $container)
642
    {
643 5
        $indexRefs = array_map(function ($index) {
644 5
            return $index['reference'];
645 5
        }, $this->indexConfigs);
646
647 5
        $managerDef = $container->getDefinition('fos_elastica.index_manager');
648 5
        $managerDef->replaceArgument(0, $indexRefs);
649 5
    }
650
651
    /**
652
     * Makes sure a specific driver has been loaded.
653
     *
654
     * @param ContainerBuilder $container
655
     * @param string           $driver
656
     */
657 4
    private function loadDriver(ContainerBuilder $container, $driver)
658
    {
659 4
        if (in_array($driver, $this->loadedDrivers)) {
660 3
            return;
661
        }
662
663 4
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
664 4
        $loader->load($driver.'.xml');
665 4
        $this->loadedDrivers[] = $driver;
666 4
    }
667
668
    /**
669
     * Loads and configures the serializer prototype.
670
     *
671
     * @param array            $config
672
     * @param ContainerBuilder $container
673
     */
674 1
    private function loadSerializer($config, ContainerBuilder $container)
675
    {
676 1
        $container->setAlias('fos_elastica.serializer', $config['serializer']);
677
678 1
        $serializer = $container->getDefinition('fos_elastica.serializer_callback_prototype');
679 1
        $serializer->setClass($config['callback_class']);
680
681 1
        if (is_subclass_of($config['callback_class'], ContainerAwareInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Symfony\Component\Depen...erAwareInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
682
            $serializer->addMethodCall('setContainer', [new Reference('service_container')]);
683
        }
684 1
    }
685
686
    /**
687
     * Creates a default manager alias for defined default manager or the first loaded driver.
688
     *
689
     * @param string           $defaultManager
690
     * @param ContainerBuilder $container
691
     */
692 5
    private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
693
    {
694 5
        if (0 == count($this->loadedDrivers)) {
695 1
            return;
696
        }
697
698 4
        if (count($this->loadedDrivers) > 1
699
            && in_array($defaultManager, $this->loadedDrivers)
700
        ) {
701
            $defaultManagerService = $defaultManager;
702
        } else {
703 4
            $defaultManagerService = $this->loadedDrivers[0];
704
        }
705
706 4
        $container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
707 4
    }
708
709
    /**
710
     * Returns a reference to a client given its configured name.
711
     *
712
     * @param string $clientName
713
     *
714
     * @return Reference
715
     *
716
     * @throws \InvalidArgumentException
717
     */
718 2
    private function getClient($clientName)
719
    {
720 2
        if (!array_key_exists($clientName, $this->clients)) {
721
            throw new InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
722
        }
723
724 2
        return $this->clients[$clientName]['reference'];
725
    }
726
}
727