Passed
Pull Request — master (#95)
by Alessandro
02:29
created

MongoDbBundleExtension   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 6
Bugs 2 Features 0
Metric Value
eloc 53
c 6
b 2
f 0
dl 0
loc 109
rs 10
ccs 52
cts 52
cp 1
wmc 14

8 Methods

Rating   Name   Duplication   Size   Complexity  
A defineDriverOptionsFactory() 0 3 2
A mustCollectData() 0 5 3
A decorateEventDispatcher() 0 7 2
A defineConnections() 0 15 2
A defineConnectionFactory() 0 6 1
A attachDataCollectionListenerToEventManager() 0 15 1
A load() 0 19 2
A defineClientRegistry() 0 15 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Facile\MongoDbBundle\DependencyInjection;
6
7
use Facile\MongoDbBundle\Event\ConnectionEvent;
8
use Facile\MongoDbBundle\Event\EventDispatcherCheck;
9
use Facile\MongoDbBundle\Event\QueryEvent;
10
use Facile\MongoDbBundle\Services\ClientRegistry;
11
use Facile\MongoDbBundle\Services\ConnectionFactory;
12
use MongoDB\Database;
13
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
14
use Symfony\Component\Config\FileLocator;
15
use Symfony\Component\DependencyInjection\Alias;
16
use Symfony\Component\DependencyInjection\ContainerBuilder;
17
use Symfony\Component\DependencyInjection\Definition;
18
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
19
use Symfony\Component\DependencyInjection\Reference;
20
use Symfony\Component\EventDispatcher\EventDispatcher;
21
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
22
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
23
24
/**
25
 * @internal
26
 */
27
final class MongoDbBundleExtension extends Extension
28
{
29
    /** @var ContainerBuilder */
30
    private $containerBuilder;
31 6
32
    public function load(array $configs, ContainerBuilder $container)
33 6
    {
34 6
        $this->containerBuilder = $container;
35
        $config = $this->processConfiguration(new Configuration(), $configs);
36 6
37 6
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
38
        $loader->load('services.xml');
39 6
40 6
        $this->decorateEventDispatcher($container);
0 ignored issues
show
Unused Code introduced by
The call to Facile\MongoDbBundle\Dep...corateEventDispatcher() has too many arguments starting with $container. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

40
        $this->/** @scrutinizer ignore-call */ 
41
               decorateEventDispatcher($container);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
41 6
        $this->defineClientRegistry($config, $container->getParameter('kernel.debug'));
42
        $this->defineConnectionFactory();
43 6
        $this->defineConnections($config['connections']);
44 3
45 3
        if ($this->mustCollectData($config)) {
46
            $loader->load('profiler.xml');
47
            $this->attachDataCollectionListenerToEventManager();
48 6
        }
49
50
        return $config;
51
    }
52
53
    private function mustCollectData(array $config): bool
54
    {
55
        return true === $this->containerBuilder->getParameter('kernel.debug')
56 6
            && class_exists(WebProfilerBundle::class)
57
            && $config['data_collection'] === true;
58 6
    }
59 6
60 6
    private function defineClientRegistry(array $config, bool $debug): void
61
    {
62
        $clientsConfig = $config['clients'];
63
        $clientRegistryDefinition = new Definition(
64
            ClientRegistry::class,
65
            [
66
                new Reference('facile_mongo_db.event_dispatcher'),
67 6
                $debug,
68
                $this->defineDriverOptionsFactory($config),
69 6
            ]
70 6
        );
71
        $clientRegistryDefinition->addMethodCall('addClientsConfigurations', [$clientsConfig]);
72 6
        $clientRegistryDefinition->setPublic(true);
73 6
74
        $this->containerBuilder->setDefinition('mongo.client_registry', $clientRegistryDefinition);
75
    }
76 6
77 6
    private function defineConnectionFactory(): void
78
    {
79 6
        $factoryDefinition = new Definition(ConnectionFactory::class, [new Reference('mongo.client_registry')]);
80 6
        $factoryDefinition->setPublic(false);
81
82 6
        $this->containerBuilder->setDefinition('mongo.connection_factory', $factoryDefinition);
83
    }
84 6
85 6
    private function defineConnections(array $connections)
86
    {
87 6
        foreach ($connections as $name => $conf) {
88 6
            $connectionDefinition = new Definition(
89
                Database::class,
90
                [
91
                    $conf['client_name'],
92
                    $conf['database_name'],
93 6
                ]
94
            );
95 6
            $connectionDefinition->setFactory([new Reference('mongo.connection_factory'), 'createConnection']);
96 6
            $connectionDefinition->setPublic(true);
97 6
            $this->containerBuilder->setDefinition('mongo.connection.' . $name, $connectionDefinition);
98
        }
99 6
        $this->containerBuilder->setAlias('mongo.connection', new Alias('mongo.connection.' . array_keys($connections)[0], true));
100 6
    }
101
102
    private function attachDataCollectionListenerToEventManager(): void
103 6
    {
104 6
        $eventManagerDefinition = $this->containerBuilder->getDefinition('facile_mongo_db.event_dispatcher');
105 6
        $eventManagerDefinition->addMethodCall(
106
            'addListener',
107 6
            [
108 6
                ConnectionEvent::CLIENT_CREATED,
109
                [new Reference('facile_mongo_db.data_collector.listener'), 'onConnectionClientCreated'],
110 3
            ]
111
        );
112 3
        $eventManagerDefinition->addMethodCall(
113 3
            'addListener',
114 3
            [
115
                QueryEvent::QUERY_EXECUTED,
116 3
                [new Reference('facile_mongo_db.data_collector.listener'), 'onQueryExecuted'],
117 3
            ]
118
        );
119
    }
120 3
121 3
    private function defineDriverOptionsFactory(array $config)
122
    {
123 3
        return isset($config['driverOptions']) ? new Reference($config['driverOptions']) : null;
124 3
    }
125
126
    /**
127 3
     * This is needed to avoid the EventDispatcher deprecation from 4.3
128
     */
129
    private function decorateEventDispatcher(): void
130
    {
131
        if (EventDispatcherCheck::shouldUseLegacyProxy()) {
132
            $definition = $this->containerBuilder->getDefinition('facile_mongo_db.event_dispatcher');
133
            $definition->setClass(LegacyEventDispatcherProxy::class);
134
            $definition->setFactory([LegacyEventDispatcherProxy::class, 'decorate']);
135
            $definition->setArguments([new Definition(EventDispatcher::class)]);
136
        }
137
    }
138
}
139