";
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$displayName = trim($_POST['display_name'] ?? '');
$password = $_POST['password'] ?? '';
$passwordConfirm = $_POST['password_confirm'] ?? '';
$errors = [];
if (strlen($username) < 3) {
$errors[] = 'Benutzername muss mindestens 3 Zeichen lang sein.';
}
if (strlen($password) < 10) {
$errors[] = 'Passwort muss mindestens 10 Zeichen lang sein.';
}
if ($password !== $passwordConfirm) {
$errors[] = 'Passwörter stimmen nicht überein.';
}
if (empty($displayName)) {
$displayName = $username;
}
if (!empty($errors)) {
echo "
";
foreach ($errors as $err) {
echo "
" . htmlspecialchars($err) . "
";
}
echo "
";
} else {
try {
$pdo = new PDO('sqlite:' . DB_PATH, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
$pdo->exec('PRAGMA journal_mode=WAL');
$pdo->exec('PRAGMA foreign_keys=ON');
// Tabellen erstellen
$pdo->exec("
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
display_name TEXT NOT NULL DEFAULT '',
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
)
");
$pdo->exec("
CREATE TABLE categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
slug TEXT NOT NULL UNIQUE,
description TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0
)
");
$pdo->exec("
CREATE TABLE articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
excerpt TEXT NOT NULL DEFAULT '',
body TEXT NOT NULL DEFAULT '',
cover_image TEXT DEFAULT NULL,
category_id INTEGER DEFAULT NULL,
status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','published')),
published_at TEXT DEFAULT NULL,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE SET NULL
)
");
$pdo->exec("
CREATE TABLE pages (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
body TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft','published')),
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
)
");
$pdo->exec("
CREATE TABLE navigation (
id INTEGER PRIMARY KEY AUTOINCREMENT,
label TEXT NOT NULL,
type TEXT NOT NULL CHECK(type IN ('url','page','category','home')),
target TEXT NOT NULL DEFAULT '',
sort_order INTEGER NOT NULL DEFAULT 0,
parent_id INTEGER DEFAULT NULL,
FOREIGN KEY (parent_id) REFERENCES navigation(id) ON DELETE CASCADE
)
");
$pdo->exec("
CREATE TABLE login_attempts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_address TEXT NOT NULL,
attempted_at TEXT NOT NULL DEFAULT (datetime('now'))
)
");
$pdo->exec("CREATE INDEX idx_login_attempts_ip ON login_attempts(ip_address, attempted_at)");
// Admin-Benutzer anlegen
$hash = password_hash($password, PASSWORD_DEFAULT);
$stmt = $pdo->prepare('INSERT INTO users (username, password_hash, display_name) VALUES (?, ?, ?)');
$stmt->execute([$username, $hash, $displayName]);
// Standard-Navigation
$pdo->exec("INSERT INTO navigation (label, type, target, sort_order) VALUES ('Startseite', 'home', '', 0)");
// Standard-Kategorien
$pdo->exec("INSERT INTO categories (name, slug, description, sort_order) VALUES ('IT', 'it', 'Technik und Programmierung', 0)");
$pdo->exec("INSERT INTO categories (name, slug, description, sort_order) VALUES ('KI', 'ki', 'Künstliche Intelligenz', 1)");
$pdo->exec("INSERT INTO categories (name, slug, description, sort_order) VALUES ('Gaming', 'gaming', 'Spiele und Gaming-Kultur', 2)");
echo "
";
echo "
Installation erfolgreich!
";
echo "
Der Admin-Account wurde erstellt. Du kannst dich jetzt anmelden: