Passed
Pull Request — master (#30)
by Mathieu
16:30 queued 06:21
created

MigrationService::doMigrations()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 3
nop 0
dl 0
loc 18
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Suricate\Migrations;
6
7
use Suricate\Interfaces\IMigration;
8
use Suricate\Service;
9
10
/**
11
 * DB Migration extension for Suricate
12
 *
13
 * @package Suricate
14
 * @author  Mathieu LESNIAK <[email protected]>
15
 *
16
 */
17
18
class MigrationService extends Service
19
{
20
    protected array $registeredMigrations = [];
21
22
    public function registerMigration(IMigration $migration)
23
    {
24
        // FIXME: test with migration outside of migration folder (eg: media module )
25
        $this->registeredMigrations[$migration->getName()] = $migration->getSQL();
26
    }
27
28
    public function scanForMigrations()
29
    {
30
        $files = glob(app_path('migrations/*.php'));
31
        foreach ($files as $file) {
32
            $migrationClassName = str_replace('.php', '', basename($file));
33
            include($file);
34
            // Class is defined inside the file
35
            if (class_exists($migrationClassName)) {
36
                $migration = new $migrationClassName();
37
                if ($migration instanceof IMigration) {
38
                    $this->registerMigration($migration);
39
                }
40
            }
41
            
42
        }
43
    }
44
45
    public function initMigrationTable(): int
46
    {
47
        $this->scanForMigrations();
48
        $migrationModel = new MigrationModel();
49
50
51
        return $migrationModel->createMigrationTable();
52
    }
53
54
    public function listMigrations()
55
    {
56
        $this->scanForMigrations();
57
58
        $migrations = MigrationModelList::loadAll();
59
        $alreadyMigrated = [];
60
        $result = [];
61
        foreach ($migrations as $migration) {
62
            $alreadyMigrated[$migration->name] = true;
63
            $result[$migration->name] = $migration->date_added;
64
        }
65
        foreach (array_keys($this->registeredMigrations) as $regMigrationName) {
66
            if (isset($alreadyMigrated[$regMigrationName])) {
67
                continue;
68
            }
69
            $result[$regMigrationName] = false;
70
        }
71
        ksort($result);
72
        return $result;
73
    }
74
75
    public function doMigrations()
76
    {
77
        echo "[Migration] Starting migrations\n";
78
79
        $migrations = $this->listMigrations();
80
        $migrationsToDo = array_filter($migrations, function ($item) {
81
            return $item === false;
82
        });
83
84
        if (count($migrationsToDo) === 0) {
85
            echo "[Migration] Nothing to migrate\n";
86
            return true;
87
        }
88
        foreach (array_keys($migrationsToDo) as $migrationName) {
89
            $migration = new $migrationName();
90
            // FIXME: do migration
91
            // FIXME: connection configuration in migration
92
            _p($migration);
93
        }
94
    }
95
96
    public function createMigration(): string|false
97
    {
98
        $migrationName = 'v' . date('Ymdhis');
99
100
        $template = <<<EOD
101
<?php
102
103
use Suricate\Interfaces\IMigration;
104
105
class {$migrationName} implements IMigration
106
{
107
    public function getName(): string
108
    {
109
        return __CLASS__;
110
    }
111
112
    public function getSQL(): string
113
    {
114
        return '';
115
    }
116
}
117
EOD;
118
        $filename = app_path('migrations/' . $migrationName . '.php');
119
        $directory = pathinfo($filename, PATHINFO_DIRNAME);
120
        if (!is_dir($directory)) {
0 ignored issues
show
Bug introduced by
It seems like $directory can also be of type array; however, parameter $filename of is_dir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
        if (!is_dir(/** @scrutinizer ignore-type */ $directory)) {
Loading history...
121
            $ret = mkdir($directory, 0755, true);
0 ignored issues
show
Bug introduced by
It seems like $directory can also be of type array; however, parameter $directory of mkdir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

121
            $ret = mkdir(/** @scrutinizer ignore-type */ $directory, 0755, true);
Loading history...
122
            if (!$ret) {
123
                return false;
124
            }
125
        }
126
        $fp = fopen($filename, 'w');
127
        if ($fp === false) {
128
            return false;
129
        }
130
        $ret = fputs($fp, $template);
131
        fclose($fp);
132
        if ($ret !== false) {
133
            return $migrationName;
134
        }
135
        return false;
136
    }
137
}
138