Completed
Pull Request — master (#1146)
by Giovanni
06:29
created

FOSElasticaExtension   C

Complexity

Total Complexity 78

Size/Duplication

Total Lines 696
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 88.7%

Importance

Changes 0
Metric Value
wmc 78
lcom 1
cbo 8
dl 0
loc 696
ccs 259
cts 292
cp 0.887
rs 5.0199
c 0
b 0
f 0

19 Methods

Rating   Name   Duplication   Size   Complexity  
A getConfiguration() 0 4 1
C load() 0 44 7
A loadIndexFinder() 0 16 1
B loadElasticaToModelTransformer() 0 25 3
A loadModelToElasticaTransformer() 0 19 3
A loadTypeProvider() 0 23 2
B loadTypePersistenceIntegration() 0 20 5
A loadClients() 0 23 3
B loadIndexes() 0 43 6
F loadTypes() 0 88 13
B loadObjectPersister() 0 37 5
C loadTypeListener() 0 46 8
C getDoctrineEvents() 0 32 7
B loadTypeFinder() 0 27 3
A loadIndexManager() 0 9 1
A loadDriver() 0 10 2
A loadSerializer() 0 12 2
A createDefaultManagerAlias() 0 16 4
A getClient() 0 8 2

How to fix   Complexity   

Complex Class

Complex classes like FOSElasticaExtension often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use FOSElasticaExtension, and based on these observations, apply Extract Interface, too.

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