Passed
Pull Request — master (#95)
by Alessandro
03:00
created

attachDataCollectionListenerToEventManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 15
ccs 9
cts 9
cp 1
crap 1
rs 9.9666
c 0
b 0
f 0
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\QueryEvent;
9
use Facile\MongoDbBundle\Services\ClientRegistry;
10
use Facile\MongoDbBundle\Services\ConnectionFactory;
11
use MongoDB\Database;
12
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
13
use Symfony\Component\Config\FileLocator;
14
use Symfony\Component\DependencyInjection\Alias;
15
use Symfony\Component\DependencyInjection\ContainerBuilder;
16
use Symfony\Component\DependencyInjection\Definition;
17
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
18
use Symfony\Component\DependencyInjection\Reference;
19
use Symfony\Component\EventDispatcher\EventDispatcher;
20
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
21
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
22
23
/**
24
 * @internal
25
 */
26
final class MongoDbBundleExtension extends Extension
27
{
28
    /** @var ContainerBuilder */
29
    private $containerBuilder;
30
31 6
    public function load(array $configs, ContainerBuilder $container)
32
    {
33 6
        $this->containerBuilder = $container;
34 6
        $config = $this->processConfiguration(new Configuration(), $configs);
35
36 6
        $loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
37 6
        $loader->load('services.xml');
38
39 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

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