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