Vollständiges, schlankes PHP/SQLite-CMS für IT-, KI- und Gaming-Inhalte: - Core: DB-Singleton, Auth mit Passwort-Hashing, Session-Cookies, CSRF-Schutz, Login-Rate-Limit, Bild-Upload mit serverseitiger Validierung - Admin: Dashboard, Artikel/Seiten-Verwaltung mit Quill WYSIWYG-Editor, Kategorien, Navigation (Drag & Drop), Medienbibliothek, Profil - Frontend: Responsive Dark-Theme, Artikel-Grid, Kategorie-Filter, Archiv, Paginierung, SEO-Meta-Tags - Sicherheit: Prepared Statements, HTML-Sanitizer, .htaccess-Schutz für sensible Verzeichnisse, PHP-Ausführungsschutz im Upload-Ordner - Installation: install.php erstellt DB-Schema und Admin-Account https://claude.ai/code/session_01Xsg4j2t4S9goMuWVpF3ezG
127 lines
5.0 KiB
PHP
127 lines
5.0 KiB
PHP
<?php
|
|
require_once __DIR__ . '/../core/auth.php';
|
|
auth_start_session();
|
|
auth_require_login();
|
|
|
|
$pdo = db();
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|
csrf_verify();
|
|
|
|
if (isset($_POST['delete_id'])) {
|
|
$stmt = $pdo->prepare('DELETE FROM categories WHERE id = ?');
|
|
$stmt->execute([(int) $_POST['delete_id']]);
|
|
flash('success', 'Kategorie gelöscht.');
|
|
redirect('/admin/categories.php');
|
|
}
|
|
|
|
if (isset($_POST['save'])) {
|
|
$catId = !empty($_POST['cat_id']) ? (int) $_POST['cat_id'] : null;
|
|
$name = trim($_POST['name'] ?? '');
|
|
$description = trim($_POST['description'] ?? '');
|
|
$sortOrder = (int) ($_POST['sort_order'] ?? 0);
|
|
|
|
if ($name === '') {
|
|
flash('error', 'Name ist erforderlich.');
|
|
} else {
|
|
$slug = slugify($name);
|
|
$slugCheck = $pdo->prepare('SELECT id FROM categories WHERE slug = ? AND id != ?');
|
|
$slugCheck->execute([$slug, $catId ?? 0]);
|
|
if ($slugCheck->fetch()) {
|
|
flash('error', 'Eine Kategorie mit diesem Namen existiert bereits.');
|
|
} else {
|
|
if ($catId) {
|
|
$stmt = $pdo->prepare('UPDATE categories SET name=?, slug=?, description=?, sort_order=? WHERE id=?');
|
|
$stmt->execute([$name, $slug, $description, $sortOrder, $catId]);
|
|
flash('success', 'Kategorie aktualisiert.');
|
|
} else {
|
|
$stmt = $pdo->prepare('INSERT INTO categories (name, slug, description, sort_order) VALUES (?, ?, ?, ?)');
|
|
$stmt->execute([$name, $slug, $description, $sortOrder]);
|
|
flash('success', 'Kategorie erstellt.');
|
|
}
|
|
}
|
|
}
|
|
redirect('/admin/categories.php');
|
|
}
|
|
}
|
|
|
|
$categories = $pdo->query('SELECT * FROM categories ORDER BY sort_order, name')->fetchAll();
|
|
$editCat = null;
|
|
if (isset($_GET['edit'])) {
|
|
$stmt = $pdo->prepare('SELECT * FROM categories WHERE id = ?');
|
|
$stmt->execute([(int) $_GET['edit']]);
|
|
$editCat = $stmt->fetch();
|
|
}
|
|
|
|
$pageTitle = 'Kategorien';
|
|
$currentPage = 'categories';
|
|
ob_start();
|
|
?>
|
|
<div class="card">
|
|
<h3><?= $editCat ? 'Kategorie bearbeiten' : 'Neue Kategorie' ?></h3>
|
|
<form method="post" class="inline-edit-form">
|
|
<?= csrf_field() ?>
|
|
<?php if ($editCat): ?>
|
|
<input type="hidden" name="cat_id" value="<?= $editCat['id'] ?>">
|
|
<?php endif; ?>
|
|
<div class="form-row-inline">
|
|
<div class="form-group">
|
|
<label for="name">Name</label>
|
|
<input type="text" id="name" name="name" required
|
|
value="<?= e($editCat['name'] ?? '') ?>">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="description">Beschreibung</label>
|
|
<input type="text" id="description" name="description"
|
|
value="<?= e($editCat['description'] ?? '') ?>">
|
|
</div>
|
|
<div class="form-group" style="width:80px">
|
|
<label for="sort_order">Reihenfolge</label>
|
|
<input type="number" id="sort_order" name="sort_order"
|
|
value="<?= (int) ($editCat['sort_order'] ?? 0) ?>">
|
|
</div>
|
|
<div class="form-group">
|
|
<label> </label>
|
|
<button type="submit" name="save" value="1" class="btn btn-primary">Speichern</button>
|
|
<?php if ($editCat): ?>
|
|
<a href="/admin/categories.php" class="btn">Abbrechen</a>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Alle Kategorien (<?= count($categories) ?>)</h3>
|
|
<?php if (empty($categories)): ?>
|
|
<p class="empty-state">Noch keine Kategorien vorhanden.</p>
|
|
<?php else: ?>
|
|
<table class="table">
|
|
<thead>
|
|
<tr><th>Name</th><th>Slug</th><th>Beschreibung</th><th>Reihenfolge</th><th>Aktionen</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<?php foreach ($categories as $cat): ?>
|
|
<tr>
|
|
<td><?= e($cat['name']) ?></td>
|
|
<td><?= e($cat['slug']) ?></td>
|
|
<td><?= e($cat['description']) ?></td>
|
|
<td><?= $cat['sort_order'] ?></td>
|
|
<td class="actions">
|
|
<a href="?edit=<?= $cat['id'] ?>" class="btn btn-sm">Bearbeiten</a>
|
|
<form method="post" class="inline-form" onsubmit="return confirm('Kategorie wirklich löschen?')">
|
|
<?= csrf_field() ?>
|
|
<input type="hidden" name="delete_id" value="<?= $cat['id'] ?>">
|
|
<button type="submit" class="btn btn-sm btn-danger">Löschen</button>
|
|
</form>
|
|
</td>
|
|
</tr>
|
|
<?php endforeach; ?>
|
|
</tbody>
|
|
</table>
|
|
<?php endif; ?>
|
|
</div>
|
|
<?php
|
|
$content = ob_get_clean();
|
|
include __DIR__ . '/templates/layout.php';
|