1*5f0c5114SCharles Chan<?php 2*5f0c5114SCharles Chan/** 3*5f0c5114SCharles Chan * 最小限度的搜索结果处理器 4*5f0c5114SCharles Chan */ 5*5f0c5114SCharles Chanclass SearchHelper { 6*5f0c5114SCharles Chan 7*5f0c5114SCharles Chan /** 8*5f0c5114SCharles Chan * 从ft_pageSearch结果中提取两个列表 9*5f0c5114SCharles Chan * 10*5f0c5114SCharles Chan * @param array $searchResults ft_pageSearch()返回的原始结果 11*5f0c5114SCharles Chan * @return array 包含两个列表的数组 12*5f0c5114SCharles Chan */ 13*5f0c5114SCharles Chan public function extractLists($searchResults, $maxLines = 3) { 14*5f0c5114SCharles Chan $links = []; 15*5f0c5114SCharles Chan $contents = []; 16*5f0c5114SCharles Chan 17*5f0c5114SCharles Chan foreach ($searchResults as $key => $result) { 18*5f0c5114SCharles Chan $normalized = $this->normalizeResult($result, $key); 19*5f0c5114SCharles Chan if (!$normalized) { 20*5f0c5114SCharles Chan continue; 21*5f0c5114SCharles Chan } 22*5f0c5114SCharles Chan 23*5f0c5114SCharles Chan // 1. 链接列表 24*5f0c5114SCharles Chan $links[] = $this->extractLinkInfo($normalized); 25*5f0c5114SCharles Chan 26*5f0c5114SCharles Chan // 2. 内容列表 27*5f0c5114SCharles Chan $contents[] = $this->extractContentInfo($normalized, $maxLines); 28*5f0c5114SCharles Chan } 29*5f0c5114SCharles Chan 30*5f0c5114SCharles Chan return [ 31*5f0c5114SCharles Chan 'links' => $links, 32*5f0c5114SCharles Chan 'contents' => $contents 33*5f0c5114SCharles Chan ]; 34*5f0c5114SCharles Chan } 35*5f0c5114SCharles Chan 36*5f0c5114SCharles Chan /** 37*5f0c5114SCharles Chan * 提取链接信息 38*5f0c5114SCharles Chan */ 39*5f0c5114SCharles Chan private function extractLinkInfo($result) { 40*5f0c5114SCharles Chan return [ 41*5f0c5114SCharles Chan 'id' => $result['id'], 42*5f0c5114SCharles Chan 'title' => $this->getPageTitle($result['id']), 43*5f0c5114SCharles Chan 'url' => wl($result['id']), 44*5f0c5114SCharles Chan 'score' => $result['score'] ?? 0, 45*5f0c5114SCharles Chan 'namespace' => getNS($result['id']) 46*5f0c5114SCharles Chan ]; 47*5f0c5114SCharles Chan } 48*5f0c5114SCharles Chan 49*5f0c5114SCharles Chan /** 50*5f0c5114SCharles Chan * 提取内容信息 51*5f0c5114SCharles Chan */ 52*5f0c5114SCharles Chan private function extractContentInfo($result, $maxLines = 3) { 53*5f0c5114SCharles Chan return [ 54*5f0c5114SCharles Chan 'id' => $result['id'], 55*5f0c5114SCharles Chan 'summary' => $this->getFirstLines($result['id'], $maxLines), 56*5f0c5114SCharles Chan 'has_content' => page_exists($result['id']) 57*5f0c5114SCharles Chan ]; 58*5f0c5114SCharles Chan } 59*5f0c5114SCharles Chan 60*5f0c5114SCharles Chan /** 61*5f0c5114SCharles Chan * 兼容不同格式的搜索结果 62*5f0c5114SCharles Chan */ 63*5f0c5114SCharles Chan private function normalizeResult($result, $key = null) { 64*5f0c5114SCharles Chan // 结果可能是字符串(页面ID) 65*5f0c5114SCharles Chan if (is_string($result) && $result !== '') { 66*5f0c5114SCharles Chan return ['id' => $result, 'score' => 0]; 67*5f0c5114SCharles Chan } 68*5f0c5114SCharles Chan 69*5f0c5114SCharles Chan // 结果可能是数组,但键名不一致 70*5f0c5114SCharles Chan if (is_array($result)) { 71*5f0c5114SCharles Chan if (!empty($result['id'])) { 72*5f0c5114SCharles Chan return $result; 73*5f0c5114SCharles Chan } 74*5f0c5114SCharles Chan if (!empty($result['page'])) { 75*5f0c5114SCharles Chan $result['id'] = $result['page']; 76*5f0c5114SCharles Chan return $result; 77*5f0c5114SCharles Chan } 78*5f0c5114SCharles Chan if (!empty($result[0]) && is_string($result[0])) { 79*5f0c5114SCharles Chan return ['id' => $result[0], 'score' => $result['score'] ?? 0]; 80*5f0c5114SCharles Chan } 81*5f0c5114SCharles Chan } 82*5f0c5114SCharles Chan 83*5f0c5114SCharles Chan // 结果可能是标量分数,ID 在 key 上 84*5f0c5114SCharles Chan if (is_string($key) && $key !== '') { 85*5f0c5114SCharles Chan return ['id' => $key, 'score' => is_numeric($result) ? $result : 0]; 86*5f0c5114SCharles Chan } 87*5f0c5114SCharles Chan 88*5f0c5114SCharles Chan return null; 89*5f0c5114SCharles Chan } 90*5f0c5114SCharles Chan 91*5f0c5114SCharles Chan /** 92*5f0c5114SCharles Chan * 获取页面标题 93*5f0c5114SCharles Chan */ 94*5f0c5114SCharles Chan private function getPageTitle($pageId) { 95*5f0c5114SCharles Chan $title = p_get_first_heading($pageId); 96*5f0c5114SCharles Chan return $title ?: $pageId; 97*5f0c5114SCharles Chan } 98*5f0c5114SCharles Chan 99*5f0c5114SCharles Chan /** 100*5f0c5114SCharles Chan * 获取页面前几行作为摘要 101*5f0c5114SCharles Chan */ 102*5f0c5114SCharles Chan private function getFirstLines($pageId, $maxLines = 3) { 103*5f0c5114SCharles Chan if (!page_exists($pageId)) { 104*5f0c5114SCharles Chan return ''; 105*5f0c5114SCharles Chan } 106*5f0c5114SCharles Chan 107*5f0c5114SCharles Chan $content = rawWiki($pageId); 108*5f0c5114SCharles Chan if ($maxLines === 0) { 109*5f0c5114SCharles Chan return $content; 110*5f0c5114SCharles Chan } 111*5f0c5114SCharles Chan 112*5f0c5114SCharles Chan $lines = explode("\n", $content, $maxLines + 1); 113*5f0c5114SCharles Chan return implode("\n", array_slice($lines, 0, $maxLines)); 114*5f0c5114SCharles Chan } 115*5f0c5114SCharles Chan 116*5f0c5114SCharles Chan /** 117*5f0c5114SCharles Chan * 使用示例 118*5f0c5114SCharles Chan */ 119*5f0c5114SCharles Chan public function exampleUsage($searchQuery) { 120*5f0c5114SCharles Chan // 1. 执行搜索 121*5f0c5114SCharles Chan $rawResults = ft_pageSearch($searchQuery); 122*5f0c5114SCharles Chan 123*5f0c5114SCharles Chan // 2. 提取两个列表 124*5f0c5114SCharles Chan $lists = $this->extractLists($rawResults); 125*5f0c5114SCharles Chan 126*5f0c5114SCharles Chan // 3. 返回结果 127*5f0c5114SCharles Chan return $lists; 128*5f0c5114SCharles Chan } 129*5f0c5114SCharles Chan} 130