ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilLuceneSearchGUI.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
36 {
37  protected ilTabsGUI $tabs;
38  protected ilHelpGUI $help;
39 
41 
42  protected ?int $root_node;
43  protected array $admin_panel_commands = [];
44  protected array $admin_view_button = [];
45  protected array $creation_selector = [];
46 
47  protected string $page_form_action = '';
48 
52  public function __construct()
53  {
54  global $DIC;
55 
56  $this->tabs = $DIC->tabs();
57  $this->help = $DIC->help();
58 
61  $this->initUserSearchCache();
62  }
63 
67  public function executeCommand(): void
68  {
69  $next_class = $this->ctrl->getNextClass($this);
70  $cmd = $this->ctrl->getCmd();
71 
72  switch ($next_class) {
73  case "ilpropertyformgui":
74  /*$this->initStandardSearchForm(ilSearchBaseGUI::SEARCH_FORM_LUCENE);
75  $ilCtrl->setReturn($this, 'storeRoot');
76  $ilCtrl->forwardCommand($this->form);*/
77  $form = $this->getSearchAreaForm();
78  $this->prepareOutput();
79  $this->ctrl->setReturn($this, 'storeRoot');
80  $this->ctrl->forwardCommand($form);
81  break;
82 
83  case 'ilobjectcopygui':
84  $this->prepareOutput();
85  $this->ctrl->setReturn($this, '');
86  $cp = new ilObjectCopyGUI($this);
87  $this->ctrl->forwardCommand($cp);
88  break;
89 
90  default:
91  $this->prepareOutput();
93  if (!$cmd) {
94  $cmd = "showSavedResults";
95  }
96  $this->handleCommand($cmd);
97  break;
98  }
99  }
100 
104  public function prepareOutput(): void
105  {
106  parent::prepareOutput();
107  $this->getTabs();
108  }
109 
113  protected function getType(): int
114  {
115  return self::SEARCH_DETAILS;
116  }
117 
122  protected function getDetails(): array
123  {
124  return $this->search_cache->getItemFilter();
125  }
126 
131  protected function getMimeDetails(): array
132  {
133  return $this->search_cache->getMimeFilter();
134  }
135 
139  protected function remoteSearch(): void
140  {
141  $queryString = '';
142  if ($this->http->wrapper()->post()->has('queryString')) {
143  $queryString = $this->http->wrapper()->post()->retrieve(
144  'queryString',
145  $this->refinery->kindlyTo()->string()
146  );
147  }
148  $root_id = ROOT_FOLDER_ID;
149  if ($this->http->wrapper()->post()->has('root_id')) {
150  $root_id = $this->http->wrapper()->post()->retrieve(
151  'root_id',
152  $this->refinery->kindlyTo()->int()
153  );
154  }
155  $qp = new ilLuceneQueryParser($queryString);
156  $qp->parseAutoWildcard();
157 
158  $query = $qp->getQuery();
159 
160  $this->search_cache->setRoot($root_id);
161  $this->search_cache->setQuery(ilUtil::stripSlashes($query));
162  $this->search_cache->save();
163 
164  $this->search();
165  }
166 
170  protected function showSavedResults(): bool
171  {
172  if (!strlen($this->search_cache->getQuery())) {
173  $this->showSearchForm();
174  return false;
175  }
176 
177  $qp = new ilLuceneQueryParser($this->search_cache->getQuery());
178  $qp->parse();
179  $searcher = ilLuceneSearcher::getInstance($qp);
180  $searcher->search();
181 
182  // Load saved results
183  $filter = ilLuceneSearchResultFilter::getInstance($this->user->getId());
184  $filter->loadFromDb();
185 
186  // Highlight
187  $searcher->highlight($filter->getResultObjIds());
188 
189  $presentation = new ilSearchResultPresentation($this);
190  $presentation->setResults($filter->getResultIds());
191  $presentation->setSearcher($searcher);
192  $this->addPager($filter, 'max_page');
193  $presentation->setPreviousNext($this->prev_link, $this->next_link);
194 
195  $this->showSearchForm();
196 
197  if ($presentation->render()) {
198  $this->tpl->setVariable('SEARCH_RESULTS', $presentation->getHTML());
199  } elseif (strlen($this->search_cache->getQuery())) {
200  $this->tpl->setOnScreenMessage(
201  'info',
202  sprintf(
203  $this->lng->txt('search_no_match_hint'),
205  )
206  );
207  }
208  return true;
209  }
210 
215  protected function search(): void
216  {
217  if (!$this->form->checkInput()) {
218  $this->search_cache->deleteCachedEntries();
219  // Reset details
221  $this->showSearchForm();
222  return;
223  }
224  ilSession::clear('max_page');
225  $this->search_cache->deleteCachedEntries();
226 
227  // Reset details
229  $this->performSearch();
230  }
231 
235  protected function performSearch(): void
236  {
237  ilSession::clear('vis_references');
238  $filter_query = '';
239  if ($this->search_cache->getItemFilter() and ilSearchSettings::getInstance()->isLuceneItemFilterEnabled()) {
240  $filter_settings = ilSearchSettings::getInstance()->getEnabledLuceneItemFilterDefinitions();
241  foreach ($this->search_cache->getItemFilter() as $obj => $value) {
242  if (!$filter_query) {
243  $filter_query .= '+( ';
244  } else {
245  $filter_query .= 'OR';
246  }
247  $filter_query .= (' ' . $filter_settings[$obj]['filter'] . ' ');
248  }
249  $filter_query .= ') ';
250  }
251  // begin-patch mime_filter
252  $mime_query = '';
253  if ($this->search_cache->getMimeFilter() and ilSearchSettings::getInstance()->isLuceneMimeFilterEnabled()) {
254  $filter_settings = ilSearchSettings::getInstance()->getEnabledLuceneMimeFilterDefinitions();
255  foreach ($this->search_cache->getMimeFilter() as $mime => $value) {
256  if (!$mime_query) {
257  $mime_query .= '+( ';
258  } else {
259  $mime_query .= 'OR';
260  }
261  $mime_query .= (' ' . $filter_settings[$mime]['filter'] . ' ');
262  }
263  $mime_query .= ') ';
264  }
265 
266  // begin-patch creation_date
267  $cdate_query = $this->parseCreationFilter();
268 
269 
270 
271  $filter_query = $filter_query . ' ' . $mime_query . ' ' . $cdate_query;
272 
273 
274  $query = $this->search_cache->getQuery();
275  if ($query) {
276  $query = ' +(' . $query . ')';
277  }
278  $qp = new ilLuceneQueryParser($filter_query . $query);
279  $qp->parse();
280  $searcher = ilLuceneSearcher::getInstance($qp);
281  $searcher->search();
282 
283  // Filter results
284  $filter = ilLuceneSearchResultFilter::getInstance($this->user->getId());
285  $filter->addFilter(new ilLucenePathFilter($this->search_cache->getRoot()));
286  $filter->setCandidates($searcher->getResult());
287  $filter->filter();
288 
289  if ($filter->getResultObjIds()) {
290  $searcher->highlight($filter->getResultObjIds());
291  }
292 
293  // Show results
294  $this->showSearchForm();
295 
296  $presentation = new ilSearchResultPresentation($this);
297  $presentation->setResults($filter->getResultIds());
298  $presentation->setSearcher($searcher);
299 
300  // TODO: other handling required
301  $this->addPager($filter, 'max_page');
302 
303  $presentation->setPreviousNext($this->prev_link, $this->next_link);
304 
305  if ($presentation->render()) {
306  $this->tpl->setVariable('SEARCH_RESULTS', $presentation->getHTML());
307  } else {
308  $this->tpl->setOnScreenMessage(
309  'info',
310  sprintf(
311  $this->lng->txt('search_no_match_hint'),
313  )
314  );
315  }
316  }
317 
321  protected function storeRoot(): void
322  {
323  $form = $this->getSearchAreaForm();
324 
325  $this->root_node = $form->getItemByPostVar('area')->getValue();
326  $this->search_cache->setRoot($this->root_node);
327  $this->search_cache->save();
328  $this->search_cache->deleteCachedEntries();
329 
331 
332  $this->performSearch();
333  }
334 
338  protected function getTabs(): void
339  {
340  $this->help->setScreenIdComponent("src_luc");
341 
342  $this->tabs->addTarget('search', $this->ctrl->getLinkTarget($this));
343 
344  if (ilSearchSettings::getInstance()->isLuceneUserSearchEnabled()) {
345  $this->tabs->addTarget('search_user', $this->ctrl->getLinkTargetByClass('illuceneusersearchgui'));
346  }
347 
348  if ($this->fields->getActiveFields() && !ilSearchSettings::getInstance()->getHideAdvancedSearch()) {
349  $this->tabs->addTarget('search_advanced', $this->ctrl->getLinkTargetByClass('illuceneAdvancedSearchgui'));
350  }
351 
352  $this->tabs->setTabActive('search');
353  }
354 
361  protected function initUserSearchCache(): void
362  {
363  $this->search_cache = ilUserSearchCache::_getInstance($this->user->getId());
364  $this->search_cache->switchSearchType(ilUserSearchCache::LUCENE_DEFAULT);
365  $page_number = $this->initPageNumberFromQuery();
366 
367  $item_filter_enabled = false;
368  if ($this->http->wrapper()->post()->has('item_filter_enabled')) {
369  $item_filter_enabled = $this->http->wrapper()->post()->retrieve(
370  'item_filter_enabled',
371  $this->refinery->kindlyTo()->bool()
372  );
373  }
374  $post_filter_type = (array) ($this->http->request()->getParsedBody()['filter_type'] ?? []);
375  if ($page_number) {
376  $this->search_cache->setResultPageNumber($page_number);
377  }
378  if ($this->http->wrapper()->post()->has('term')) {
379  $term = $this->http->wrapper()->post()->retrieve(
380  'term',
381  $this->refinery->kindlyTo()->string()
382  );
383  $this->search_cache->setQuery($term);
384  if ($item_filter_enabled) {
385  $filtered = array();
386  foreach (ilSearchSettings::getInstance()->getEnabledLuceneItemFilterDefinitions() as $type => $data) {
387  if ($post_filter_type[$type] ?? false) {
388  $filtered[$type] = 1;
389  }
390  }
391  $this->search_cache->setItemFilter($filtered);
392 
393  // Mime filter
394  $mime = array();
395  foreach (ilSearchSettings::getInstance()->getEnabledLuceneMimeFilterDefinitions() as $type => $data) {
396  if ($post_filter_type[$type] ?? false) {
397  $mime[$type] = 1;
398  }
399  }
400  $this->search_cache->setMimeFilter($mime);
401  }
402  $this->search_cache->setCreationFilter($this->loadCreationFilter());
403  if (!$item_filter_enabled) {
404  // @todo: keep item filter settings
405  $this->search_cache->setItemFilter(array());
406  $this->search_cache->setMimeFilter(array());
407  }
408  $post_screation = (array) ($this->http->request()->getParsedBody()['screation'] ?? []);
409  if (!count($post_screation)) {
410  $this->search_cache->setCreationFilter([]);
411  }
412  }
413  }
414 
420  protected function fillAdminPanel(): void
421  {
422  $adm_view_cmp = $adm_cmds = $creation_selector = $adm_view = false;
423 
424  // admin panel commands
425  if ((count($this->admin_panel_commands) > 0)) {
426  foreach ($this->admin_panel_commands as $cmd) {
427  $this->tpl->setCurrentBlock("lucene_admin_panel_cmd");
428  $this->tpl->setVariable("LUCENE_PANEL_CMD", $cmd["cmd"]);
429  $this->tpl->setVariable("LUCENE_TXT_PANEL_CMD", $cmd["txt"]);
430  $this->tpl->parseCurrentBlock();
431  }
432 
433  $adm_cmds = true;
434  }
435  if ($adm_cmds) {
436  $this->tpl->setCurrentBlock("lucene_adm_view_components");
437  $this->tpl->setVariable("LUCENE_ADM_IMG_ARROW", ilUtil::getImagePath("arrow_upright.svg"));
438  $this->tpl->setVariable("LUCENE_ADM_ALT_ARROW", $this->lng->txt("actions"));
439  $this->tpl->parseCurrentBlock();
440  $adm_view_cmp = true;
441  }
442 
443  // admin view button
444  if (is_array($this->admin_view_button)) {
445  if (is_array($this->admin_view_button)) {
446  $this->tpl->setCurrentBlock("lucene_admin_button");
447  $this->tpl->setVariable(
448  "LUCENE_ADMIN_MODE_LINK",
449  $this->admin_view_button["link"]
450  );
451  $this->tpl->setVariable(
452  "LUCENE_TXT_ADMIN_MODE",
453  $this->admin_view_button["txt"]
454  );
455  $this->tpl->parseCurrentBlock();
456  }
457  $this->tpl->setCurrentBlock("lucene_admin_view");
458  $this->tpl->parseCurrentBlock();
459  $adm_view = true;
460  }
461 
462  // creation selector
463  if (is_array($this->creation_selector)) {
464  $this->tpl->setCurrentBlock("lucene_add_commands");
465  if ($adm_cmds) {
466  $this->tpl->setVariable("LUCENE_ADD_COM_WIDTH", 'width="1"');
467  }
468  $this->tpl->setVariable(
469  "LUCENE_SELECT_OBJTYPE_REPOS",
470  $this->creation_selector["options"]
471  );
472  $this->tpl->setVariable(
473  "LUCENE_BTN_NAME_REPOS",
474  $this->creation_selector["command"]
475  );
476  $this->tpl->setVariable(
477  "LUCENE_TXT_ADD_REPOS",
478  $this->creation_selector["txt"]
479  );
480  $this->tpl->parseCurrentBlock();
481  $creation_selector = true;
482  }
483  if ($adm_view || $creation_selector) {
484  $this->tpl->setCurrentBlock("lucene_adm_panel");
485  if ($adm_view_cmp) {
486  $this->tpl->setVariable("LUCENE_ADM_TBL_WIDTH", 'width:"100%";');
487  }
488  $this->tpl->parseCurrentBlock();
489  }
490  }
491 
495  protected function addAdminPanelCommand(string $a_cmd, string $a_txt): void
496  {
497  $this->admin_panel_commands[] =
498  array("cmd" => $a_cmd, "txt" => $a_txt);
499  }
500 
504  protected function setAdminViewButton(string $a_link, string $a_txt): void
505  {
506  $this->admin_view_button =
507  array("link" => $a_link, "txt" => $a_txt);
508  }
509 
510  protected function setPageFormAction(string $a_action): void
511  {
512  $this->page_form_action = $a_action;
513  }
514 
519  protected function showSearchForm(): void
520  {
521  $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.lucene_search.html', 'Services/Search');
522 
523  ilOverlayGUI::initJavascript();
524  $this->tpl->addJavascript("./Services/Search/js/Search.js");
525 
526 
527  $this->tpl->setVariable("FORM_ACTION", $this->ctrl->getFormAction($this, 'performSearch'));
528  $this->tpl->setVariable("TERM", ilLegacyFormElementsUtil::prepareFormOutput($this->search_cache->getQuery()));
529  $this->tpl->setVariable("SEARCH_LABEL", $this->lng->txt("search"));
531  $btn->setCommand("performSearch");
532  $btn->setCaption("search");
533  $this->tpl->setVariable("SUBMIT_BTN", $btn->render());
534  $this->tpl->setVariable("TXT_OPTIONS", $this->lng->txt("options"));
535  $this->tpl->setVariable("ARR_IMG", ilGlyphGUI::get(ilGlyphGUI::CARET));
536  $this->tpl->setVariable("TXT_COMBINATION", $this->lng->txt("search_term_combination"));
537  $this->tpl->setVariable('TXT_COMBINATION_DEFAULT', ilSearchSettings::getInstance()->getDefaultOperator() == ilSearchSettings::OPERATOR_AND ? $this->lng->txt('search_all_words') : $this->lng->txt('search_any_word'));
538  $this->tpl->setVariable("TXT_AREA", $this->lng->txt("search_area"));
539 
540  if (ilSearchSettings::getInstance()->isLuceneItemFilterEnabled()) {
541  $this->tpl->setCurrentBlock("type_sel");
542  $this->tpl->setVariable('TXT_TYPE_DEFAULT', $this->lng->txt("search_off"));
543  $this->tpl->setVariable("ARR_IMGT", ilGlyphGUI::get(ilGlyphGUI::CARET));
544  $this->tpl->setVariable("TXT_FILTER_BY_TYPE", $this->lng->txt("search_filter_by_type"));
545  $this->tpl->setVariable('FORM', $this->form->getHTML());
546  $this->tpl->parseCurrentBlock();
547  }
548 
549  // search area form
550  $this->tpl->setVariable('SEARCH_AREA_FORM', $this->getSearchAreaForm()->getHTML());
551  $this->tpl->setVariable("TXT_CHANGE", $this->lng->txt("change"));
552 
553  if (ilSearchSettings::getInstance()->isDateFilterEnabled()) {
554  // begin-patch creation_date
555  $this->tpl->setVariable('TXT_FILTER_BY_CDATE', $this->lng->txt('search_filter_cd'));
556  $this->tpl->setVariable('TXT_CD_OFF', $this->lng->txt('search_off'));
557  $this->tpl->setVariable('FORM_CD', $this->getCreationDateForm()->getHTML());
558  $this->tpl->setVariable("ARR_IMG_CD", ilGlyphGUI::get(ilGlyphGUI::CARET));
559  // end-patch creation_date
560  }
561  }
562 
563 
567  protected function parseCreationFilter(): string
568  {
569  $options = $this->search_cache->getCreationFilter();
570 
571  if (!($options['enabled'] ?? false)) {
572  return '';
573  }
574  $limit = new ilDate($options['date'], IL_CAL_UNIX);
575 
576  switch ($options['ontype']) {
577  case 1:
578  // after
579  $limit->increment(IL_CAL_DAY, 1);
580  $now = new ilDate(time(), IL_CAL_UNIX);
581  return '+(cdate:[' . $limit->get(IL_CAL_DATE) . ' TO ' . $now->get(IL_CAL_DATE) . '*]) ';
582 
583  case 2:
584  // before
585  return '+(cdate:[* TO ' . $limit->get(IL_CAL_DATE) . ']) ';
586 
587  case 3:
588  // on
589  return '+(cdate:' . $limit->get(IL_CAL_DATE) . '*) ';
590 
591  }
592  return '';
593  }
594  // end-patch creation_date
595 }
showSearchForm()
Show search form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
remoteSearch()
Search from main menu.
getDetails()
Needed for base class search form.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static get(string $a_glyph, string $a_text="")
GUI class for the workflow of copying objects.
$type
$errors fields
Definition: imgupload.php:67
parse()
parse query string
getItemByPostVar(string $a_post_var)
const ROOT_FOLDER_ID
Definition: constants.php:32
ilPropertyFormGUI $form
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static _getInstance(int $a_usr_id)
static getImagePath(string $img, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
Help GUI class.
static getInstance(ilLuceneQueryParser $qp)
Get singleton instance.
parseCreationFilter()
Parse creation date.
getMimeDetails()
Needed for base class search form.
handleCommand(string $a_cmd)
executeCommand()
Execute Command.
static prepareFormOutput($a_str, bool $a_strip=false)
const IL_CAL_UNIX
prepareOutput()
Add admin panel command.
setPageFormAction(string $a_action)
static resetDetails()
As long as static::resetDetails is not possible this method is final.
global $DIC
Definition: feed.php:28
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
showSavedResults()
Show saved results.
const IL_CAL_DAY
static http()
Fetches the global http state from ILIAS.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
addAdminPanelCommand(string $a_cmd, string $a_txt)
Add a command to the admin panel.
performSearch()
Perform search.
$query
form( $class_path, string $cmd)
search()
Search (button pressed)
storeRoot()
Store new root node.
initUserSearchCache()
Init user search cache.
ilLuceneAdvancedSearchFields $fields
const IL_CAL_DATE
setAdminViewButton(string $a_link, string $a_txt)
Show admin view button.
addPager($result, string $a_session_key)
initStandardSearchForm(int $a_mode)
__construct(Container $dic, ilPlugin $plugin)
fillAdminPanel()
Put admin panel into template:
static clear(string $a_var)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...