205 lines
5.9 KiB
PHP
205 lines
5.9 KiB
PHP
<?php
|
|
|
|
// 0) Umgebung / Domains / Error-Level
|
|
require_once __DIR__ . "/config.php";
|
|
|
|
// -----------------------------------------------------------
|
|
// Session starten
|
|
// -----------------------------------------------------------
|
|
if (php_sapi_name() !== 'cli') {
|
|
if (session_status() === PHP_SESSION_NONE) {
|
|
|
|
session_name('usbcheck_session');
|
|
|
|
session_set_cookie_params([
|
|
'lifetime' => 0,
|
|
'path' => '/',
|
|
'domain' => '',
|
|
'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'),
|
|
'httponly' => true,
|
|
'samesite' => 'Lax',
|
|
]);
|
|
|
|
session_start();
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// Helper: Browser-Sprache aus HTTP_ACCEPT_LANGUAGE
|
|
// -----------------------------------------------------------
|
|
function usb_detect_browser_lang(array $availableLangs): ?string
|
|
{
|
|
if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE']) || empty($availableLangs)) {
|
|
return 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;
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 1) Sprache aus ?lang holen (nur 2-Buchstaben-Code validieren)
|
|
// -----------------------------------------------------------
|
|
$requestedLang = null;
|
|
|
|
if (isset($_GET['lang']) && is_string($_GET['lang'])) {
|
|
$tmp = strtolower($_GET['lang']);
|
|
if (preg_match('/^[a-z]{2}$/', $tmp)) {
|
|
$requestedLang = $tmp;
|
|
}
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 2) Verfügbare JSON-Sprachen aus /public/assets/i18n
|
|
// -----------------------------------------------------------
|
|
$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 = $json['meta'] ?? [];
|
|
|
|
// optional: meta.enabled === false → ausblenden (z.B. Templates)
|
|
if (array_key_exists('enabled', $meta) && $meta['enabled'] === false) {
|
|
continue;
|
|
}
|
|
|
|
// Sprachcode aus 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)) {
|
|
continue;
|
|
}
|
|
|
|
$label = $meta['label'] ?? strtoupper($code);
|
|
$flag = $meta['flag'] ?? '🏳️'; // Flag kommt primär aus JSON, sonst neutrale Flagge
|
|
|
|
$availableLangs[$code] = [
|
|
'code' => $code,
|
|
'label' => $label,
|
|
'flag' => $flag,
|
|
];
|
|
}
|
|
|
|
// Falls wirklich gar keine Sprachdatei existiert → Minimal-Fallback
|
|
if (empty($availableLangs)) {
|
|
$availableLangs = [
|
|
'en' => [
|
|
'code' => 'en',
|
|
'label' => 'English',
|
|
'flag' => '🏳️',
|
|
],
|
|
];
|
|
}
|
|
|
|
// -----------------------------------------------------------
|
|
// 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;
|
|
|
|
// 1) ?lang=xx (gültig & vorhanden)
|
|
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;
|
|
}
|
|
}
|
|
|
|
// 3) Wenn noch immer nichts → 'en', falls vorhanden
|
|
if ($lang === null && isset($availableLangs['en'])) {
|
|
$lang = 'en';
|
|
}
|
|
|
|
// 4) Wenn immer noch nichts → erste Sprache aus $availableLangs
|
|
if ($lang === null) {
|
|
$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.json), 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';
|