Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
59.15% covered (warning)
59.15%
84 / 142
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
MigrationController
59.15% covered (warning)
59.15%
84 / 142
0.00% covered (danger)
0.00%
0 / 5
205.00
0.00% covered (danger)
0.00%
0 / 1
 create
85.71% covered (success)
85.71%
12 / 14
0.00% covered (danger)
0.00%
0 / 1
6.10
 run
54.84% covered (warning)
54.84%
17 / 31
0.00% covered (danger)
0.00%
0 / 1
16.46
 rollback
54.84% covered (warning)
54.84%
17 / 31
0.00% covered (danger)
0.00%
0 / 1
16.46
 point
62.16% covered (warning)
62.16%
23 / 37
0.00% covered (danger)
0.00%
0 / 1
29.87
 reset
51.72% covered (warning)
51.72%
15 / 29
0.00% covered (danger)
0.00%
0 / 1
15.20
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/pop-bootstrap
6 * @author     Nick Sagona, III <nick@nolainteractive.com>
7 * @copyright  Copyright (c) 2012-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Kettle\Controller;
15
16use Pop\Console\Color;
17use Pop\Db\Sql\Migrator;
18use Pop\Kettle\Model;
19
20/**
21 * Console database controller class
22 *
23 * @category   Pop\Kettle
24 * @package    Pop\Kettle
25 * @author     Nick Sagona, III <nick@nolainteractive.com>
26 * @copyright  Copyright (c) 2012-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
27 * @license    http://www.popphp.org/license     New BSD License
28 * @version    2.3.2
29 */
30class MigrationController extends AbstractController
31{
32
33    /**
34     * Create command
35     *
36     * @param  string  $class
37     * @param  ?string $database
38     * @return void
39     */
40    public function create(string $class, ?string $database = 'default'): void
41    {
42        $location  = getcwd();
43
44        if ($database === null) {
45            $databases = ['default'];
46        } else if ($database == 'all') {
47            $databases = array_filter(scandir($location . '/database/migrations'), function($value) {
48                return (($value != '.') && ($value != '..'));
49            });
50        } else {
51            $databases = [$database];
52        }
53
54        foreach ($databases as $db) {
55            if (!file_exists($location . '/database/migrations/' . $db)) {
56                mkdir($location . '/database/migrations/' . $db);
57            }
58
59            $migrationClass = $class . uniqid();
60            Migrator::create($migrationClass, $location . '/database/migrations/' . $db);
61            $this->console->write("Migration class '" . $migrationClass . "' created for '" . $db . "'.");
62        }
63    }
64
65    /**
66     * Run command
67     *
68     * @param  int|string|null $steps
69     * @param  ?string         $database
70     * @return void
71     */
72    public function run(int|string|null $steps = 1, ?string $database = 'default'): void
73    {
74        $location = getcwd();
75        $dbModel  = new Model\Database();
76
77        if ($database === null) {
78            $databases = ['default'];
79        } else if ($database == 'all') {
80            $databases = array_filter(scandir($location . '/database/migrations'), function($value) {
81                return (($value != '.') && ($value != '..'));
82            });
83        } else {
84            $databases = [$database];
85        }
86
87        if ($steps === null) {
88            $steps = 1;
89        }
90
91        if (!file_exists($location . '/app/config/database.php')) {
92            $this->console->write($this->console->colorize(
93                'The database configuration was not found.', Color::BOLD_RED
94            ));
95        } else {
96            foreach ($databases as $db) {
97                if (!file_exists($location . '/database/migrations/' . $db)) {
98                    $this->console->write($this->console->colorize(
99                        "The database migration folder was not found for '" . $db . "'.", Color::BOLD_RED
100                    ));
101                } else {
102                    $this->console->write("Running database migration for '" . $db . "'...");
103
104                    $dbConfig = include $location . '/app/config/database.php';
105                    if (!isset($dbConfig[$db])) {
106                        $this->console->write($this->console->colorize(
107                            "The database configuration was not found for '" . $db . "'.", Color::BOLD_RED
108                        ));
109                    } else {
110                        $dbAdapter = $dbModel->createAdapter($dbConfig[$db]);
111                        $migrator  = new Migrator($dbAdapter, $location . '/database/migrations/' . $db);
112                        $migrator->run($steps);
113                        $this->console->write();
114                        $this->console->write('Done!');
115                    }
116                }
117            }
118        }
119    }
120
121    /**
122     * Rollback command
123     *
124     * @param  int|string|null $steps
125     * @param  ?string         $database
126     * @return void
127     */
128    public function rollback(int|string|null $steps = 1, ?string $database = 'default'): void
129    {
130        $location = getcwd();
131        $dbModel  = new Model\Database();
132
133        if ($database === null) {
134            $databases = ['default'];
135        } else if ($database == 'all') {
136            $databases = array_filter(scandir($location . '/database/migrations'), function($value) {
137                return (($value != '.') && ($value != '..'));
138            });
139        } else {
140            $databases = [$database];
141        }
142
143        if ($steps === null) {
144            $steps = 1;
145        }
146
147        if (!file_exists($location . '/app/config/database.php')) {
148            $this->console->write($this->console->colorize(
149                'The database configuration was not found.', Color::BOLD_RED
150            ));
151        } else {
152            foreach ($databases as $db) {
153                if (!file_exists($location . '/database/migrations/' . $db)) {
154                    $this->console->write($this->console->colorize(
155                        "The database migration folder was not found for '" . $db . "'.", Color::BOLD_RED
156                    ));
157                } else {
158                    $this->console->write("Rolling back database migration for '" . $db . "'...");
159
160                    $dbConfig = include $location . '/app/config/database.php';
161                    if (!isset($dbConfig[$db])) {
162                        $this->console->write($this->console->colorize(
163                            "The database configuration was not found for '" . $db . "'.", Color::BOLD_RED
164                        ));
165                    } else {
166                        $dbAdapter = $dbModel->createAdapter($dbConfig[$db]);
167                        $migrator  = new Migrator($dbAdapter, $location . '/database/migrations/' . $db);
168                        $migrator->rollback($steps);
169                        $this->console->write();
170                        $this->console->write('Done!');
171                    }
172                }
173            }
174        }
175    }
176
177    /**
178     * Point command
179     *
180     * @param  mixed   $id
181     * @param  ?string $database
182     * @return void
183     */
184    public function point(mixed $id = 'latest', ?string $database = 'default'): void
185    {
186        $location = getcwd();
187
188        if ($id === null) {
189            $id = 'latest';
190        }
191        if ($database === null) {
192            $database = 'default';
193        }
194
195        if (!file_exists($location . '/database/migrations/' . $database)) {
196            $this->console->write($this->console->colorize(
197                "The database '" . $database . "' does not exist in the migration folder.", Color::BOLD_RED
198            ));
199        } else if (file_exists($location . '/database/migrations/' . $database . '/.current')) {
200            $ids = array_map(function($value) {
201                return substr($value, 0, strpos($value, '_'));
202            },
203                array_values(array_filter(scandir($location . '/database/migrations/' . $database), function ($value){
204                        if (($value != '.') && ($value != '..') && ($value != '.current') && ($value != '.empty') && (stripos($value, '_') !== false)) {
205                            return $value;
206                        }
207                    })
208                ));
209
210            if (!empty($ids) && is_array($ids)) {
211                sort($ids, SORT_NUMERIC);
212            }
213
214            if (empty($ids)) {
215                $this->console->write($this->console->colorize(
216                    "No migrations for the database '" . $database . "' were found.", Color::BOLD_RED
217                ));
218            } else if (is_numeric($id)) {
219                if (!in_array($id, $ids)) {
220                    $this->console->write($this->console->colorize(
221                        "The migration '" . $id . "' for the database '" . $database . "' does not exist.", Color::BOLD_RED
222                    ));
223                } else {
224                    file_put_contents($location . '/database/migrations/' . $database . '/.current', $id);
225                    $this->console->write();
226                    $this->console->write('Done!');
227                }
228            } else if ($id == 'latest') {
229                $id = end($ids);
230                file_put_contents($location . '/database/migrations/' . $database . '/.current', $id);
231                $this->console->write();
232                $this->console->write('Done!');
233            }
234        }
235    }
236
237    /**
238     * Reset command
239     *
240     * @param  ?string $database
241     * @return void
242     */
243    public function reset(?string $database = 'default'): void
244    {
245        $location = getcwd();
246        $dbModel  = new Model\Database();
247
248        if ($database === null) {
249            $databases = ['default'];
250        } else if ($database == 'all') {
251            $databases = array_filter(scandir($location . '/database/migrations'), function($value) {
252                return (($value != '.') && ($value != '..'));
253            });
254        } else {
255            $databases = [$database];
256        }
257
258        if (!file_exists($location . '/app/config/database.php')) {
259            $this->console->write($this->console->colorize(
260                'The database configuration was not found.', Color::BOLD_RED
261            ));
262        } else {
263            foreach ($databases as $db) {
264                if (!file_exists($location . '/database/migrations/' . $db)) {
265                    $this->console->write($this->console->colorize(
266                        "The database migration folder was not found for '" . $db . "'.", Color::BOLD_RED
267                    ));
268                } else {
269                    $this->console->write("Resetting the database for '" . $db . "'...");
270
271                    $dbConfig = include $location . '/app/config/database.php';
272                    if (!isset($dbConfig[$db])) {
273                        $this->console->write($this->console->colorize(
274                            "The database configuration was not found for '" . $db . "'.", Color::BOLD_RED
275                        ));
276                    } else {
277                        $dbAdapter = $dbModel->createAdapter($dbConfig[$db]);
278                        $migrator  = new Migrator($dbAdapter, $location . '/database/migrations/' . $db);
279                        $migrator->rollbackAll();
280                        $this->console->write();
281                        $this->console->write('Done!');
282                    }
283                }
284            }
285        }
286    }
287
288}