From 85c1b9dd67e9ae4ec50274742dc8683ef8ae33dd Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 1 Mar 2026 05:16:39 +0000 Subject: [PATCH] updating install file --- ...15_add_super_admin_and_extra_settings.sql} | 0 ...ables.sql => 016_split_mailbox_tables.sql} | 0 db/migrations/migrate.php | 75 ++++++++++++++-- includes/header.php | 2 +- install.php | 85 ++++++++++++++----- test_install.php | 1 + 6 files changed, 136 insertions(+), 27 deletions(-) rename db/migrations/{014_add_super_admin_and_extra_settings.sql => 015_add_super_admin_and_extra_settings.sql} (100%) rename db/migrations/{015_split_mailbox_tables.sql => 016_split_mailbox_tables.sql} (100%) mode change 100644 => 100755 install.php create mode 100644 test_install.php diff --git a/db/migrations/014_add_super_admin_and_extra_settings.sql b/db/migrations/015_add_super_admin_and_extra_settings.sql similarity index 100% rename from db/migrations/014_add_super_admin_and_extra_settings.sql rename to db/migrations/015_add_super_admin_and_extra_settings.sql diff --git a/db/migrations/015_split_mailbox_tables.sql b/db/migrations/016_split_mailbox_tables.sql similarity index 100% rename from db/migrations/015_split_mailbox_tables.sql rename to db/migrations/016_split_mailbox_tables.sql diff --git a/db/migrations/migrate.php b/db/migrations/migrate.php index 7f47a3a..3c5ff1e 100644 --- a/db/migrations/migrate.php +++ b/db/migrations/migrate.php @@ -3,19 +3,82 @@ require_once __DIR__ . '/../config.php'; function runMigrations() { $pdo = db(); + // Create migration table if not exists + $pdo->exec("CREATE TABLE IF NOT EXISTS migrations ( + id INT AUTO_INCREMENT PRIMARY KEY, + migration_name VARCHAR(255) NOT NULL UNIQUE, + applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + )"); + + $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + $migrationsDir = __DIR__; $files = glob($migrationsDir . '/*.sql'); sort($files); foreach ($files as $file) { + $migration_name = basename($file); + + // Check if already applied + $stmt = $pdo->prepare("SELECT id FROM migrations WHERE migration_name = ?"); + $stmt->execute([$migration_name]); + if ($stmt->fetch()) { + echo "Already applied: $migration_name" . PHP_EOL; + continue; + } + + echo "Applying: $migration_name" . PHP_EOL; $sql = file_get_contents($file); - try { - $pdo->exec($sql); - echo "Successfully applied migration: " . basename($file) . PHP_EOL; - } catch (PDOException $e) { - echo "Error applying migration " . basename($file) . ": " . $e->getMessage() . PHP_EOL; + + // Split SQL into individual statements by ; followed by newline + $statements = preg_split('/;(?:\\s*[\r\n]+)/', $sql); + + $success = true; + foreach ($statements as $statement) { + $statement = trim($statement); + if (empty($statement)) continue; + + // Basic comment removal + $statement_lines = explode("\n", $statement); + $clean_statement = ""; + foreach ($statement_lines as $line) { + if (trim(substr(trim($line), 0, 2)) === '--') continue; + $clean_statement .= $line . "\n"; + } + $clean_statement = trim($clean_statement); + if (empty($clean_statement)) continue; + + try { + $stmt = $pdo->query($clean_statement); + if ($stmt) { + $stmt->closeCursor(); + } + } catch (PDOException $e) { + $msg = $e->getMessage(); + // If the error is about a table already existing, it's fine for our idempotency + if (strpos($msg, "already exists") !== false || + strpos($msg, "Duplicate column") !== false || + strpos($msg, "Duplicate entry") !== false || + strpos($msg, "already a column") !== false || + strpos($msg, "Duplicate key") !== false) { + continue; + } + echo "Error in $migration_name at statement: " . substr($clean_statement, 0, 100) . "... " . PHP_EOL; + echo "Error: " . $msg . PHP_EOL; + $success = false; + break; + } + } + + if ($success) { + $stmt = $pdo->prepare("INSERT INTO migrations (migration_name) VALUES (?)"); + $stmt->execute([$migration_name]); + echo "Successfully applied migration: $migration_name" . PHP_EOL; + } else { + echo "Migration failed: $migration_name. Stopping." . PHP_EOL; + break; } } } -runMigrations(); +runMigrations(); \ No newline at end of file diff --git a/includes/header.php b/includes/header.php index 8114caa..29cf2e0 100644 --- a/includes/header.php +++ b/includes/header.php @@ -111,7 +111,7 @@ if (isLoggedIn()) { } // Auth Check (after fetch to ensure session is updated) -if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'forgot_password.php') { +if (!isLoggedIn() && basename($_SERVER['PHP_SELF']) !== 'login.php' && basename($_SERVER['PHP_SELF']) !== 'forgot_password.php' && basename($_SERVER['PHP_SELF']) !== 'install.php') { redirect('login.php'); } ?> diff --git a/install.php b/install.php old mode 100644 new mode 100755 index 55fcff0..ffb921a --- a/install.php +++ b/install.php @@ -56,6 +56,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $content .= " \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); "; $content .= " \$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); +"; + $content .= " \$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); "; $content .= " } catch (PDOException \$e) {\n"; $content .= " die('Connection failed: ' . \$e->getMessage());\n"; @@ -85,6 +87,15 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { throw new Exception("The 'db()' function is not defined in your config file."); } $pdo = db(); + $pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true); + + // Create migration table if not exists + $pdo->exec("CREATE TABLE IF NOT EXISTS migrations ( + id INT AUTO_INCREMENT PRIMARY KEY, + migration_name VARCHAR(255) NOT NULL UNIQUE, + applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + )"); + $migrations_dir = __DIR__ . '/db/migrations/'; $files = glob($migrations_dir . '*.sql'); if ($files === false) $files = []; @@ -94,35 +105,69 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $errors = []; foreach ($files as $file) { + $migration_name = basename($file); + + // Check if already applied + $stmt = $pdo->prepare("SELECT id FROM migrations WHERE migration_name = ?"); + $stmt->execute([$migration_name]); + if ($stmt->fetch()) { + continue; + } + $sql = file_get_contents($file); if (empty($sql)) continue; - try { - $statements = array_filter(array_map('trim', explode(';', $sql))); - foreach ($statements as $stmt_sql) { - if (empty($stmt_sql)) continue; - try { - $pdo->exec($stmt_sql); - } catch (Throwable $e) { - $msg = $e->getMessage(); - if (strpos($msg, 'Duplicate column name') !== false || - strpos($msg, 'Duplicate key name') !== false || - strpos($msg, 'Duplicate table') !== false || - strpos($msg, 'already exists') !== false || strpos($msg, 'Duplicate key on write or update') !== false || strpos($msg, 'errno: 121') !== false) { - continue; - } else { - throw $e; - } + // Split SQL into individual statements by ; followed by newline + $statements = preg_split('/;(?:\\s*[ +]+)/', $sql); + + $file_success = true; + foreach ($statements as $stmt_sql) { + $stmt_sql = trim($stmt_sql); + if (empty($stmt_sql)) continue; + + // Basic comment removal + $stmt_lines = explode("\n", $stmt_sql); + $clean_stmt = ""; + foreach ($stmt_lines as $line) { + if (trim(substr(trim($line), 0, 2)) === '--') continue; + $clean_stmt .= $line . "\n"; + } + $clean_stmt = trim($clean_stmt); + if (empty($clean_stmt)) continue; + + try { + $res = $pdo->query($clean_stmt); + if ($res) { + $res->closeCursor(); + } + } catch (Throwable $e) { + $msg = $e->getMessage(); + // If the error is about a table already existing, it's fine + if (strpos($msg, "already exists") !== false || + strpos($msg, "Duplicate column") !== false || + strpos($msg, "Duplicate entry") !== false || + strpos($msg, "already a column") !== false || + strpos($msg, "Duplicate key") !== false || + strpos($msg, "errno: 121") !== false) { + continue; + } else { + $errors[] = $migration_name . " at statement: " . substr($clean_stmt, 0, 50) . "... Error: " . $msg; + $file_success = false; + break; } } + } + + if ($file_success) { + $ins = $pdo->prepare("INSERT INTO migrations (migration_name) VALUES (?)"); + $ins->execute([$migration_name]); $applied++; - } catch (Throwable $e) { - $errors[] = basename($file) . ": " . $e->getMessage(); } } if (empty($errors)) { - $success = "Successfully applied $applied migrations."; + $success = "Successfully applied migrations."; header('Location: ' . htmlspecialchars($_SERVER['SCRIPT_NAME']) . '?step=4'); exit; } else { @@ -290,4 +335,4 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { - \ No newline at end of file + diff --git a/test_install.php b/test_install.php new file mode 100644 index 0000000..ad37b31 --- /dev/null +++ b/test_install.php @@ -0,0 +1 @@ + \ No newline at end of file