Files
2026-09-01 10:46:29 -03:00

131 lines
4.7 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Illuminate\Database\Capsule\Manager as Capsule;
class RollbackCommand extends Command
{
protected static $defaultName = 'migrate:rollback';
protected static $defaultDescription = 'Reverte a última leva de migrações do banco de dados';
protected function configure(): void
{
$this
->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('<error>Tabela de migrations não encontrada.</error>');
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('<info>Nenhuma migração para reverter.</info>');
return Command::SUCCESS;
}
$migrationsToRollback = Capsule::table('migrations')
->where('batch', $lastBatch)
->orderBy('id', 'desc')
->get();
}
if ($migrationsToRollback->isEmpty()) {
$output->writeln('<info>Nenhuma migração para reverter.</info>');
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("<error>Arquivo de migração não encontrado: {$fileName}.php</error>");
continue;
}
// Converter nome para classe
$cleanName = preg_replace('/^\d+_/', '', $fileName);
$className = str_replace(' ', '', ucwords(str_replace('_', ' ', $cleanName)));
$output->write("Revertendo migration: <info>{$fileName}</info>... ");
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('<info>OK</info>');
} else {
$output->writeln('<comment>Método down() não encontrado.</comment>');
}
} else {
$output->writeln("<error>Classe {$className} não encontrada.</error>");
}
} catch (\Exception $e) {
$output->writeln("<error>Erro: " . $e->getMessage() . "</error>");
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;
}
}