'Main', 'epg_url' => $existing['epg_url'], 'm3u_url' => $existing['m3u_url'] ?? '', ]]; $existing['allow_personal_epg'] = false; unset($existing['epg_url'], $existing['m3u_url']); file_put_contents($config_path, json_encode($existing, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); } // Bootstrap an admin key for older configs that do not have one yet. if (empty($existing['admin_key'])) { $existing['admin_key'] = bin2hex(random_bytes(16)); file_put_contents($config_path, json_encode($existing, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); } } $is_first_setup = !file_exists($config_path); $existing = $is_first_setup ? [] : json_decode(file_get_contents($config_path), true); $admin_key = $existing['admin_key'] ?? null; $mode = 'setup'; $error = ''; $new_key = ''; if (!$is_first_setup) { if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['admin_key_input'])) { if (trim($_POST['admin_key_input']) === $admin_key) { $mode = 'setup'; } else { $mode = 'lock'; $error = 'Invalid admin key.'; } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['group_name'])) { if (trim($_POST['admin_key_hidden'] ?? '') !== $admin_key) { $mode = 'lock'; $error = 'Invalid admin key.'; } else { $mode = 'setup'; } } else { $mode = 'lock'; } } if ($mode === 'setup' && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['group_name'])) { $group_name = trim($_POST['group_name'] ?? ''); $allow_personal_epg = isset($_POST['allow_personal_epg']); $names = $_POST['source_name'] ?? []; $epg_urls = $_POST['source_epg_url'] ?? []; $m3u_urls = $_POST['source_m3u_url'] ?? []; $epg_sources = []; foreach ($names as $i => $name) { $epg_url = trim($epg_urls[$i] ?? ''); $m3u_url = trim($m3u_urls[$i] ?? ''); if (empty($epg_url)) continue; if (!filter_var($epg_url, FILTER_VALIDATE_URL)) { $error = "Invalid EPG URL for source \"$name\"."; break; } if (!empty($m3u_url) && !filter_var($m3u_url, FILTER_VALIDATE_URL)) { $error = "Invalid M3U URL for source \"$name\"."; break; } $epg_sources[] = [ 'name' => trim($name) ?: 'Source ' . ($i + 1), 'epg_url' => $epg_url, 'm3u_url' => $m3u_url, ]; } if (empty($error)) { if (empty($group_name)) { $error = 'Group name is required.'; } elseif (empty($epg_sources)) { $error = 'At least one EPG source is required.'; } else { $new_key = $is_first_setup ? strtoupper(bin2hex(random_bytes(8))) : $admin_key; $config = [ 'group_name' => $group_name, 'epg_sources' => $epg_sources, 'allow_personal_epg' => $allow_personal_epg, 'admin_key' => $new_key, ]; $written = file_put_contents($config_path, json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); if ($written === false) { $error = 'Cannot write config.json. Check permissions (chmod 775 .).'; } else { $mode = 'success'; } } } } $prefill_group = $_POST['group_name'] ?? $existing['group_name'] ?? ''; $prefill_sources = $existing['epg_sources'] ?? []; $prefill_epg = !empty($existing['allow_personal_epg']); $submitted_key = trim($_POST['admin_key_input'] ?? $_POST['admin_key_hidden'] ?? ''); ?>
config.json.config.json on the server.
This file is excluded from the Git repository (.gitignore).