Completed
Push — master ( 6e27f1...d5fec2 )
by Nicolas
03:36
created

Migrator::rollback()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22

Duplication

Lines 22
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
nc 3
nop 0
dl 22
loc 22
ccs 0
cts 11
cp 0
crap 12
rs 9.568
c 0
b 0
f 0
1
<?php
2
3
namespace Nwidart\Modules\Migrations;
4
5
use Illuminate\Contracts\Foundation\Application;
6
use Illuminate\Support\Collection;
7
use Nwidart\Modules\Module;
8
use Nwidart\Modules\Support\Config\GenerateConfigReader;
9
10
class Migrator
11
{
12
    /**
13
     * Pingpong Module instance.
14
     *
15
     * @var \Nwidart\Modules\Module
16
     */
17
    protected $module;
18
19
    /**
20
     * Laravel Application instance.
21
     *
22
     * @var Application.
23
     */
24
    protected $laravel;
25
26
    /**
27
     * The database connection to be used
28
     *
29
     * @var string
30
     */
31
    protected $database = '';
32
33
    /**
34
     * Create new instance.
35
     *
36
     * @param \Nwidart\Modules\Module $module
37
     */
38 1
    public function __construct(Module $module)
39
    {
40 1
        $this->module = $module;
41 1
        $this->laravel = $module->getLaravel();
42 1
    }
43
44
    /**
45
     * Set the database connection to be used
46
     *
47
     * @param $database
48
     *
49
     * @return $this
50
     */
51
    public function setDatabase($database)
52
    {
53
        if (is_string($database) && $database) {
54
            $this->database = $database;
55
        }
56
57
        return $this;
58
    }
59
60
    /**
61
     * @return Module
62
     */
63 1
    public function getModule()
64
    {
65 1
        return $this->module;
66
    }
67
68
    /**
69
     * Get migration path.
70
     *
71
     * @return string
72
     */
73 1
    public function getPath()
74
    {
75 1
        $config = $this->module->get('migration');
76
77 1
        $migrationPath = GenerateConfigReader::read('migration');
78 1
        $path = (is_array($config) && array_key_exists('path', $config)) ? $config['path'] : $migrationPath->getPath();
79
80 1
        return $this->module->getExtraPath($path);
81
    }
82
83
    /**
84
     * Get migration files.
85
     *
86
     * @param boolean $reverse
87
     * @return array
88
     */
89
    public function getMigrations($reverse = false)
90
    {
91
        $files = $this->laravel['files']->glob($this->getPath() . '/*_*.php');
92
93
        // Once we have the array of files in the directory we will just remove the
94
        // extension and take the basename of the file which is all we need when
95
        // finding the migrations that haven't been run against the databases.
96
        if ($files === false) {
97
            return [];
98
        }
99
100
        $files = array_map(function ($file) {
101
            return str_replace('.php', '', basename($file));
102
        }, $files);
103
104
        // Once we have all of the formatted file names we will sort them and since
105
        // they all start with a timestamp this should give us the migrations in
106
        // the order they were actually created by the application developers.
107
        sort($files);
108
109
        if ($reverse) {
110
            return array_reverse($files);
111
        }
112
113
        return $files;
114
    }
115
116
    /**
117
     * Rollback migration.
118
     *
119
     * @return array
120
     */
121 View Code Duplication
    public function rollback()
122
    {
123
        $migrations = $this->getLast($this->getMigrations(true));
124
125
        $this->requireFiles($migrations->toArray());
126
127
        $migrated = [];
128
129
        foreach ($migrations as $migration) {
130
            $data = $this->find($migration);
131
132
            if ($data->count()) {
133
                $migrated[] = $migration;
134
135
                $this->down($migration);
136
137
                $data->delete();
138
            }
139
        }
140
141
        return $migrated;
142
    }
143
144
    /**
145
     * Reset migration.
146
     *
147
     * @return array
148
     */
149 View Code Duplication
    public function reset()
150
    {
151
        $migrations = $this->getMigrations(true);
152
153
        $this->requireFiles($migrations);
154
155
        $migrated = [];
156
157
        foreach ($migrations as $migration) {
158
            $data = $this->find($migration);
159
160
            if ($data->count()) {
161
                $migrated[] = $migration;
162
163
                $this->down($migration);
164
165
                $data->delete();
166
            }
167
        }
168
169
        return $migrated;
170
    }
171
172
    /**
173
     * Run down schema from the given migration name.
174
     *
175
     * @param string $migration
176
     */
177
    public function down($migration)
178
    {
179
        $this->resolve($migration)->down();
180
    }
181
182
    /**
183
     * Run up schema from the given migration name.
184
     *
185
     * @param string $migration
186
     */
187
    public function up($migration)
188
    {
189
        $this->resolve($migration)->up();
190
    }
191
192
    /**
193
     * Resolve a migration instance from a file.
194
     *
195
     * @param string $file
196
     *
197
     * @return object
198
     */
199
    public function resolve($file)
200
    {
201
        $file = implode('_', array_slice(explode('_', $file), 4));
202
203
        $class = studly_case($file);
204
205
        return new $class();
206
    }
207
208
    /**
209
     * Require in all the migration files in a given path.
210
     *
211
     * @param array  $files
212
     */
213
    public function requireFiles(array $files)
214
    {
215
        $path = $this->getPath();
216
        foreach ($files as $file) {
217
            $this->laravel['files']->requireOnce($path . '/' . $file . '.php');
218
        }
219
    }
220
221
    /**
222
     * Get table instance.
223
     *
224
     * @return \Illuminate\Database\Query\Builder
225
     */
226
    public function table()
227
    {
228
        return $this->laravel['db']->connection($this->database ?: null)->table(config('database.migrations'));
229
    }
230
231
    /**
232
     * Find migration data from database by given migration name.
233
     *
234
     * @param string $migration
235
     *
236
     * @return object
237
     */
238
    public function find($migration)
239
    {
240
        return $this->table()->whereMigration($migration);
241
    }
242
243
    /**
244
     * Save new migration to database.
245
     *
246
     * @param string $migration
247
     *
248
     * @return mixed
249
     */
250
    public function log($migration)
251
    {
252
        return $this->table()->insert([
253
            'migration' => $migration,
254
            'batch' => $this->getNextBatchNumber(),
255
        ]);
256
    }
257
258
    /**
259
     * Get the next migration batch number.
260
     *
261
     * @return int
262
     */
263
    public function getNextBatchNumber()
264
    {
265
        return $this->getLastBatchNumber() + 1;
266
    }
267
268
    /**
269
     * Get the last migration batch number.
270
     *
271
     * @param array|null $migrations
272
     * @return int
273
     */
274
    public function getLastBatchNumber($migrations = null)
275
    {
276
        $table = $this->table();
277
278
        if (is_array($migrations)) {
279
            $table = $table->whereIn('migration', $migrations);
280
        }
281
282
        return $table->max('batch');
283
    }
284
285
    /**
286
     * Get the last migration batch.
287
     *
288
     * @param array $migrations
289
     *
290
     * @return Collection
291
     */
292
    public function getLast($migrations)
293
    {
294
        $query = $this->table()
295
            ->where('batch', $this->getLastBatchNumber($migrations))
296
            ->whereIn('migration', $migrations);
297
298
        $result = $query->orderBy('migration', 'desc')->get();
299
300
        return collect($result)->map(function ($item) {
301
            return (array) $item;
302
        })->pluck('migration');
303
    }
304
305
    /**
306
     * Get the ran migrations.
307
     *
308
     * @return Collection
309
     */
310
    public function getRan()
311
    {
312
        return $this->table()->pluck('migration');
313
    }
314
}
315