fetchOne( 'SELECT id FROM students WHERE class_id = ? AND display_name = ? AND deleted_at IS NULL', [$classId, $displayName] ); if ($row) $studentId = (int)$row['id']; } $db->execute( 'INSERT INTO student_sessions (id, class_id, display_name, student_id) VALUES (?, ?, ?, ?)', [$uuid, $classId, $displayName, $studentId] ); setcookie(self::COOKIE_NAME, $uuid, [ 'expires' => time() + self::COOKIE_TTL, 'path' => BASE_PATH . '/', 'samesite' => 'Lax', 'secure' => IS_PRODUCTION, 'httponly' => true, ]); return $uuid; } /** API-Guard: 401 wenn keine Session */ public static function requireStudent(): string { $id = self::studentId(); if (!$id) { http_response_code(401); echo json_encode(['error' => 'Keine Session']); exit; } return $id; } /** Lehrer eingeloggt? */ public static function teacherId(): ?int { return $_SESSION['teacher_id'] ?? null; } /** Lehrer-Login */ public static function loginTeacher(int $teacherId): void { self::start(); $_SESSION['teacher_id'] = $teacherId; } /** Lehrer-Guard: 401 wenn nicht eingeloggt */ public static function requireTeacher(): int { $id = self::teacherId(); if (!$id) { http_response_code(401); echo json_encode(['error' => 'Nicht eingeloggt']); exit; } return $id; } public static function logout(): void { self::start(); session_destroy(); setcookie(self::COOKIE_NAME, '', [ 'expires' => 1, 'path' => BASE_PATH . '/', 'samesite' => 'Lax', 'secure' => IS_PRODUCTION, 'httponly' => true, ]); } }