diff --git a/system/Commands/Database/MigrateRollback.php b/system/Commands/Database/MigrateRollback.php index f206d7fc5162..e1c788e7702e 100644 --- a/system/Commands/Database/MigrateRollback.php +++ b/system/Commands/Database/MigrateRollback.php @@ -15,6 +15,7 @@ use CodeIgniter\CLI\BaseCommand; use CodeIgniter\CLI\CLI; +use CodeIgniter\Database\MigrationRunner; use Throwable; /** @@ -78,10 +79,23 @@ public function run(array $params) // @codeCoverageIgnoreEnd } + /** @var MigrationRunner $runner */ $runner = service('migrations'); try { $batch = $params['b'] ?? CLI::getOption('b') ?? $runner->getLastBatch() - 1; + + if (is_string($batch)) { + if (! ctype_digit($batch)) { + CLI::error('Invalid batch number: ' . $batch, 'light_gray', 'red'); + CLI::newLine(); + + return EXIT_ERROR; + } + + $batch = (int) $batch; + } + CLI::write(lang('Migrations.rollingBack') . ' ' . $batch, 'yellow'); if (! $runner->regress($batch)) { diff --git a/tests/system/Commands/DatabaseCommandsTest.php b/tests/system/Commands/DatabaseCommandsTest.php index 1ccdea9251ee..02d6e6b38963 100644 --- a/tests/system/Commands/DatabaseCommandsTest.php +++ b/tests/system/Commands/DatabaseCommandsTest.php @@ -53,6 +53,24 @@ public function testMigrate(): void $this->assertStringContainsString('Migrations complete.', $this->getBuffer()); } + public function testMigrateRollbackValidBatchNumber(): void + { + command('migrate --all'); + $this->clearBuffer(); + + command('migrate:rollback -b 1'); + $this->assertStringContainsString('Done rolling back migrations.', $this->getBuffer()); + } + + public function testMigrateRollbackInvalidBatchNumber(): void + { + command('migrate --all'); + $this->clearBuffer(); + + command('migrate:rollback -b x'); + $this->assertStringContainsString('Invalid batch number: x', $this->getBuffer()); + } + public function testMigrateRollback(): void { command('migrate --all -g tests');