ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
class.ilLuceneSearchGUI.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
23 
34 {
35  protected ilTabsGUI $tabs;
36  protected ilHelpGUI $help;
39 
40  protected ?int $root_node;
41  protected array $admin_panel_commands = [];
42  protected array $admin_view_button = [];
43  protected array $creation_selector = [];
44 
45  protected string $page_form_action = '';
46 
50  public function __construct()
51  {
52  global $DIC;
53 
55  $this->tabs = $DIC->tabs();
56  $this->help = $DIC->help();
57 
58  $this->ui_factory = $DIC->ui()->factory();
59  $this->ui_renderer = $DIC->ui()->renderer();
60 
61  $this->initFilter(self::SEARCH_FORM_LUCENE);
62  $this->initUserSearchCache();
63  }
64 
68  public function executeCommand(): void
69  {
70  $next_class = $this->ctrl->getNextClass($this);
71  $cmd = $this->ctrl->getCmd();
72 
73  switch ($next_class) {
74  case 'ilobjectcopygui':
75  $this->prepareOutput();
76  $this->ctrl->setReturn($this, '');
77  $cp = new ilObjectCopyGUI($this);
78  $this->ctrl->forwardCommand($cp);
79  break;
80 
81  default:
82  $this->prepareOutput();
83  if (!$cmd) {
84  $cmd = "showSavedResults";
85  }
86  $this->handleCommand($cmd);
87  break;
88  }
89  }
90 
94  public function prepareOutput(): void
95  {
96  parent::prepareOutput();
97  $this->getTabs();
98  }
99 
103  protected function getType(): int
104  {
105  return self::SEARCH_DETAILS;
106  }
107 
112  protected function getDetails(): array
113  {
114  return $this->search_cache->getItemFilter();
115  }
116 
121  protected function getMimeDetails(): array
122  {
123  return $this->search_cache->getMimeFilter();
124  }
125 
129  protected function remoteSearch(): void
130  {
131  $queryString = '';
132  if ($this->http->wrapper()->post()->has('queryString')) {
133  $queryString = $this->http->wrapper()->post()->retrieve(
134  'queryString',
135  $this->refinery->kindlyTo()->string()
136  );
137  }
138  $root_id = ROOT_FOLDER_ID;
139  if ($this->http->wrapper()->post()->has('root_id')) {
140  $root_id = $this->http->wrapper()->post()->retrieve(
141  'root_id',
142  $this->refinery->kindlyTo()->int()
143  );
144  }
145  $qp = new ilLuceneQueryParser($queryString);
146  $qp->parseAutoWildcard();
147 
148  $query = $qp->getQuery();
149 
150  $this->search_cache->setRoot($root_id);
151  $this->search_cache->setQuery(ilUtil::stripSlashes($query));
152  $this->search_cache->save();
153 
154  $this->search();
155  }
156 
160  protected function showSavedResults(): bool
161  {
162  if (!strlen($this->search_cache->getQuery())) {
163  $this->showSearchForm();
164  return false;
165  }
166 
167  $qp = new ilLuceneQueryParser($this->search_cache->getQuery());
168  $qp->parse();
169  $searcher = ilLuceneSearcher::getInstance($qp);
170  $searcher->search();
171 
172  // Load saved results
173  $filter = ilLuceneSearchResultFilter::getInstance($this->user->getId());
174  $filter->loadFromDb();
175 
176  // Highlight
177  $searcher->highlight($filter->getResultObjIds());
178 
179  $presentation = new ilSearchResultPresentation($this);
180  $presentation->setResults($filter->getResultIds());
181  $presentation->setSearcher($searcher);
182  $this->addPager($filter, 'max_page');
183  $presentation->setPreviousNext($this->prev_link, $this->next_link);
184 
185  $this->showSearchForm();
186 
187  if ($presentation->render()) {
188  $this->tpl->setVariable('SEARCH_RESULTS', $presentation->getHTML());
189  } elseif (strlen($this->search_cache->getQuery())) {
190  $this->tpl->setOnScreenMessage(
191  'info',
192  sprintf(
193  $this->lng->txt('search_no_match_hint'),
195  )
196  );
197  }
198  return true;
199  }
200 
204  protected function search(): void
205  {
206  ilSession::clear('max_page');
207 
208  // Reset details
210  $this->performSearch();
211  }
212 
213  protected function performSearchFilter(): void
214  {
215  $this->performSearch();
216  }
217 
221  protected function performSearch(): void
222  {
223  $this->search_cache->deleteCachedEntries();
224  ilSession::clear('vis_references');
225  $filter_query = '';
226  if ($this->search_cache->getItemFilter() and ilSearchSettings::getInstance()->isLuceneItemFilterEnabled()) {
227  $filter_settings = ilSearchSettings::getInstance()->getEnabledLuceneItemFilterDefinitions();
228  foreach ($this->search_cache->getItemFilter() as $obj => $value) {
229  if (!$filter_query) {
230  $filter_query .= '+( ';
231  } else {
232  $filter_query .= 'OR';
233  }
234  $filter_query .= (' ' . $filter_settings[$obj]['filter'] . ' ');
235  }
236  $filter_query .= ') ';
237  }
238  // begin-patch mime_filter
239  $mime_query = '';
240  if ($this->search_cache->getMimeFilter() and ilSearchSettings::getInstance()->isLuceneMimeFilterEnabled()) {
241  $filter_settings = ilSearchSettings::getInstance()->getEnabledLuceneMimeFilterDefinitions();
242  foreach ($this->search_cache->getMimeFilter() as $mime => $value) {
243  if (!$mime_query) {
244  $mime_query .= '+( ';
245  } else {
246  $mime_query .= 'OR';
247  }
248  $mime_query .= (' ' . $filter_settings[$mime]['filter'] . ' ');
249  }
250  $mime_query .= ') ';
251  }
252 
253  // begin-patch creation_date
254  $cdate_query = $this->parseCreationFilter();
255 
256 
257 
258  $filter_query = $filter_query . ' ' . $mime_query . ' ' . $cdate_query;
259 
260 
261  $query = $this->search_cache->getQuery();
262  if ($query) {
263  $query = ' +(' . $query . ')';
264  }
265  $qp = new ilLuceneQueryParser($filter_query . $query);
266  $qp->parse();
267  $searcher = ilLuceneSearcher::getInstance($qp);
268  $searcher->search();
269 
270  // Filter results
271  $filter = ilLuceneSearchResultFilter::getInstance($this->user->getId());
272  $filter->addFilter(new ilLucenePathFilter($this->search_cache->getRoot()));
273  $filter->setCandidates($searcher->getResult());
274  $filter->filter();
275 
276  if ($filter->getResultObjIds()) {
277  $searcher->highlight($filter->getResultObjIds());
278  }
279 
280  // Show results
281  $this->showSearchForm();
282 
283  $presentation = new ilSearchResultPresentation($this);
284  $presentation->setResults($filter->getResultIds());
285  $presentation->setSearcher($searcher);
286 
287  // TODO: other handling required
288  $this->addPager($filter, 'max_page');
289 
290  $presentation->setPreviousNext($this->prev_link, $this->next_link);
291 
292  if ($presentation->render()) {
293  $this->tpl->setVariable('SEARCH_RESULTS', $presentation->getHTML());
294  } else {
295  $this->tpl->setOnScreenMessage(
296  'info',
297  sprintf(
298  $this->lng->txt('search_no_match_hint'),
300  )
301  );
302  }
303  }
304 
308  protected function getTabs(): void
309  {
310  $this->help->setScreenIdComponent("src_luc");
311 
312  $this->tabs->addTarget('search', $this->ctrl->getLinkTarget($this));
313 
314  if (ilSearchSettings::getInstance()->isLuceneUserSearchEnabled()) {
315  $this->tabs->addTarget('search_user', $this->ctrl->getLinkTargetByClass('illuceneusersearchgui'));
316  }
317 
318  $this->tabs->setTabActive('search');
319  }
320 
321  protected function initUserSearchCache(): void
322  {
323  $this->search_cache = ilUserSearchCache::_getInstance($this->user->getId());
324  $this->search_cache->switchSearchType(ilUserSearchCache::LUCENE_DEFAULT);
325  $page_number = $this->initPageNumberFromQuery();
326 
327  if ($this->http->wrapper()->post()->has('cmd')) {
328  $requested_cmd = (array) $this->http->wrapper()->post()->retrieve('cmd', $this->getStringArrayTransformation());
329  } elseif ($this->http->wrapper()->query()->has('cmd')) {
330  $requested_cmd = (array) $this->http->wrapper()->query()->retrieve(
331  'cmd',
332  $this->refinery->kindlyTo()->string()
333  );
334  $requested_cmd = [$requested_cmd[0] => "Search"];
335  } else {
336  $requested_cmd = [];
337  }
338  $new_search = (bool) ($requested_cmd["performSearch"] ?? false);
339  $new_filter = (bool) ($requested_cmd["performSearchFilter"] ?? false);
340  $new_search_or_filter = $new_search || $new_filter;
341 
342  if ($this->http->wrapper()->post()->has('root_id')) {
343  $filter_scope = $this->http->wrapper()->post()->retrieve(
344  'root_id',
345  $this->refinery->kindlyTo()->int()
346  );
347  } else {
348  $filter_scope = (int) ($this->search_filter_data["search_scope"] ?? ROOT_FOLDER_ID);
349  }
350 
351  $filter_type_active = (is_null($this->search_filter_data["search_type"] ?? null))
352  ? false
353  : true;
354  $requested_filter_type = (array) ($this->search_filter_data["search_type"] ?? []);
355  $requested_filter_type = array_flip($requested_filter_type);
356  $requested_filter_type = array_fill_keys(array_keys($requested_filter_type), "1");
357 
358  if ($page_number) {
359  $this->search_cache->setResultPageNumber($page_number);
360  }
361 
362  if ($this->http->wrapper()->post()->has('term')) {
363  $term = $this->http->wrapper()->post()->retrieve(
364  'term',
365  $this->refinery->kindlyTo()->string()
366  );
367  } else {
368  $term = $this->search_cache->getQuery();
369  }
370  $this->search_cache->setQuery($term);
371 
372  if ($filter_type_active) {
373  $filtered = [];
374  foreach (ilSearchSettings::getInstance()->getEnabledLuceneItemFilterDefinitions() as $type => $data) {
375  if ($requested_filter_type[$type] ?? false) {
376  $filtered[$type] = 1;
377  }
378  }
379  $this->search_cache->setItemFilter($filtered);
380 
381  // Mime filter
382  $mime = [];
383  foreach (ilSearchSettings::getInstance()->getEnabledLuceneMimeFilterDefinitions() as $type => $data) {
384  if ($requested_filter_type[$type] ?? false) {
385  $mime[$type] = 1;
386  }
387  }
388  $this->search_cache->setMimeFilter($mime);
389  }
390  $this->search_cache->setCreationFilter($this->loadCreationFilter());
391  if (!$filter_type_active) {
392  // @todo: keep item filter settings?
393  $this->search_cache->setItemFilter([]);
394  $this->search_cache->setMimeFilter([]);
395  }
396  if (!isset($this->search_filter_data["search_date"])) {
397  $this->search_cache->setCreationFilter([]);
398  }
399 
400  if ($new_filter) {
401  $this->search_cache->setRoot($filter_scope);
402  }
403  }
404 
410  protected function fillAdminPanel(): void
411  {
412  $adm_view_cmp = $adm_cmds = $creation_selector = $adm_view = false;
413 
414  // admin panel commands
415  if ((count($this->admin_panel_commands) > 0)) {
416  foreach ($this->admin_panel_commands as $cmd) {
417  $this->tpl->setCurrentBlock("lucene_admin_panel_cmd");
418  $this->tpl->setVariable("LUCENE_PANEL_CMD", $cmd["cmd"]);
419  $this->tpl->setVariable("LUCENE_TXT_PANEL_CMD", $cmd["txt"]);
420  $this->tpl->parseCurrentBlock();
421  }
422 
423  $adm_cmds = true;
424  }
425  if ($adm_cmds) {
426  $this->tpl->setCurrentBlock("lucene_adm_view_components");
427  $this->tpl->setVariable("LUCENE_ADM_IMG_ARROW", ilUtil::getImagePath("nav/arrow_upright.svg"));
428  $this->tpl->setVariable("LUCENE_ADM_ALT_ARROW", $this->lng->txt("actions"));
429  $this->tpl->parseCurrentBlock();
430  $adm_view_cmp = true;
431  }
432 
433  // admin view button
434  if (is_array($this->admin_view_button)) {
435  if (is_array($this->admin_view_button)) {
436  $this->tpl->setCurrentBlock("lucene_admin_button");
437  $this->tpl->setVariable(
438  "LUCENE_ADMIN_MODE_LINK",
439  $this->admin_view_button["link"]
440  );
441  $this->tpl->setVariable(
442  "LUCENE_TXT_ADMIN_MODE",
443  $this->admin_view_button["txt"]
444  );
445  $this->tpl->parseCurrentBlock();
446  }
447  $this->tpl->setCurrentBlock("lucene_admin_view");
448  $this->tpl->parseCurrentBlock();
449  $adm_view = true;
450  }
451 
452  // creation selector
453  if (is_array($this->creation_selector)) {
454  $this->tpl->setCurrentBlock("lucene_add_commands");
455  if ($adm_cmds) {
456  $this->tpl->setVariable("LUCENE_ADD_COM_WIDTH", 'width="1"');
457  }
458  $this->tpl->setVariable(
459  "LUCENE_SELECT_OBJTYPE_REPOS",
460  $this->creation_selector["options"]
461  );
462  $this->tpl->setVariable(
463  "LUCENE_BTN_NAME_REPOS",
464  $this->creation_selector["command"]
465  );
466  $this->tpl->setVariable(
467  "LUCENE_TXT_ADD_REPOS",
468  $this->creation_selector["txt"]
469  );
470  $this->tpl->parseCurrentBlock();
471  $creation_selector = true;
472  }
473  if ($adm_view || $creation_selector) {
474  $this->tpl->setCurrentBlock("lucene_adm_panel");
475  if ($adm_view_cmp) {
476  $this->tpl->setVariable("LUCENE_ADM_TBL_WIDTH", 'width:"100%";');
477  }
478  $this->tpl->parseCurrentBlock();
479  }
480  }
481 
485  protected function addAdminPanelCommand(string $a_cmd, string $a_txt): void
486  {
487  $this->admin_panel_commands[] =
488  array("cmd" => $a_cmd, "txt" => $a_txt);
489  }
490 
494  protected function setAdminViewButton(string $a_link, string $a_txt): void
495  {
496  $this->admin_view_button =
497  array("link" => $a_link, "txt" => $a_txt);
498  }
499 
500  protected function setPageFormAction(string $a_action): void
501  {
502  $this->page_form_action = $a_action;
503  }
504 
505  protected function showSearchForm(): void
506  {
507  $this->tpl->addBlockFile('ADM_CONTENT', 'adm_content', 'tpl.search.html', 'components/ILIAS/Search');
508  $this->renderSearch($this->search_cache->getQuery(), $this->search_cache->getRoot());
509  }
510 
514  protected function parseCreationFilter(): string
515  {
516  $options = $this->search_cache->getCreationFilter();
517 
518  if (!($options['date_start'] ?? false) && !($options['date_end'] ?? false)) {
519  return '';
520  }
521 
522  $start = null;
523  $end = null;
524  if (($options['date_start'] ?? false)) {
525  $start = new ilDate($options['date_start'] ?? "", IL_CAL_DATE);
526  }
527  if (($options['date_end'] ?? false)) {
528  $end = new ilDate($options['date_end'] ?? "", IL_CAL_DATE);
529  }
530 
531  if ($start && is_null($end)) {
532  $now = new ilDate(time(), IL_CAL_UNIX);
533  return '+(cdate:[' . $start->get(IL_CAL_DATE) . ' TO ' . $now->get(IL_CAL_DATE) . '*]) ';
534  } elseif ($end && is_null($start)) {
535  return '+(cdate:[* TO ' . $end->get(IL_CAL_DATE) . ']) ';
536  } else {
537  return '+(cdate:[' . $start->get(IL_CAL_DATE) . ' TO ' . $end->get(IL_CAL_DATE) . '*]) ';
538  }
539 
540  return '';
541  }
542 }
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...
GUI class for the workflow of copying objects.
parse()
parse query string
const ROOT_FOLDER_ID
Definition: constants.php:32
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
static _getInstance(int $a_usr_id)
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.
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
showSavedResults()
Show saved results.
static http()
Fetches the global http state from ILIAS.
Presentation of search results using object list gui.
addAdminPanelCommand(string $a_cmd, string $a_txt)
Add a command to the admin panel.
global $DIC
Definition: shib_login.php:26
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
performSearch()
Perform search.
search()
Search (button pressed)
renderSearch(string $term, int $root_node=0)
const IL_CAL_DATE
setAdminViewButton(string $a_link, string $a_txt)
Show admin view button.
addPager($result, string $a_session_key)
__construct(Container $dic, ilPlugin $plugin)
fillAdminPanel()
Put admin panel into template:
static clear(string $a_var)