xref: /plugin/ragasker/SearchHelper.php (revision 5f0c5114d87f8140fd00a9b6f05655e54e173dde)
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