Migrator::getMigrations()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 25
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 25
rs 9.9332
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Salah3id\Domains\Migrations;
4
5
use Illuminate\Contracts\Foundation\Application;
6
use Illuminate\Support\Collection;
7
use Illuminate\Support\Str;
8
use Salah3id\Domains\Domain;
9
use Salah3id\Domains\Support\Config\GenerateConfigReader;
10
11
class Migrator
12
{
13
    /**
14
     * Domain instance.
15
     * @var Domain
16
     */
17
    protected $domain;
18
19
    /**
20
     * Laravel Application instance.
21
     *
22
     * @var Application.
0 ignored issues
show
Documentation Bug introduced by
The doc comment Application. at position 0 could not be parsed: Unknown type name 'Application.' at position 0 in Application..
Loading history...
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
     * @param Domain $domain
36
     * @param Application $application
37
     */
38
    public function __construct(Domain $domain, Application $application)
39
    {
40
        $this->domain = $domain;
41
        $this->laravel = $application;
42
    }
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 Domain
62
     */
63
    public function getDomain()
64
    {
65
        return $this->domain;
66
    }
67
68
    /**
69
     * Get migration path.
70
     *
71
     * @return string
72
     */
73
    public function getPath()
74
    {
75
        $config = $this->domain->get('migration');
76
77
        $migrationPath = GenerateConfigReader::read('migration');
78
        $path = (is_array($config) && array_key_exists('path', $config)) ? $config['path'] : $migrationPath->getPath();
79
80
        return $this->domain->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
    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
    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
        $name = implode('_', array_slice(explode('_', $file), 4));
202
203
        $class = Str::studly($name);
204
205
        if (!class_exists($class) && file_exists($this->getPath() . '/' . $file . '.php')) {
206
            return include $this->getPath() . '/' . $file . '.php';
207
        }
208
209
        return new $class();
210
    }
211
212
    /**
213
     * Require in all the migration files in a given path.
214
     *
215
     * @param array  $files
216
     */
217
    public function requireFiles(array $files)
218
    {
219
        $path = $this->getPath();
220
        foreach ($files as $file) {
221
            $this->laravel['files']->requireOnce($path . '/' . $file . '.php');
222
        }
223
    }
224
225
    /**
226
     * Get table instance.
227
     *
228
     * @return \Illuminate\Database\Query\Builder
229
     */
230
    public function table()
231
    {
232
        return $this->laravel['db']->connection($this->database ?: null)->table(config('database.migrations'));
233
    }
234
235
    /**
236
     * Find migration data from database by given migration name.
237
     *
238
     * @param string $migration
239
     *
240
     * @return object
241
     */
242
    public function find($migration)
243
    {
244
        return $this->table()->whereMigration($migration);
245
    }
246
247
    /**
248
     * Save new migration to database.
249
     *
250
     * @param string $migration
251
     *
252
     * @return mixed
253
     */
254
    public function log($migration)
255
    {
256
        return $this->table()->insert([
257
            'migration' => $migration,
258
            'batch' => $this->getNextBatchNumber(),
259
        ]);
260
    }
261
262
    /**
263
     * Get the next migration batch number.
264
     *
265
     * @return int
266
     */
267
    public function getNextBatchNumber()
268
    {
269
        return $this->getLastBatchNumber() + 1;
270
    }
271
272
    /**
273
     * Get the last migration batch number.
274
     *
275
     * @param array|null $migrations
276
     * @return int
277
     */
278
    public function getLastBatchNumber($migrations = null)
279
    {
280
        $table = $this->table();
281
282
        if (is_array($migrations)) {
283
            $table = $table->whereIn('migration', $migrations);
284
        }
285
286
        return $table->max('batch');
287
    }
288
289
    /**
290
     * Get the last migration batch.
291
     *
292
     * @param array $migrations
293
     *
294
     * @return Collection
295
     */
296
    public function getLast($migrations)
297
    {
298
        $query = $this->table()
299
            ->where('batch', $this->getLastBatchNumber($migrations))
300
            ->whereIn('migration', $migrations);
301
302
        $result = $query->orderBy('migration', 'desc')->get();
303
304
        return collect($result)->map(function ($item) {
305
            return (array) $item;
306
        })->pluck('migration');
307
    }
308
309
    /**
310
     * Get the ran migrations.
311
     *
312
     * @return Collection
313
     */
314
    public function getRan()
315
    {
316
        return $this->table()->pluck('migration');
317
    }
318
}
319