663fde3909
Full source for loveandrosary.com: slide-based Rosary/novena/Divine Mercy Chaplet presentation tool with multi-user roles, SVG bead ring, audio uploads, donate strip, and public session profiles. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
219 lines
9.5 KiB
PHP
219 lines
9.5 KiB
PHP
<?php
|
|
/**
|
|
* install.php — Full database installer.
|
|
* Creates all tables, seeds settings and superadmin account.
|
|
* Run once in browser, then DELETE this file.
|
|
*/
|
|
require_once __DIR__ . '/config/db.php';
|
|
|
|
$pdo = get_pdo();
|
|
$log = [];
|
|
$errors = [];
|
|
|
|
function inst_sql(PDO $pdo, string $label, string $sql, array &$log, array &$errors): void {
|
|
try {
|
|
$pdo->exec($sql);
|
|
$log[] = ['ok', $label];
|
|
} catch (PDOException $e) {
|
|
if (in_array($e->errorInfo[1], [1060, 1061, 1050], true)) {
|
|
$log[] = ['skip', $label . ' (already exists, skipped)'];
|
|
} else {
|
|
$errors[] = $label . ': ' . $e->getMessage();
|
|
$log[] = ['err', $label . ': ' . $e->getMessage()];
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── 1. sessions ──────────────────────────────────────────────────────────────
|
|
inst_sql($pdo, 'Create sessions table', "
|
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
user_id INT NULL,
|
|
is_public TINYINT(1) NOT NULL DEFAULT 1,
|
|
slug VARCHAR(255) NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
occasion VARCHAR(50) NOT NULL,
|
|
mystery_set VARCHAR(50) NOT NULL,
|
|
novena_day TINYINT NULL,
|
|
novena_group_id INT NULL,
|
|
subject_name VARCHAR(255) NULL,
|
|
subject_pronoun VARCHAR(10) NULL,
|
|
subject_dates VARCHAR(150) NULL,
|
|
photo_path VARCHAR(500) NULL,
|
|
is_pinned TINYINT(1) NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
", $log, $errors);
|
|
|
|
// ── 2. novena_groups ─────────────────────────────────────────────────────────
|
|
inst_sql($pdo, 'Create novena_groups table', "
|
|
CREATE TABLE IF NOT EXISTS novena_groups (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
user_id INT NULL,
|
|
is_public TINYINT(1) NOT NULL DEFAULT 1,
|
|
slug VARCHAR(255) NULL,
|
|
name VARCHAR(255) NOT NULL,
|
|
mystery_set VARCHAR(50) NOT NULL DEFAULT 'sorrowful',
|
|
subject_name VARCHAR(255) NULL,
|
|
subject_pronoun VARCHAR(10) NULL,
|
|
subject_dates VARCHAR(150) NULL,
|
|
photo_path VARCHAR(500) NULL,
|
|
is_pinned TINYINT(1) NOT NULL DEFAULT 0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
", $log, $errors);
|
|
|
|
// ── 3. users ─────────────────────────────────────────────────────────────────
|
|
inst_sql($pdo, 'Create users table', "
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
|
username VARCHAR(50) NOT NULL UNIQUE,
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
display_name VARCHAR(100) NULL,
|
|
role ENUM('superadmin','admin','superuser','user') NOT NULL DEFAULT 'user',
|
|
rosary_limit INT NOT NULL DEFAULT 1,
|
|
email_confirmed TINYINT(1) NOT NULL DEFAULT 0,
|
|
confirm_token VARCHAR(64) NULL,
|
|
reset_token VARCHAR(64) NULL,
|
|
reset_expires DATETIME NULL,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
", $log, $errors);
|
|
|
|
// ── 4. site_settings ─────────────────────────────────────────────────────────
|
|
inst_sql($pdo, 'Create site_settings table', "
|
|
CREATE TABLE IF NOT EXISTS site_settings (
|
|
key_name VARCHAR(100) PRIMARY KEY,
|
|
val TEXT NULL,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
|
", $log, $errors);
|
|
|
|
// ── 5. Seed site_settings ────────────────────────────────────────────────────
|
|
$defaults = [
|
|
'smtp_host' => '',
|
|
'smtp_port' => '587',
|
|
'smtp_user' => '',
|
|
'smtp_pass' => '',
|
|
'smtp_from' => '',
|
|
'smtp_from_name' => 'Rosary Presenter',
|
|
'site_name' => 'Rosary Presenter',
|
|
'site_url' => '',
|
|
];
|
|
$ins_setting = $pdo->prepare('INSERT IGNORE INTO site_settings (key_name, val) VALUES (?, ?)');
|
|
foreach ($defaults as $k => $v) {
|
|
try {
|
|
$ins_setting->execute([$k, $v]);
|
|
$log[] = ['ok', "Seeded site_settings: {$k}"];
|
|
} catch (PDOException $e) {
|
|
$errors[] = "site_settings {$k}: " . $e->getMessage();
|
|
}
|
|
}
|
|
|
|
// ── 6. Seed superadmin ───────────────────────────────────────────────────────
|
|
$hash = password_hash('supadmin', PASSWORD_BCRYPT);
|
|
try {
|
|
$pdo->prepare("
|
|
INSERT IGNORE INTO users
|
|
(username, email, password_hash, display_name, role, rosary_limit, email_confirmed)
|
|
VALUES ('supadmin', 'admin@example.com', ?, 'Super Admin', 'superadmin', -1, 1)
|
|
")->execute([$hash]);
|
|
$log[] = ['ok', 'Seeded superadmin account (username: supadmin)'];
|
|
} catch (PDOException $e) {
|
|
$errors[] = 'Seed superadmin: ' . $e->getMessage();
|
|
}
|
|
|
|
$overall_ok = empty($errors);
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>Install — <?= APP_NAME ?></title>
|
|
<style>
|
|
*{box-sizing:border-box}
|
|
body{font-family:system-ui,-apple-system,sans-serif;background:#f4f4f5;margin:0;padding:32px 16px}
|
|
.wrap{max-width:720px;margin:0 auto}
|
|
h1{font-size:26px;margin-bottom:4px}
|
|
.banner{border-radius:8px;padding:20px 24px;margin-bottom:24px;font-size:15px}
|
|
.banner.ok{background:#d1fae5;border:1px solid #6ee7b7;color:#065f46}
|
|
.banner.err{background:#fee2e2;border:1px solid #fca5a5;color:#991b1b}
|
|
.warn{background:#fef3c7;border:1px solid #fcd34d;color:#92400e;border-radius:8px;padding:16px 20px;margin-bottom:24px;font-weight:600}
|
|
.card{background:#fff;border-radius:8px;padding:24px;margin-bottom:20px;box-shadow:0 1px 3px rgba(0,0,0,.07)}
|
|
.cred{background:#1e3a5f;color:#e0f2fe;border-radius:6px;padding:16px 20px;font-family:monospace;font-size:15px;line-height:1.9}
|
|
table{width:100%;border-collapse:collapse;font-size:13px}
|
|
th,td{text-align:left;padding:6px 10px;border-bottom:1px solid #e5e7eb}
|
|
th{background:#f9fafb;font-weight:600}
|
|
.ok{color:#15803d}.err{color:#b91c1c}.skip{color:#d97706}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="wrap">
|
|
<h1>✝ <?= APP_NAME ?> — Installer</h1>
|
|
|
|
<?php if ($overall_ok): ?>
|
|
<div class="banner ok">
|
|
<strong>Installation complete!</strong> All tables created and seeded successfully.
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="banner err">
|
|
<strong>Installation finished with errors.</strong>
|
|
Review the log below. Check your credentials in <code>config/db.php</code> and try again.
|
|
</div>
|
|
<?php endif; ?>
|
|
|
|
<div class="warn">
|
|
⚠ DELETE <code>install.php</code> from your server immediately after reviewing this page.
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2 style="margin-top:0">Superadmin Credentials</h2>
|
|
<div class="cred">
|
|
Username: supadmin<br>
|
|
Password: supadmin<br>
|
|
Role: superadmin (unlimited rosaries)
|
|
</div>
|
|
<p style="color:#b91c1c;font-weight:600;margin-top:12px">
|
|
Change the password immediately — go to
|
|
<a href="<?= BASE_URL ?>/admin/profile">/admin/profile</a> after logging in.<br>
|
|
Also update the email from <code>admin@example.com</code> to your real address.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2 style="margin-top:0">Installation Log</h2>
|
|
<table>
|
|
<thead><tr><th>Status</th><th>Step</th></tr></thead>
|
|
<tbody>
|
|
<?php foreach ($log as [$status, $msg]): ?>
|
|
<tr>
|
|
<td class="<?= $status ?>">
|
|
<?= $status === 'ok' ? '✓ OK' : ($status === 'skip' ? '— SKIP' : '✗ ERROR') ?>
|
|
</td>
|
|
<td><?= htmlspecialchars($msg) ?></td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<?php if ($overall_ok): ?>
|
|
<div class="card">
|
|
<h2 style="margin-top:0">Next Steps</h2>
|
|
<ol style="line-height:2">
|
|
<li>Delete <code>install.php</code> from your server.</li>
|
|
<li>Go to <a href="<?= BASE_URL ?>/login">/login</a> — sign in with <strong>supadmin / supadmin</strong>.</li>
|
|
<li>Go to <a href="<?= BASE_URL ?>/admin/profile">/admin/profile</a> — change your password and email.</li>
|
|
<li>Go to <a href="<?= BASE_URL ?>/admin/settings">/admin/settings</a> — set your site URL and configure SMTP.</li>
|
|
</ol>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</body>
|
|
</html>
|