diff --git a/install.php b/install.php index 0eee691..456f580 100644 --- a/install.php +++ b/install.php @@ -56,20 +56,55 @@ require_once __DIR__ . '/../includes/functions.php'; // 1. Run Base Schema $schema = file_get_contents(__DIR__ . '/db/schema.sql'); + // Split schema by ; to execute one by one to avoid issues with some PDO drivers + // But usually PDO::exec handles multiple if allowed. + // Better to use a simpler approach for schema.sql $pdo->exec($schema); - // 2. Run Migrations + // 2. Create migrations table if not exists + $pdo->exec("CREATE TABLE IF NOT EXISTS migrations ( + id INT AUTO_INCREMENT PRIMARY KEY, + migration VARCHAR(255) UNIQUE NOT NULL, + applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + )"); + + // 3. Run Migrations $migrations_dir = __DIR__ . '/db/migrations/'; $migrations = glob($migrations_dir . '*.sql'); sort($migrations); - foreach ($migrations as $migration) { - $sql = file_get_contents($migration); - if (!empty(trim($sql))) { - $pdo->exec($sql); + + // Get applied migrations + $stmt = $pdo->query("SELECT migration FROM migrations"); + $applied = $stmt->fetchAll(PDO::FETCH_COLUMN); + + foreach ($migrations as $migration_path) { + $migration_name = basename($migration_path); + if (!in_array($migration_name, $applied)) { + $sql = file_get_contents($migration_path); + if (!empty(trim($sql))) { + // Some migrations might fail because they were partially applied before we had tracking + // We will wrap each in a try-catch or just execute and catch specific duplicate column errors + try { + $pdo->exec($sql); + $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); + $stmt->execute([$migration_name]); + } catch (PDOException $e) { + // If it's "Duplicate column name" or "Duplicate key name", we might want to skip and mark as applied + // to recover from a broken state + if (strpos($e->getMessage(), 'Duplicate column name') !== false || + strpos($e->getMessage(), 'Duplicate key name') !== false || + strpos($e->getMessage(), 'already exists') !== false) { + $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); + $stmt->execute([$migration_name]); + } else { + throw $e; + } + } + } } } - // 3. Seed initial data (from init.php logic) + // 4. Seed initial data (from init.php logic) $stmt = $pdo->query("SELECT COUNT(*) FROM outlets"); if ($stmt->fetchColumn() == 0) { $pdo->exec("INSERT INTO outlets (name, address) VALUES ('Main Downtown', '123 Main St'), ('Westside Hub', '456 West Blvd')"); @@ -109,6 +144,14 @@ require_once __DIR__ . '/../includes/functions.php'; $group_id = $pdo->lastInsertId(); } + $stmt = $pdo->prepare("SELECT id FROM users WHERE username = ?"); + $stmt->execute([$username]); + if ($stmt->fetch()) { + // Admin already exists, just move to next step + header("Location: install.php?step=4"); + exit; + } + $stmt = $pdo->prepare("INSERT INTO users (group_id, username, password, full_name, email, is_active) VALUES (?, ?, ?, ?, ?, 1)"); $stmt->execute([$group_id, $username, $hashed_pass, 'Super Admin', $email]); @@ -223,4 +266,4 @@ require_once __DIR__ . '/../includes/functions.php'; - + \ No newline at end of file