37f6238d05
Vorbereitung für den JWT+Redis-Umschalter: alle verstreuten $_SESSION['teacher_id'|admin_id']-Zugriffe laufen jetzt durch Session::-Helper, damit der Backend-Tausch später EINE Datei (Session.php) ist statt 18 Stellen. - Session.php: neue Admin-Helper adminId()/loginAdmin()/logoutAdmin()/ requireAdmin() (mirror der Teacher-Helper). teacherId()/adminId() starten die Session jetzt lazy (Aufrufer müssen Session::start() nicht mehr). - 18 Fundstellen kanalisiert (admin.php, admin-accounts, admin-modules, licenses, levels, waypoints, foto-upload, admin_gate, save_map). - Country.php + app.php cockpit_href: über Session:: mit class_exists-Fallback (Bootstrap/Lib-Kontext, Session evtl. nicht geladen). Verhaltensneutral: 14/14 Lint OK, Helper-Round-Trip 6/6 PASS, Live-Smoke (admin status/modules/accounts/licenses) weist unauth. Requests wie bisher mit 401/403 ab. AUTH_BACKEND bleibt 'session' — Live unverändert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
94 lines
3.5 KiB
PHP
94 lines
3.5 KiB
PHP
<?php
|
|
/**
|
|
* Admin API: Module-Verwaltung
|
|
* GET /api/admin-modules → Liste aller Module (mit Emoji, Titel, Bild, Status)
|
|
* PUT /api/admin-modules → Ein Modul aktualisieren (Emoji, Titel, Subtitle, Status, Bild)
|
|
* POST /api/admin-modules → Upload eines neuen Card-Bildes (multipart)
|
|
*
|
|
* Auth: Super-Admin Session ($_SESSION['admin_id'])
|
|
*/
|
|
|
|
if (session_status() === PHP_SESSION_NONE) session_start();
|
|
|
|
if (!Session::adminId()) {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Nicht eingeloggt']);
|
|
exit;
|
|
}
|
|
|
|
$db = Database::get();
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
try {
|
|
// === GET: Liste aller Module ===
|
|
if ($method === 'GET') {
|
|
$modules = $db->fetchAll('
|
|
SELECT module_id, title, subtitle, icon, card_image, status,
|
|
duration_min, age_min, age_max, play_url, page_url, sort_order
|
|
FROM module_info
|
|
ORDER BY sort_order, title
|
|
');
|
|
Response::json(['modules' => $modules]);
|
|
}
|
|
|
|
// === PUT: Modul aktualisieren ===
|
|
if ($method === 'PUT') {
|
|
$body = json_decode(file_get_contents('php://input'), true);
|
|
$id = trim($body['module_id'] ?? '');
|
|
if (!$id) Response::error('module_id fehlt');
|
|
|
|
$exists = $db->fetchOne('SELECT module_id FROM module_info WHERE module_id = ?', [$id]);
|
|
if (!$exists) Response::error('Modul nicht gefunden', 404);
|
|
|
|
$fields = [];
|
|
$params = [];
|
|
|
|
// Erlaubte Felder
|
|
$allowed = ['title', 'subtitle', 'icon', 'card_image', 'status',
|
|
'duration_min', 'age_min', 'age_max', 'play_url', 'page_url', 'sort_order'];
|
|
foreach ($allowed as $f) {
|
|
if (array_key_exists($f, $body)) {
|
|
$fields[] = "$f = ?";
|
|
$params[] = $body[$f] === '' ? null : $body[$f];
|
|
}
|
|
}
|
|
if (!$fields) Response::error('Keine Felder zum Aktualisieren');
|
|
|
|
$params[] = $id;
|
|
$sql = 'UPDATE module_info SET ' . implode(', ', $fields) . ' WHERE module_id = ?';
|
|
$db->execute($sql, $params);
|
|
|
|
$updated = $db->fetchOne('SELECT * FROM module_info WHERE module_id = ?', [$id]);
|
|
Response::json(['ok' => true, 'module' => $updated]);
|
|
}
|
|
|
|
// === POST: Bild-Upload ===
|
|
if ($method === 'POST') {
|
|
$id = trim($_POST['module_id'] ?? '');
|
|
if (!$id) Response::error('module_id fehlt');
|
|
if (empty($_FILES['image'])) Response::error('Kein Bild hochgeladen');
|
|
|
|
$file = $_FILES['image'];
|
|
if ($file['error'] !== UPLOAD_ERR_OK) Response::error('Upload-Fehler');
|
|
if ($file['size'] > 5 * 1024 * 1024) Response::error('Bild zu gross (max 5 MB)');
|
|
|
|
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
|
if (!in_array($ext, ['png', 'jpg', 'jpeg', 'webp', 'svg'])) Response::error('Nur PNG, JPG, WEBP, SVG');
|
|
|
|
$targetDir = __DIR__ . '/../../assets/img/';
|
|
$filename = 'card-' . preg_replace('/[^a-z0-9]/', '', $id) . '.' . $ext;
|
|
$targetPath = $targetDir . $filename;
|
|
|
|
if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
|
|
Response::error('Datei konnte nicht gespeichert werden');
|
|
}
|
|
|
|
$db->execute('UPDATE module_info SET card_image = ? WHERE module_id = ?', [$filename, $id]);
|
|
Response::json(['ok' => true, 'card_image' => $filename]);
|
|
}
|
|
|
|
Response::error('Methode nicht unterstützt', 405);
|
|
} catch (Throwable $e) {
|
|
Response::error('Fehler: ' . $e->getMessage(), 500);
|
|
}
|