Completed
Pull Request — master (#25)
by Alexander
14:09 queued 11:39
created

ElasticaExtension   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 98.18%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 8
dl 0
loc 121
ccs 54
cts 55
cp 0.9818
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A createLoggerReference() 0 11 2
A load() 0 16 1
A loadLogger() 0 12 2
A loadClients() 0 6 2
A loadClient() 0 14 1
B setupAutowire() 0 20 5
A createClientId() 0 7 1
1
<?php
2
3
namespace GBProd\ElasticaBundle\DependencyInjection;
4
5
use Elastica\Client;
6
use GBProd\ElasticaBundle\Logger\ElasticaLogger;
7
use Symfony\Component\Config\FileLocator;
8
use Symfony\Component\DependencyInjection\ContainerBuilder;
9
use Symfony\Component\DependencyInjection\ContainerInterface;
10
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
11
use Symfony\Component\DependencyInjection\Exception\LogicException;
12
use Symfony\Component\DependencyInjection\Loader;
13
use Symfony\Component\DependencyInjection\Reference;
14
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
15
16
/**
17
 * Extension class for ElasticaExtension
18
 *
19
 * @author gbprod <[email protected]>
20
 */
21
class ElasticaExtension extends Extension
22
{
23
    const CLIENT_ID_TEMPLATE = 'elastica.%s_client';
24
25
    /**
26
     * {@inheritdoc}
27
     */
28 10
    public function load(array $configs, ContainerBuilder $container)
29
    {
30 10
        $configuration = new Configuration();
31 10
        $config = $this->processConfiguration($configuration, $configs);
32
33 10
        $loader = new Loader\YamlFileLoader(
34 10
            $container,
35 10
            new FileLocator(__DIR__ . '/../Resources/config')
36
        );
37
38 10
        $loader->load('services.yml');
39
40 10
        $this->loadLogger($config, $container);
41 10
        $this->loadClients($config, $container);
42 10
        $this->setupAutowire($config, $container);
43 9
    }
44
45 10
    private function loadLogger(array $config, ContainerBuilder $container)
46
    {
47
        $definition = $container
48 10
            ->register('elastica.logger', ElasticaLogger::class)
49 10
            ->addArgument($this->createLoggerReference($config))
50 10
            ->addArgument('%kernel.debug%')
51 10
            ->setPublic(true);
52
53 10
        if ('logger' === $config['logger']) {
54 8
            $definition->addTag('monolog.logger', ['channel' => 'elastica']);
55
        }
56 10
    }
57
58 10
    private function createLoggerReference(array $config)
59
    {
60 10
        if (null !== $config['logger']) {
61 9
            return new Reference(
62 9
                $config['logger'],
63 9
                ContainerInterface::IGNORE_ON_INVALID_REFERENCE
64
            );
65
        }
66
67 1
        return null;
68
    }
69
70
    /**
71
     * @param array $config
72
     * @param ContainerBuilder $container
73
     * @throws \Symfony\Component\DependencyInjection\Exception\LogicException
74
     * @throws InvalidArgumentException
75
     */
76 10
    private function loadClients(array $config, ContainerBuilder $container)
77
    {
78 10
        foreach ($config['clients'] as $clientName => $clientConfig) {
79 6
            $this->loadClient($clientName, $clientConfig, $container);
80
        }
81 10
    }
82
83
    /**
84
     * @param string $clientName
85
     * @param array $clientConfig
86
     * @param ContainerBuilder $container
87
     * @throws \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
88
     */
89 6
    private function loadClient($clientName, array $clientConfig, ContainerBuilder $container)
90
    {
91
        $container
92 6
            ->register($this->createClientId($clientName), Client::class)
93 6
            ->addArgument($clientConfig)
94 6
            ->addMethodCall('setLogger', [
95 6
                new Reference('elastica.logger')
96
            ])
97 6
            ->addMethodCall('setConfigValue', [
98 6
                'log',
99 6
                $container->getParameter('kernel.debug')
100
            ])
101 6
            ->setPublic(true);
102 6
    }
103
104
    /**
105
     * Configure service auto-wiring for default Elastica client
106
     * for Symfony 3.3+
107
     *
108
     * @param array $config
109
     * @param ContainerBuilder $container
110
     * @throws \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
111
     * @throws \Symfony\Component\DependencyInjection\Exception\LogicException
112
     */
113 10
    private function setupAutowire(array $config, ContainerBuilder $container)
114
    {
115 10
        if (!method_exists($container, 'autowire')) {
116
            // This container have no support for services auto-wiring
117
            return;
118
        }
119 10
        if (!$config['autowire']) {
120
            // Auto-wiring for default client is explicitly disabled
121 1
            return;
122
        }
123 9
        if (!array_key_exists('default', $config['clients'])) {
124
            // No "default" client is available
125 5
            return;
126
        }
127 4
        if ($container->hasDefinition(Client::class)) {
128 1
            throw new LogicException('Default Elasticsearch client autowiring setup is enabled, ' .
129 1
                'but Elastica client service is already defined in container');
130
        }
131 3
        $container->setAlias(Client::class, $this->createClientId('default'));
132 3
    }
133
134 6
    private function createClientId($clientName)
135
    {
136 6
        return sprintf(
137 6
            self::CLIENT_ID_TEMPLATE,
138 6
            $clientName
139
        );
140
    }
141
}
142