Passed
Pull Request — master (#30)
by Mathieu
24:17 queued 14:14
created

MigrationService::listMigrations()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 6
nop 0
dl 0
loc 19
rs 9.8333
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(): bool
46
    {
47
        $this->scanForMigrations();
48
        $migrationModel = new MigrationModel();
49
50
        return $migrationModel->createMigrationTable();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $migrationModel->createMigrationTable() could return the type null which is incompatible with the type-hinted return boolean. Consider adding an additional type-check to rule them out.
Loading history...
51
    }
52
53
    public function listMigrations()
54
    {
55
        $this->scanForMigrations();
56
57
        $migrations = MigrationModelList::loadAll();
58
        $alreadyMigrated = [];
59
        $result = [];
60
        foreach ($migrations as $migration) {
61
            $alreadyMigrated[$migration->name] = true;
62
            $result[$migration->name] = $migration->date_added;
63
        }
64
        foreach (array_keys($this->registeredMigrations) as $regMigrationName) {
65
            if (isset($alreadyMigrated[$regMigrationName])) {
66
                continue;
67
            }
68
            $result[$regMigrationName] = false;
69
        }
70
        ksort($result);
71
        return $result;
72
    }
73
74
    public function doMigrations()
75
    {
76
        echo "[Migration] Starting migrations\n";
77
78
        $migrations = $this->listMigrations();
79
        $migrationsToDo = array_filter($migrations, function ($item) {
80
            return $item === false;
81
        });
82
83
        if (count($migrationsToDo) === 0) {
84
            echo "[Migration] Nothing to migrate\n";
85
            return true;
86
        }
87
        foreach (array_keys($migrationsToDo) as $migrationName) {
88
            $migration = new $migrationName();
89
            // FIXME: do migration
90
            // FIXME: connection configuration in migration
91
            _p($migration);
92
        }
93
    }
94
95
    public function createMigration(): string|false
96
    {
97
        $migrationName = 'v' . date('Ymdhis');
98
99
        $template = <<<EOD
100
<?php
101
102
use Suricate\Interfaces\IMigration;
103
104
class {$migrationName} implements IMigration
105
{
106
    public function getName(): string
107
    {
108
        return __CLASS__;
109
    }
110
111
    public function getSQL(): string
112
    {
113
        return '';
114
    }
115
}
116
EOD;
117
        $filename = app_path('migrations/' . $migrationName . '.php');
118
        $directory = pathinfo($filename, PATHINFO_DIRNAME);
119
        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

119
        if (!is_dir(/** @scrutinizer ignore-type */ $directory)) {
Loading history...
120
            $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

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