['label' => 'Österreich', 'flag' => '🇦🇹'], 'DE' => ['label' => 'Deutschland', 'flag' => '🇩🇪'], 'CH' => ['label' => 'Schweiz', 'flag' => '🇨🇭'], 'LI' => ['label' => 'Liechtenstein','flag' => '🇱🇮'], ]; public static function allCountries(): array { return array_keys(self::META); } public static function isValid(?string $code): bool { return is_string($code) && isset(self::META[strtoupper($code)]); } public static function flag(string $code): string { return self::META[strtoupper($code)]['flag'] ?? '🏳️'; } public static function label(string $code): string { return self::META[strtoupper($code)]['label'] ?? $code; } /** * Liefert das aktuell gültige Land nach der Kaskade. * Cached pro Request. */ public static function current(): string { if (self::$cached !== null) return self::$cached; // 1. URL-Override (?country=AT) if (!empty($_GET['country']) && self::isValid($_GET['country'])) { return self::$cached = strtoupper($_GET['country']); } if (session_status() === PHP_SESSION_NONE) @session_start(); // 2. Session-Override (gezielt gesetzt, hält während Session) if (!empty($_SESSION['ggs_country']) && self::isValid($_SESSION['ggs_country'])) { return self::$cached = strtoupper($_SESSION['ggs_country']); } // 3-5. DB-Kaskade try { $db = getDB(); // 3. Schüler*in aktiv? $studentId = $_SESSION['student_id'] ?? null; if ($studentId) { $row = self::fetchFirst($db, ' SELECT s.country AS s_country, c.country AS c_country, t.country AS t_country FROM students s LEFT JOIN classes c ON c.id = s.class_id LEFT JOIN teachers t ON t.id = c.teacher_id WHERE s.id = ? AND s.deleted_at IS NULL LIMIT 1 ', [$studentId]); if ($row) { foreach (['s_country','c_country','t_country'] as $f) { if (!empty($row[$f]) && self::isValid($row[$f])) { return self::$cached = strtoupper($row[$f]); } } } } // 4./5. Lehrperson eingeloggt? $teacherId = $_SESSION['teacher_id'] ?? null; if ($teacherId) { $val = self::fetchFirst($db, 'SELECT country FROM teachers WHERE id = ? LIMIT 1', [$teacherId] ); if ($val && !empty($val['country']) && self::isValid($val['country'])) { return self::$cached = strtoupper($val['country']); } } } catch (Throwable $e) { // DB-Fehler → Cookie/Default weiter probieren } // 6. Cookie (Gast-Setting) if (!empty($_COOKIE['ggs-country']) && self::isValid($_COOKIE['ggs-country'])) { return self::$cached = strtoupper($_COOKIE['ggs-country']); } // 7. Default return self::$cached = self::DEFAULT; } /** * Setzt das aktuelle Land. Persistiert: * - Eingeloggter Schüler → students_sessions.country? Nein, wir nehmen `students.country`? * Aktuell: Session-Speicher + Cookie, damit die Einstellung nicht sofort die * DB verändert. DB-Schreiben bewusst dem Admin/Profile überlassen. * - Für Lehrperson: dto. * - Gast: nur Cookie * * Setzt zusätzlich `$_SESSION['ggs_country']` und einen Cookie für 1 Jahr. */ public static function setCurrent(string $code): bool { if (!self::isValid($code)) return false; $code = strtoupper($code); if (session_status() === PHP_SESSION_NONE) @session_start(); $_SESSION['ggs_country'] = $code; // Cookie 1 Jahr, SameSite=Lax, Path=BASE_PATH $path = defined('BASE_PATH') && BASE_PATH !== '' ? BASE_PATH : '/'; @setcookie('ggs-country', $code, [ 'expires' => time() + 60*60*24*365, 'path' => $path, 'samesite' => 'Lax', 'secure' => !empty($_SERVER['HTTPS']), 'httponly' => false, // Client-JS darf es auch lesen (symmetrischer Fallback) ]); self::$cached = $code; return true; } /** Nur Internes Helpergriff — fetch one Row */ private static function fetchFirst(PDO $db, string $sql, array $params): ?array { $stmt = $db->prepare($sql); $stmt->execute($params); $row = $stmt->fetch(PDO::FETCH_ASSOC); return $row ?: null; } }