Passed
Push — master ( a25875...d379e9 )
by Dominik
03:08
created

getDbApcuCacheFactoryDefinition()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\DoctrineDbServiceProvider\ServiceProvider;
6
7
use Chubbyphp\DoctrineDbServiceProvider\Logger\DoctrineDbalLogger;
8
use Chubbyphp\DoctrineDbServiceProvider\Registry\DoctrineDbalConnectionRegistry;
9
use Doctrine\Common\Cache\ApcuCache;
10
use Doctrine\Common\Cache\ArrayCache;
11
use Doctrine\Common\Cache\Cache;
12
use Doctrine\Common\EventManager;
13
use Doctrine\DBAL\Configuration;
14
use Doctrine\DBAL\DriverManager;
15
use Doctrine\DBAL\Types\Type;
16
use Pimple\Container;
17
use Pimple\ServiceProviderInterface;
18
19
/**
20
 * This provider is heavily inspired by
21
 * https://github.com/silexphp/Silex-Providers/blob/master/DoctrineServiceProvider.php.
22
 */
23
final class DoctrineDbalServiceProvider implements ServiceProviderInterface
24
{
25 3
    public function register(Container $container): void
26
    {
27 3
        $container['doctrine.dbal.connection_registry'] = $this->getDbConnectionRegistryDefintion($container);
28 3
        $container['doctrine.dbal.db'] = $this->getDbDefinition($container);
29 3
        $container['doctrine.dbal.db.cache_factory.apcu'] = $this->getDbApcuCacheFactoryDefinition($container);
30 3
        $container['doctrine.dbal.db.cache_factory.array'] = $this->getDbArrayCacheFactoryDefinition($container);
31 3
        $container['doctrine.dbal.db.config'] = $this->getDbConfigDefinition($container);
32 3
        $container['doctrine.dbal.db.default_options'] = $this->getDbDefaultOptions();
33 3
        $container['doctrine.dbal.db.event_manager'] = $this->getDbEventManagerDefinition($container);
34 3
        $container['doctrine.dbal.dbs'] = $this->getDbsDefinition($container);
35 3
        $container['doctrine.dbal.dbs.config'] = $this->getDbsConfigDefinition($container);
36 3
        $container['doctrine.dbal.dbs.event_manager'] = $this->getDbsEventManagerDefinition($container);
37 3
        $container['doctrine.dbal.dbs.options.initializer'] = $this->getDbsOptionsInitializerDefinition($container);
38 3
        $container['doctrine.dbal.types'] = [];
39 3
    }
40
41 3
    private function getDbConnectionRegistryDefintion(Container $container): callable
42
    {
43
        return static function () use ($container) {
44 1
            return new DoctrineDbalConnectionRegistry($container);
45 3
        };
46
    }
47
48 3
    private function getDbDefinition(Container $container): callable
49
    {
50
        return static function () use ($container) {
51 2
            $dbs = $container['doctrine.dbal.dbs'];
52
53 2
            return $dbs[$container['doctrine.dbal.dbs.default']];
54 3
        };
55
    }
56
57 3
    private function getDbApcuCacheFactoryDefinition(Container $container): callable
58
    {
59
        return $container->protect(static function () {
60 1
            return new ApcuCache();
61 3
        });
62
    }
63
64 3
    private function getDbArrayCacheFactoryDefinition(Container $container): callable
65
    {
66
        return $container->protect(static function () {
67 1
            return new ArrayCache();
68 3
        });
69
    }
70
71 3
    private function getDbConfigDefinition(Container $container): callable
72
    {
73
        return static function () use ($container) {
74 3
            $dbs = $container['doctrine.dbal.dbs.config'];
75
76 3
            return $dbs[$container['doctrine.dbal.dbs.default']];
77 3
        };
78
    }
79
80
    /**
81
     * @return array<string, array|string|float|int|bool>
0 ignored issues
show
Documentation introduced by
The doc-type array<string, could not be parsed: Expected ">" at position 5, but found "end of type". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
82
     */
83 3
    private function getDbDefaultOptions(): array
84
    {
85
        return [
86 3
            'configuration' => [
87
                'auto_commit' => true,
88
                'cache.result' => ['type' => 'array'],
89
                'filter_schema_assets_expression' => null,
90
            ],
91
            'connection' => [
92
                'charset' => 'utf8mb4',
93
                'dbname' => null,
94
                'driver' => 'pdo_mysql',
95
                'host' => 'localhost',
96
                'password' => null,
97
                'path' => null,
98
                'port' => 3306,
99
                'user' => 'root',
100
            ],
101
        ];
102
    }
103
104 3
    private function getDbEventManagerDefinition(Container $container): callable
105
    {
106
        return static function () use ($container) {
107 3
            $dbs = $container['doctrine.dbal.dbs.event_manager'];
108
109 3
            return $dbs[$container['doctrine.dbal.dbs.default']];
110 3
        };
111
    }
112
113 3
    private function getDbsDefinition(Container $container): callable
114
    {
115
        return static function () use ($container) {
116 3
            $container['doctrine.dbal.dbs.options.initializer']();
117
118 3
            $dbs = new Container();
119 3
            foreach ($container['doctrine.dbal.dbs.options'] as $name => $options) {
120 3
                if ($container['doctrine.dbal.dbs.default'] === $name) {
121 3
                    $config = $container['doctrine.dbal.db.config'];
122 3
                    $manager = $container['doctrine.dbal.db.event_manager'];
123
                } else {
124 1
                    $config = $container['doctrine.dbal.dbs.config'][$name];
125 1
                    $manager = $container['doctrine.dbal.dbs.event_manager'][$name];
126
                }
127
128
                $dbs[$name] = static function () use ($options, $config, $manager) {
129 3
                    return DriverManager::getConnection($options['connection'], $config, $manager);
130 3
                };
131
            }
132
133 3
            return $dbs;
134 3
        };
135
    }
136
137 3
    private function getDbsConfigDefinition(Container $container): callable
138
    {
139
        return function () use ($container) {
140 3
            $container['doctrine.dbal.dbs.options.initializer']();
141
142 3
            $addLogger = $container['logger'] ?? false;
143
144 3
            $configs = new Container();
145 3
            foreach ($container['doctrine.dbal.dbs.options'] as $name => $options) {
146
                $configs[$name] = function () use ($addLogger, $container, $options) {
147 3
                    $configOptions = $options['configuration'];
148
149 3
                    $config = new Configuration();
150
151 3
                    if ($addLogger) {
152 2
                        $config->setSQLLogger(new DoctrineDbalLogger($container['logger']));
153
                    }
154
155 3
                    $config->setResultCacheImpl($this->getCache($container, $configOptions['cache.result']));
156
157 3
                    $config->setFilterSchemaAssetsExpression($configOptions['filter_schema_assets_expression']);
158 3
                    $config->setAutoCommit($configOptions['auto_commit']);
159
160 3
                    return $config;
161 3
                };
162
            }
163
164 3
            return $configs;
165 3
        };
166
    }
167
168 3 View Code Duplication
    private function getCache(Container $container, array $cacheDefinition): Cache
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
169
    {
170 3
        $cacheType = $cacheDefinition['type'];
171 3
        $cacheOptions = $cacheDefinition['options'] ?? [];
172
173 3
        $cacheFactory = $container[sprintf('doctrine.dbal.db.cache_factory.%s', $cacheType)];
174
175 3
        return $cacheFactory($cacheOptions);
176
    }
177
178 3
    private function getDbsEventManagerDefinition(Container $container): callable
179
    {
180
        return static function () use ($container) {
181 3
            $container['doctrine.dbal.dbs.options.initializer']();
182
183 3
            $managers = new Container();
184 3
            foreach (array_keys($container['doctrine.dbal.dbs.options']) as $name) {
185
                $managers[$name] = static function () {
186 3
                    return new EventManager();
187 3
                };
188
            }
189
190 3
            return $managers;
191 3
        };
192
    }
193
194 3
    private function getDbsOptionsInitializerDefinition(Container $container): callable
195
    {
196
        return $container->protect(static function () use ($container): void {
197 3
            static $initialized = false;
198
199 3
            if ($initialized) {
200 3
                return;
201
            }
202
203 3
            $initialized = true;
204
205 3
            foreach ((array) $container['doctrine.dbal.types'] as $typeName => $typeClass) {
206 1
                if (Type::hasType($typeName)) {
207 1
                    Type::overrideType($typeName, $typeClass);
208
                } else {
209 1
                    Type::addType($typeName, $typeClass);
210
                }
211
            }
212
213 3
            if (!isset($container['doctrine.dbal.dbs.options'])) {
214 2
                $container['doctrine.dbal.dbs.options'] = [
215 2
                    'default' => $container['doctrine.dbal.db.options'] ?? [],
216
                ];
217
            }
218
219 3
            $tmp = $container['doctrine.dbal.dbs.options'];
220 3
            foreach ($tmp as $name => &$options) {
221 3
                $options = array_replace_recursive($container['doctrine.dbal.db.default_options'], $options);
222
223 3
                if (!isset($container['doctrine.dbal.dbs.default'])) {
224 3
                    $container['doctrine.dbal.dbs.default'] = $name;
225
                }
226
            }
227
228 3
            $container['doctrine.dbal.dbs.options'] = $tmp;
229 3
        });
230
    }
231
}
232