/** Datei: library/ARUNOX/Migrations/BaseMigration.php **/ initTable(); } /** * Runs all pending migrations. */ public static function run(): void { $applied = self::$entity->getApplied(); $files = self::getFiles(); foreach ($files as $file) { $name = basename($file, '.php'); if (!in_array($name, $applied)) { self::execute($file, $name); } } } /** * Finds all migration files in the specified directories. * * @return array */ private static function getFiles(): array { $files = []; foreach (self::$directories as $dir) { if (is_dir($dir)) { $files = array_merge($files, glob($dir . '/*.php')); } } return $files; } /** * Executes a single migration file. * * @param string $file * @param string $name */ private static function execute(string $file, string $name): void { try { Database::begin(); require_once $file; if (!class_exists($name)) { throw new Exception("Migration class {$name} not found in {$file}"); } $migration = new $name(); if (!$migration instanceof Migration) { throw new Exception("Migration class {$name} must extend the abstract Migration class"); } $migration->up(); self::$entity->record($name); Database::commit(); echo "Migration {$name} executed successfully.\n"; } catch (Exception $e) { Database::rollback(); echo "Migration {$name} failed: " . $e->getMessage() . "\n"; } } } /** Datei: library/ARUNOX/Migrations/Entity.php **/ table} ( id INT AUTO_INCREMENT PRIMARY KEY, migration VARCHAR(255) NOT NULL UNIQUE, executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP )")->execute(); } /** * Retrieves the list of applied migrations. * * @return array */ public function getApplied(): array { return Database::query("SELECT migration FROM {$this->table}") ->fetchAll(\PDO::FETCH_COLUMN); } /** * Records a migration as executed. * * @param string $migration */ public function record(string $migration): void { Database::query("INSERT INTO {$this->table} (migration) VALUES (:migration)") ->bind(['migration' => $migration]) ->execute(); } }