'SAMIR', 'nizer' => 'NIZER', 'good' => 'GOOD', 'cris' => 'CRIS', ]; function normalizeChannelUrl(string $url): string { $url = trim($url); return preg_replace('/\.ts($|\?)/i', '$1', $url); } function normalizeSearchText(string $text): string { $text = trim(mb_strtolower($text, 'UTF-8')); $converted = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $text); if ($converted !== false) { $text = $converted; } $text = strtolower($text); $text = preg_replace('/[^a-z0-9]+/', '', $text); return $text ?? ''; } function startsWithText(string $text, string $search): bool { if ($search === '') return false; return substr($text, 0, strlen($search)) === $search; } function isValidLogoUrl(string $url): bool { $url = trim($url); if ($url === '') { return false; } return preg_match('#^https?://#i', $url) === 1; } function hasValidAccess(string $accessPassword): bool { $key = isset($_REQUEST['key']) ? (string)$_REQUEST['key'] : ''; return $key !== '' && hash_equals($accessPassword, $key); } function loadChannelsFromJson(string $jsonFile): array { if (!file_exists($jsonFile)) { return []; } $content = file_get_contents($jsonFile); if ($content === false || trim($content) === '') { return []; } $data = json_decode($content, true); if (!is_array($data)) { return []; } $items = []; foreach ($data as $rec) { if (!is_array($rec)) { continue; } $lista = isset($rec['lista_name']) ? trim((string)$rec['lista_name']) : ''; $name = isset($rec['name_chanel']) ? trim((string)$rec['name_chanel']) : ''; $link = isset($rec['link_chanel']) ? trim((string)$rec['link_chanel']) : ''; $id = isset($rec['id_chanel']) ? trim((string)$rec['id_chanel']) : ''; $logo = isset($rec['logo_chanel']) ? trim((string)$rec['logo_chanel']) : ''; if ($lista === '' || $link === '') { continue; } $items[] = [ 'lista_name' => $lista, 'name_chanel' => $name !== '' ? $name : 'Sem nome', 'link_chanel' => normalizeChannelUrl($link), 'id_chanel' => $id, 'logo_chanel' => isValidLogoUrl($logo) ? $logo : '', 'search_name' => normalizeSearchText($name), 'search_id' => normalizeSearchText($id), ]; } return $items; } function groupChannelsByList(array $items, array $columnOrder): array { $grouped = []; foreach ($columnOrder as $key => $label) { $grouped[$label] = []; } foreach ($items as $item) { $listKey = mb_strtolower(trim((string)$item['lista_name']), 'UTF-8'); if (!isset($columnOrder[$listKey])) { continue; } $label = $columnOrder[$listKey]; $grouped[$label][] = [ 'name' => $item['name_chanel'], 'url' => $item['link_chanel'], 'id' => $item['id_chanel'], 'logo' => $item['logo_chanel'], 'lista_name' => $item['lista_name'], ]; } return $grouped; } if (isset($_GET['logout']) && $_GET['logout'] == '1') { header('Location: ./'); exit; } if (isset($_GET['api']) && $_GET['api'] === 'search') { header('Content-Type: application/json; charset=UTF-8'); if (!hasValidAccess($accessPassword)) { http_response_code(401); echo json_encode([ 'success' => false, 'message' => 'Não autorizado.' ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } $query = isset($_GET['q']) ? trim((string)$_GET['q']) : ''; $queryNormalized = normalizeSearchText($query); $allChannels = loadChannelsFromJson($jsonFile); if ($queryNormalized !== '') { $scored = []; foreach ($allChannels as $item) { $name = $item['search_name'] ?? ''; $id = $item['search_id'] ?? ''; $matched = false; $score = 999; if ($name !== '' && startsWithText($name, $queryNormalized)) { $score = 1; $matched = true; } elseif ($id !== '' && startsWithText($id, $queryNormalized)) { $score = 2; $matched = true; } elseif ($name !== '' && strpos($name, $queryNormalized) !== false) { $score = 3; $matched = true; } elseif ($id !== '' && strpos($id, $queryNormalized) !== false) { $score = 4; $matched = true; } if ($matched) { $item['_score'] = $score; $scored[] = $item; } } usort($scored, function ($a, $b) { $scoreCompare = ($a['_score'] ?? 999) <=> ($b['_score'] ?? 999); if ($scoreCompare !== 0) { return $scoreCompare; } $nameCompare = strcasecmp($a['name_chanel'] ?? '', $b['name_chanel'] ?? ''); if ($nameCompare !== 0) { return $nameCompare; } return strcasecmp($a['id_chanel'] ?? '', $b['id_chanel'] ?? ''); }); $allChannels = $scored; } $result = groupChannelsByList($allChannels, $columnOrder); echo json_encode([ 'success' => true, 'query' => $query, 'data' => $result, ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } $loginError = ''; $hasAccess = hasValidAccess($accessPassword); if (!$hasAccess && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['panel_password'])) { $postedPassword = (string)($_POST['panel_password'] ?? ''); if (hash_equals($accessPassword, $postedPassword)) { header('Location: ./?key=' . urlencode($postedPassword)); exit; } else { $loginError = 'Senha incorreta.'; } } if (!$hasAccess): ?> Acesso ao Painel
Painel protegido
Digite a senha para acessar
Painel JSON Canais
Sair
Digite para pesquisar no JSON por nome ou ID.