ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilSearchResult.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
34 include_once('Services/Search/classes/class.ilUserSearchCache.php');
35 
36 define('DEFAULT_SEARCH', 0);
37 define('ADVANCED_SEARCH', 1);
38 define('ADVANCED_MD_SEARCH', 4);
39 
41 {
42  public $permission = 'visible';
43 
44  public $user_id;
45  public $entries = array();
46  public $results = array();
47  public $observers = array();
48 
49  protected $search_cache = null;
50  protected $offset = 0;
51 
52  // OBJECT VARIABLES
53  public $ilias;
54  public $ilAccess;
55 
56  // Stores info if MAX HITS is reached or not
57  public $limit_reached = false;
58  public $result;
59 
60  protected $preventOverwritingMaxhits = false;
61 
66  public function __construct($a_user_id = 0)
67  {
68  global $DIC;
69 
70  $ilias = $DIC['ilias'];
71  $ilAccess = $DIC['ilAccess'];
72  $ilDB = $DIC['ilDB'];
73  $ilUser = $DIC['ilUser'];
74 
75  $this->ilAccess = $ilAccess;
76  if ($a_user_id) {
77  $this->user_id = $a_user_id;
78  } else {
79  $this->user_id = $ilUser->getId();
80  }
82  $this->initUserSearchCache();
83 
84  $this->db = $ilDB;
85  }
86 
90  public function setRequiredPermission($a_permission)
91  {
92  $this->permission = $a_permission;
93  }
94 
95  public function getRequiredPermission()
96  {
97  return $this->permission;
98  }
99 
100 
101  public function setUserId($a_user_id)
102  {
103  $this->user_id = $a_user_id;
104  }
105  public function getUserId()
106  {
107  return $this->user_id;
108  }
109 
110  public function getEntries()
111  {
112  return $this->entries ? $this->entries : array();
113  }
114 
115  public function isLimitReached()
116  {
117  return $this->limit_reached ? true : false;
118  }
119 
120  public function setMaxHits($a_max_hits)
121  {
122  $this->max_hits = $a_max_hits;
123  }
124  public function getMaxHits()
125  {
126  return $this->max_hits;
127  }
128 
136  public function isOffsetReached($a_counter)
137  {
138  return ($a_counter < $this->offset) ? false : true;
139  }
140 
151  public function addEntry($a_obj_id, $a_type, $found, $a_child_id = 0)
152  {
153  // Create new entry if it not exists
154  if (!$this->entries[$a_obj_id]) {
155  $this->entries[$a_obj_id]['obj_id'] = $a_obj_id;
156  $this->entries[$a_obj_id]['type'] = $a_type;
157  $this->entries[$a_obj_id]['found'] = $found;
158  $this->entries[$a_obj_id]['child'] = [];
159 
160  if ($a_child_id and $a_child_id != $a_obj_id) {
161  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
162  }
163  } else {
164  // replace or add child ('pg','st') id
165  if ($a_child_id and $a_child_id != $a_obj_id) {
166  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
167  }
168 
169  // UPDATE FOUND
170  $counter = 0;
171  foreach ($found as $position) {
172  if ($position) {
173  $this->entries[$a_obj_id]['found'][$counter] = $position;
174  }
175  $counter++;
176  }
177  }
178  return true;
179  }
180 
186  public function numEntries()
187  {
188  return count($this->getEntries());
189  }
190 
197  public function mergeEntries(&$result_obj)
198  {
199  foreach ($result_obj->getEntries() as $entry) {
200  $this->addEntry($entry['obj_id'], $entry['type'], $entry['found']);
201  $this->__updateEntryChilds($entry['obj_id'], $entry['child']);
202  }
203  return true;
204  }
205 
213  public function diffEntriesFromResult(&$result_obj)
214  {
215  $new_entries = $this->getEntries();
216  $this->entries = array();
217 
218  // Get all checked objects
219  foreach ($this->search_cache->getCheckedItems() as $ref_id => $obj_id) {
220  if (isset($new_entries[$obj_id])) {
221  $this->addEntry(
222  $new_entries[$obj_id]['obj_id'],
223  $new_entries[$obj_id]['type'],
224  $new_entries[$obj_id]['found']
225  );
226  $this->__updateEntryChilds(
227  $new_entries[$obj_id]['obj_id'],
228  $new_entries[$obj_id]['child']
229  );
230  }
231  }
232  }
233 
240  public function intersectEntries(&$result_obj)
241  {
242  $new_entries = $this->getEntries();
243  $this->entries = array();
244 
245  foreach ($result_obj->getEntries() as $entry) {
246  $obj_id = $entry['obj_id'];
247  if (isset($new_entries[$obj_id])) {
248  $this->addEntry(
249  $new_entries[$obj_id]['obj_id'],
250  $new_entries[$obj_id]['type'],
251  $new_entries[$obj_id]['found']
252  );
253 
254  $this->__updateEntryChilds(
255  $new_entries[$obj_id]['obj_id'],
256  $new_entries[$obj_id]['child']
257  );
258  }
259  }
260  }
261 
262 
272  public function addResult($a_ref_id, $a_obj_id, $a_type)
273  {
274  $this->results[$a_ref_id]['ref_id'] = $a_ref_id;
275  $this->results[$a_ref_id]['obj_id'] = $a_obj_id;
276  $this->results[$a_ref_id]['type'] = $a_type;
277  }
278 
279  public function getResults()
280  {
281  return $this->results ? $this->results : array();
282  }
283 
290  public function getResultIds()
291  {
292  foreach ($this->getResults() as $id => $tmp) {
293  $ids[] = $id;
294  }
295  return $ids ? $ids : array();
296  }
297 
298  public function getResultsByObjId()
299  {
300  $tmp_res = array();
301  foreach ($this->getResults() as $ref_id => $res_data) {
302  $tmp_res[$res_data['obj_id']][] = $ref_id;
303  }
304  return $tmp_res ? $tmp_res : array();
305  }
306 
307 
314  public function getUniqueResults()
315  {
316  $obj_ids = array();
317  foreach ($this->results as $result) {
318  if (in_array($result['obj_id'], $obj_ids)) {
319  continue;
320  }
321  $obj_ids[] = $result['obj_id'];
322  $objects[] = $result;
323  }
324  return $objects ? $objects : array();
325  }
326 
327  public function getResultsForPresentation()
328  {
329  $res = array();
330 
331  foreach ($this->getResults() as $result) {
332  $res[$result['ref_id']] = $result['obj_id'];
333  }
334  return $res;
335  }
336 
337  public function getSubitemIds()
338  {
339  $res = array();
340  foreach ($this->getResults() as $row) {
341  $res[$row['obj_id']] = $row['child'];
342  }
343  return $res ? $res : array();
344  }
345 
346 
347 
360  public function filter($a_root_node, $check_and)
361  {
362  global $DIC;
363 
364  $tree = $DIC['tree'];
365 
366  // get ref_ids and check access
367  $counter = 0;
368  $offset_counter = 0;
369  foreach ($this->getEntries() as $entry) {
370  // boolean and failed continue
371  if ($check_and and in_array(0, $entry['found'])) {
372  continue;
373  }
374  // Types like role, rolt, user do not need rbac checks
375  $type = ilObject::_lookupType($entry['obj_id']);
376  if ($type == 'rolt' or $type == 'usr' or $type == 'role') {
377  if ($this->callListeners($entry['obj_id'], $entry)) {
378  $this->addResult($entry['obj_id'], $entry['obj_id'], $type);
379  if (is_array($entry['child'])) {
380  $counter += count($entry['child']);
381  }
382  // Stop if maximum of hits is reached
383  if (++$counter > $this->getMaxHits()) {
384  $this->limit_reached = true;
385  return true;
386  }
387  }
388  continue;
389  }
390  // Check referenced objects
391  foreach (ilObject::_getAllReferences($entry['obj_id']) as $ref_id) {
392  // Failed check: if ref id check is failed by previous search
393  if ($this->search_cache->isFailed($ref_id)) {
394  continue;
395  }
396  // Offset check
397  if ($this->search_cache->isChecked($ref_id) and !$this->isOffsetReached($offset_counter)) {
398  ++$offset_counter;
399  continue;
400  }
401 
402  if (!$this->callListeners($ref_id, $entry)) {
403  continue;
404  }
405 
406 
407 
408  // RBAC check
409  $type = ilObject::_lookupType($ref_id, true);
410  if ($this->ilAccess->checkAccessOfUser(
411  $this->getUserId(),
412  $this->getRequiredPermission(),
413  '',
414  $ref_id,
415  $type,
416  $entry['obj_id']
417  )) {
418  if ($a_root_node == ROOT_FOLDER_ID or $tree->isGrandChild($a_root_node, $ref_id)) {
419  // Call listeners
420  #if($this->callListeners($ref_id,$entry))
421  if (1) {
422  $this->addResult($ref_id, $entry['obj_id'], $type);
423  $this->search_cache->appendToChecked($ref_id, $entry['obj_id']);
424  $this->__updateResultChilds($ref_id, $entry['child']);
425 
426  $counter++;
427  $offset_counter++;
428  // Stop if maximum of hits is reached
429 
430  if ($counter >= $this->getMaxHits()) {
431  $this->limit_reached = true;
432  $this->search_cache->setResults($this->results);
433  return true;
434  }
435  }
436  }
437  continue;
438  }
439  $this->search_cache->appendToFailed($ref_id);
440  }
441  }
442  $this->search_cache->setResults($this->results);
443  return false;
444  }
445 
451  public function filterResults($a_root_node)
452  {
453  global $DIC;
454 
455  $tree = $DIC['tree'];
456 
457  $tmp_results = $this->getResults();
458  $this->results = array();
459  foreach ($tmp_results as $result) {
460  if ($tree->isGrandChild($a_root_node, $result['ref_id']) and $tree->isInTree($result['ref_id'])) {
461  $this->addResult($result['ref_id'], $result['obj_id'], $result['type']);
462  $this->__updateResultChilds($result['ref_id'], $result['child']);
463  }
464  }
465 
466  return true;
467  }
468 
469 
476  public function save($a_type = DEFAULT_SEARCH)
477  {
478  $this->search_cache->save();
479  return false;
480  }
487  public function read($a_type = DEFAULT_SEARCH)
488  {
489  $this->results = $this->search_cache->getResults();
490  }
491 
492  // PRIVATE
500  public function __updateEntryChilds($a_obj_id, $a_childs)
501  {
502  if ($this->entries[$a_obj_id] and is_array($a_childs)) {
503  foreach ($a_childs as $child_id) {
504  if ($child_id) {
505  $this->entries[$a_obj_id]['child'][$child_id] = $child_id;
506  }
507  }
508  return true;
509  }
510  return false;
511  }
519  public function __updateResultChilds($a_ref_id, $a_childs)
520  {
521  if ($this->results[$a_ref_id] and is_array($a_childs)) {
522  foreach ($a_childs as $child_id) {
523  $this->results[$a_ref_id]['child'][$child_id] = $child_id;
524  }
525  return true;
526  }
527  return false;
528  }
529 
530 
531 
532  public function __initSearchSettingsObject()
533  {
534  include_once 'Services/Search/classes/class.ilSearchSettings.php';
535 
536  $this->search_settings = new ilSearchSettings();
537  if (!$this->preventOverwritingMaxhits()) {
538  $this->setMaxHits($this->search_settings->getMaxHits());
539  }
540  }
541 
548  protected function initUserSearchCache()
549  {
550  include_once('Services/Search/classes/class.ilUserSearchCache.php');
551  $this->search_cache = ilUserSearchCache::_getInstance($this->getUserId());
552  $this->offset = $this->getMaxHits() * ($this->search_cache->getResultPageNumber() - 1) ;
553  }
554 
564  public function preventOverwritingMaxhits($a_flag = null)
565  {
566  if (null === $a_flag) {
568  }
569 
570  $this->preventOverwritingMaxhits = $a_flag;
571 
572  return $this;
573  }
574 
584  public function addObserver(&$a_class, $a_method)
585  {
586  $this->observers[] = array('class' => $a_class,
587  'method' => $a_method);
588  return true;
589  }
590  public function callListeners($a_ref_id, &$a_data)
591  {
592  foreach ($this->observers as $observer) {
593  $class = &$observer['class'];
594  $method = $observer['method'];
595 
596  if (!$class->$method($a_ref_id, $a_data)) {
597  return false;
598  }
599  }
600  return true;
601  }
602 } // END class.Search
read($a_type=DEFAULT_SEARCH)
read search results
isOffsetReached($a_counter)
Check if offset is reached.
const DEFAULT_SEARCH
getResultIds()
get result ids
$type
global $DIC
Definition: saml.php:7
addEntry($a_obj_id, $a_type, $found, $a_child_id=0)
add search result entry Entries are stored with &#39;obj_id&#39;.
filterResults($a_root_node)
Filter search area of result set public.
checkAccessOfUser($a_user_id, $a_permission, $a_cmd, $a_ref_id, $a_type="", $a_obj_id="", $a_tree_id="")
check access for an object (provide $a_type and $a_obj_id if available for better performance)(option...
if(!array_key_exists('StateId', $_REQUEST)) $id
initUserSearchCache()
Init user search cache.
addObserver(&$a_class, $a_method)
The observer is used to call functions for filtering result.
getUniqueResults()
Get unique results.
Class ilAccessHandler.
static _getAllReferences($a_id)
get all reference ids of object
__construct($a_user_id=0)
Constructor public.
diffEntriesFromResult(&$result_obj)
diff entries of this instance and another result object Used for search in results ...
$a_type
Definition: workflow.php:92
static _getInstance($a_usr_id)
Get singleton instance.
foreach($_POST as $key=> $value) $res
$ilUser
Definition: imgupload.php:18
__updateResultChilds($a_ref_id, $a_childs)
Update childs for a specific result.
addResult($a_ref_id, $a_obj_id, $a_type)
add search result Results are stored with &#39;ref_id&#39;.
__updateEntryChilds($a_obj_id, $a_childs)
Update childs for a specific entry.
static _lookupType($a_id, $a_reference=false)
lookup object type
$row
intersectEntries(&$result_obj)
Build intersection of entries (all entries that are present in both result sets)
setRequiredPermission($a_permission)
Set the required permission for the rbac checks in function &#39;filter()&#39;.
mergeEntries(&$result_obj)
merge entries of this instance and another result object
global $ilDB
numEntries()
Check number of entries public.
filter($a_root_node, $check_and)
Filter search result.
callListeners($a_ref_id, &$a_data)
save($a_type=DEFAULT_SEARCH)
Save search results.
preventOverwritingMaxhits($a_flag=null)
If you call this function and pass "true" the maxhits setting will not be overwritten in __initSearch...