Failed Conditions
Push — master ( 43e3de...a45d89 )
by Asmir
02:14 queued 10s
created

DependencyFactory   C

Complexity

Total Complexity 53

Size/Duplication

Total Lines 423
Duplicated Lines 0 %

Test Coverage

Coverage 77.45%

Importance

Changes 7
Bugs 1 Features 0
Metric Value
wmc 53
eloc 168
c 7
b 1
f 0
dl 0
loc 423
ccs 158
cts 204
cp 0.7745
rs 6.96

40 Methods

Rating   Name   Duplication   Size   Complexity  
A fromEntityManager() 0 10 1
A fromConnection() 0 10 1
A assertNotFrozen() 0 4 2
A getLogger() 0 4 1
A getConnection() 0 10 3
A getFileBuilder() 0 4 1
A getConfiguration() 0 8 2
A freeze() 0 4 1
A getMigrationFactory() 0 4 1
A setService() 0 4 1
A getDiffGenerator() 0 10 1
A getMigrationRepository() 0 9 1
A getSchemaDumper() 0 16 2
A getParameterFormatter() 0 4 1
A getEventDispatcher() 0 6 1
A getSchemaDiffProvider() 0 7 1
A getMigrationsFinder() 0 7 3
A getEntityManager() 0 12 3
A hasEntityManager() 0 3 1
A getVersionComparator() 0 4 1
A __construct() 0 8 2
A getClassNameGenerator() 0 4 1
A isFrozen() 0 3 1
A getSchemaProvider() 0 4 1
A setConfigurationLoader() 0 4 1
A getMigrationSqlGenerator() 0 6 1
A setDefinition() 0 4 1
A getMigrationStatusInfosHelper() 0 9 1
A getStopwatch() 0 4 1
A getQueryWriter() 0 6 1
A getMigrationGenerator() 0 4 1
A getVersionExecutor() 0 11 1
A getDependency() 0 11 4
A getMigrationStatusCalculator() 0 6 1
A getRollup() 0 6 1
A getMetadataStorage() 0 8 1
A getConsoleInputMigratorConfigurationFactory() 0 5 1
A getMigrator() 0 9 1
A getMigrationPlanCalculator() 0 6 1
A getVersionAliasResolver() 0 7 1

How to fix   Complexity   

Complex Class

Complex classes like DependencyFactory often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use DependencyFactory, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\Migrations\Configuration\Configuration;
9
use Doctrine\Migrations\Configuration\Connection\ConnectionLoader;
10
use Doctrine\Migrations\Configuration\EntityManager\EntityManagerLoader;
11
use Doctrine\Migrations\Configuration\Migration\ConfigurationLoader;
12
use Doctrine\Migrations\Exception\FrozenDependencies;
13
use Doctrine\Migrations\Exception\MissingDependency;
14
use Doctrine\Migrations\Finder\GlobFinder;
15
use Doctrine\Migrations\Finder\MigrationFinder;
16
use Doctrine\Migrations\Finder\RecursiveRegexFinder;
17
use Doctrine\Migrations\Generator\ClassNameGenerator;
18
use Doctrine\Migrations\Generator\ConcatenationFileBuilder;
19
use Doctrine\Migrations\Generator\DiffGenerator;
20
use Doctrine\Migrations\Generator\FileBuilder;
21
use Doctrine\Migrations\Generator\Generator;
22
use Doctrine\Migrations\Generator\SqlGenerator;
23
use Doctrine\Migrations\Metadata\Storage\MetadataStorage;
24
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorage;
25
use Doctrine\Migrations\Metadata\Storage\TableMetadataStorageConfiguration;
26
use Doctrine\Migrations\Provider\DBALSchemaDiffProvider;
27
use Doctrine\Migrations\Provider\LazySchemaDiffProvider;
28
use Doctrine\Migrations\Provider\OrmSchemaProvider;
29
use Doctrine\Migrations\Provider\SchemaDiffProvider;
30
use Doctrine\Migrations\Provider\SchemaProvider;
31
use Doctrine\Migrations\Tools\Console\ConsoleInputMigratorConfigurationFactory;
32
use Doctrine\Migrations\Tools\Console\Helper\MigrationStatusInfosHelper;
33
use Doctrine\Migrations\Tools\Console\MigratorConfigurationFactory;
34
use Doctrine\Migrations\Version\AliasResolver;
35
use Doctrine\Migrations\Version\AlphabeticalComparator;
36
use Doctrine\Migrations\Version\Comparator;
37
use Doctrine\Migrations\Version\CurrentMigrationStatusCalculator;
38
use Doctrine\Migrations\Version\DbalExecutor;
39
use Doctrine\Migrations\Version\DbalMigrationFactory;
40
use Doctrine\Migrations\Version\DefaultAliasResolver;
41
use Doctrine\Migrations\Version\Executor;
42
use Doctrine\Migrations\Version\MigrationFactory;
43
use Doctrine\Migrations\Version\MigrationPlanCalculator;
44
use Doctrine\Migrations\Version\MigrationStatusCalculator;
45
use Doctrine\Migrations\Version\SortedMigrationPlanCalculator;
46
use Doctrine\ORM\EntityManagerInterface;
47
use Psr\Log\LoggerInterface;
48
use Psr\Log\NullLogger;
49
use Symfony\Component\Stopwatch\Stopwatch;
50
use function array_key_exists;
51
use function call_user_func;
52
use function preg_quote;
53
use function sprintf;
54
55
/**
56
 * The DependencyFactory is responsible for wiring up and managing internal class dependencies.
57
 */
58
class DependencyFactory
59
{
60
    /** @var Configuration */
61
    private $configuration;
62
63
    /** @var object[]|callable[] */
64
    private $dependencies = [];
65
66
    /** @var Connection */
67
    private $connection;
68
69
    /** @var EntityManagerInterface|null */
70
    private $em;
71
72
    /** @var bool */
73
    private $frozen = false;
74
75
    /** @var ConfigurationLoader */
76
    private $configurationLoader;
77
78
    /** @var ConnectionLoader */
79
    private $connectionLoader;
80
81
    /** @var EntityManagerLoader|null */
82
    private $emLoader;
83
84
    /** @var callable[] */
85
    private $factories = [];
86
87 60
    public static function fromConnection(
88
        ConfigurationLoader $configurationLoader,
89
        ConnectionLoader $connectionLoader,
90
        ?LoggerInterface $logger = null
91
    ) : self {
92 60
        $dependencyFactory                      = new self($logger);
93 60
        $dependencyFactory->configurationLoader = $configurationLoader;
94 60
        $dependencyFactory->connectionLoader    = $connectionLoader;
95
96 60
        return $dependencyFactory;
97
    }
98
99 1
    public static function fromEntityManager(
100
        ConfigurationLoader $configurationLoader,
101
        EntityManagerLoader $emLoader,
102
        ?LoggerInterface $logger = null
103
    ) : self {
104 1
        $dependencyFactory                      = new self($logger);
105 1
        $dependencyFactory->configurationLoader = $configurationLoader;
106 1
        $dependencyFactory->emLoader            = $emLoader;
107
108 1
        return $dependencyFactory;
109
    }
110
111 61
    private function __construct(?LoggerInterface $logger)
112
    {
113 61
        if ($logger === null) {
114 45
            return;
115
        }
116
117
        $this->setDefinition(LoggerInterface::class, static function () use ($logger) : LoggerInterface {
118 14
            return $logger;
119 16
        });
120 16
    }
121
122 53
    public function isFrozen() : bool
123
    {
124 53
        return $this->frozen;
125
    }
126
127 56
    public function freeze() : void
128
    {
129 56
        $this->frozen = true;
130 56
        $this->getConfiguration()->freeze();
131 56
    }
132
133 42
    private function assertNotFrozen() : void
134
    {
135 42
        if ($this->frozen) {
136 2
            throw FrozenDependencies::new();
137
        }
138 40
    }
139
140 34
    public function hasEntityManager() : bool
141
    {
142 34
        return $this->emLoader !== null;
143
    }
144
145 2
    public function setConfigurationLoader(ConfigurationLoader $configurationLoader) : void
146
    {
147 2
        $this->assertNotFrozen();
148 2
        $this->configurationLoader = $configurationLoader;
149 2
    }
150
151 56
    public function getConfiguration() : Configuration
152
    {
153 56
        if ($this->configuration === null) {
154 56
            $this->configuration = $this->configurationLoader->getConfiguration();
155 56
            $this->freeze();
156
        }
157
158 56
        return $this->configuration;
159
    }
160
161 34
    public function getConnection() : Connection
162
    {
163 34
        if ($this->connection === null) {
164 34
            $this->connection = $this->hasEntityManager()
165 1
                ? $this->getEntityManager()->getConnection()
166 33
                : $this->connectionLoader->getConnection();
167 34
            $this->freeze();
168
        }
169
170 34
        return $this->connection;
171
    }
172
173 2
    public function getEntityManager() : EntityManagerInterface
174
    {
175 2
        if ($this->em === null) {
176 2
            if ($this->emLoader === null) {
177 1
                throw MissingDependency::noEntityManager();
178
            }
179
180 1
            $this->em = $this->emLoader->getEntityManager();
181 1
            $this->freeze();
182
        }
183
184 1
        return $this->em;
185
    }
186
187 31
    public function getVersionComparator() : Comparator
188
    {
189
        return $this->getDependency(Comparator::class, static function () : AlphabeticalComparator {
190 31
            return new AlphabeticalComparator();
191 31
        });
192
    }
193
194 39
    public function getLogger() : LoggerInterface
195
    {
196
        return $this->getDependency(LoggerInterface::class, static function () : LoggerInterface {
197 14
            return new NullLogger();
198 39
        });
199
    }
200
201 1
    public function getEventDispatcher() : EventDispatcher
202
    {
203
        return $this->getDependency(EventDispatcher::class, function () : EventDispatcher {
204 1
            return new EventDispatcher(
205 1
                $this->getConnection(),
206 1
                $this->getConnection()->getEventManager()
207
            );
208 1
        });
209
    }
210
211
    public function getClassNameGenerator() : ClassNameGenerator
212
    {
213
        return $this->getDependency(ClassNameGenerator::class, static function () : ClassNameGenerator {
214
            return new ClassNameGenerator();
215
        });
216
    }
217
218
    public function getSchemaDumper() : SchemaDumper
219
    {
220
        return $this->getDependency(SchemaDumper::class, function () : SchemaDumper {
221
            $excludedTables = [];
222
223
            $metadataConfig = $this->getConfiguration()->getMetadataStorageConfiguration();
224
            if ($metadataConfig instanceof TableMetadataStorageConfiguration) {
225
                $excludedTables[] = sprintf('/^%s$/', preg_quote($metadataConfig->getTableName(), '/'));
226
            }
227
228
            return new SchemaDumper(
229
                $this->getConnection()->getDatabasePlatform(),
230
                $this->getConnection()->getSchemaManager(),
231
                $this->getMigrationGenerator(),
232
                $this->getMigrationSqlGenerator(),
233
                $excludedTables
234
            );
235
        });
236
    }
237
238
    private function getSchemaProvider() : SchemaProvider
239
    {
240
        return $this->getDependency(SchemaProvider::class, function () : SchemaProvider {
241
            return new OrmSchemaProvider($this->getEntityManager());
242
        });
243
    }
244
245
    public function getDiffGenerator() : DiffGenerator
246
    {
247
        return $this->getDependency(DiffGenerator::class, function () : DiffGenerator {
248
            return new DiffGenerator(
249
                $this->getConnection()->getConfiguration(),
250
                $this->getConnection()->getSchemaManager(),
251
                $this->getSchemaProvider(),
252
                $this->getConnection()->getDatabasePlatform(),
253
                $this->getMigrationGenerator(),
254
                $this->getMigrationSqlGenerator()
255
            );
256
        });
257
    }
258
259 1
    public function getSchemaDiffProvider() : SchemaDiffProvider
260
    {
261
        return $this->getDependency(SchemaDiffProvider::class, function () : LazySchemaDiffProvider {
262 1
            return LazySchemaDiffProvider::fromDefaultProxyFactoryConfiguration(
263 1
                new DBALSchemaDiffProvider(
264 1
                    $this->getConnection()->getSchemaManager(),
265 1
                    $this->getConnection()->getDatabasePlatform()
266
                )
267
            );
268 1
        });
269
    }
270
271
    private function getFileBuilder() : FileBuilder
272
    {
273
        return $this->getDependency(FileBuilder::class, static function () : FileBuilder {
274
            return new ConcatenationFileBuilder();
275
        });
276
    }
277
278 1
    private function getParameterFormatter() : ParameterFormatter
279
    {
280
        return $this->getDependency(ParameterFormatter::class, function () : ParameterFormatter {
281 1
            return new InlineParameterFormatter($this->getConnection());
282 1
        });
283
    }
284
285 34
    public function getMigrationsFinder() : MigrationFinder
286
    {
287
        return $this->getDependency(MigrationFinder::class, function () : MigrationFinder {
288 34
            $configs              = $this->getConfiguration();
289 34
            $needsRecursiveFinder = $configs->areMigrationsOrganizedByYear() || $configs->areMigrationsOrganizedByYearAndMonth();
290
291 34
            return $needsRecursiveFinder ? new RecursiveRegexFinder() : new GlobFinder();
292 34
        });
293
    }
294
295 43
    public function getMigrationRepository() : MigrationsRepository
296
    {
297
        return $this->getDependency(MigrationsRepository::class, function () : MigrationsRepository {
298 31
            return new FilesystemMigrationsRepository(
299 31
                $this->getConfiguration()->getMigrationClasses(),
300 31
                $this->getConfiguration()->getMigrationDirectories(),
301 31
                $this->getMigrationsFinder(),
302 31
                $this->getMigrationFactory(),
303 31
                $this->getVersionComparator()
304
            );
305 43
        });
306
    }
307
308 31
    public function getMigrationFactory() : MigrationFactory
309
    {
310
        return $this->getDependency(MigrationFactory::class, function () : MigrationFactory {
311 31
            return new DbalMigrationFactory($this->getConnection(), $this->getLogger());
312 31
        });
313
    }
314
315
    /**
316
     * @param object|callable $service
317
     */
318 25
    public function setService(string $id, $service) : void
319
    {
320 25
        $this->assertNotFrozen();
321 24
        $this->dependencies[$id] = $service;
322 24
    }
323
324 43
    public function getMetadataStorage() : MetadataStorage
325
    {
326
        return $this->getDependency(MetadataStorage::class, function () : MetadataStorage {
327 31
            return new TableMetadataStorage(
328 31
                $this->getConnection(),
329 31
                $this->getVersionComparator(),
330 31
                $this->getConfiguration()->getMetadataStorageConfiguration(),
331 31
                $this->getMigrationRepository()
332
            );
333 43
        });
334
    }
335
336 1
    private function getVersionExecutor() : Executor
337
    {
338
        return $this->getDependency(Executor::class, function () : Executor {
339 1
            return new DbalExecutor(
340 1
                $this->getMetadataStorage(),
341 1
                $this->getEventDispatcher(),
342 1
                $this->getConnection(),
343 1
                $this->getSchemaDiffProvider(),
344 1
                $this->getLogger(),
345 1
                $this->getParameterFormatter(),
346 1
                $this->getStopwatch()
347
            );
348 1
        });
349
    }
350
351 4
    public function getQueryWriter() : QueryWriter
352
    {
353
        return $this->getDependency(QueryWriter::class, function () : QueryWriter {
354
            return new FileQueryWriter(
355
                $this->getFileBuilder(),
356
                $this->getLogger()
357
            );
358 4
        });
359
    }
360
361 19
    public function getVersionAliasResolver() : AliasResolver
362
    {
363
        return $this->getDependency(AliasResolver::class, function () : AliasResolver {
364 19
            return new DefaultAliasResolver(
365 19
                $this->getMigrationRepository(),
366 19
                $this->getMetadataStorage(),
367 19
                $this->getMigrationStatusCalculator()
368
            );
369 19
        });
370
    }
371
372 25
    public function getMigrationStatusCalculator() : MigrationStatusCalculator
373
    {
374
        return $this->getDependency(MigrationStatusCalculator::class, function () : MigrationStatusCalculator {
375 25
            return new CurrentMigrationStatusCalculator(
376 25
                $this->getMigrationRepository(),
377 25
                $this->getMetadataStorage()
378
            );
379 25
        });
380
    }
381
382 14
    public function getMigrationPlanCalculator() : MigrationPlanCalculator
383
    {
384
        return $this->getDependency(MigrationPlanCalculator::class, function () : MigrationPlanCalculator {
385 10
            return new SortedMigrationPlanCalculator(
386 10
                $this->getMigrationRepository(),
387 10
                $this->getMetadataStorage()
388
            );
389 14
        });
390
    }
391
392
    public function getMigrationGenerator() : Generator
393
    {
394
        return $this->getDependency(Generator::class, function () : Generator {
395
            return new Generator($this->getConfiguration());
396
        });
397
    }
398
399
    public function getMigrationSqlGenerator() : SqlGenerator
400
    {
401
        return $this->getDependency(SqlGenerator::class, function () : SqlGenerator {
402
            return new SqlGenerator(
403
                $this->getConfiguration(),
404
                $this->getConnection()->getDatabasePlatform()
405
            );
406
        });
407
    }
408
409 20
    public function getConsoleInputMigratorConfigurationFactory() : MigratorConfigurationFactory
410
    {
411
        return $this->getDependency(MigratorConfigurationFactory::class, function () : MigratorConfigurationFactory {
412 20
            return new ConsoleInputMigratorConfigurationFactory(
413 20
                $this->getConfiguration()
414
            );
415 20
        });
416
    }
417
418 3
    public function getMigrationStatusInfosHelper() : MigrationStatusInfosHelper
419
    {
420
        return $this->getDependency(MigrationStatusInfosHelper::class, function () : MigrationStatusInfosHelper {
421 3
            return new MigrationStatusInfosHelper(
422 3
                $this->getConfiguration(),
423 3
                $this->getConnection(),
424 3
                $this->getVersionAliasResolver(),
425 3
                $this->getMigrationRepository(),
426 3
                $this->getMetadataStorage()
427
            );
428 3
        });
429
    }
430
431 10
    public function getMigrator() : Migrator
432
    {
433
        return $this->getDependency(Migrator::class, function () : Migrator {
434 1
            return new DbalMigrator(
435 1
                $this->getConnection(),
436 1
                $this->getEventDispatcher(),
437 1
                $this->getVersionExecutor(),
438 1
                $this->getLogger(),
439 1
                $this->getStopwatch()
440
            );
441 10
        });
442
    }
443
444 1
    public function getStopwatch() : Stopwatch
445
    {
446
        return $this->getDependency(Stopwatch::class, static function () : Stopwatch {
447 1
            return new Stopwatch(true);
448 1
        });
449
    }
450
451
    public function getRollup() : Rollup
452
    {
453
        return $this->getDependency(Rollup::class, function () : Rollup {
454
            return new Rollup(
455
                $this->getMetadataStorage(),
456
                $this->getMigrationRepository()
457
            );
458
        });
459
    }
460
461
    /**
462
     * @return mixed
463
     */
464 54
    private function getDependency(string $id, callable $callback)
465
    {
466 54
        if (array_key_exists($id, $this->factories) && ! array_key_exists($id, $this->dependencies)) {
467 15
            $this->dependencies[$id] = call_user_func($this->factories[$id], $this);
468
        }
469
470 54
        if (! array_key_exists($id, $this->dependencies)) {
471 50
            $this->dependencies[$id] = $callback();
472
        }
473
474 54
        return $this->dependencies[$id];
475
    }
476
477 18
    public function setDefinition(string $id, callable $service) : void
478
    {
479 18
        $this->assertNotFrozen();
480 17
        $this->factories[$id] = $service;
481 17
    }
482
}
483