\$row ? (string) \$row->source_url : ''", "'update_time' => time()", "->whereNull('delete_time')", "->order('create_time', 'asc')", "->order('id', 'asc')", "\$row['default_play_url'] = \$row['stream_options'][0]['url'] ?? '';", "if (\$url === '')", ]; foreach ($requiredSnippets as $needle) { if (strpos($service, $needle) === false) { fwrite(STDERR, "missing service token: {$needle}\n"); exit(1); } } $whereNullCount = substr_count($service, "->whereNull('delete_time')"); if ($whereNullCount < 2) { fwrite(STDERR, "missing explicit delete_time guard on both queries\n"); exit(1); } if (!is_file($apiControllerPath)) { fwrite(STDERR, "missing api controller file\n"); exit(1); } $apiController = file_get_contents($apiControllerPath); foreach ([ "'live_list'", 'MatchLiveService::getLiveListForApi', ] as $needle) { if (strpos($apiController, $needle) === false) { fwrite(STDERR, "missing api controller token: {$needle}\n"); exit(1); } } if (!is_file($adminLogicPath)) { fwrite(STDERR, "missing admin logic file\n"); exit(1); } $adminLogic = file_get_contents($adminLogicPath); if (strpos($adminLogic, "'live_url'") !== false) { fwrite(STDERR, "match admin logic still manually allows live_url\n"); exit(1); } if (!is_file($listsPath)) { fwrite(STDERR, "missing match live lists file\n"); exit(1); } $lists = file_get_contents($listsPath); foreach ([ "\$matchId = (int) (\$this->params['match_id'] ?? 0);", "if (\$matchId <= 0) {", "\$query->where('match_id', 0);", ] as $needle) { if (strpos($lists, $needle) === false) { fwrite(STDERR, "missing lists guard token: {$needle}\n"); exit(1); } } if (!is_file($matchLiveLogicPath)) { fwrite(STDERR, "missing match live logic file\n"); exit(1); } $matchLiveLogic = file_get_contents($matchLiveLogicPath); foreach ([ "'play_url_m3u8' => ''", "'play_url_hd_m3u8' => ''", "'play_url_flv' => ''", "'play_url_hd_flv' => ''", "'fetch_status' => 0", "'fetch_error' => ''", "'last_fetch_at' => 0", "'next_fetch_at' => \$now", ] as $needle) { if (strpos($matchLiveLogic, $needle) === false) { fwrite(STDERR, "missing match live logic reset token: {$needle}\n"); exit(1); } } if (!is_file($validatePath)) { fwrite(STDERR, "missing match live validate file\n"); exit(1); } $validate = file_get_contents($validatePath); foreach ([ 'checkTrimmedTitle', 'checkTrimmedSourceUrl', '$value = trim((string) $value);', ] as $needle) { if (strpos($validate, $needle) === false) { fwrite(STDERR, "missing trimmed validation token: {$needle}\n"); exit(1); } } $childLivePos = strpos($apiController, "!empty(\$data['live_list'][0]['source_url'])"); $worldCupFallbackPos = strpos($apiController, "if (empty(\$data['live_url']) && \$this->isWorldCupMatch(\$data))"); if ($childLivePos === false || $worldCupFallbackPos === false || $childLivePos >= $worldCupFallbackPos) { fwrite(STDERR, "match detail live_url fallback order mismatch\n"); exit(1); } $orderedOptionSnippets = [ "['label' => 'M3U8', 'field' => 'play_url_m3u8']", "['label' => 'HD M3U8', 'field' => 'play_url_hd_m3u8']", "['label' => 'FLV', 'field' => 'play_url_flv']", "['label' => 'HD FLV', 'field' => 'play_url_hd_flv']", ]; $lastPos = -1; foreach ($orderedOptionSnippets as $snippet) { $pos = strpos($service, $snippet); if ($pos === false) { fwrite(STDERR, "missing ordered stream option snippet: {$snippet}\n"); exit(1); } if ($pos <= $lastPos) { fwrite(STDERR, "stream option order mismatch\n"); exit(1); } $lastPos = $pos; } echo "service static checks passed\n";