Failed Conditions
Pull Request — master (#959)
by Asmir
02:21
created

DependencyFactory::setConfigurationLoader()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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