1 | <?php |
||
2 | /* For licensing terms, see /license.txt */ |
||
3 | /** |
||
4 | * Search widget. Shows the search screen contents. |
||
5 | * |
||
6 | * @package chamilo.include.search |
||
7 | */ |
||
8 | require_once api_get_path(LIBRARY_PATH).'specific_fields_manager.lib.php'; |
||
9 | |||
10 | /** |
||
11 | * Add some required CSS and JS to html's head. |
||
12 | * |
||
13 | * Note that $htmlHeadXtra should be passed by reference and not value, |
||
14 | * otherwise this function will have no effect and your form will be broken. |
||
15 | * |
||
16 | * @param array $htmlHeadXtra A reference to the doc $htmlHeadXtra |
||
17 | */ |
||
18 | function search_widget_prepare(&$htmlHeadXtra) |
||
19 | { |
||
20 | $htmlHeadXtra[] = ' |
||
21 | <!-- script type="text/javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.autocomplete.js"></script --> |
||
22 | <script type="text/javascript" src="'.api_get_path(WEB_LIBRARY_PATH).'search/search_widget.js"></script> |
||
23 | <link rel="stylesheet" type="text/css" href="'.api_get_path(WEB_LIBRARY_PATH).'javascript/jquery.autocomplete.css" /> |
||
24 | <link rel="stylesheet" type="text/css" href="'.api_get_path(WEB_LIBRARY_PATH).'search/search_widget.css" />'; |
||
25 | } |
||
26 | |||
27 | /** |
||
28 | * Get one term html select. |
||
29 | */ |
||
30 | function format_one_specific_field_select($prefix, $sf_term_array, $op, $extra_select_attr = 'size="7" class="sf-select-multiple"') |
||
31 | { |
||
32 | global $charset; |
||
33 | $multiple_select = '<select '.$extra_select_attr.' title="'.$prefix.'" id="sf-'.$prefix.'" name="sf_'.$prefix.'[]">'; |
||
34 | |||
35 | $all_selected = ''; |
||
36 | if (!empty($_REQUEST['sf_'.$prefix])) { |
||
37 | if (in_array('__all__', $_REQUEST['sf_'.$prefix])) { |
||
38 | $all_selected = 'selected="selected"'; |
||
39 | } |
||
40 | } |
||
41 | if ($op == 'and') { |
||
42 | $all_selected_name = get_lang('All'); |
||
43 | } elseif ($op == 'or') { |
||
44 | $all_selected_name = get_lang('Any'); |
||
45 | } |
||
46 | $multiple_select .= '<option value="__all__" '.$all_selected.' >-- '.$all_selected_name.' --</option>'; |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Loading history...
|
|||
47 | |||
48 | foreach ($sf_term_array as $raw_term) { |
||
49 | $term = substr($raw_term, 1); |
||
50 | if (empty($term)) { |
||
51 | continue; |
||
52 | } |
||
53 | $html_term = htmlspecialchars($term, ENT_QUOTES, $charset); |
||
54 | $selected = ''; |
||
55 | if (!empty($_REQUEST['sf_'.$prefix]) && is_array($_REQUEST['sf_'.$prefix]) && in_array($term, $_REQUEST['sf_'.$prefix])) { |
||
56 | $selected = 'selected="selected"'; |
||
57 | } |
||
58 | $multiple_select .= '<option value="'.$html_term.'" '.$selected.'>'.$html_term.'</option>'; |
||
59 | } |
||
60 | $multiple_select .= '</select>'; |
||
61 | |||
62 | return $multiple_select; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Get terms html selects. |
||
67 | */ |
||
68 | function format_specific_fields_selects($sf_terms, $op, $prefilter_prefix = '') |
||
69 | { |
||
70 | // Process each prefix type term |
||
71 | $i = 0; |
||
72 | $max = count($sf_terms); |
||
73 | $multiple_selects = ''; |
||
74 | foreach ($sf_terms as $prefix => $sf_term_array) { |
||
75 | if ($prefix == $prefilter_prefix) { |
||
76 | continue; |
||
77 | } |
||
78 | $multiple_select = ''; |
||
79 | if ($i > 0) { |
||
80 | //print "+" image |
||
81 | $multiple_select .= '<td><img class="sf-select-splitter" src="../img/search-big-plus.gif" alt="plus-sign-decoration"/></td>'; |
||
82 | } |
||
83 | //sorting the array of terms |
||
84 | $temp = []; |
||
85 | if (!empty($sf_term_array)) { |
||
86 | foreach ($sf_term_array as $key => $value) { |
||
87 | $temp[trim(stripslashes($value['name']))] = $key; |
||
88 | } |
||
89 | } |
||
90 | $temp = array_flip($temp); |
||
91 | unset($sf_term_array); |
||
92 | natcasesort($temp); |
||
93 | $sf_term_array = $temp; |
||
94 | |||
95 | $sf_copy = $sf_term_array; |
||
96 | // get specific field name |
||
97 | $sf_value = get_specific_field_list(['code' => "'$prefix'"]); |
||
98 | $sf_value = array_shift($sf_value); |
||
99 | $multiple_select .= '<td><label class="sf-select-multiple-title" for="sf_'.$prefix.'[]">'.$sf_value['name'].'</label><br />'; |
||
100 | $multiple_select .= format_one_specific_field_select($prefix, $sf_term_array, $op, 'multiple="multiple" size="7" class="sf-select-multiple"'); |
||
101 | $multiple_select .= '</td>'; |
||
102 | $multiple_selects .= $multiple_select; |
||
103 | $i++; |
||
104 | } |
||
105 | |||
106 | return $multiple_selects; |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * Build the normal form. |
||
111 | * |
||
112 | * First, natural way. |
||
113 | */ |
||
114 | function search_widget_normal_form($action, $show_thesaurus, $sf_terms, $op) |
||
115 | { |
||
116 | $thesaurus_icon = Display::return_icon('thesaurus.gif', get_lang('SearchAdvancedOptions'), ['id' => 'thesaurus-icon']); |
||
117 | $advanced_options = '<a id="tags-toggle" href="#">'.get_lang('SearchAdvancedOptions').'</a>'; |
||
118 | $display_thesaurus = ($show_thesaurus == true ? 'block' : 'none'); |
||
119 | $help = '<h3>'.get_lang('SearchKeywordsHelpTitle').'</h3>'.get_lang('SearchKeywordsHelpComment'); |
||
120 | $mode = (!empty($_REQUEST['mode']) ? htmlentities($_REQUEST['mode']) : 'gallery'); |
||
121 | $type = (!empty($_REQUEST['type']) ? htmlentities($_REQUEST['type']) : 'normal'); |
||
122 | |||
123 | /** |
||
124 | * POST avoid long urls, but we are using GET because |
||
125 | * SortableTableFromArray pagination is done with simple links, so now we |
||
126 | * could not send a form in pagination. |
||
127 | */ |
||
128 | if (isset($_GET['action']) && strcmp(trim($_GET['action']), 'search') === 0) { |
||
129 | $action = 'index.php'; |
||
130 | } |
||
131 | $navigator_info = api_get_navigator(); |
||
132 | |||
133 | if ($navigator_info['name'] == 'Internet Explorer' && $navigator_info['version'] == '6') { |
||
134 | $submit_button1 = '<input type="submit" id="submit" value="'.get_lang('Search').'" />'; |
||
135 | $submit_button2 = '<input class="lower-submit" type="submit" value="'.get_lang('Search').'" />'; |
||
136 | $reset_button = '<input type="submit" id="tags-clean" value="'.get_lang('SearchResetKeywords').'" />'; |
||
137 | } else { |
||
138 | $submit_button1 = '<button class="search" type="submit" id="submit" value="'.get_lang("Search").'" /> '.get_lang('Search').'</button>'; |
||
139 | $submit_button2 = '<button class="search" type="submit" value="'.get_lang('Search').'" />'.get_lang('Search').'</button>'; |
||
140 | $reset_button = '<button class="save" type="submit" id="tags-clean" value="'.get_lang('SearchResetKeywords').'" />'.get_lang('SearchResetKeywords').'</button> '; |
||
141 | } |
||
142 | |||
143 | $query = isset($_REQUEST['query']) ? Security::remove_XSS($_REQUEST['query']) : null; |
||
144 | |||
145 | $form = '<form id="chamilo_search" action="'.$action.'" method="GET"> |
||
146 | <input type="text" id="query" name="query" size="40" value="'.$query.'" /> |
||
147 | <input type="hidden" name="mode" value="'.$mode.'"/> |
||
148 | <input type="hidden" name="type" value="'.$type.'"/> |
||
149 | <input type="hidden" name="tablename_page_nr" value="1" /> |
||
150 | '.$submit_button1.' |
||
151 | <br /><br />'; |
||
152 | $list = get_specific_field_list(); |
||
153 | |||
154 | if (!empty($list)) { |
||
155 | $form .= '<span class="search-links-box">'.$advanced_options.' </span> |
||
156 | <div id="tags" class="tags" style="display:'.$display_thesaurus.';"> |
||
157 | <div class="search-help-box">'.$help.'</div> |
||
158 | <table> |
||
159 | <tr>'; |
||
160 | $form .= format_specific_fields_selects($sf_terms, $op); |
||
161 | $or_checked = ''; |
||
162 | $and_checked = ''; |
||
163 | if ($op == 'or') { |
||
164 | $or_checked = 'checked="checked"'; |
||
165 | } elseif ($op == 'and') { |
||
166 | $and_checked = 'checked="checked"'; |
||
167 | } |
||
168 | $form .= '</tr> |
||
169 | <tr> |
||
170 | <td id="operator-select"> |
||
171 | '.get_lang('SearchCombineSearchWith').':<br /> |
||
172 | <input type="radio" class="search-operator" name="operator" value="or" '.$or_checked.'>'.api_strtoupper(get_lang('Or')).'</input> |
||
173 | <input type="radio" class="search-operator" name="operator" value="and" '.$and_checked.'>'.api_strtoupper(get_lang('And')).'</input> |
||
174 | </td> |
||
175 | <td></td> |
||
176 | <td> |
||
177 | <br /> |
||
178 | '.$reset_button.' |
||
179 | '.$submit_button2.' |
||
180 | </td> |
||
181 | </tr> |
||
182 | </table> |
||
183 | </div>'; |
||
184 | } |
||
185 | $form .= '</form> |
||
186 | <br style="clear: both;"/>'; |
||
187 | |||
188 | return $form; |
||
189 | } |
||
190 | |||
191 | /** |
||
192 | * Build the prefilter form. |
||
193 | * |
||
194 | * This type allow filter all other multiple select terms by one term in a dinamic way |
||
195 | */ |
||
196 | function search_widget_prefilter_form( |
||
197 | $action, |
||
198 | $show_thesaurus, |
||
199 | $sf_terms, |
||
200 | $op, |
||
201 | $prefilter_prefix = null |
||
202 | ) { |
||
203 | $thesaurus_icon = Display::return_icon('thesaurus.gif', get_lang('SearchAdvancedOptions'), ['id' => 'thesaurus-icon']); |
||
204 | $advanced_options = '<a id="tags-toggle" href="#">'.get_lang('SearchAdvancedOptions').'</a>'; |
||
205 | $display_thesaurus = ($show_thesaurus == true ? 'block' : 'none'); |
||
206 | $help = '<h3>'.get_lang('SearchKeywordsHelpTitle').'</h3>'.get_lang('SearchKeywordsHelpComment'); |
||
207 | $mode = (!empty($_REQUEST['mode']) ? htmlentities($_REQUEST['mode']) : 'gallery'); |
||
208 | $type = (!empty($_REQUEST['type']) ? htmlentities($_REQUEST['type']) : 'normal'); |
||
209 | |||
210 | /** |
||
211 | * POST avoid long urls, but we are using GET because |
||
212 | * SortableTableFromArray pagination is done with simple links, so now we |
||
213 | * could not send a form in pagination. |
||
214 | */ |
||
215 | if (isset($_GET['action']) && strcmp(trim($_GET['action']), 'search') === 0) { |
||
216 | $action = 'index.php'; |
||
217 | } |
||
218 | |||
219 | $form = ' |
||
220 | <form id="chamilo_search" action="'.$action.'" method="GET"> |
||
221 | <input type="text" id="query" name="query" size="40" /> |
||
222 | <input type="hidden" name="mode" value="'.$mode.'"/> |
||
223 | <input type="hidden" name="type" value="'.$type.'"/> |
||
224 | <input type="hidden" name="tablename_page_nr" value="1" /> |
||
225 | <input type="submit" id="submit" value="'.get_lang("Search").'" /> |
||
226 | <br /><br />'; |
||
227 | $list = get_specific_field_list(); |
||
228 | if (!empty($list)) { |
||
229 | $form .= ' <span class="search-links-box">'.$thesaurus_icon.$advanced_options.' </span> |
||
230 | <div id="tags" class="tags" style="display:'.$display_thesaurus.';"> |
||
231 | <div class="search-help-box">'.$help.'</div> |
||
232 | <table> |
||
233 | <tr>'; |
||
234 | if (!is_null($prefilter_prefix)) { |
||
235 | //sorting the array of terms |
||
236 | $temp = []; |
||
237 | foreach ($sf_terms[$prefilter_prefix] as $key => $value) { |
||
238 | $temp[trim(stripslashes($value['name']))] = $key; |
||
239 | } |
||
240 | $temp = array_flip($temp); |
||
241 | unset($sf_term_array); |
||
242 | natcasesort($temp); |
||
243 | $sf_term_array = $temp; |
||
244 | |||
245 | // get specific field name |
||
246 | $sf_value = get_specific_field_list(['code' => "'$prefilter_prefix'"]); |
||
247 | $sf_value = array_shift($sf_value); |
||
248 | $form .= '<label class="sf-select-multiple-title" for="sf_'.$prefix.'[]">'.$icons_for_search_terms[$prefix].' '.$sf_value['name'].'</label><br />'; |
||
249 | |||
250 | $form .= format_one_specific_field_select($prefilter_prefix, $sf_term_array, $op, 'id="prefilter"'); |
||
251 | $form .= format_specific_fields_selects($sf_terms, $op, $prefilter_prefix); |
||
252 | } else { |
||
253 | $form .= format_specific_fields_selects($sf_terms, $op); |
||
254 | } |
||
255 | $or_checked = ''; |
||
256 | $and_checked = ''; |
||
257 | if ($op == 'or') { |
||
258 | $or_checked = 'checked="checked"'; |
||
259 | } elseif ($op == 'and') { |
||
260 | $and_checked = 'checked="checked"'; |
||
261 | } |
||
262 | $form .= ' |
||
263 | </tr> |
||
264 | <tr> |
||
265 | <td id="operator-select"> |
||
266 | '.get_lang('SearchCombineSearchWith').':<br /> |
||
267 | <input type="radio" class="search-operator" name="operator" value="or" '.$or_checked.'>'.api_strtoupper(get_lang('Or')).'</input> |
||
268 | <input type="radio" class="search-operator" name="operator" value="and" '.$and_checked.'>'.api_strtoupper(get_lang('And')).'</input> |
||
269 | </td> |
||
270 | <td></td> |
||
271 | <td> |
||
272 | <br /> |
||
273 | <input class="lower-submit" type="submit" value="'.get_lang('Search').'" /> |
||
274 | <input type="submit" id="tags-clean" value="'.get_lang('SearchResetKeywords').'" /> |
||
275 | </td> |
||
276 | </tr> |
||
277 | </table> |
||
278 | </div>'; |
||
279 | } |
||
280 | $form .= ' |
||
281 | </form> |
||
282 | <br style="clear: both;"/>'; |
||
283 | |||
284 | return $form; |
||
285 | } |
||
286 | |||
287 | /** |
||
288 | * Show search form. |
||
289 | */ |
||
290 | function display_search_form($action, $show_thesaurus, $sf_terms, $op) |
||
291 | { |
||
292 | $type = (!empty($_REQUEST['type']) ? htmlentities($_REQUEST['type']) : 'normal'); |
||
293 | |||
294 | switch ($type) { |
||
295 | case 'prefilter': |
||
296 | $prefilter_prefix = api_get_setting('search_prefilter_prefix'); |
||
297 | $form = search_widget_prefilter_form( |
||
298 | $action, |
||
299 | $show_thesaurus, |
||
300 | $sf_terms, |
||
301 | $op, |
||
302 | $prefilter_prefix |
||
303 | ); |
||
304 | break; |
||
305 | case 'normal': |
||
306 | default: |
||
307 | $form = search_widget_normal_form( |
||
308 | $action, |
||
309 | $show_thesaurus, |
||
310 | $sf_terms, |
||
311 | $op |
||
312 | ); |
||
313 | break; |
||
314 | } |
||
315 | |||
316 | // show built form |
||
317 | echo $form; |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * Show the search widget. |
||
322 | * |
||
323 | * The form will post to index.php by default, you can pass a value to |
||
324 | * $action to use a custom action. |
||
325 | * IMPORTANT: you have to call search_widget_prepare() before calling this |
||
326 | * function or otherwise the form will not behave correctly. |
||
327 | * |
||
328 | * @param string $action Just in case your action is not |
||
329 | * index.php |
||
330 | */ |
||
331 | function search_widget_show($action = 'index.php') |
||
332 | { |
||
333 | require_once api_get_path(LIBRARY_PATH).'search/ChamiloQuery.php'; |
||
334 | // TODO: load images dinamically when they're avalaible from specific field ui to add |
||
335 | $groupId = api_get_group_id(); |
||
336 | |||
337 | $sf_terms = []; |
||
338 | $specific_fields = get_specific_field_list(); |
||
339 | $url_params = []; |
||
340 | |||
341 | if (($cid = api_get_course_id()) != -1) { // with cid |
||
342 | // get search engine terms |
||
343 | $course_filter = chamilo_get_boolean_query(XAPIAN_PREFIX_COURSEID.$cid); |
||
344 | $dkterms = chamilo_query_simple_query('', 0, 1000, [$course_filter]); |
||
345 | |||
346 | //prepare specific fields names (and also get possible URL param names) |
||
347 | foreach ($specific_fields as $specific_field) { |
||
348 | $temp = []; |
||
349 | if (is_array($dkterms) && count($dkterms) > 0) { |
||
350 | foreach ($dkterms[1] as $obj) { |
||
351 | $temp = array_merge($obj['sf-'.$specific_field['code']], $temp); |
||
352 | } |
||
353 | } |
||
354 | $sf_terms[$specific_field['code']] = $temp; |
||
355 | $url_params[] = 'sf_'.$specific_field['code']; |
||
356 | unset($temp); |
||
357 | } |
||
358 | } else { // without cid |
||
359 | // prepare specific fields names (and also get possible URL param names) |
||
360 | foreach ($specific_fields as $specific_field) { |
||
361 | //get Xapian terms for a specific term prefix, in ISO, apparently |
||
362 | $sf_terms[$specific_field['code']] = xapian_get_all_terms(1000, $specific_field['code']); |
||
363 | $url_params[] = 'sf_'.$specific_field['code']; |
||
364 | } |
||
365 | } |
||
366 | echo '<h2>'.get_lang('Search').'</h2>'; |
||
367 | |||
368 | // Tool introduction |
||
369 | // TODO: Settings for the online editor to be checked (insert an image for example). Probably this is a special case here. |
||
370 | if (api_get_course_id() !== -1) { |
||
371 | if (!empty($groupId)) { |
||
372 | Display::display_introduction_section(TOOL_SEARCH.$groupId); |
||
373 | } else { |
||
374 | Display::display_introduction_section(TOOL_SEARCH); |
||
375 | } |
||
376 | } |
||
377 | |||
378 | $op = 'or'; |
||
379 | if (!empty($_REQUEST['operator']) && in_array($op, ['or', 'and'])) { |
||
380 | $op = $_REQUEST['operator']; |
||
381 | } |
||
382 | |||
383 | //check if URL params are defined (to see if we show the thesaurus or not) |
||
384 | $show_thesaurus = false; |
||
385 | foreach ($url_params as $param) { |
||
386 | if (isset($_REQUEST[$param]) && is_array($_REQUEST[$param])) { |
||
387 | $thesaurus_decided = false; |
||
388 | foreach ($_REQUEST[$param] as $term) { |
||
389 | if (!empty($term)) { |
||
390 | $show_thesaurus = true; |
||
391 | $thesaurus_decided = true; |
||
392 | break; |
||
393 | } |
||
394 | } |
||
395 | if ($thesaurus_decided) { |
||
396 | break; |
||
397 | } |
||
398 | } |
||
399 | } |
||
400 | |||
401 | // create the form |
||
402 | // TODO: use FormValidator |
||
403 | display_search_form($action, $show_thesaurus, $sf_terms, $op); |
||
404 | } |
||
405 |