configureDHMiddleware()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 14
nc 4
nop 2
dl 0
loc 25
c 0
b 0
f 0
cc 4
rs 9.7998
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DH\AuditorBundle\DependencyInjection\Compiler;
6
7
use DH\Auditor\Provider\Doctrine\Auditing\Annotation\AnnotationLoader;
8
use DH\Auditor\Provider\Doctrine\Auditing\Logger\Middleware\DHMiddleware;
9
use DH\Auditor\Provider\Doctrine\DoctrineProvider;
10
use DH\Auditor\Provider\Doctrine\Service\AuditingService;
11
use DH\Auditor\Provider\Doctrine\Service\StorageService;
12
use Doctrine\DBAL\Driver\Middleware;
13
use Symfony\Component\DependencyInjection\ChildDefinition;
14
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Definition;
17
use Symfony\Component\DependencyInjection\Reference;
18
19
/** @see \DH\AuditorBundle\Tests\DependencyInjection\Compiler\DoctrineMiddlewareCompilerPassTest */
20
class DoctrineProviderConfigurationCompilerPass implements CompilerPassInterface
21
{
22
    private bool $isDHMiddlewareSupported = false;
23
24
    public function process(ContainerBuilder $container): void
25
    {
26
        if (!$container->hasDefinition(DoctrineProvider::class)) {
27
            return;
28
        }
29
30
        $doctrineProviderConfigurationKey = 'dh_auditor.provider.doctrine.configuration';
31
        if (!$container->hasParameter($doctrineProviderConfigurationKey)) {
32
            return;
33
        }
34
35
        $providerDefinition = $container->getDefinition(DoctrineProvider::class);
36
        $config = $container->getParameter($doctrineProviderConfigurationKey);
37
38
        \assert(\is_array($config) && \array_key_exists('storage_services', $config));
39
        foreach (array_unique($config['storage_services']) as $entityManagerName) {
40
            $entityManagerName = str_replace('@', '', $entityManagerName);
41
            $entityManagerReference = new Reference($entityManagerName);
42
43
            $service = 'dh_auditor.provider.doctrine.storage_services.'.$entityManagerName;
44
            $serviceDefinition = new Definition(StorageService::class, [
45
                $service,
46
                $entityManagerReference,
47
            ]);
48
            $container->setDefinition($service, $serviceDefinition);
49
            $serviceReference = new Reference($service);
50
51
            $providerDefinition->addMethodCall('registerStorageService', [$serviceReference]);
52
        }
53
54
        \assert(\is_array($config) && \array_key_exists('auditing_services', $config));
55
56
        $this->registerDHMiddleware($container);
57
58
        foreach (array_unique($config['auditing_services']) as $entityManagerName) {
59
            $entityManagerName = str_replace('@', '', $entityManagerName);
60
            $entityManagerReference = new Reference($entityManagerName);
61
62
            $service = 'dh_auditor.provider.doctrine.auditing_services.'.$entityManagerName;
63
            $serviceDefinition = new Definition(AuditingService::class, [
64
                $service,
65
                $entityManagerReference,
66
            ]);
67
            $container->setDefinition($service, $serviceDefinition);
68
            $serviceReference = new Reference($service);
69
70
            $annotationLoaderDefinition = new Definition(AnnotationLoader::class, [$entityManagerReference]);
71
            $container->setDefinition(AnnotationLoader::class, $annotationLoaderDefinition);
72
73
            $providerDefinition->addMethodCall('registerAuditingService', [$serviceReference]);
74
            $this->configureDHMiddleware($container, $entityManagerName);
75
        }
76
    }
77
78
    private function registerDHMiddleware(ContainerBuilder $container): void
79
    {
80
        if (interface_exists(Middleware::class) && class_exists(DHMiddleware::class)) {
81
            $this->isDHMiddlewareSupported = true;
82
            $container->register('doctrine.dbal.dh_middleware', DHMiddleware::class);
83
        }
84
    }
85
86
    private function configureDHMiddleware(ContainerBuilder $container, string $entityManagerName): void
87
    {
88
        if (!$this->isDHMiddlewareSupported) {
89
            return;
90
        }
91
92
        $argument = $container->getDefinition($entityManagerName)->getArgument(0);
93
        if (!$argument instanceof Reference) {
94
            return;
95
        }
96
97
        $connectionName = (string) $argument;
98
99
        /** @see vendor/doctrine/doctrine-bundle/DependencyInjection/DoctrineExtension.php */
100
        $configurationName = $connectionName.'.configuration';
101
        if (!$container->hasDefinition($configurationName)) {
102
            return;
103
        }
104
105
        $container
106
            ->setDefinition(
107
                $connectionName.'.dh_middleware',
108
                new ChildDefinition('doctrine.dbal.dh_middleware')
109
            )
110
            ->addTag('doctrine.middleware')
111
        ;
112
    }
113
}
114