Completed
Push — master ( f7313f...f3d09b )
by Karel
03:49
created

FOSElasticaExtension::loadTypeFinder()   B

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3.0123

Importance

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