Passed
Push — master ( b694dd...6c1d9a )
by Paul
14:45 queued 06:38
created

Migrate::runAll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules;
4
5
use DirectoryIterator;
6
use GeminiLabs\SiteReviews\Database;
7
use GeminiLabs\SiteReviews\Database\OptionManager;
8
use GeminiLabs\SiteReviews\Helper;
9
use GeminiLabs\SiteReviews\Helpers\Arr;
10
11
class Migrate
12
{
13
    /**
14
     * @var string
15
     */
16
    public $currentVersion;
17
18
    /**
19
     * @var string[]
20
     */
21
    public $migrations;
22
23
    /**
24
     * @var string
25
     */
26
    public $migrationsKey;
27
28 14
    public function __construct()
29
    {
30 14
        $this->currentVersion = $this->currentVersion();
31 14
        $this->migrations = $this->availableMigrations();
32 14
        $this->migrationsKey = glsr()->prefix.'migrations';
33 14
    }
34
35
    /**
36
     * @return bool
37
     */
38
    public function isMigrationNeeded()
39
    {
40
        if (empty($this->migrations)) {
41
            return false;
42
        }
43
        if (!empty($this->pendingMigrations())) {
44
            // check if this is a fresh install of the plugin
45
            return glsr(OptionManager::class)->get('version_upgraded_from') !== '0.0.0';
46
        }
47
        return false;
48
    }
49
50
    /**
51
     * @return void
52
     */
53 7
    public function reset()
54
    {
55 7
        delete_option($this->migrationsKey);
56 7
    }
57
58
    /**
59
     * @return void
60
     */
61 7
    public function run()
62
    {
63 7
        if (glsr(Database::class)->isMigrationNeeded()) {
64
            $this->runAll();
65
        } else {
66 7
            $this->runMigrations();
67
        }
68 7
    }
69
70
    /**
71
     * @return void
72
     */
73 7
    public function runAll()
74
    {
75 7
        $this->reset();
76 7
        $this->runMigrations();
77 7
    }
78
79
    /**
80
     * @return array
81
     */
82 14
    protected function availableMigrations()
83
    {
84 14
        $migrations = [];
85 14
        $dir = glsr()->path('plugin/Modules/Migrations');
86 14
        if (is_dir($dir)) {
87 14
            $iterator = new DirectoryIterator($dir);
88 14
            foreach ($iterator as $fileinfo) {
89 14
                if ('file' === $fileinfo->getType()) {
90 14
                    $migrations[] = str_replace('.php', '', $fileinfo->getFilename());
91
                }
92
            }
93 14
            natsort($migrations);
94
        }
95 14
        return Arr::reindex($migrations);
96
    }
97
98
    /**
99
     * @return array
100
     */
101 7
    protected function createMigrations()
102
    {
103 7
        $migrations = [];
104 7
        foreach ($this->migrations as $migration) {
105 7
            $migrations[$migration] = false;
106
        }
107 7
        return $migrations;
108
    }
109
110
    /**
111
     * @return string
112
     */
113 14
    protected function currentVersion()
114
    {
115 14
        $fallback = '0.0.0';
116 14
        $majorVersions = range(glsr()->version('major'), 1);
117 14
        foreach ($majorVersions as $majorVersion) {
118 14
            $settings = get_option(OptionManager::databaseKey($majorVersion));
119 14
            $version = Arr::get($settings, 'version', $fallback);
120 14
            if (Helper::isGreaterThan($version, $fallback)) {
121 5
                return $version;
122
            }
123
        }
124 9
        return $fallback;
125
    }
126
127
    /**
128
     * @return string[]
129
     */
130 14
    protected function pendingMigrations(array $migrations = [])
131
    {
132 14
        if (empty($migrations)) {
133
            $migrations = $this->storedMigrations();
134
        }
135
        return array_keys(array_filter($migrations, function ($hasRun) {
136 14
            return !$hasRun;
137 14
        }));
138
    }
139
140
    /**
141
     * @return void
142
     */
143 14
    protected function runMigrations()
144
    {
145 14
        wp_raise_memory_limit('admin');
146 14
        $migrations = $this->storedMigrations();
147 14
        glsr()->action('migration/start', $migrations);
148 14
        foreach ($this->pendingMigrations($migrations) as $migration) {
149 14
            if (class_exists($classname = __NAMESPACE__.'\Migrations\\'.$migration)) {
150 14
                if (glsr($classname)->run()) {
151 14
                    $migrations[$migration] = true;
152 14
                    glsr_log()->debug("[$migration] has run successfully");
153 14
                    continue;
154
                }
155
                glsr_log()->error("[$migration] was unsuccessful");
156
            }
157
        }
158 14
        $this->storeMigrations($migrations);
159 14
        if ($this->currentVersion !== glsr()->version) {
160 9
            $this->updateVersionFrom($this->currentVersion);
161
        }
162 14
        glsr(OptionManager::class)->set('last_migration_run', current_time('timestamp'));
163 14
        glsr()->action('migration/end', $migrations);
164 14
    }
165
166
    /**
167
     * @return void
168
     */
169 14
    protected function storeMigrations(array $migrations)
170
    {
171 14
        update_option($this->migrationsKey, $migrations);
172 14
    }
173
174
    /**
175
     * @return array
176
     */
177 14
    protected function storedMigrations()
178
    {
179 14
        $migrations = Arr::consolidate(get_option($this->migrationsKey));
180 14
        if (!Arr::compare(array_keys($migrations), array_values($this->migrations))) {
181 7
            $newMigrations = $this->createMigrations();
182 7
            foreach ($newMigrations as $migration => &$hasRun) {
183 7
                $hasRun = Arr::get($migrations, $migration, false);
184
            }
185 7
            $migrations = $newMigrations;
186 7
            $this->storeMigrations($migrations);
187
        }
188 14
        return array_map('wp_validate_boolean', $migrations);
189
    }
190
191
    /**
192
     * @param string $previousVersion
193
     * @return void
194
     */
195 9
    protected function updateVersionFrom($previousVersion)
196
    {
197 9
        glsr(OptionManager::class)->set('version', glsr()->version);
198 9
        glsr(OptionManager::class)->set('version_upgraded_from', $previousVersion);
199 9
    }
200
}
201