setHelp('Este comando reverte as migrações que foram executadas na última operação de migração.')
->addOption('step', 's', \Symfony\Component\Console\Input\InputOption::VALUE_OPTIONAL, 'The number of migrations to be reverted', 0);
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$step = (int) $input->getOption('step');
$output->writeln([
'Iniciando rollback das migrations...',
'=====================================',
'',
]);
if (!Capsule::schema()->hasTable('migrations')) {
$output->writeln('Tabela de migrations não encontrada.');
return Command::FAILURE;
}
if ($step === 999) {
// Special case for migrate:reset or fresh
$migrationsToRollback = Capsule::table('migrations')
->orderBy('id', 'desc')
->get();
} elseif ($step > 0) {
// Revert specific number of migrations
$migrationsToRollback = Capsule::table('migrations')
->orderBy('id', 'desc')
->limit($step)
->get();
} else {
// Pegar o último batch
$lastBatch = Capsule::table('migrations')->max('batch');
if (!$lastBatch) {
$output->writeln('Nenhuma migração para reverter.');
return Command::SUCCESS;
}
$migrationsToRollback = Capsule::table('migrations')
->where('batch', $lastBatch)
->orderBy('id', 'desc')
->get();
}
if ($migrationsToRollback->isEmpty()) {
$output->writeln('Nenhuma migração para reverter.');
return Command::SUCCESS;
}
$migrationsPath = dirname(__DIR__, 3) . '/database/migrations';
$modulesPath = dirname(__DIR__, 3) . '/modules';
foreach ($migrationsToRollback as $row) {
$fileName = $row->migration;
$file = $this->findMigrationFile($fileName, $migrationsPath, $modulesPath);
if (!$file) {
$output->writeln("Arquivo de migração não encontrado: {$fileName}.php");
continue;
}
// Converter nome para classe
$cleanName = preg_replace('/^\d+_/', '', $fileName);
$className = str_replace(' ', '', ucwords(str_replace('_', ' ', $cleanName)));
$output->write("Revertendo migration: {$fileName}... ");
try {
require_once $file;
if (class_exists($className)) {
$migration = new $className();
if (method_exists($migration, 'down')) {
$migration->down();
// Remover registro da tabela de migrations
Capsule::table('migrations')->where('id', $row->id)->delete();
$output->writeln('OK');
} else {
$output->writeln('Método down() não encontrado.');
}
} else {
$output->writeln("Classe {$className} não encontrada.");
}
} catch (\Exception $e) {
$output->writeln("Erro: " . $e->getMessage() . "");
return Command::FAILURE;
}
}
return Command::SUCCESS;
}
protected function findMigrationFile(string $name, string $corePath, string $modulesPath): ?string
{
// Procurar no core
$coreFile = $corePath . '/' . $name . '.php';
if (file_exists($coreFile)) {
return $coreFile;
}
// Procurar nos módulos
$moduleFiles = glob($modulesPath . '/*/database/migrations/' . $name . '.php');
if ($moduleFiles && count($moduleFiles) > 0) {
return $moduleFiles[0];
}
return null;
}
}