'sim-05', 'name' => 'Klimawächter 2D', 'desc' => 'Treibhauseffekt-Simulation', 'icon' => '🌡️'], ['id' => 'sim-05-3d', 'name' => 'Klimawächter 3D', 'desc' => '3D-Klimasimulation', 'icon' => '🌊'], ['id' => 'sim-07', 'name' => 'Erdbeben', 'desc' => 'Plattentektonik & Stadtplanung', 'icon' => '🌋'], ['id' => 'sim-09', 'name' => 'Energiemix', 'desc' => 'Energiewende planen', 'icon' => '⚡'], ['id' => 'sim-10', 'name' => 'Lieferketten', 'desc' => 'Globale Lieferketten', 'icon' => '👕'], ['id' => 'sim-11', 'name' => 'Regenwald', 'desc' => 'Regenwald-Expedition', 'icon' => '🌴'], ['id' => 'sim-12', 'name' => 'Flussmanagement', 'desc' => 'Fluss & Hochwasserschutz', 'icon' => '🏞️'], ['id' => 'sim-13', 'name' => 'Stadt & Raumplanung', 'desc' => 'Stadtsimulation mit Kacheln', 'icon' => '🏗️'], ['id' => 'sim-14', 'name' => 'Helikopter-Navigation', 'desc' => 'Rettungshubschrauber steuern', 'icon' => '🚁'], ]; if ($method === 'GET') { // Schüler*innen-Ansicht: welche Module sind für mich freigeschaltet? if (isset($_GET['student']) && $_GET['student'] === '1') { $sessionId = Session::requireStudent(); $session = $db->fetchOne('SELECT class_id FROM student_sessions WHERE id = ?', [$sessionId]); if (!$session || !$session['class_id']) { // Kein Klasse = alle Module frei (Autodidakt) $result = []; foreach ($ALL_MODULES as $mod) { $result[] = ['id' => $mod['id'], 'name' => $mod['name'], 'icon' => $mod['icon'], 'mode' => 'free']; } Response::ok($result); } $classId = $session['class_id']; $classMap = []; $settings = $db->fetchAll('SELECT module_id, mode FROM class_modules WHERE class_id = ?', [$classId]); foreach ($settings as $s) $classMap[$s['module_id']] = $s['mode']; // Individuelle Overrides für diesen Schüler // Finde student_id aus session $studentRow = $db->fetchOne( 'SELECT s.id FROM students s JOIN student_sessions ss ON ss.class_id = s.class_id AND ss.display_name = s.display_name WHERE ss.id = ?', [$sessionId] ); $overrides = []; if ($studentRow) { $rows = $db->fetchAll('SELECT module_id, mode FROM student_modules WHERE student_id = ?', [$studentRow['id']]); foreach ($rows as $r) $overrides[$r['module_id']] = $r['mode']; } $result = []; foreach ($ALL_MODULES as $mod) { $mode = $overrides[$mod['id']] ?? $classMap[$mod['id']] ?? 'locked'; $result[] = ['id' => $mod['id'], 'name' => $mod['name'], 'icon' => $mod['icon'], 'mode' => $mode]; } Response::ok($result); } $teacherId = Session::requireTeacher(); $classId = (int)($_GET['class_id'] ?? 0); if (!$classId) Response::error('class_id erforderlich'); $class = $db->fetchOne('SELECT id FROM classes WHERE id = ? AND teacher_id = ?', [$classId, $teacherId]); if (!$class) Response::error('Klasse nicht gefunden', 404); // Klassen-Defaults laden $settings = $db->fetchAll('SELECT module_id, mode FROM class_modules WHERE class_id = ?', [$classId]); $classMap = []; foreach ($settings as $s) $classMap[$s['module_id']] = $s['mode']; // Matrix-Modus: alle Schüler × alle Module if (isset($_GET['matrix']) && $_GET['matrix'] === '1') { $students = $db->fetchAll( 'SELECT id, username, display_name, emoji_avatar FROM students WHERE class_id = ? ORDER BY username', [$classId] ); // Individuelle Overrides laden $studentIds = array_column($students, 'id'); $overrides = []; if (!empty($studentIds)) { $placeholders = implode(',', array_fill(0, count($studentIds), '?')); $rows = $db->fetchAll( "SELECT student_id, module_id, mode FROM student_modules WHERE student_id IN ($placeholders)", $studentIds ); foreach ($rows as $r) { $overrides[$r['student_id']][$r['module_id']] = $r['mode']; } } // Matrix aufbauen $matrix = []; foreach ($students as $s) { $row = [ 'id' => (int)$s['id'], 'username' => $s['username'], 'displayName' => $s['display_name'] ?: $s['username'], 'emoji' => $s['emoji_avatar'] ?: '🧑‍🎓', 'modules' => [], ]; foreach ($ALL_MODULES as $mod) { $row['modules'][$mod['id']] = $overrides[$s['id']][$mod['id']] ?? $classMap[$mod['id']] ?? 'locked'; } $matrix[] = $row; } // Modul-Infos mit Klassen-Defaults $modulesInfo = []; foreach ($ALL_MODULES as $mod) { $modulesInfo[] = [ 'id' => $mod['id'], 'name' => $mod['name'], 'desc' => $mod['desc'], 'icon' => $mod['icon'], 'classMode' => $classMap[$mod['id']] ?? 'locked', ]; } Response::ok(['modules' => $modulesInfo, 'students' => $matrix]); } // Standard: nur Klassen-Defaults $result = []; foreach ($ALL_MODULES as $mod) { $result[] = [ 'id' => $mod['id'], 'name' => $mod['name'], 'desc' => $mod['desc'], 'icon' => $mod['icon'], 'mode' => $classMap[$mod['id']] ?? 'locked', ]; } Response::ok($result); } if ($method === 'POST') { $teacherId = Session::requireTeacher(); $body = json_decode(file_get_contents('php://input'), true); $action = $body['action'] ?? ''; $classId = (int)($body['classId'] ?? 0); $moduleId = $body['moduleId'] ?? ''; if (!$classId || !$moduleId) Response::error('classId und moduleId erforderlich'); $class = $db->fetchOne('SELECT id FROM classes WHERE id = ? AND teacher_id = ?', [$classId, $teacherId]); if (!$class) Response::error('Klasse nicht gefunden', 404); // Klassen-Default setzen if ($action === 'set_mode') { $mode = $body['mode'] ?? 'locked'; if (!in_array($mode, ['locked', 'free', 'teacher_started'])) Response::error('Ungültiger Modus'); $db->execute( 'INSERT INTO class_modules (class_id, module_id, enabled, mode) VALUES (?, ?, 1, ?) ON DUPLICATE KEY UPDATE mode = VALUES(mode), enabled = 1', [$classId, $moduleId, $mode] ); Response::ok(); } // Individuell pro Schüler setzen if ($action === 'set_student_mode') { $studentId = (int)($body['studentId'] ?? 0); $mode = $body['mode'] ?? 'locked'; if (!$studentId) Response::error('studentId erforderlich'); if (!in_array($mode, ['locked', 'free', 'teacher_started'])) Response::error('Ungültiger Modus'); // Prüfen dass Schüler zur Klasse gehört $student = $db->fetchOne('SELECT id FROM students WHERE id = ? AND class_id = ?', [$studentId, $classId]); if (!$student) Response::error('Schüler nicht in dieser Klasse'); $db->execute( 'INSERT INTO student_modules (student_id, module_id, mode) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE mode = VALUES(mode)', [$studentId, $moduleId, $mode] ); Response::ok(); } // Klassen-Default für ALLE Schüler übernehmen (reset overrides) if ($action === 'reset_overrides') { $db->execute( 'DELETE sm FROM student_modules sm JOIN students s ON s.id = sm.student_id WHERE s.class_id = ? AND sm.module_id = ?', [$classId, $moduleId] ); Response::ok(); } Response::error('Unbekannte Aktion'); } Response::error('Methode nicht erlaubt', 405);