Files
geograsim/App/php/lib/Country.php
T
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

169 lines
5.9 KiB
PHP

<?php
/**
* Country — Landeinstellung (AT / DE / CH / LI)
* ---------------------------------------------
* Ermittelt das aktuelle Land für Rendering-Entscheidungen (Lehrplan-Filter,
* Inhalts-Priorisierung, Footer-Länderlinks). Auflösungs-Kaskade:
*
* 1. Explizites `?country=AT` in der URL (höchste Priorität, zum Testen)
* 2. Session-Override (über setCurrent() gesetzt)
* 3. `student_sessions.country` (Schüler*in aktiv)
* 4. `classes.country` (von Klasse erben)
* 5. `teachers.country` (Lehrperson eingeloggt)
* 6. Cookie `ggs-country` (Client-Setting für Gast)
* 7. 'AT' Default
*
* Beispiel:
* $country = Country::current(); // 'AT'
* echo Country::flag('DE'); // 🇩🇪
* echo Country::label('CH'); // Schweiz
* foreach (Country::allCountries() as $c) ...
*/
require_once __DIR__ . '/../config/db.php';
class Country
{
public const DEFAULT = 'AT';
private static ?string $cached = null;
private const META = [
'AT' => ['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;
}
}