Files
Adminator a68c58ac9e Weltkueche Teil A: Land pro Lehrer persistent (teachers.country) + Sim-Verdrahtung
- profil.html: Länderauswahl (AT/DE/CH/LI) im Lehrer-Profil, lädt/zeigt aktuelles Land.
- profile.php: speichert country in teachers.country; gibt country zurück.
- weltkueche.php: injiziert window.WK_COUNTRY = Country::current() (Kaskade Schüler→Klasse→Lehrer→AT) — Fundament für die konsumentenland-basierte Herkunft (Teil B).
Spalte teachers.country existierte bereits, keine Migration nötig.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-21 12:13:27 +02:00

94 lines
3.6 KiB
PHP

<?php
/**
* Weltküche — PHP-Wrapper
* Lädt sims/weltkueche/game.html, injiziert Session-Kontext + Pfad-Basis.
*/
require_once __DIR__ . '/../php/config/app.php';
require_once __DIR__ . '/../php/lib/Database.php';
require_once __DIR__ . '/../php/lib/Session.php';
require_once __DIR__ . '/../php/lib/Country.php';
if (session_status() === PHP_SESSION_NONE) Session::start();
$sessionId = Session::studentId() ?? '';
$studentName = 'Gast';
$classId = null;
$mode = 'free';
try {
$db = Database::get();
if ($sessionId) {
$row = $db->fetchOne(
'SELECT class_id, display_name FROM student_sessions WHERE id = ?',
[$sessionId]
);
if ($row) {
$studentName = $row['display_name'] ?: 'Schüler*in';
$classId = (int)$row['class_id'];
}
}
} catch (Exception $e) { /* still als Demo lauffähig */ }
$gamePath = __DIR__ . '/../sims/weltkueche/game.html';
if (!file_exists($gamePath)) {
http_response_code(503);
echo '<h1>Weltküche wird gerade vorbereitet.</h1><p><a href="' . cockpit_href() . '">Zurück</a></p>';
exit;
}
$html = file_get_contents($gamePath);
// Session-Kontext + Plattform-Basis injizieren.
// Setzt sowohl die Weltküche-eigenen WK_*-Vars (legacy) als auch das
// Plattform-Kontext-Objekt __GGS__, ohne das der Live-Client (Heartbeat
// an das Lehrer-Cockpit) still abbricht.
$base = BASE_PATH . '/sims/weltkueche/';
$ggs = [
'sessionId' => $sessionId,
'simId' => 'weltkueche',
'classId' => $classId,
'baseUrl' => BASE_URL,
'basePath' => BASE_PATH,
'apiUrl' => BASE_URL . '/php/api',
'studentName' => $studentName,
'mode' => $mode,
];
$injection = '<script>'
. 'window.WK_BASE = ' . json_encode($base) . ';'
. 'window.WK_SESSION_ID = ' . json_encode($sessionId) . ';'
. 'window.WK_STUDENT_NAME = ' . json_encode($studentName) . ';'
. 'window.WK_CLASS_ID = ' . json_encode($classId) . ';'
. 'window.WK_MODE = ' . json_encode($mode) . ';'
. 'window.WK_API_BASE = ' . json_encode(BASE_PATH . '/api') . ';'
. 'window.WK_COUNTRY = ' . json_encode(class_exists('Country') ? Country::current() : 'AT') . ';'
. 'window.__GGS__ = ' . json_encode($ggs, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . ';'
. '</script>';
// Asset-Pfade umbiegen (relativ → absolut) — NUR href= und src= Attribute,
// NICHT in JS-Strings. Sonst entstehen doppelte Pfade in fetch()-Calls,
// weil das JS bereits window.WK_BASE davor konkateniert.
$html = preg_replace(
"/(href|src)=([\"'])assets\//",
"$1=$2{$base}assets/",
$html
);
// Injection vor </head>
$html = str_replace('</head>', $injection . "\n</head>", $html);
// Cockpit-Link absolut
$html = str_replace('href="../../schueler.html"', 'href="' . cockpit_href() . '"', $html);
// Live-Heartbeat-Client + Glossar-Tooltip-Standard der Plattform anhängen
$liveScript = '<script src="' . BASE_PATH . '/assets/js/live-client.js" defer></script>';
$glossarScript = '<script src="' . BASE_PATH . '/assets/js/glossar-tooltip.js" defer></script>'
. '<script>window.addEventListener("DOMContentLoaded",function(){'
. 'if(window.GlossarTooltip)GlossarTooltip.init({apiBase:' . json_encode(BASE_PATH . '/php/api') . ',moduleId:"weltkueche"});'
. '});</script>';
$html = str_replace('</body>', $liveScript . "\n" . $glossarScript . "\n</body>", $html);
// Cache-Bust für game.html selbst (nicht via HTTP-Header sondern als Direkt-Ausgabe)
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Content-Type: text/html; charset=UTF-8');
echo $html;