Files
2026-10-16 19:12:13 +00:00

124 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/common.php';
api_require_method('GET', 'POST');
$staff = api_require_staff();
api_require_admin_or_permission($staff, 'manage_kb');
$pdo = get_db();
if ($_SERVER['REQUEST_METHOD'] === 'GET') {
$categories = $pdo->query('SELECT * FROM kb_categories ORDER BY sort_order, name')->fetchAll();
$articles = $pdo->query(
'SELECT a.*, c.name AS category_name FROM kb_articles a JOIN kb_categories c ON c.id=a.category_id ORDER BY a.title'
)->fetchAll();
api_json([
'categories' => array_map(fn(array $c) => [
'id' => (int) $c['id'],
'name' => $c['name'],
], $categories),
'articles' => array_map(fn(array $a) => [
'id' => (int) $a['id'],
'categoryId' => (int) $a['category_id'],
'categoryName' => $a['category_name'],
'title' => $a['title'],
'body' => $a['body'],
'isPublished' => (bool) $a['is_published'],
'views' => (int) $a['views'],
], $articles),
]);
}
$body = api_request_body();
$action = $body['action'] ?? '';
if ($action === 'create_category') {
$name = trim((string) ($body['name'] ?? ''));
if ($name === '') {
api_error(422, 'NAME_REQUIRED', 'Bitte einen Kategorienamen angeben.');
}
$slug = slugify($name);
$pdo->prepare('INSERT INTO kb_categories (name, slug, sort_order) VALUES (?,?,0)')->execute([$name, $slug]);
$newId = (int) $pdo->lastInsertId();
audit_log($staff['id'], "KB-Kategorie erstellt: {$name} (Mobile App)");
api_json(['id' => $newId]);
}
if ($action === 'delete_category') {
$id = (int) ($body['id'] ?? 0);
$stmt = $pdo->prepare('SELECT COUNT(*) FROM kb_articles WHERE category_id = ?');
$stmt->execute([$id]);
if ((int) $stmt->fetchColumn() > 0) {
api_error(422, 'CATEGORY_NOT_EMPTY', 'Diese Kategorie enthält noch Artikel und kann nicht gelöscht werden.');
}
$nameStmt = $pdo->prepare('SELECT name FROM kb_categories WHERE id = ?');
$nameStmt->execute([$id]);
$catName = $nameStmt->fetchColumn();
$pdo->prepare('DELETE FROM kb_categories WHERE id = ?')->execute([$id]);
audit_log($staff['id'], "KB-Kategorie gelöscht: {$catName} (Mobile App)");
api_json(['ok' => true]);
}
if ($action === 'save_article') {
$id = (int) ($body['id'] ?? 0);
$title = trim((string) ($body['title'] ?? ''));
$categoryId = (int) ($body['categoryId'] ?? 0);
$articleBody = sanitize_staff_html((string) ($body['body'] ?? ''));
$isPublished = !empty($body['isPublished']) ? 1 : 0;
if ($title === '') {
api_error(422, 'TITLE_REQUIRED', 'Bitte einen Titel angeben.');
}
if (trim(strip_tags($articleBody)) === '') {
api_error(422, 'BODY_REQUIRED', 'Bitte einen Inhalt angeben.');
}
$catCheck = $pdo->prepare('SELECT COUNT(*) FROM kb_categories WHERE id = ?');
$catCheck->execute([$categoryId]);
if (!(bool) $catCheck->fetchColumn()) {
api_error(422, 'INVALID_CATEGORY', 'Bitte eine gültige Kategorie wählen.');
}
if ($id === 0) {
$slug = slugify($title);
$base = $slug;
$i = 2;
$check = $pdo->prepare('SELECT COUNT(*) FROM kb_articles WHERE slug = ?');
while (true) {
$check->execute([$slug]);
if ((int) $check->fetchColumn() === 0) break;
$slug = $base . '-' . $i++;
}
$pdo->prepare('INSERT INTO kb_articles (category_id, title, slug, body, is_published, created_at, updated_at) VALUES (?,?,?,?,?,?,?)')
->execute([$categoryId, $title, $slug, $articleBody, $isPublished, db_now(), db_now()]);
$newId = (int) $pdo->lastInsertId();
audit_log($staff['id'], "KB-Artikel erstellt: {$title} (Mobile App)");
} else {
$existsStmt = $pdo->prepare('SELECT COUNT(*) FROM kb_articles WHERE id = ?');
$existsStmt->execute([$id]);
if (!(bool) $existsStmt->fetchColumn()) {
api_error(404, 'ARTICLE_NOT_FOUND', 'Der Artikel wurde nicht gefunden.');
}
$pdo->prepare('UPDATE kb_articles SET category_id=?, title=?, body=?, is_published=?, updated_at=? WHERE id=?')
->execute([$categoryId, $title, $articleBody, $isPublished, db_now(), $id]);
$newId = $id;
audit_log($staff['id'], "KB-Artikel aktualisiert: {$title} (Mobile App)");
}
api_json(['id' => $newId]);
}
if ($action === 'delete_article') {
$id = (int) ($body['id'] ?? 0);
$titleStmt = $pdo->prepare('SELECT title FROM kb_articles WHERE id = ?');
$titleStmt->execute([$id]);
$artTitle = $titleStmt->fetchColumn();
if ($artTitle === false) {
api_error(404, 'ARTICLE_NOT_FOUND', 'Der Artikel wurde nicht gefunden.');
}
$pdo->prepare('DELETE FROM kb_articles WHERE id = ?')->execute([$id]);
audit_log($staff['id'], "KB-Artikel gelöscht: {$artTitle} (Mobile App)");
api_json(['ok' => true]);
}
api_error(422, 'INVALID_ACTION', 'Unbekannte Aktion.');