This commit is contained in:
2025-11-26 23:19:10 +01:00
parent cd8dc3af79
commit cf84158039

View File

@@ -25,24 +25,37 @@ if (php_sapi_name() !== 'cli') {
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// Helper: Browser-Sprache aus HTTP_ACCEPT_LANGUAGE // Helper: Browser-Sprache aus HTTP_ACCEPT_LANGUAGE bestimmen
// ----------------------------------------------------------- // -----------------------------------------------------------
function usb_detect_browser_lang(array $availableLangs): ?string function usb_detect_browser_lang(array $availableLangs): ?string
{ {
if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) || empty($availableLangs)) { if (empty($availableLangs)) {
return null; return null;
} }
$raw = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $header = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '';
$parts = explode(',', $raw); if ($header === '') {
return null;
}
// z.B. "de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7,it;q=0.6"
$parts = explode(',', $header);
foreach ($parts as $part) { foreach ($parts as $part) {
$part = trim($part); $part = trim($part);
if ($part === '') continue; if ($part === '') {
continue;
}
// z.B. "de-DE;q=0.9" → "de-DE" // Sprache vor dem ; nehmen (z.B. "de-DE" oder "en-US")
$langPart = explode(';', $part)[0]; $langTag = strtolower(explode(';', $part)[0]);
$code2 = strtolower(substr($langPart, 0, 2));
if ($langTag === '') {
continue;
}
// 2-Buchstaben-Code extrahieren
$code2 = substr($langTag, 0, 2);
if (preg_match('/^[a-z]{2}$/', $code2) && isset($availableLangs[$code2])) { if (preg_match('/^[a-z]{2}$/', $code2) && isset($availableLangs[$code2])) {
return $code2; return $code2;
@@ -53,19 +66,21 @@ function usb_detect_browser_lang(array $availableLangs): ?string
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 1) Sprache aus ?lang holen (nur 2-Buchstaben-Code validieren) // 1) Sprache aus ?lang lesen (nur 2-Buchstaben-Code zulassen)
// ----------------------------------------------------------- // -----------------------------------------------------------
$requestedLang = $_GET['lang'] ?? null;
if (is_string($requestedLang)) {
$requestedLang = strtolower($requestedLang);
if (!preg_match('/^[a-z]{2}$/', $requestedLang)) {
$requestedLang = null; $requestedLang = null;
if (isset($_GET['lang']) && is_string($_GET['lang'])) {
$tmp = strtolower($_GET['lang']);
if (preg_match('/^[a-z]{2}$/', $tmp)) {
$requestedLang = $tmp;
} }
} else {
$requestedLang = null;
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 2) Verfügbare JSON-Sprachen aus /public/assets/i18n // 2) Verfügbare JSON-Sprachen erkennen
// ----------------------------------------------------------- // -----------------------------------------------------------
$i18nDir = __DIR__ . '/../public/assets/i18n'; $i18nDir = __DIR__ . '/../public/assets/i18n';
@@ -92,21 +107,20 @@ foreach ($langFiles as $file) {
$meta = $json['meta'] ?? []; $meta = $json['meta'] ?? [];
// optional: meta.enabled === false ausblenden (z.B. Templates) // Option: nur Sprachen mit enabled=false ausblenden
if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) { if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) {
continue; continue;
} }
// Sprachcode aus meta.code oder Dateiname // Sprachcode bestimmen (immer 2-Buchstaben)
$code = strtolower($meta['code'] ?? basename($file, '.json')); $code = strtolower($meta['code'] ?? basename($file, '.json'));
// Nur 2-Buchstaben-Codes zulassen (de, en, fr, it, dk, es, ...)
if (!preg_match('/^[a-z]{2}$/', $code)) { if (!preg_match('/^[a-z]{2}$/', $code)) {
// Sonderdateien (template.json etc.) ignorieren
continue; continue;
} }
$label = $meta['label'] ?? strtoupper($code); $label = $meta['label'] ?? strtoupper($code);
$flag = $meta['flag'] ?? '🏳️'; // Flag kommt primär aus JSON, sonst neutrale Flagge $flag = $meta['flag'] ?? '🏳️';
$availableLangs[$code] = [ $availableLangs[$code] = [
'code' => $code, 'code' => $code,
@@ -115,7 +129,7 @@ foreach ($langFiles as $file) {
]; ];
} }
// Falls wirklich gar keine Sprachdatei existiert → Minimal-Fallback // Falls keine Sprachdateien gefunden wurden → Minimal-Fallback
if (empty($availableLangs)) { if (empty($availableLangs)) {
$availableLangs = [ $availableLangs = [
'en' => [ 'en' => [
@@ -128,20 +142,15 @@ if (empty($availableLangs)) {
// ----------------------------------------------------------- // -----------------------------------------------------------
// 3) Endgültige Sprache wählen nach deiner Priorität // 3) Endgültige Sprache wählen nach deiner Priorität
//
// 1) ?lang=xx, wenn gültig & vorhanden
// 2) HTTP_ACCEPT_LANGUAGE (erste Sprache, 2 Buchstaben)
// 3) 'en', wenn vorhanden
// 4) sonst erste Sprache aus $availableLangs
// ----------------------------------------------------------- // -----------------------------------------------------------
$lang = null; $lang = null;
// 1) ?lang=xx (gültig & vorhanden) // 1) ?lang=xx wird bevorzugt, wenn gültig + vorhanden
if ($requestedLang && isset($availableLangs[$requestedLang])) { if ($requestedLang && isset($availableLangs[$requestedLang])) {
$lang = $requestedLang; $lang = $requestedLang;
} }
// 2) Browser-Sprache aus HTTP_ACCEPT_LANGUAGE // 2) Sonst HTTP_ACCEPT_LANGUAGE (Browser), erste passende Sprache
if ($lang === null) { if ($lang === null) {
$browserLang = usb_detect_browser_lang($availableLangs); $browserLang = usb_detect_browser_lang($availableLangs);
if ($browserLang !== null) { if ($browserLang !== null) {
@@ -149,12 +158,12 @@ if ($lang === null) {
} }
} }
// 3) Wenn noch immer nichts → 'en', falls vorhanden // 3) Wenn Browser-Sprache nicht existiert → 'en', wenn vorhanden
if ($lang === null && isset($availableLangs['en'])) { if ($lang === null && isset($availableLangs['en'])) {
$lang = 'en'; $lang = 'en';
} }
// 4) Wenn immer noch nichts → erste Sprache aus $availableLangs // 4) Sonst: erste Sprache aus $availableLangs
if ($lang === null) { if ($lang === null) {
$keys = array_keys($availableLangs); $keys = array_keys($availableLangs);
$lang = $keys[0] ?? 'en'; $lang = $keys[0] ?? 'en';
@@ -174,7 +183,7 @@ if (is_readable($activeLangFile)) {
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 5) Fallback-Sprache (en.json), falls vorhanden // 5) Fallback-Sprache: immer EN, wenn vorhanden & nicht aktuell
// ----------------------------------------------------------- // -----------------------------------------------------------
$fallbackLangData = []; $fallbackLangData = [];
$fallbackFile = $i18nDir . '/en.json'; $fallbackFile = $i18nDir . '/en.json';