Completed
Push — master ( 5e4454...b7878b )
by Karel
04:20
created

FOSElasticaExtension   C

Complexity

Total Complexity 79

Size/Duplication

Total Lines 705
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 87.16%

Importance

Changes 0
Metric Value
wmc 79
lcom 1
cbo 8
dl 0
loc 705
ccs 258
cts 296
cp 0.8716
rs 5
c 0
b 0
f 0

19 Methods

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

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