Completed
Push — master ( dc7866...8155ff )
by Changwan
06:46
created

Migrator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace Wandu\Database\Migrator;
3
4
use DirectoryIterator;
5
use RuntimeException;
6
use SplFileInfo;
7
use Wandu\Database\Contracts\Migrator\MigrateAdapterInterface;
8
use Wandu\Database\Contracts\Migrator\MigrationInterface;
9
use Wandu\DI\ContainerInterface;
10
11
class Migrator
12
{
13
    /** @var \Wandu\Database\Contracts\Migrator\MigrateAdapterInterface */
14
    protected $adapter;
15
    
16
    /** @var \Wandu\Database\Migrator\Configuration */
17
    protected $config;
18
19
    /** @var \Wandu\DI\ContainerInterface */
20
    protected $container;
21
    
22
    /**
23
     * @param \Wandu\Database\Contracts\Migrator\MigrateAdapterInterface $adapter
24
     * @param \Wandu\Database\Migrator\Configuration $config
25
     * @param \Wandu\DI\ContainerInterface $container
26
     */
27
    public function __construct(MigrateAdapterInterface $adapter, Configuration $config, ContainerInterface $container)
28
    {
29
        $this->adapter = $adapter;
30
        $this->config = $config;
31
        $this->container = $container;
32
    }
33
34
    /**
35
     * @return array|\Wandu\Database\Migrator\MigrationContainer[]
36
     */
37
    public function migrations()
38
    {
39
        $migrations = [];
40
        foreach ($this->getAllMigrationFiles() as $file) {
41
            $migrations[] = new MigrationContainer($file, $this->adapter, $this->container);
42
        }
43
        return $migrations;
44
    }
45
46
    /**
47
     * @param string $migrationId
48
     * @return \Wandu\Database\Migrator\MigrationContainer
49
     */
50
    public function migration($migrationId)
51
    {
52
        foreach ($this->getAllMigrationFiles() as $file) {
53
            if (strpos($file, $migrationId . '_') !== false) {
54
                return new MigrationContainer($file, $this->adapter, $this->container);
55
            }
56
        }
57
        throw new RuntimeException("there is no migration id \"{$migrationId}\".");
58
    }
59
60
    /**
61
     * @param string $migrationId
62
     */
63
    public function up($migrationId)
64
    {
65
        if (!preg_match('/^\d{6}_\d{6}$/', $migrationId)) {
66
            throw new RuntimeException("invalid migration id. it must be like 000000_000000.");
67
        }
68
        $version = $this->adapter->version($migrationId);
69
        if ($version) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
70
            throw new RuntimeException("this {$migrationId} is already applied.");
71
        }
72
        
73
        $this->migration($migrationId)->up();
74
    }
75
76
    /**
77
     * @param string $migrationId
78
     */
79
    public function down($migrationId)
80
    {
81
        if (!preg_match('/^\d{6}_\d{6}$/', $migrationId)) {
82
            throw new RuntimeException("invalid migration id. it must be like 000000_000000.");
83
        }
84
        $version = $this->adapter->version($migrationId);
85
        if (!$version) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $version of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
86
            throw new RuntimeException("this {$migrationId} is not already applied.");
87
        }
88
89
        $this->migration($migrationId)->down();
90
    }
91
92
    /**
93
     * @return array|\Wandu\Database\Migrator\MigrationContainer[]
94
     */
95
    public function migrate()
96
    {
97
        $migratedMigrations = [];
98
        $migrations = $this->migrations();
99
        foreach ($migrations as $migration) {
100
            if (!$this->adapter->version($migration->getId())) {
101
                $migration->up();
102
                $migratedMigrations[] = $migration;
103
            }
104
        }
105
        return $migratedMigrations;
106
    }
107
    
108
    /**
109
     * @return array
110
     */
111
    protected function getAllMigrationFiles()
112
    {
113
        $files = [];
114
        foreach (new DirectoryIterator($this->config->getPath()) as $file) {
115
            if ($file->isDot() || $file->isDir() || $file->getFilename()[0] === '.') continue;
116
            $files[] = $file->getFileInfo();
117
        }
118
        usort($files, function (SplFileInfo $file, SplFileInfo $nextFile) {
119
            if ($file->getFilename() > $nextFile->getFilename()) {
120
                return 1;
121
            }
122
            return $file->getFilename() < $nextFile->getFilename() ? -1 : 0;
123
        });
124
        return $files;
125
    }
126
}
127