Completed
Push — master ( dbfc77...6e739b )
by Asmir
18s queued 12s
created

registerMigrationInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 2
dl 0
loc 12
ccs 7
cts 7
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Doctrine\Migrations;
6
7
use Doctrine\Migrations\Exception\DuplicateMigrationVersion;
8
use Doctrine\Migrations\Exception\MigrationClassNotFound;
9
use Doctrine\Migrations\Exception\MigrationException;
10
use Doctrine\Migrations\Finder\MigrationFinder;
11
use Doctrine\Migrations\Metadata\AvailableMigration;
12
use Doctrine\Migrations\Metadata\AvailableMigrationsList;
13
use Doctrine\Migrations\Version\Comparator;
14
use Doctrine\Migrations\Version\MigrationFactory;
15
use Doctrine\Migrations\Version\Version;
16
use function class_exists;
17
use function uasort;
18
19
/**
20
 * The MigrationRepository class is responsible for retrieving migrations, determining what the current migration
21
 * version, etc.
22
 *
23
 * @internal
24
 */
25
class FilesystemMigrationsRepository implements MigrationsRepository
26
{
27
    /** @var bool */
28
    private $migrationsLoaded = false;
29
30
    /** @var array<string, string> */
31
    private $migrationDirectories;
32
33
    /** @var MigrationFinder */
34
    private $migrationFinder;
35
36
    /** @var MigrationFactory */
37
    private $versionFactory;
38
39
    /** @var AvailableMigration[] */
40
    private $migrations = [];
41
42
    /** @var Comparator */
43
    private $sorter;
44
45
    /**
46
     * @param array<string, string> $migrationDirectories
47
     * @param string[]              $classes
48
     */
49 71
    public function __construct(
50
        array $classes,
51
        array $migrationDirectories,
52
        MigrationFinder $migrationFinder,
53
        MigrationFactory $versionFactory,
54
        Comparator $sorter
55
    ) {
56 71
        $this->migrationDirectories = $migrationDirectories;
57 71
        $this->migrationFinder      = $migrationFinder;
58 71
        $this->versionFactory       = $versionFactory;
59 71
        $this->sorter               = $sorter;
60
61 71
        $this->registerMigrations($classes);
62 71
    }
63
64 56
    private function registerMigrationInstance(Version $version, AbstractMigration $migration) : AvailableMigration
65
    {
66 56
        if (isset($this->migrations[(string) $version])) {
67 1
            throw DuplicateMigrationVersion::new(
68 1
                (string) $version,
69 1
                (string) $version
70
            );
71
        }
72
73 56
        $this->migrations[(string) $version] = new AvailableMigration($version, $migration);
74
75 56
        return $this->migrations[(string) $version];
76
    }
77
78
    /** @throws MigrationException */
79 7
    public function registerMigration(string $migrationClassName) : AvailableMigration
80
    {
81 7
        $this->ensureMigrationClassExists($migrationClassName);
82
83 7
        $version   = new Version($migrationClassName);
84 7
        $migration = $this->versionFactory->createVersion($migrationClassName);
85
86 7
        return $this->registerMigrationInstance($version, $migration);
87
    }
88
89
    /**
90
     * @param string[] $migrations
91
     *
92
     * @return AvailableMigration[]
93
     */
94 71
    private function registerMigrations(array $migrations) : array
95
    {
96 71
        $versions = [];
97
98 71
        foreach ($migrations as $class) {
99 7
            $versions[] = $this->registerMigration($class);
100
        }
101
102 71
        return $versions;
103
    }
104
105 10
    public function hasMigration(string $version) : bool
106
    {
107 10
        $this->loadMigrationsFromDirectories();
108
109 10
        return isset($this->migrations[$version]);
110
    }
111
112 14
    public function getMigration(Version $version) : AvailableMigration
113
    {
114 14
        $this->loadMigrationsFromDirectories();
115
116 14
        if (! isset($this->migrations[(string) $version])) {
117 4
            throw MigrationClassNotFound::new((string) $version);
118
        }
119
120 11
        return $this->migrations[(string) $version];
121
    }
122
123 59
    public function getMigrations() : AvailableMigrationsList
124
    {
125 59
        $this->loadMigrationsFromDirectories();
126
127 59
        return new AvailableMigrationsList($this->migrations);
128
    }
129
130
    /** @throws MigrationException */
131 7
    private function ensureMigrationClassExists(string $class) : void
132
    {
133 7
        if (! class_exists($class)) {
134
            throw MigrationClassNotFound::new($class);
135
        }
136 7
    }
137
138 62
    private function loadMigrationsFromDirectories() : void
139
    {
140 62
        $migrationDirectories = $this->migrationDirectories;
141
142 62
        if ($this->migrationsLoaded) {
143 37
            return;
144
        }
145
146 62
        $this->migrationsLoaded = true;
147
148 62
        foreach ($migrationDirectories as $namespace => $path) {
149 29
                $migrations = $this->migrationFinder->findMigrations(
150 29
                    $path,
151 29
                    $namespace
152
                );
153 29
                $this->registerMigrations($migrations);
154
        }
155
156
        uasort($this->migrations, function (AvailableMigration $a, AvailableMigration $b) : int {
157 36
            return $this->sorter->compare($a->getVersion(), $b->getVersion());
158 62
        });
159 62
    }
160
}
161