Completed
Push — 3.1.x ( b8b6d2...fd2df9 )
by Karel
14:12 queued 11:28
created

FOSElasticaExtension::load()   C

Complexity

Conditions 7
Paths 17

Size

Total Lines 44
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

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