0, 'path' => '/', 'domain' => '', 'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'), 'httponly' => true, 'samesite' => 'Lax', ]); session_start(); } } // ----------------------------------------------------------- // 1) Sprache aus GET (optional) ermitteln // ----------------------------------------------------------- $lang = $_GET['lang'] ?? null; if (is_string($lang)) { $lang = strtolower($lang); if (!preg_match('/^[a-z]{2}$/', $lang)) { $lang = null; } } else { $lang = null; } // ----------------------------------------------------------- // 1b) Browser-Sprache aus HTTP_ACCEPT_LANGUAGE // ----------------------------------------------------------- $browserLang = null; if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE']; $parts = explode(',', $accept); if (!empty($parts[0])) { $primary = strtolower(trim($parts[0])); if (preg_match('/^([a-z]{2})/', $primary, $m)) { $browserLang = $m[1]; // z.B. "de" aus "de-DE" } } } // ----------------------------------------------------------- // 2) Verfügbare JSON-Sprachen erkennen // ----------------------------------------------------------- $i18nDir = __DIR__ . '/../public/assets/i18n'; $langFiles = []; if (is_dir($i18nDir)) { $langFiles = glob($i18nDir . '/*.json') ?: []; } $availableLangs = []; // Alle vorhandenen JSONs einsammeln foreach ($langFiles as $file) { $raw = @file_get_contents($file); if ($raw === false) { error_log('i18n: Konnte Datei nicht lesen: ' . $file); continue; } $json = json_decode($raw, true); if (!is_array($json)) { error_log('i18n: Ungültiges JSON in ' . $file . ' :: ' . json_last_error_msg()); continue; } // meta ist optional $meta = $json['meta'] ?? []; // Optional: Sprachen mit enabled=false ausblenden if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) { continue; } // Sprachcode bestimmen (meta.code oder Dateiname) $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)) { // Sonderdatei (z.B. template.json) ignorieren continue; } // Label: aus meta.label oder Fallback = strtoupper(code) $label = $meta['label'] ?? strtoupper($code); // Flag: ausschließlich aus meta.flag oder neutrale Flagge, // KEINE festen Mappings mehr für de/en/fr/it $flag = $meta['flag'] ?? '🏳️'; $availableLangs[$code] = [ 'code' => $code, 'label' => $label, 'flag' => $flag, ]; } // Falls keine Sprachdateien gefunden wurden → Minimal-Fallback if (empty($availableLangs)) { $availableLangs = [ 'en' => [ 'code' => 'en', 'label' => 'English', 'flag' => '🇬🇧', ], ]; } // ----------------------------------------------------------- // 3) Endgültige Sprache bestimmen (ohne harte Standardsprachen) // // Reihenfolge: // a) ?lang=xx → wenn gültig und in available // b) Browser-Sprache → wenn in available // c) 'en', wenn vorhanden // d) sonst: erste verfügbare Sprache // ----------------------------------------------------------- if ($lang && isset($availableLangs[$lang])) { // GET-Parameter ist gültig, nichts weiter tun } else { if ($browserLang && isset($availableLangs[$browserLang])) { $lang = $browserLang; } elseif (isset($availableLangs['en'])) { $lang = 'en'; } else { $keys = array_keys($availableLangs); $lang = $keys[0] ?? 'en'; } } // ----------------------------------------------------------- // 4) Aktive Sprachdatei laden // ----------------------------------------------------------- $activeLangFile = $i18nDir . '/' . $lang . '.json'; $activeLangData = []; if (is_readable($activeLangFile)) { $json = json_decode(@file_get_contents($activeLangFile), true); if (is_array($json)) { $activeLangData = $json; } } // ----------------------------------------------------------- // 5) Fallback-Sprache (EN), falls vorhanden // ----------------------------------------------------------- $fallbackLangData = []; $fallbackFile = $i18nDir . '/en.json'; if ($lang !== 'en' && is_readable($fallbackFile)) { $json = json_decode(@file_get_contents($fallbackFile), true); if (is_array($json)) { $fallbackLangData = $json; } } // ----------------------------------------------------------- // 6) Globale i18n-Struktur bereitstellen // ----------------------------------------------------------- $GLOBALS['lang'] = $lang; $GLOBALS['availableLangs'] = $availableLangs; $GLOBALS['i18n'] = [ 'current' => $activeLangData, 'fallback' => $fallbackLangData, ]; // ----------------------------------------------------------- // 7) Rest des Systems laden // ----------------------------------------------------------- require_once __DIR__ . "/db.php"; require_once __DIR__ . '/../src/functions.php';