setHelp('This command checks and executes all pending database migrations.');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$output->writeln([
'Iniciando execução das migrations...',
'=====================================',
'',
]);
// Ensure migrations table exists
$this->ensureMigrationsTableExists();
$migrationsPath = dirname(__DIR__, 3) . '/database/migrations';
$modulesPath = dirname(__DIR__, 3) . '/modules';
$migrationFiles = [];
// Core migrations
if (is_dir($migrationsPath)) {
$coreFiles = glob($migrationsPath . '/*.php');
if ($coreFiles) {
$migrationFiles = array_merge($migrationFiles, $coreFiles);
}
} else {
$output->writeln("Diretório de migrations não encontrado: $migrationsPath");
}
// Module migrations
if (is_dir($modulesPath)) {
$moduleFiles = glob($modulesPath . '/*/database/migrations/*.php');
if ($moduleFiles) {
$migrationFiles = array_merge($migrationFiles, $moduleFiles);
}
}
// Sort migration files by filename (keeping chronological order if timestamp/numbering exists)
usort($migrationFiles, function($a, $b) {
return basename($a) <=> basename($b);
});
if (empty($migrationFiles)) {
$output->writeln('Nenhuma migração encontrada.');
return Command::SUCCESS;
}
// Get already executed migrations
$executedMigrations = Capsule::table('migrations')->pluck('migration')->toArray();
$nextBatch = Capsule::table('migrations')->max('batch') + 1;
$count = 0;
foreach ($migrationFiles as $file) {
$fileName = basename($file, '.php');
// Skip if already executed
if (in_array($fileName, $executedMigrations)) {
continue;
}
// Remove numeric prefix (e.g. 001_)
$cleanName = preg_replace('/^\d+_/', '', $fileName);
// Convert snake_case to PascalCase (e.g. create_bus_table -> CreateBusTable)
$className = str_replace(' ', '', ucwords(str_replace('_', ' ', $cleanName)));
$output->write("Executando migration: {$fileName}... ");
try {
require_once $file;
if (class_exists($className)) {
$migration = new $className();
// Check if up method exists
if (method_exists($migration, 'up')) {
$migration->up();
// Record migration as executed
Capsule::table('migrations')->insert([
'migration' => $fileName,
'batch' => $nextBatch
]);
$output->writeln('OK');
$count++;
} else {
$output->writeln('SKIPPED (método up não encontrado)');
}
} else {
$output->writeln("ERRO (Classe {$className} não encontrada)");
}
} catch (\Exception $e) {
$output->writeln("FALHA");
$output->writeln("Erro: " . $e->getMessage() . "");
return Command::FAILURE;
}
}
if ($count === 0) {
$output->writeln('Nada para migrar.');
} else {
$output->writeln([
'',
"Total de {$count} migration(s) processada(s) com sucesso!",
]);
}
return Command::SUCCESS;
}
/**
* Ensure the migrations table exists in the database.
*
* @return void
*/
protected function ensureMigrationsTableExists(): void
{
if (!Capsule::schema()->hasTable('migrations')) {
Capsule::schema()->create('migrations', function ($table) {
$table->increments('id');
$table->string('migration');
$table->integer('batch');
});
}
}
}