1<?php
2
3/**
4 * DokuWiki Plugin elasticsearch (Form Helper Component)
5 *
6 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html
7 * @author  Andreas Gohr <gohr@cosmocode.de>
8 * @author  Anna Dabrowska <dabrowska@cosmocode.de>
9 */
10
11use dokuwiki\Extension\Plugin;
12use dokuwiki\Form\Form;
13
14/**
15 * Search form helper
16 */
17class helper_plugin_elasticsearch_form extends Plugin
18{
19    /**
20     * Replacement for the standard search form
21     *
22     * @param array $aggregations
23     */
24    public function tpl($aggregations)
25    {
26        global $lang;
27        global $QUERY;
28
29        $searchForm = (new Form(['method' => 'get'], true))->addClass('search-results-form');
30        $searchForm->setHiddenField('do', 'search');
31
32        $searchForm->addFieldsetOpen()->addClass('search-form');
33        $searchForm->addTextInput('q')->val($QUERY)->useInput(false);
34        $searchForm->addButton('', $lang['btn_search'])->attr('type', 'submit');
35
36        $this->addAdvancedSearch($searchForm, $aggregations);
37
38        $searchForm->addFieldsetClose();
39
40        echo $searchForm->toHTML();
41    }
42
43    /**
44     * Advanced search
45     *
46     * @param Form $searchForm
47     * @param array $aggregations
48     */
49    protected function addAdvancedSearch(Form $searchForm, array $aggregations)
50    {
51        $searchForm->addTagOpen('div')
52            ->addClass('advancedOptions')
53            ->attr('style', 'display: none;')
54            ->attr('aria-hidden', 'true');
55
56        foreach ($aggregations as $term => $aggregation) {
57            // keep canonical 'ns' search parameter for namespaces
58            $param = $term === 'namespace' ? 'ns' : $term;
59            $this->addCheckboxSelector($searchForm, $aggregation['buckets'], $param);
60        }
61        $this->addDateSelector($searchForm);
62        $this->addLanguageSelector($searchForm);
63        $searchForm->addTagClose('div');
64    }
65
66    /**
67     * Filter with checkboxes
68     *
69     * @param Form $searchForm
70     * @param array $aggregations Namespace aggregations
71     * @param string $param Prefix to use in input names
72     */
73    protected function addCheckboxSelector(Form $searchForm, array $aggregations, $param)
74    {
75        if ($aggregations !== []) {
76            $pluginSearchConfigs = \action_plugin_elasticsearch_search::getRawPluginSearchConfigs();
77            $selectorId = empty($pluginSearchConfigs[$param]['id'])
78                ? 'plugin__elasticsearch-' . $param
79                : $pluginSearchConfigs[$param]['id'];
80
81            $searchForm->addTagOpen('div')
82                ->addClass('toggle')
83                ->id($selectorId)
84                ->attr('aria-haspopup', 'true');
85
86            // popup toggler
87            $searchForm->addTagOpen('div')->addClass('current');
88            $label = $param === 'ns' ? $this->getLang('nsp') : $pluginSearchConfigs[$param]['label'];
89            $searchForm->addHTML($label);
90            $searchForm->addTagClose('div');
91
92            // options
93            $i = 0;
94            $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
95            foreach ($aggregations as $agg) {
96                $searchForm->addTagOpen('li');
97                $searchForm->addCheckbox($param . '[]')->val($agg['key'])->id("__$param-" . $i);
98                $searchForm->addLabel(shorten('', $agg['key'], 25) . ' (' . $agg['doc_count'] . ')', "__$param-" . $i)
99                    ->attr('title', $agg['key']);
100                $searchForm->addTagClose('li');
101                $i++;
102            }
103            $searchForm->addTagClose('ul');
104
105            $searchForm->addTagClose('div');
106        }
107    }
108
109    /**
110     * Date range filter
111     *
112     * @param Form $searchForm
113     */
114    protected function addDateSelector(Form $searchForm)
115    {
116        global $lang;
117
118        $options = [
119            'any' => $lang['search_any_time'],
120            'week' =>  $lang['search_past_7_days'],
121            'month' => $lang['search_past_month'],
122            'year' => $lang['search_past_year'],
123        ];
124
125        $searchForm->addTagOpen('div')->addClass('toggle')->attr('aria-haspopup', 'true');
126
127        // popup toggler
128        $searchForm->addTagOpen('div')->addClass('current');
129        $searchForm->addHTML($this->getLang('lastmod'));
130        $searchForm->addTagClose('div');
131
132        // options
133        $i = 0;
134        $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
135        foreach ($options as $opt => $label) {
136            $searchForm->addTagOpen('li');
137            $searchForm->addRadioButton('min')->val($opt)->id('__min-' . $i);
138            $searchForm->addLabel($label, '__min-' . $i);
139            $searchForm->addTagClose('li');
140            $i++;
141        }
142        $searchForm->addTagClose('ul');
143
144        $searchForm->addTagClose('div');
145    }
146
147    /**
148     * Language filter based on the translation plugin
149     *
150     * @param Form $searchForm
151     */
152    protected function addLanguageSelector(Form $searchForm)
153    {
154        /** @var helper_plugin_translation $transplugin */
155        $transplugin = plugin_load('helper', 'translation');
156        if (!$transplugin) return;
157
158        $translations = $transplugin->translations;
159        if (empty($translations)) return;
160
161        $searchForm->addTagOpen('div')
162            ->addClass('toggle')
163            ->id('plugin__elasticsearch-lang')
164            ->attr('aria-haspopup', 'true');
165
166        // popup toggler
167        $searchForm->addTagOpen('div')->addClass('current');
168        $label = $this->getLang('lang');
169        $searchForm->addHTML($label);
170        $searchForm->addTagClose('div');
171
172        // options
173        $i = 0;
174        $searchForm->addTagOpen('ul')->attr('aria-expanded', 'false');
175        foreach ($translations as $lang) {
176            $searchForm->addTagOpen('li');
177            $searchForm->addCheckbox('lang[]')->val($lang)->id("__lang-" . $i);
178            $searchForm->addLabel($lang, "__lang-" . $i)
179                ->attr('title', $lang);
180            $searchForm->addTagClose('li');
181            $i++;
182        }
183        $searchForm->addTagClose('ul');
184        $searchForm->addTagClose('div');
185    }
186}
187