This commit is contained in:
2025-11-26 23:01:53 +01:00
parent e3084b66ab
commit 0cf33d302a

View File

@@ -25,36 +25,47 @@ if (php_sapi_name() !== 'cli') {
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 1) Sprache aus GET (optional) ermitteln // Helper: Browser-Sprache aus HTTP_ACCEPT_LANGUAGE
// ----------------------------------------------------------- // -----------------------------------------------------------
$lang = $_GET['lang'] ?? null; function usb_detect_browser_lang(array $availableLangs): ?string
{
if (is_string($lang)) { if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) || empty($availableLangs)) {
$lang = strtolower($lang); return null;
if (!preg_match('/^[a-z]{2}$/', $lang)) {
$lang = null;
} }
} else {
$lang = null; $raw = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$parts = explode(',', $raw);
foreach ($parts as $part) {
$part = trim($part);
if ($part === '') continue;
// z.B. "de-DE;q=0.9" → "de-DE"
$langPart = explode(';', $part)[0];
$code2 = strtolower(substr($langPart, 0, 2));
if (preg_match('/^[a-z]{2}$/', $code2) && isset($availableLangs[$code2])) {
return $code2;
}
}
return null;
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 1b) Browser-Sprache aus HTTP_ACCEPT_LANGUAGE // 1) Sprache aus ?lang holen (nur 2-Buchstaben-Code validieren)
// ----------------------------------------------------------- // -----------------------------------------------------------
$browserLang = null; $requestedLang = null;
if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE']; if (isset($_GET['lang']) && is_string($_GET['lang'])) {
$parts = explode(',', $accept); $tmp = strtolower($_GET['lang']);
if (!empty($parts[0])) { if (preg_match('/^[a-z]{2}$/', $tmp)) {
$primary = strtolower(trim($parts[0])); $requestedLang = $tmp;
if (preg_match('/^([a-z]{2})/', $primary, $m)) {
$browserLang = $m[1]; // z.B. "de" aus "de-DE"
}
} }
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 2) Verfügbare JSON-Sprachen erkennen // 2) Verfügbare JSON-Sprachen aus /public/assets/i18n
// ----------------------------------------------------------- // -----------------------------------------------------------
$i18nDir = __DIR__ . '/../public/assets/i18n'; $i18nDir = __DIR__ . '/../public/assets/i18n';
@@ -79,29 +90,23 @@ foreach ($langFiles as $file) {
continue; continue;
} }
// meta ist optional
$meta = $json['meta'] ?? []; $meta = $json['meta'] ?? [];
// Optional: Sprachen mit enabled=false ausblenden // optional: meta.enabled === false ausblenden (z.B. Templates)
if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) { if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) {
continue; continue;
} }
// Sprachcode bestimmen (meta.code oder Dateiname) // Sprachcode aus meta.code oder Dateiname
$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, ...) // 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)) {
// Sonderdatei (z.B. template.json) ignorieren
continue; continue;
} }
// Label: aus meta.label oder Fallback = strtoupper(code)
$label = $meta['label'] ?? strtoupper($code); $label = $meta['label'] ?? strtoupper($code);
$flag = $meta['flag'] ?? '🏳️'; // Flag kommt primär aus JSON, sonst neutrale Flagge
// Flag: ausschließlich aus meta.flag oder neutrale Flagge,
// KEINE festen Mappings mehr für de/en/fr/it
$flag = $meta['flag'] ?? '🏳️';
$availableLangs[$code] = [ $availableLangs[$code] = [
'code' => $code, 'code' => $code,
@@ -110,38 +115,50 @@ foreach ($langFiles as $file) {
]; ];
} }
// Falls keine Sprachdateien gefunden wurden → Minimal-Fallback // Falls wirklich gar keine Sprachdatei existiert → Minimal-Fallback
if (empty($availableLangs)) { if (empty($availableLangs)) {
$availableLangs = [ $availableLangs = [
'en' => [ 'en' => [
'code' => 'en', 'code' => 'en',
'label' => 'English', 'label' => 'English',
'flag' => '🇬🇧', 'flag' => '🏳️',
], ],
]; ];
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 3) Endgültige Sprache bestimmen (ohne harte Standardsprachen) // 3) Endgültige Sprache wählen nach deiner Priorität
// //
// Reihenfolge: // 1) ?lang=xx, wenn gültig & vorhanden
// a) ?lang=xx → wenn gültig und in available // 2) HTTP_ACCEPT_LANGUAGE (erste Sprache, 2 Buchstaben)
// b) Browser-Sprache → wenn in available // 3) 'en', wenn vorhanden
// c) 'en', wenn vorhanden // 4) sonst erste Sprache aus $availableLangs
// d) sonst: erste verfügbare Sprache
// ----------------------------------------------------------- // -----------------------------------------------------------
if ($lang && isset($availableLangs[$lang])) { $lang = null;
// GET-Parameter ist gültig, nichts weiter tun
} else { // 1) ?lang=xx (gültig & vorhanden)
if ($browserLang && isset($availableLangs[$browserLang])) { if ($requestedLang && isset($availableLangs[$requestedLang])) {
$lang = $requestedLang;
}
// 2) Browser-Sprache aus HTTP_ACCEPT_LANGUAGE
if ($lang === null) {
$browserLang = usb_detect_browser_lang($availableLangs);
if ($browserLang !== null) {
$lang = $browserLang; $lang = $browserLang;
} elseif (isset($availableLangs['en'])) { }
}
// 3) Wenn noch immer nichts → 'en', falls vorhanden
if ($lang === null && isset($availableLangs['en'])) {
$lang = 'en'; $lang = 'en';
} else { }
// 4) Wenn immer noch nichts → erste Sprache aus $availableLangs
if ($lang === null) {
$keys = array_keys($availableLangs); $keys = array_keys($availableLangs);
$lang = $keys[0] ?? 'en'; $lang = $keys[0] ?? 'en';
} }
}
// ----------------------------------------------------------- // -----------------------------------------------------------
// 4) Aktive Sprachdatei laden // 4) Aktive Sprachdatei laden
@@ -157,7 +174,7 @@ if (is_readable($activeLangFile)) {
} }
// ----------------------------------------------------------- // -----------------------------------------------------------
// 5) Fallback-Sprache (EN), falls vorhanden // 5) Fallback-Sprache (en.json), falls vorhanden
// ----------------------------------------------------------- // -----------------------------------------------------------
$fallbackLangData = []; $fallbackLangData = [];
$fallbackFile = $i18nDir . '/en.json'; $fallbackFile = $i18nDir . '/en.json';