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