Completed
Push — master ( 4e4cd8...063296 )
by Maksim
16s
created

FOSElasticaExtension::loadTypePagerProvider()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 51
Code Lines 31

Duplication

Lines 18
Ratio 35.29 %

Code Coverage

Tests 24
CRAP Score 5.1281

Importance

Changes 0
Metric Value
dl 18
loc 51
ccs 24
cts 29
cp 0.8276
rs 8.6588
c 0
b 0
f 0
cc 5
eloc 31
nc 5
nop 4
crap 5.1281

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\DependencyInjection;
13
14
use Symfony\Component\Config\FileLocator;
15
use Pagerfanta\Pagerfanta;
16
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\DefinitionDecorator;
19
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
20
use Symfony\Component\DependencyInjection\Reference;
21
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
22
23
class FOSElasticaExtension extends Extension
24
{
25
    /**
26
     * Definition of elastica clients as configured by this extension.
27
     *
28
     * @var array
29
     */
30
    private $clients = [];
31
32
    /**
33
     * An array of indexes as configured by the extension.
34
     *
35
     * @var array
36
     */
37
    private $indexConfigs = [];
38
39
    /**
40
     * If we've encountered a type mapped to a specific persistence driver, it will be loaded
41
     * here.
42
     *
43
     * @var array
44
     */
45
    private $loadedDrivers = [];
46
47 10
    public function load(array $configs, ContainerBuilder $container)
48
    {
49 10
        $configuration = $this->getConfiguration($configs, $container);
50 10
        $config = $this->processConfiguration($configuration, $configs);
51
52 10
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
53
54 10
        if (empty($config['clients']) || empty($config['indexes'])) {
55
            // No Clients or indexes are defined
56
            return;
57
        }
58
59 10
        foreach (['config', 'index', 'persister', 'provider', 'source', 'transformer', 'event_listener'] as $basename) {
60 10
            $loader->load(sprintf('%s.xml', $basename));
61
        }
62
63 10
        if (empty($config['default_client'])) {
64 10
            $keys = array_keys($config['clients']);
65 10
            $config['default_client'] = reset($keys);
66
        }
67
68 10
        if (empty($config['default_index'])) {
69 10
            $keys = array_keys($config['indexes']);
70 10
            $config['default_index'] = reset($keys);
71
        }
72
73 10
        if (isset($config['serializer'])) {
74 1
            $loader->load('serializer.xml');
75
76 1
            $this->loadSerializer($config['serializer'], $container);
77
        }
78
79 10
        $this->loadClients($config['clients'], $container);
80 10
        $container->setAlias('fos_elastica.client', sprintf('fos_elastica.client.%s', $config['default_client']));
81
82 10
        $this->loadIndexes($config['indexes'], $container);
83 10
        $container->setAlias('fos_elastica.index', sprintf('fos_elastica.index.%s', $config['default_index']));
84 10
        $container->setParameter('fos_elastica.default_index', $config['default_index']);
85
86 10
        $container->getDefinition('fos_elastica.config_source.container')->replaceArgument(0, $this->indexConfigs);
87
88 10
        $this->loadIndexManager($container);
89
90 10
        $this->createDefaultManagerAlias($config['default_manager'], $container);
91 10
    }
92
93
    /**
94
     * @param array            $config
95
     * @param ContainerBuilder $container
96
     *
97
     * @return Configuration
98
     */
99 10
    public function getConfiguration(array $config, ContainerBuilder $container)
100
    {
101 10
        return new Configuration($container->getParameter('kernel.debug'));
102
    }
103
104
    /**
105
     * Loads the configured clients.
106
     *
107
     * @param array            $clients   An array of clients configurations
108
     * @param ContainerBuilder $container A ContainerBuilder instance
109
     *
110
     * @return array
111
     */
112 10
    private function loadClients(array $clients, ContainerBuilder $container)
113
    {
114 10
        foreach ($clients as $name => $clientConfig) {
115 10
            $clientId = sprintf('fos_elastica.client.%s', $name);
116
117 10
            $clientDef = new DefinitionDecorator('fos_elastica.client_prototype');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
118 10
            $clientDef->replaceArgument(0, $clientConfig);
119
120 10
            $logger = $clientConfig['connections'][0]['logger'];
121 10
            if (false !== $logger) {
122 10
                $clientDef->addMethodCall('setLogger', [new Reference($logger)]);
123
            }
124
125 10
            $clientDef->addTag('fos_elastica.client');
126
127 10
            $container->setDefinition($clientId, $clientDef);
128
129 10
            $this->clients[$name] = [
130 10
                'id' => $clientId,
131 10
                'reference' => new Reference($clientId),
132
            ];
133
        }
134 10
    }
135
136
    /**
137
     * Loads the configured indexes.
138
     *
139
     * @param array            $indexes   An array of indexes configurations
140
     * @param ContainerBuilder $container A ContainerBuilder instance
141
     *
142
     * @throws \InvalidArgumentException
143
     *
144
     * @return array
145
     */
146 10
    private function loadIndexes(array $indexes, ContainerBuilder $container)
147
    {
148 10
        $indexableCallbacks = [];
149
150 10
        foreach ($indexes as $name => $index) {
151 10
            $indexId = sprintf('fos_elastica.index.%s', $name);
152 10
            $indexName = isset($index['index_name']) ? $index['index_name'] : $name;
153
154 10
            $indexDef = new DefinitionDecorator('fos_elastica.index_prototype');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
155 10
            $indexDef->setFactory([new Reference('fos_elastica.client'), 'getIndex']);
156 10
            $indexDef->replaceArgument(0, $indexName);
157 10
            $indexDef->addTag('fos_elastica.index', [
158 10
                'name' => $name,
159
            ]);
160
161 10
            if (isset($index['client'])) {
162 2
                $client = $this->getClient($index['client']);
163
164 2
                $indexDef->setFactory([$client, 'getIndex']);
165
            }
166
167 10
            $container->setDefinition($indexId, $indexDef);
168 10
            $reference = new Reference($indexId);
169
170 10
            $this->indexConfigs[$name] = [
171 10
                'elasticsearch_name' => $indexName,
172 10
                'reference' => $reference,
173 10
                'name' => $name,
174 10
                'settings' => $index['settings'],
175 10
                'type_prototype' => isset($index['type_prototype']) ? $index['type_prototype'] : [],
176 10
                'use_alias' => $index['use_alias'],
177
            ];
178
179 10
            if ($index['finder']) {
180
                $this->loadIndexFinder($container, $name, $reference);
181
            }
182
183 10
            $this->loadTypes((array) $index['types'], $container, $this->indexConfigs[$name], $indexableCallbacks);
184
        }
185
186 10
        $indexable = $container->getDefinition('fos_elastica.indexable');
187 10
        $indexable->replaceArgument(0, $indexableCallbacks);
188 10
    }
189
190
    /**
191
     * Loads the configured index finders.
192
     *
193
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
194
     * @param string                                                  $name      The index name
195
     * @param Reference                                               $index     Reference to the related index
196
     *
197
     * @return string
198
     */
199
    private function loadIndexFinder(ContainerBuilder $container, $name, Reference $index)
200
    {
201
        /* Note: transformer services may conflict with "collection.index", if
202
         * an index and type names were "collection" and an index, respectively.
203
         */
204
        $transformerId = sprintf('fos_elastica.elastica_to_model_transformer.collection.%s', $name);
205
        $transformerDef = new DefinitionDecorator('fos_elastica.elastica_to_model_transformer.collection');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
206
        $container->setDefinition($transformerId, $transformerDef);
207
208
        $finderId = sprintf('fos_elastica.finder.%s', $name);
209
        $finderDef = new DefinitionDecorator('fos_elastica.finder');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
210
        $finderDef->replaceArgument(0, $index);
211
        $finderDef->replaceArgument(1, new Reference($transformerId));
212
213
        $container->setDefinition($finderId, $finderDef);
214
    }
215
216
    /**
217
     * Loads the configured types.
218
     *
219
     * @param array            $types
220
     * @param ContainerBuilder $container
221
     * @param array            $indexConfig
222
     * @param array            $indexableCallbacks
223
     */
224 10
    private function loadTypes(array $types, ContainerBuilder $container, array $indexConfig, array &$indexableCallbacks)
225
    {
226 10
        foreach ($types as $name => $type) {
227 10
            $indexName = $indexConfig['name'];
228
229 10
            $typeId = sprintf('%s.%s', $indexConfig['reference'], $name);
230 10
            $typeDef = new DefinitionDecorator('fos_elastica.type_prototype');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
231 10
            $typeDef->setFactory([$indexConfig['reference'], 'getType']);
232 10
            $typeDef->replaceArgument(0, $name);
233
234 10
            $container->setDefinition($typeId, $typeDef);
235
236
            $typeConfig = [
237 10
                'name' => $name,
238
                'mapping' => [], // An array containing anything that gets sent directly to ElasticSearch
239
                'config' => [],
240
            ];
241
242
            foreach ([
243 10
                'dynamic_templates',
244
                'properties',
245
                '_all',
246
                '_id',
247
                '_parent',
248
                '_routing',
249
                '_source',
250
            ] as $field) {
251 10
                if (isset($type[$field])) {
252 10
                    $typeConfig['mapping'][$field] = $type[$field];
253
                }
254
            }
255
256
            foreach ([
257 10
                'persistence',
258
                'serializer',
259
                'analyzer',
260
                'search_analyzer',
261
                'dynamic',
262
                'date_detection',
263
                'dynamic_date_formats',
264
                'numeric_detection',
265
            ] as $field) {
266 10
                $typeConfig['config'][$field] = array_key_exists($field, $type) ?
267 10
                    $type[$field] :
268 10
                    null;
269
            }
270
271 10
            $this->indexConfigs[$indexName]['types'][$name] = $typeConfig;
272
273 10
            if (isset($type['persistence'])) {
274 9
                $this->loadTypePersistenceIntegration($type['persistence'], $container, new Reference($typeId), $indexName, $name);
275
276 9
                $typeConfig['persistence'] = $type['persistence'];
277
            }
278
279 10
            if (isset($type['_parent'])) {
280
                // _parent mapping cannot contain `property` and `identifier`, so removing them after building `persistence`
281 2
                unset($indexConfig['types'][$name]['mapping']['_parent']['property'], $indexConfig['types'][$name]['mapping']['_parent']['identifier']);
282
            }
283
284 10
            if (isset($type['indexable_callback'])) {
285 1
                $indexableCallbacks[sprintf('%s/%s', $indexName, $name)] = $type['indexable_callback'];
286
            }
287
288 10
            if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
289 1
                $typeSerializerId = sprintf('%s.serializer.callback', $typeId);
290 1
                $typeSerializerDef = new DefinitionDecorator('fos_elastica.serializer_callback_prototype');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
291
292 1
                if (isset($type['serializer']['groups'])) {
293 1
                    $typeSerializerDef->addMethodCall('setGroups', [$type['serializer']['groups']]);
294
                }
295
296 1
                if (isset($type['serializer']['serialize_null'])) {
297 1
                    $typeSerializerDef->addMethodCall('setSerializeNull', [$type['serializer']['serialize_null']]);
298
                }
299
300 1
                if (isset($type['serializer']['version'])) {
301 1
                    $typeSerializerDef->addMethodCall('setVersion', [$type['serializer']['version']]);
302
                }
303
304 1
                $typeDef->addMethodCall('setSerializer', [[new Reference($typeSerializerId), 'serialize']]);
305 10
                $container->setDefinition($typeSerializerId, $typeSerializerDef);
306
            }
307
        }
308 10
    }
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 9
    private function loadTypePersistenceIntegration(array $typeConfig, ContainerBuilder $container, Reference $typeRef, $indexName, $typeName)
320
    {
321 9
        if (isset($typeConfig['driver'])) {
322 9
            $this->loadDriver($container, $typeConfig['driver']);
323
        }
324
325 9
        $elasticaToModelTransformerId = $this->loadElasticaToModelTransformer($typeConfig, $container, $indexName, $typeName);
326 9
        $modelToElasticaTransformerId = $this->loadModelToElasticaTransformer($typeConfig, $container, $indexName, $typeName);
327 9
        $objectPersisterId = $this->loadObjectPersister($typeConfig, $typeRef, $container, $indexName, $typeName, $modelToElasticaTransformerId);
328
329 9
        if (isset($typeConfig['provider'])) {
330 9
            $this->loadTypeProvider($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
331
332 9
            if (isset($typeConfig['provider']['pager_provider']) && $typeConfig['provider']['pager_provider']) {
333 4
                if (!class_exists(Pagerfanta::class)) {
334
                    throw new \InvalidArgumentException('A pager provider needs "pagerfanta/pagerfanta:^1"  to be installed.');
335
                }
336
337 4
                $this->loadTypePagerProvider($typeConfig, $container, $indexName, $typeName);
338
            }
339
        }
340 9
        if (isset($typeConfig['finder'])) {
341 9
            $this->loadTypeFinder($typeConfig, $container, $elasticaToModelTransformerId, $typeRef, $indexName, $typeName);
342
        }
343 9
        if (isset($typeConfig['listener'])) {
344 9
            $this->loadTypeListener($typeConfig, $container, $objectPersisterId, $indexName, $typeName);
345
        }
346 9
    }
347
348
    /**
349
     * Creates and loads an ElasticaToModelTransformer.
350
     *
351
     * @param array            $typeConfig
352
     * @param ContainerBuilder $container
353
     * @param string           $indexName
354
     * @param string           $typeName
355
     *
356
     * @return string
357
     */
358 9
    private function loadElasticaToModelTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
359
    {
360 9
        if (isset($typeConfig['elastica_to_model_transformer']['service'])) {
361 1
            return $typeConfig['elastica_to_model_transformer']['service'];
362
        }
363
364
        /* Note: transformer services may conflict with "prototype.driver", if
365
         * the index and type names were "prototype" and a driver, respectively.
366
         */
367 8
        $abstractId = sprintf('fos_elastica.elastica_to_model_transformer.prototype.%s', $typeConfig['driver']);
368 8
        $serviceId = sprintf('fos_elastica.elastica_to_model_transformer.%s.%s', $indexName, $typeName);
369 8
        $serviceDef = new DefinitionDecorator($abstractId);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
370 8
        $serviceDef->addTag('fos_elastica.elastica_to_model_transformer', ['type' => $typeName, 'index' => $indexName]);
371
372
        // Doctrine has a mandatory service as first argument
373 8
        $argPos = ('propel' === $typeConfig['driver']) ? 0 : 1;
374
375 8
        $serviceDef->replaceArgument($argPos, $typeConfig['model']);
376 8
        $serviceDef->replaceArgument($argPos + 1, array_merge($typeConfig['elastica_to_model_transformer'], [
377 8
            'identifier' => $typeConfig['identifier'],
378
        ]));
379 8
        $container->setDefinition($serviceId, $serviceDef);
380
381 8
        return $serviceId;
382
    }
383
384
    /**
385
     * Creates and loads a ModelToElasticaTransformer for an index/type.
386
     *
387
     * @param array            $typeConfig
388
     * @param ContainerBuilder $container
389
     * @param string           $indexName
390
     * @param string           $typeName
391
     *
392
     * @return string
393
     */
394 9
    private function loadModelToElasticaTransformer(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
395
    {
396 9
        if (isset($typeConfig['model_to_elastica_transformer']['service'])) {
397
            return $typeConfig['model_to_elastica_transformer']['service'];
398
        }
399
400 9
        $abstractId = $container->hasDefinition('fos_elastica.serializer_callback_prototype') ?
401 1
            'fos_elastica.model_to_elastica_identifier_transformer' :
402 9
            'fos_elastica.model_to_elastica_transformer';
403
404 9
        $serviceId = sprintf('fos_elastica.model_to_elastica_transformer.%s.%s', $indexName, $typeName);
405 9
        $serviceDef = new DefinitionDecorator($abstractId);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
406 9
        $serviceDef->replaceArgument(0, [
407 9
            'identifier' => $typeConfig['identifier'],
408
        ]);
409 9
        $container->setDefinition($serviceId, $serviceDef);
410
411 9
        return $serviceId;
412
    }
413
414
    /**
415
     * Creates and loads an object persister for a type.
416
     *
417
     * @param array            $typeConfig
418
     * @param Reference        $typeRef
419
     * @param ContainerBuilder $container
420
     * @param string           $indexName
421
     * @param string           $typeName
422
     * @param string           $transformerId
423
     *
424
     * @return string
425
     */
426 9
    private function loadObjectPersister(array $typeConfig, Reference $typeRef, ContainerBuilder $container, $indexName, $typeName, $transformerId)
427
    {
428 9
        if (isset($typeConfig['persister']['service'])) {
429 1
            return $typeConfig['persister']['service'];
430
        }
431
432
        $arguments = [
433 8
            $typeRef,
434 8
            new Reference($transformerId),
435 8
            $typeConfig['model'],
436
        ];
437
438 8
        if ($container->hasDefinition('fos_elastica.serializer_callback_prototype')) {
439 1
            $abstractId = 'fos_elastica.object_serializer_persister';
440 1
            $callbackId = sprintf('%s.%s.serializer.callback', $this->indexConfigs[$indexName]['reference'], $typeName);
441 1
            $arguments[] = [new Reference($callbackId), 'serialize'];
442
        } else {
443 7
            $abstractId = 'fos_elastica.object_persister';
444 7
            $mapping = $this->indexConfigs[$indexName]['types'][$typeName]['mapping'];
445 7
            $argument = $mapping['properties'];
446 7
            if (isset($mapping['_parent'])) {
447 1
                $argument['_parent'] = $mapping['_parent'];
448
            }
449 7
            $arguments[] = $argument;
450
        }
451
452 8
        $serviceId = sprintf('fos_elastica.object_persister.%s.%s', $indexName, $typeName);
453 8
        $serviceDef = new DefinitionDecorator($abstractId);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
454 8
        foreach ($arguments as $i => $argument) {
455 8
            $serviceDef->replaceArgument($i, $argument);
456
        }
457
458 8
        $serviceDef->addTag('fos_elastica.persister', ['index' => $indexName, 'type' => $typeName]);
459
460 8
        $container->setDefinition($serviceId, $serviceDef);
461
462 8
        return $serviceId;
463
    }
464
465
    /**
466
     * Loads a provider for a type.
467
     *
468
     * @param array            $typeConfig
469
     * @param ContainerBuilder $container
470
     * @param string           $objectPersisterId
471
     * @param string           $indexName
472
     * @param string           $typpeName
0 ignored issues
show
Documentation introduced by
There is no parameter named $typpeName. Did you maybe mean $typeName?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
473
     *
474
     * @return string
475
     */
476 9
    private function loadTypeProvider(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
477
    {
478 9
        if (isset($typeConfig['provider']['service'])) {
479
            return $typeConfig['provider']['service'];
480
        }
481
482
        /* Note: provider services may conflict with "prototype.driver", if the
483
         * index and type names were "prototype" and a driver, respectively.
484
         */
485 9
        $providerId = sprintf('fos_elastica.provider.%s.%s', $indexName, $typeName);
486 9
        $providerDef = new DefinitionDecorator('fos_elastica.provider.prototype.'.$typeConfig['driver']);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
487 9
        $providerDef->addTag('fos_elastica.provider', ['index' => $indexName, 'type' => $typeName]);
488 9
        $providerDef->replaceArgument(0, new Reference($objectPersisterId));
489 9
        $providerDef->replaceArgument(2, $typeConfig['model']);
490
        // Propel provider can simply ignore Doctrine-specific options
491 9
        $providerDef->replaceArgument(3, array_merge(array_diff_key($typeConfig['provider'], ['service' => 1]), [
492 9
            'indexName' => $indexName,
493 9
            'typeName' => $typeName,
494
        ]));
495 9
        $container->setDefinition($providerId, $providerDef);
496
497 9
        return $providerId;
498
    }
499
500
    /**
501
     * Loads a pager provider for a type.
502
     *
503
     * @param array            $typeConfig
504
     * @param ContainerBuilder $container
505
     * @param string           $indexName
506
     * @param string           $typeName
507
     *
508
     * @return string
509
     */
510 4
    private function loadTypePagerProvider(array $typeConfig, ContainerBuilder $container, $indexName, $typeName)
511
    {
512
//     TODO don't forget to uncomment in master branch
513
//        if (isset($typeConfig['provider']['service'])) {
514
//            return $typeConfig['provider']['service'];
515
//        }
516
517 4
        $baseConfig = $typeConfig['provider'];
518 4
        unset($baseConfig['service']);
519
520 4
        $driver = $typeConfig['driver'];
521
522
        switch ($driver) {
523 4
            case 'orm':
524 1
                $providerDef = new DefinitionDecorator('fos_elastica.pager_provider.prototype.'.$driver);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
525 1
                $providerDef->replaceArgument(1, $typeConfig['model']);
526 1
                $providerDef->replaceArgument(2, $baseConfig);
527
528 1
                break;
529 3 View Code Duplication
            case 'mongodb':
530
                $providerDef = new DefinitionDecorator('fos_elastica.pager_provider.prototype.'.$driver);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
531
                $providerDef->replaceArgument(1, $typeConfig['model']);
532
                $providerDef->replaceArgument(2, $baseConfig);
533
534
                break;
535 3 View Code Duplication
            case 'phpcr':
536 1
                $providerDef = new DefinitionDecorator('fos_elastica.pager_provider.prototype.'.$driver);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
537 1
                $providerDef->replaceArgument(1, $typeConfig['model']);
538 1
                $providerDef->replaceArgument(2, $baseConfig);
539
540 1
                break;
541 2 View Code Duplication
            case 'propel':
542 2
                $providerDef = new DefinitionDecorator('fos_elastica.pager_provider.prototype.'.$driver);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
543 2
                $providerDef->replaceArgument(0, $typeConfig['model']);
544 2
                $providerDef->replaceArgument(1, $baseConfig);
545
546 2
                break;
547
            default:
548
                throw new \LogicException(sprintf('The pager provider for driver "%s" does not exist.', $driver));
549
        }
550
551
        /* Note: provider services may conflict with "prototype.driver", if the
552
         * index and type names were "prototype" and a driver, respectively.
553
         */
554 4
        $providerId = sprintf('fos_elastica.pager_provider.%s.%s', $indexName, $typeName);
555 4
        $providerDef->addTag('fos_elastica.pager_provider', ['index' => $indexName, 'type' => $typeName]);
556
557 4
        $container->setDefinition($providerId, $providerDef);
558
559 4
        return $providerId;
560
    }
561
562
    /**
563
     * Loads doctrine listeners to handle indexing of new or updated objects.
564
     *
565
     * @param array            $typeConfig
566
     * @param ContainerBuilder $container
567
     * @param string           $objectPersisterId
568
     * @param string           $indexName
569
     * @param string           $typeName
570
     *
571
     * @return string
572
     */
573 9
    private function loadTypeListener(array $typeConfig, ContainerBuilder $container, $objectPersisterId, $indexName, $typeName)
574
    {
575 9
        if (isset($typeConfig['listener']['service'])) {
576
            return $typeConfig['listener']['service'];
577
        }
578
579
        /* Note: listener services may conflict with "prototype.driver", if the
580
         * index and type names were "prototype" and a driver, respectively.
581
         */
582 9
        $abstractListenerId = sprintf('fos_elastica.listener.prototype.%s', $typeConfig['driver']);
583 9
        $listenerId = sprintf('fos_elastica.listener.%s.%s', $indexName, $typeName);
584 9
        $listenerDef = new DefinitionDecorator($abstractListenerId);
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
585 9
        $listenerDef->replaceArgument(0, new Reference($objectPersisterId));
586 9
        $listenerDef->replaceArgument(3, $typeConfig['listener']['logger'] ?
587
            new Reference($typeConfig['listener']['logger']) :
588 9
            null
589
        );
590
        $listenerConfig = [
591 9
            'identifier' => $typeConfig['identifier'],
592 9
            'indexName' => $indexName,
593 9
            'typeName' => $typeName,
594
        ];
595
596 9
        $tagName = null;
597 9
        switch ($typeConfig['driver']) {
598 9
            case 'orm':
599 6
                $tagName = 'doctrine.event_listener';
600 6
                break;
601 3
            case 'phpcr':
602 1
                $tagName = 'doctrine_phpcr.event_listener';
603 1
                break;
604 2
            case 'mongodb':
605
                $tagName = 'doctrine_mongodb.odm.event_listener';
606
                break;
607
        }
608
609 9
        if ($typeConfig['listener']['defer']) {
610
            $listenerDef->setPublic(true);
611
            $listenerDef->addTag(
612
                'kernel.event_listener',
613
                ['event' => 'kernel.terminate', 'method' => 'onTerminate']
614
            );
615
            $listenerDef->addTag(
616
                'kernel.event_listener',
617
                ['event' => 'console.terminate', 'method' => 'onTerminate']
618
            );
619
            $listenerConfig['defer'] = true;
620
        }
621
622 9
        $listenerDef->replaceArgument(2, $listenerConfig);
623
624 9
        if (null !== $tagName) {
625 7
            foreach ($this->getDoctrineEvents($typeConfig) as $event) {
626 7
                $listenerDef->addTag($tagName, ['event' => $event]);
627
            }
628
        }
629
630 9
        $container->setDefinition($listenerId, $listenerDef);
631
632 9
        return $listenerId;
633
    }
634
635
    /**
636
     * Map Elastica to Doctrine events for the current driver.
637
     */
638 7
    private function getDoctrineEvents(array $typeConfig)
639
    {
640 7
        switch ($typeConfig['driver']) {
641 7
            case 'orm':
642 6
                $eventsClass = '\Doctrine\ORM\Events';
643 6
                break;
644 1
            case 'phpcr':
645 1
                $eventsClass = '\Doctrine\ODM\PHPCR\Event';
646 1
                break;
647
            case 'mongodb':
648
                $eventsClass = '\Doctrine\ODM\MongoDB\Events';
649
                break;
650
            default:
651
                throw new \InvalidArgumentException(sprintf('Cannot determine events for driver "%s"', $typeConfig['driver']));
652
        }
653
654 7
        $events = [];
655
        $eventMapping = [
656 7
            'insert' => [constant($eventsClass.'::postPersist')],
657 7
            'update' => [constant($eventsClass.'::postUpdate')],
658 7
            'delete' => [constant($eventsClass.'::preRemove')],
659 7
            'flush' => [constant($eventsClass.'::postFlush')],
660
        ];
661
662 7
        foreach ($eventMapping as $event => $doctrineEvents) {
663 7
            if (isset($typeConfig['listener'][$event]) && $typeConfig['listener'][$event]) {
664 7
                $events = array_merge($events, $doctrineEvents);
665
            }
666
        }
667
668 7
        return $events;
669
    }
670
671
    /**
672
     * Loads a Type specific Finder.
673
     *
674
     * @param array            $typeConfig
675
     * @param ContainerBuilder $container
676
     * @param string           $elasticaToModelId
677
     * @param Reference        $typeRef
678
     * @param string           $indexName
679
     * @param string           $typeName
680
     *
681
     * @return string
682
     */
683 9
    private function loadTypeFinder(array $typeConfig, ContainerBuilder $container, $elasticaToModelId, Reference $typeRef, $indexName, $typeName)
684
    {
685 9
        if (isset($typeConfig['finder']['service'])) {
686
            $finderId = $typeConfig['finder']['service'];
687
        } else {
688 9
            $finderId = sprintf('fos_elastica.finder.%s.%s', $indexName, $typeName);
689 9
            $finderDef = new DefinitionDecorator('fos_elastica.finder');
0 ignored issues
show
Deprecated Code introduced by
The class Symfony\Component\Depend...ion\DefinitionDecorator has been deprecated with message: The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
690 9
            $finderDef->replaceArgument(0, $typeRef);
691 9
            $finderDef->replaceArgument(1, new Reference($elasticaToModelId));
692 9
            $container->setDefinition($finderId, $finderDef);
693
        }
694
695 9
        $indexTypeName = "$indexName/$typeName";
696 9
        $arguments = [$indexTypeName, new Reference($finderId)];
697 9
        if (isset($typeConfig['repository'])) {
698 1
            $arguments[] = $typeConfig['repository'];
699
        }
700
701 9
        $container->getDefinition('fos_elastica.repository_manager')
702 9
            ->addMethodCall('addType', $arguments);
703
704 9
        $managerId = sprintf('fos_elastica.manager.%s', $typeConfig['driver']);
705 9
        $container->getDefinition($managerId)
706 9
            ->addMethodCall('addEntity', [$typeConfig['model'], $indexTypeName]);
707
708 9
        return $finderId;
709
    }
710
711
    /**
712
     * Loads the index manager.
713
     *
714
     * @param ContainerBuilder $container
715
     **/
716
    private function loadIndexManager(ContainerBuilder $container)
717
    {
718 10
        $indexRefs = array_map(function ($index) {
719 10
            return $index['reference'];
720 10
        }, $this->indexConfigs);
721
722 10
        $managerDef = $container->getDefinition('fos_elastica.index_manager');
723 10
        $managerDef->replaceArgument(0, $indexRefs);
724 10
    }
725
726
    /**
727
     * Makes sure a specific driver has been loaded.
728
     *
729
     * @param ContainerBuilder $container
730
     * @param string           $driver
731
     */
732 9
    private function loadDriver(ContainerBuilder $container, $driver)
733
    {
734 9
        if (in_array($driver, $this->loadedDrivers)) {
735 3
            return;
736
        }
737
738 9
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
739 9
        $loader->load($driver.'.xml');
740 9
        $this->loadedDrivers[] = $driver;
741 9
    }
742
743
    /**
744
     * Loads and configures the serializer prototype.
745
     *
746
     * @param array            $config
747
     * @param ContainerBuilder $container
748
     */
749 1
    private function loadSerializer($config, ContainerBuilder $container)
750
    {
751 1
        $container->setAlias('fos_elastica.serializer', $config['serializer']);
752
753 1
        $serializer = $container->getDefinition('fos_elastica.serializer_callback_prototype');
754 1
        $serializer->setClass($config['callback_class']);
755
756 1
        if (is_subclass_of($config['callback_class'], ContainerAwareInterface::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Symfony\Component\Depen...erAwareInterface::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
757
            $serializer->addMethodCall('setContainer', [new Reference('service_container')]);
758
        }
759 1
    }
760
761
    /**
762
     * Creates a default manager alias for defined default manager or the first loaded driver.
763
     *
764
     * @param string           $defaultManager
765
     * @param ContainerBuilder $container
766
     */
767 10
    private function createDefaultManagerAlias($defaultManager, ContainerBuilder $container)
768
    {
769 10
        if (0 == count($this->loadedDrivers)) {
770 1
            return;
771
        }
772
773 9
        if (count($this->loadedDrivers) > 1
774 9
            && in_array($defaultManager, $this->loadedDrivers)
775
        ) {
776
            $defaultManagerService = $defaultManager;
777
        } else {
778 9
            $defaultManagerService = $this->loadedDrivers[0];
779
        }
780
781 9
        $container->setAlias('fos_elastica.manager', sprintf('fos_elastica.manager.%s', $defaultManagerService));
782 9
    }
783
784
    /**
785
     * Returns a reference to a client given its configured name.
786
     *
787
     * @param string $clientName
788
     *
789
     * @return Reference
790
     *
791
     * @throws \InvalidArgumentException
792
     */
793 2
    private function getClient($clientName)
794
    {
795 2
        if (!array_key_exists($clientName, $this->clients)) {
796
            throw new \InvalidArgumentException(sprintf('The elastica client with name "%s" is not defined', $clientName));
797
        }
798
799 2
        return $this->clients[$clientName]['reference'];
800
    }
801
}
802