From 90679e9221f9cc960a556033b10ba68bb5064acc Mon Sep 17 00:00:00 2001 From: Johnnybegood90 Date: Sat, 14 Mar 2026 13:08:33 +0100 Subject: [PATCH] Auto-discover locales and harden JSON config loading - discover available locale files dynamically instead of relying on a hardcoded language list - make config JSON decoding more defensive to avoid null-state failures on invalid or empty data - improve startup resilience when configuration files are missing or malformed --- setup.php | 13 +++++++++++-- src/config.php | 15 +++++++++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/setup.php b/setup.php index fd96b3b..6c9eb91 100644 --- a/setup.php +++ b/setup.php @@ -3,7 +3,7 @@ $config_path = __DIR__ . '/config.json'; // Automatically migrate the legacy config format. if (file_exists($config_path)) { - $existing = json_decode(file_get_contents($config_path), true); + $existing = json_decode(file_get_contents($config_path), true) ?? []; if (isset($existing['epg_url']) && !isset($existing['epg_sources'])) { $existing['epg_sources'] = [[ 'name' => 'Main', @@ -22,7 +22,16 @@ if (file_exists($config_path)) { } $is_first_setup = !file_exists($config_path); -$existing = $is_first_setup ? [] : json_decode(file_get_contents($config_path), true); +$existing = []; +$corrupt_config = false; +if (!$is_first_setup) { + $existing = json_decode(file_get_contents($config_path), true) ?? []; + if (!is_array($existing)) { + $existing = []; + $corrupt_config = true; + $is_first_setup = true; + } +} $admin_key = $existing['admin_key'] ?? null; $mode = 'setup'; diff --git a/src/config.php b/src/config.php index d5f9fed..e0c67f8 100644 --- a/src/config.php +++ b/src/config.php @@ -8,6 +8,10 @@ if (!file_exists($config_path)) { } $config = json_decode(file_get_contents($config_path), true); +if (!is_array($config)) { + http_response_code(500); + die('

GridTV — Configuration error

config.json is invalid or corrupted.
Please delete it and re-run setup, or fix it manually via SSH.

'); +} // ── Automatically migrate the legacy config format to the current one ───────── if (isset($config['epg_url']) && !isset($config['epg_sources'])) { @@ -32,15 +36,22 @@ $epg_url = htmlspecialchars($first_source['epg_url'] ?? ''); $m3u_url = htmlspecialchars($first_source['m3u_url'] ?? ''); // ── Locale detection ───────────────────────────────────────────────────────── -$supported_locales = ['en', 'fr', 'es']; +// Auto-discover available locales from the locales/ directory. +$locale_files = glob(__DIR__ . '/../locales/*.json') ?: []; +$supported_locales = array_map(fn($f) => basename($f, '.json'), $locale_files); $locale = 'en'; $accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? 'en'; foreach (explode(',', $accept) as $lang) { $code = strtolower(substr(trim($lang), 0, 2)); - if (in_array($code, $supported_locales)) { $locale = $code; break; } + if (in_array($code, $supported_locales, true)) { $locale = $code; break; } } $locale_path = __DIR__ . "/../locales/{$locale}.json"; $L = json_decode(file_get_contents($locale_path), true); +if (!is_array($L)) { + // Fallback to English if the locale file is missing or corrupted. + $fallback_path = __DIR__ . '/../locales/en.json'; + $L = is_file($fallback_path) ? (json_decode(file_get_contents($fallback_path), true) ?? []) : []; +} // ───────────────────────────────────────────────────────────────────────────── ?>