ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
class.ilLuceneSearchGUI.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
21use ILIAS\UI\Factory as UIFactory;
22use ILIAS\UI\Renderer as UIRenderer;
23
34{
35 protected ilTabsGUI $tabs;
36 protected ilHelpGUI $help;
37 protected UIFactory $ui_factory;
38 protected UIRenderer $ui_renderer;
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 {
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}
Builds a Color from either hex- or rgb values.
Definition: Factory.php:31
const IL_CAL_DATE
const IL_CAL_UNIX
Class for single dates.
Help GUI class.
static prepareFormOutput($a_str, bool $a_strip=false)
addAdminPanelCommand(string $a_cmd, string $a_txt)
Add a command to the admin panel.
setPageFormAction(string $a_action)
remoteSearch()
Search from main menu.
parseCreationFilter()
Parse creation date.
showSavedResults()
Show saved results.
fillAdminPanel()
Put admin panel into template:
setAdminViewButton(string $a_link, string $a_txt)
Show admin view button.
getMimeDetails()
Needed for base class search form.
getDetails()
Needed for base class search form.
executeCommand()
Execute Command.
performSearch()
Perform search.
search()
Search (button pressed)
prepareOutput()
Add admin panel command.
static getInstance(ilLuceneQueryParser $qp)
Get singleton instance.
GUI class for the workflow of copying objects.
renderSearch(string $term, int $root_node=0)
addPager($result, string $a_session_key)
handleCommand(string $a_cmd)
Presentation of search results using object list gui.
static clear(string $a_var)
static resetDetails()
As long as static::resetDetails is not possible this method is final.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static _getInstance(int $a_usr_id)
static getImagePath(string $image_name, string $module_path="", string $mode="output", bool $offline=false)
get image path (for images located in a template directory)
static stripSlashes(string $a_str, bool $a_strip_html=true, string $a_allow="")
const ROOT_FOLDER_ID
Definition: constants.php:32
An entity that renders components to a string output.
Definition: Renderer.php:31
static http()
Fetches the global http state from ILIAS.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
global $DIC
Definition: shib_login.php:26