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