Completed
Pull Request — master (#692)
by Renan
03:49
created

DoctrineDBALLoggerPass   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 80
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 5
dl 0
loc 80
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 10 2
B ensureIsValidServiceDefinition() 0 34 4
A attachServiceToAllConnections() 0 17 3
A createEmptyChain() 0 9 1
1
<?php
2
3
namespace Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler;
4
5
use Doctrine\DBAL\Logging\SQLLogger;
6
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
7
use Symfony\Component\DependencyInjection\ContainerBuilder;
8
use Symfony\Component\DependencyInjection\Definition;
9
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
10
use Symfony\Component\DependencyInjection\Reference;
11
12
final class DoctrineDBALLoggerPass implements CompilerPassInterface
13
{
14
    private const TAG_NAME = 'doctrine.dbal.logger';
15
    private const LOGGER_INTERFACE = SQLLogger::class;
16
    private const BASE_CHAIN_NAME = 'doctrine.dbal.logger.chain';
17
18
    public function process(ContainerBuilder $container)
19
    {
20
        $serviceList = $container->findTaggedServiceIds(self::TAG_NAME, true);
21
        $serviceList = array_keys($serviceList);
22
23
        foreach ($serviceList as $serviceId) {
24
            $this->ensureIsValidServiceDefinition($container, $serviceId);
25
            $this->attachServiceToAllConnections($container, $serviceId);
26
        }
27
    }
28
29
    private function ensureIsValidServiceDefinition(ContainerBuilder $container, string $serviceId): void
30
    {
31
        $serviceDefinition = $container->getDefinition($serviceId);
32
33
        $serviceClass = $container->getParameterBag()->resolveValue(
34
            $serviceDefinition->getClass()
35
        );
36
        $reflectionClass = $container->getReflectionClass($serviceClass);
37
38
        if (!$reflectionClass) {
39
            throw new InvalidArgumentException(sprintf(
40
                'Class "%s" used for service "%s" cannot be found.',
41
                $serviceClass,
42
                $serviceId
43
            ));
44
        }
45
46
        if (!$reflectionClass->implementsInterface(self::LOGGER_INTERFACE)) {
47
            throw new InvalidArgumentException(sprintf(
48
                'The service "%s" tagged "%s" must implement "%s".',
49
                $serviceId,
50
                self::TAG_NAME,
51
                self::LOGGER_INTERFACE
52
            ));
53
        }
54
55
        if ($reflectionClass->isAbstract()) {
56
            throw new InvalidArgumentException(sprintf(
57
                'The service "%s" tagged "%s" must not be abstract.',
58
                $serviceId,
59
                self::TAG_NAME
60
            ));
61
        }
62
    }
63
64
    private function attachServiceToAllConnections(ContainerBuilder $container, string $serviceId): void
65
    {
66
        $serviceReference = new Reference($serviceId);
67
68
        $connectionList = $container->getParameter('doctrine.connections');
69
70
        foreach ($connectionList as $connectionName => $connectionId) {
71
            $chainId = self::BASE_CHAIN_NAME . '.' . $connectionName;
72
73
            if (!$container->hasDefinition($chainId)) {
74
                $this->createEmptyChain($container, $chainId, $connectionId);
75
            }
76
77
            $chainDefinition = $container->getDefinition($chainId);
78
            $chainDefinition->addMethodCall('addLogger', array($serviceReference));
79
        }
80
    }
81
82
    private function createEmptyChain(ContainerBuilder $container, string $chainId, string $connectionId): void
83
    {
84
        $chainReference = new Reference($chainId);
85
86
        $container->setDefinition($chainId, new Definition(self::BASE_CHAIN_NAME));
87
88
        $configurationDefinition = $container->getDefinition($connectionId . '.configuration');
89
        $configurationDefinition->addMethodCall('setSQLLogger', array($chainReference));
90
    }
91
}
92