Passed
Push — master ( 229462...d74785 )
by Andreas
02:20 queued 14s
created

MigrationRepository::getCurrentVersion()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 23
c 1
b 0
f 0
nc 5
nop 0
dl 0
loc 40
ccs 24
cts 24
cp 1
crap 6
rs 8.9297

1 Method

Rating   Name   Duplication   Size   Complexity  
A MigrationRepository::loadMigrationsFromDirectories() 0 16 3
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\MigrationFactory;
14
use Doctrine\Migrations\Version\Version;
15
use function class_exists;
16
use function strcmp;
17
use function uasort;
18
19
/**
20
 * The MigrationRepository class is responsible for retrieving migrations, determing what the current migration
21
 * version, etc.
22
 *
23
 * @internal
24
 */
25
class MigrationRepository
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 callable */
43
    private $sorter;
44
45
    /**
46
     * @param array<string, string> $migrationDirectories
47
     * @param string[]              $classes
48
     */
49 61
    public function __construct(
50
        array $classes,
51
        array $migrationDirectories,
52
        MigrationFinder $migrationFinder,
53
        MigrationFactory $versionFactory,
54
        ?callable $sorter = null
55
    ) {
56 61
        $this->migrationDirectories = $migrationDirectories;
57 61
        $this->migrationFinder      = $migrationFinder;
58 61
        $this->versionFactory       = $versionFactory;
59
        $this->sorter               = $sorter ?: static function (AvailableMigration $m1, AvailableMigration $m2) {
60 32
            return strcmp((string) $m1->getVersion(), (string) $m2->getVersion());
61 61
        };
62
63 61
        $this->registerMigrations($classes);
64 61
    }
65
66
    /**
67
     * @internal DO NOT USE, THIS METHOD IS HERE ONLY TO EASE THE TESTING, WILL BE REMOVED IN UPCOMING MINOR/BUGFIX RELEASE
68
     */
69 51
    public function registerMigrationInstance(Version $version, AbstractMigration $migration) : AvailableMigration
70
    {
71 51
        if (isset($this->migrations[(string) $version])) {
72 1
            throw DuplicateMigrationVersion::new(
73 1
                (string) $version,
74 1
                (string) $version
75
            );
76
        }
77
78 51
        $this->migrations[(string) $version] = new AvailableMigration($version, $migration);
79
80 51
        uasort($this->migrations, $this->sorter);
81
82 51
        return $this->migrations[(string) $version];
83
    }
84
85
    /** @throws MigrationException */
86 7
    public function registerMigration(string $migrationClassName) : AvailableMigration
87
    {
88 7
        $this->ensureMigrationClassExists($migrationClassName);
89
90 7
        $version   = new Version($migrationClassName);
91 7
        $migration = $this->versionFactory->createVersion($migrationClassName);
92
93 7
        return $this->registerMigrationInstance($version, $migration);
94
    }
95
96
    /**
97
     * @param string[] $migrations
98
     *
99
     * @return AvailableMigration[]
100
     */
101 61
    private function registerMigrations(array $migrations) : array
102
    {
103 61
        $versions = [];
104
105 61
        foreach ($migrations as $class) {
106 7
            $versions[] = $this->registerMigration($class);
107
        }
108
109 61
        return $versions;
110
    }
111
112 1
    public function hasMigration(string $version) : bool
113
    {
114 1
        $this->loadMigrationsFromDirectories();
115
116 1
        return isset($this->migrations[$version]);
117
    }
118
119 12
    public function getMigration(Version $version) : AvailableMigration
120
    {
121 12
        $this->loadMigrationsFromDirectories();
122
123 12
        if (! isset($this->migrations[(string) $version])) {
124 3
            throw MigrationClassNotFound::new((string) $version);
125
        }
126
127 10
        return $this->migrations[(string) $version];
128
    }
129
130 53
    public function getMigrations() : AvailableMigrationsList
131
    {
132 53
        $this->loadMigrationsFromDirectories();
133
134 53
        return new AvailableMigrationsList($this->migrations);
135
    }
136
137
    /** @throws MigrationException */
138 7
    private function ensureMigrationClassExists(string $class) : void
139
    {
140 7
        if (! class_exists($class)) {
141
            throw MigrationClassNotFound::new($class);
142
        }
143 7
    }
144
145 56
    private function loadMigrationsFromDirectories() : void
146
    {
147 56
        $migrationDirectories = $this->migrationDirectories;
148
149 56
        if ($this->migrationsLoaded) {
150 33
            return;
151
        }
152
153 56
        $this->migrationsLoaded = true;
154
155 56
        foreach ($migrationDirectories as $namespace => $path) {
156 37
                $migrations = $this->migrationFinder->findMigrations(
157 37
                    $path,
158 37
                    $namespace
159
                );
160 37
                $this->registerMigrations($migrations);
161
        }
162 56
    }
163
}
164