39496-vm/install.php
2026-04-07 13:34:58 +00:00

265 lines
12 KiB
PHP

<?php
session_start();
// Define steps
$step = isset($_GET['step']) ? (int)$_GET['step'] : 1;
$error = '';
$success = '';
// Check if config exists
$configFile = __DIR__ . '/db/config.php';
$configExists = file_exists($configFile);
$dbHost = '127.0.0.1';
$dbName = '';
$dbUser = '';
$dbPass = '';
if ($configExists) {
require_once $configFile;
if (defined('DB_HOST')) $dbHost = DB_HOST;
if (defined('DB_NAME')) $dbName = DB_NAME;
if (defined('DB_USER')) $dbUser = DB_USER;
if (defined('DB_PASS')) $dbPass = DB_PASS;
}
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($step === 2) {
$dbHost = $_POST['db_host'] ?? '127.0.0.1';
$dbName = $_POST['db_name'] ?? '';
$dbUser = $_POST['db_user'] ?? '';
$dbPass = $_POST['db_pass'] ?? '';
try {
// Test connection
$pdo = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8mb4", $dbUser, $dbPass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
]);
// Save configuration
$configContent = "<?php\n" .
"// Generated by install.php\n" .
"define('DB_HOST', " . var_export($dbHost, true) . ");\n" .
"define('DB_NAME', " . var_export($dbName, true) . ");\n" .
"define('DB_USER', " . var_export($dbUser, true) . ");\n" .
"define('DB_PASS', " . var_export($dbPass, true) . ");\n\n" .
"function db() {\n" .
" static \$pdo;\n" .
" if (!\$pdo) {\n" .
" \$pdo = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME.';charset=utf8mb4', DB_USER, DB_PASS, [\n" .
" PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,\n" .
" PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,\n" .
" ]);\n" .
" }\n" .
" return \$pdo;\n" .
"}\n";
if (!is_dir(__DIR__ . '/db')) {
mkdir(__DIR__ . '/db', 0755, true);
}
file_put_contents($configFile, $configContent);
header("Location: ?step=3");
exit;
} catch (PDOException $e) {
$error = "Database Connection Failed: " . $e->getMessage();
}
} elseif ($step === 3) {
require_once $configFile;
try {
$pdo = db();
$schemaFile = __DIR__ . '/db/migrations/schema.sql';
if (!file_exists($schemaFile)) {
throw new Exception("Schema file not found at $schemaFile");
}
$sql = file_get_contents($schemaFile);
$pdo->exec($sql);
header("Location: ?step=4");
exit;
} catch (Exception $e) {
$error = "Migration Failed: " . $e->getMessage();
}
} elseif ($step === 4) {
require_once $configFile;
try {
$pdo = db();
$seedsFile = __DIR__ . '/db/migrations/seeds.sql';
if (!file_exists($seedsFile)) {
throw new Exception("Seeds file not found at $seedsFile");
}
$sql = file_get_contents($seedsFile);
$pdo->exec($sql);
header("Location: ?step=5");
exit;
} catch (Exception $e) {
$error = "Seeding Failed: " . $e->getMessage();
}
}
}
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Platform Installer - Step <?php echo $step; ?></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
<style>
body { background: #f4f7f6; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
.install-card { background: #fff; border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,0.05); overflow: hidden; max-width: 600px; width: 100%; margin: 2rem; }
.install-header { background: #007bff; color: #fff; padding: 2rem; text-align: center; }
.install-header h1 { margin: 0; font-size: 1.8rem; font-weight: 600; }
.install-body { padding: 2rem; }
.step-indicator { display: flex; justify-content: space-between; margin-bottom: 2rem; position: relative; }
.step-indicator::before { content: ''; position: absolute; top: 15px; left: 0; right: 0; height: 3px; background: #e9ecef; z-index: 1; }
.step { width: 32px; height: 32px; border-radius: 50%; background: #e9ecef; color: #6c757d; display: flex; align-items: center; justify-content: center; font-weight: bold; position: relative; z-index: 2; transition: all 0.3s; }
.step.active { background: #007bff; color: #fff; box-shadow: 0 0 0 4px rgba(0,123,255,0.2); }
.step.completed { background: #28a745; color: #fff; }
.btn-primary { background: #007bff; border: none; padding: 0.75rem 1.5rem; font-weight: 500; border-radius: 8px; }
.btn-primary:hover { background: #0056b3; }
.alert { border-radius: 8px; }
.code-block { background: #f8f9fa; padding: 1rem; border-radius: 8px; font-family: monospace; border: 1px solid #dee2e6; }
</style>
</head>
<body>
<div class="install-card">
<div class="install-header">
<h1>Installation Wizard</h1>
<p class="mb-0 mt-2 opacity-75">Setup your platform in 5 easy steps</p>
</div>
<div class="install-body">
<div class="step-indicator">
<?php for ($i = 1; $i <= 5; $i++): ?>
<div class="step <?php echo $i === $step ? 'active' : ($i < $step ? 'completed' : ''); ?>">
<?php echo $i < $step ? '✓' : $i; ?>
</div>
<?php endfor; ?>
</div>
<?php if ($error): ?>
<div class="alert alert-danger"><?php echo htmlspecialchars($error); ?></div>
<?php endif; ?>
<?php if ($step === 1): ?>
<h3 class="mb-3">Step 1: Welcome & Requirements</h3>
<p>Welcome to the platform installation wizard! We will guide you through setting up the database, migrating tables, and loading the initial data.</p>
<ul class="list-group mb-4">
<li class="list-group-item d-flex justify-content-between align-items-center">
PHP Version >= 8.0
<?php if (version_compare(PHP_VERSION, '8.0.0', '>=')): ?>
<span class="badge bg-success rounded-pill">OK (<?php echo PHP_VERSION; ?>)</span>
<?php else: ?>
<span class="badge bg-danger rounded-pill">Fail (<?php echo PHP_VERSION; ?>)</span>
<?php endif; ?>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
PDO MySQL Extension
<?php if (extension_loaded('pdo_mysql')):
?>
<span class="badge bg-success rounded-pill">OK</span>
<?php else:
?>
<span class="badge bg-danger rounded-pill">Fail</span>
<?php endif; ?>
</li>
<li class="list-group-item d-flex justify-content-between align-items-center">
Writable Config Directory (db/)
<?php if (is_writable(__DIR__ . '/db') || is_writable(__DIR__)): ?>
<span class="badge bg-success rounded-pill">OK</span>
<?php else:
?>
<span class="badge bg-danger rounded-pill">Fail</span>
<?php endif; ?>
</li>
</ul>
<div class="d-flex justify-content-end">
<a href="?step=2" class="btn btn-primary">Next Step: Database Config &rarr;</a>
</div>
<?php elseif ($step === 2): ?>
<h3 class="mb-3">Step 2: Database Configuration</h3>
<p class="text-muted">Enter your database credentials below. If `db/config.php` already exists, the fields will be pre-filled.</p>
<form method="POST">
<div class="mb-3">
<label class="form-label">Database Host</label>
<input type="text" name="db_host" class="form-control" value="<?php echo htmlspecialchars($dbHost); ?>" required>
</div>
<div class="mb-3">
<label class="form-label">Database Name</label>
<input type="text" name="db_name" class="form-control" value="<?php echo htmlspecialchars($dbName); ?>" required>
</div>
<div class="mb-3">
<label class="form-label">Database User</label>
<input type="text" name="db_user" class="form-control" value="<?php echo htmlspecialchars($dbUser); ?>" required>
</div>
<div class="mb-3">
<label class="form-label">Database Password</label>
<input type="password" name="db_pass" class="form-control" value="<?php echo htmlspecialchars($dbPass); ?>">
</div>
<div class="d-flex justify-content-between mt-4">
<a href="?step=1" class="btn btn-outline-secondary">&larr; Back</a>
<button type="submit" class="btn btn-primary">Save & Test Connection &rarr;</button>
</div>
</form>
<?php elseif ($step === 3): ?>
<h3 class="mb-3">Step 3: Database Migrations</h3>
<p>Your database configuration is valid! The next step is to create the necessary tables in your database using the schema file.</p>
<div class="alert alert-info">
<strong>Action:</strong> Running this will execute `db/migrations/schema.sql` to build the database structure. Existing tables might be dropped and recreated.
</div>
<form method="POST">
<div class="d-flex justify-content-between mt-4">
<a href="?step=2" class="btn btn-outline-secondary">&larr; Back</a>
<button type="submit" class="btn btn-primary">Run Migrations &rarr;</button>
</div>
</form>
<?php elseif ($step === 4): ?>
<h3 class="mb-3">Step 4: Database Seeding</h3>
<p>Tables have been created successfully! The next step is to insert the initial data (seeds) into the database.</p>
<div class="alert alert-info">
<strong>Action:</strong> Running this will execute `db/migrations/seeds.sql` to load default data, including the admin account and platform settings.
</div>
<form method="POST">
<div class="d-flex justify-content-between mt-4">
<a href="?step=3" class="btn btn-outline-secondary">&larr; Back</a>
<button type="submit" class="btn btn-success">Run Seeds &rarr;</button>
</div>
</form>
<?php elseif ($step === 5): ?>
<div class="text-center py-4">
<div class="mb-4">
<svg style="color: #28a745; width: 64px; height: 64px;" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
</div>
<h3 class="mb-3">Installation Complete!</h3>
<p class="text-muted">Your platform has been successfully installed and configured.</p>
<div class="alert alert-warning text-start">
<strong>Security Warning:</strong> Please delete the <code>install.php</code> file from your server to prevent unauthorized re-installation.
</div>
<div class="mt-4">
<a href="index.php" class="btn btn-primary me-2">Go to Landing Page</a>
<a href="login.php" class="btn btn-outline-primary">Go to Admin Login</a>
</div>
</div>
<?php endif; ?>
</div>
</div>
</body>
</html>