xref: /dokuwiki/inc/Ui/Search.php (revision 21fcef82b754bee0920be30454d93aca097b5b00)
1<?php
2
3namespace dokuwiki\Ui;
4
5class Search extends Ui
6{
7    protected $query;
8    protected $pageLookupResults = array();
9    protected $fullTextResults = array();
10    protected $highlight = array();
11
12    /**
13     * Search constructor.
14     *
15     * @param string $query the search query
16     */
17    public function __construct($query)
18    {
19        $this->query = $query;
20    }
21
22    /**
23     * run the search
24     */
25    public function execute()
26    {
27        $this->pageLookupResults = ft_pageLookup($this->query, true, useHeading('navigation'));
28        $this->fullTextResults = ft_pageSearch($this->query, $highlight);
29        $this->highlight = $highlight;
30    }
31
32    /**
33     * display the search result
34     *
35     * @return void
36     */
37    public function show()
38    {
39        $searchHTML = '';
40
41        $searchHTML .= $this->getSearchIntroHTML($this->query);
42
43        $searchHTML .= $this->getPageLookupHTML($this->pageLookupResults);
44
45        $searchHTML .= $this->getFulltextResultsHTML($this->fullTextResults, $this->highlight);
46
47        echo $searchHTML;
48    }
49
50    /**
51     * Build the intro text for the search page
52     *
53     * @param string $query the search query
54     *
55     * @return string
56     */
57    protected function getSearchIntroHTML($query)
58    {
59        global $ID, $lang;
60
61        $intro = p_locale_xhtml('searchpage');
62        // allow use of placeholder in search intro
63        $pagecreateinfo = (auth_quickaclcheck($ID) >= AUTH_CREATE) ? $lang['searchcreatepage'] : '';
64        $intro = str_replace(
65            array('@QUERY@', '@SEARCH@', '@CREATEPAGEINFO@'),
66            array(hsc(rawurlencode($query)), hsc($query), $pagecreateinfo),
67            $intro
68        );
69        return $intro;
70    }
71
72
73    /**
74     * Build HTML for a list of pages with matching pagenames
75     *
76     * @param array $data search results
77     *
78     * @return string
79     */
80    protected function getPageLookupHTML($data)
81    {
82        if (empty($data)) {
83            return '';
84        }
85
86        global $lang;
87
88        $html = '<div class="search_quickresult">';
89        $html .= '<h3>' . $lang['quickhits'] . ':</h3>';
90        $html .= '<ul class="search_quickhits">';
91        foreach ($data as $id => $title) {
92            $html .= '<li> ';
93            if (useHeading('navigation')) {
94                $name = $title;
95            } else {
96                $ns = getNS($id);
97                if ($ns) {
98                    $name = shorten(noNS($id), ' (' . $ns . ')', 30);
99                } else {
100                    $name = $id;
101                }
102            }
103            $html .= html_wikilink(':' . $id, $name);
104            $html .= '</li> ';
105        }
106        $html .= '</ul> ';
107        //clear float (see http://www.complexspiral.com/publications/containing-floats/)
108        $html .= '<div class="clearer"></div>';
109        $html .= '</div>';
110
111        return $html;
112    }
113
114    /**
115     * Build HTML for fulltext search results or "no results" message
116     *
117     * @param array $data      the results of the fulltext search
118     * @param array $highlight the terms to be highlighted in the results
119     *
120     * @return string
121     */
122    protected function getFulltextResultsHTML($data, $highlight)
123    {
124        global $lang;
125
126        if (empty($data)) {
127            return '<div class="nothing">' . $lang['nothingfound'] . '</div>';
128        }
129
130        $html = '';
131        $html .= '<dl class="search_results">';
132        $num = 1;
133        foreach ($data as $id => $cnt) {
134            $html .= '<dt>';
135            $html .= html_wikilink(':' . $id, useHeading('navigation') ? null : $id, $highlight);
136            if ($cnt !== 0) {
137                $html .= ': ' . $cnt . ' ' . $lang['hits'] . '';
138            }
139            $html .= '</dt>';
140            if ($cnt !== 0) {
141                if ($num < FT_SNIPPET_NUMBER) { // create snippets for the first number of matches only
142                    $html .= '<dd>' . ft_snippet($id, $highlight) . '</dd>';
143                }
144                $num++;
145            }
146        }
147        $html .= '</dl>';
148
149        return $html;
150    }
151}
152