ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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  var $permission = 'visible';
43 
44  var $user_id;
45  var $entries = array();
46  var $results = array();
47  var $observers = array();
48 
49  protected $search_cache = null;
50  protected $offset = 0;
51 
52  // OBJECT VARIABLES
53  var $ilias;
54  var $ilAccess;
55 
56  // Stores info if MAX HITS is reached or not
57  var $limit_reached = false;
58  var $result;
59 
60  protected $preventOverwritingMaxhits = false;
61 
66  function __construct($a_user_id = 0)
67  {
69 
70  $this->ilAccess = $ilAccess;
71  if($a_user_id)
72  {
73  $this->user_id = $a_user_id;
74  }
75  else
76  {
77  $this->user_id = $ilUser->getId();
78  }
80  $this->initUserSearchCache();
81 
82  $this->db = $ilDB;
83  }
84 
88  function setRequiredPermission($a_permission)
89  {
90  $this->permission = $a_permission;
91  }
92 
94  {
95  return $this->permission;
96  }
97 
98 
99  function setUserId($a_user_id)
100  {
101  $this->user_id = $a_user_id;
102  }
103  function getUserId()
104  {
105  return $this->user_id;
106  }
107 
108  function getEntries()
109  {
110  return $this->entries ? $this->entries : array();
111  }
112 
113  function isLimitReached()
114  {
115  return $this->limit_reached ? true : false;
116  }
117 
118  function setMaxHits($a_max_hits)
119  {
120  $this->max_hits = $a_max_hits;
121  }
122  function getMaxHits()
123  {
124  return $this->max_hits;
125  }
126 
134  public function isOffsetReached($a_counter)
135  {
136  return ($a_counter < $this->offset) ? false : true;
137  }
138 
149  function addEntry($a_obj_id,$a_type,$found,$a_child_id = 0)
150  {
151  // Create new entry if it not exists
152  if(!$this->entries[$a_obj_id])
153  {
154  $this->entries[$a_obj_id]['obj_id'] = $a_obj_id;
155  $this->entries[$a_obj_id]['type'] = $a_type;
156  $this->entries[$a_obj_id]['found'] = $found;
157 
158  if($a_child_id and $a_child_id != $a_obj_id)
159  {
160  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
161  }
162  }
163  else
164  {
165  // replace or add child ('pg','st') id
166  if($a_child_id and $a_child_id != $a_obj_id)
167  {
168  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
169  }
170 
171  // UPDATE FOUND
172  $counter = 0;
173  foreach($found as $position)
174  {
175  if($position)
176  {
177  $this->entries[$a_obj_id]['found'][$counter] = $position;
178  }
179  $counter++;
180  }
181  }
182  return true;
183  }
184 
190  function numEntries()
191  {
192  return count($this->getEntries());
193  }
194 
201  function mergeEntries(&$result_obj)
202  {
203  foreach($result_obj->getEntries() as $entry)
204  {
205  $this->addEntry($entry['obj_id'],$entry['type'],$entry['found']);
206  $this->__updateEntryChilds($entry['obj_id'],$entry['child']);
207  }
208  return true;
209  }
210 
218  function diffEntriesFromResult(&$result_obj)
219  {
220  $new_entries = $this->getEntries();
221  $this->entries = array();
222 
223  // Get all checked objects
224  foreach($this->search_cache->getCheckedItems() as $ref_id => $obj_id)
225  {
226  if(isset($new_entries[$obj_id]))
227  {
228  $this->addEntry($new_entries[$obj_id]['obj_id'],
229  $new_entries[$obj_id]['type'],
230  $new_entries[$obj_id]['found']);
231  $this->__updateEntryChilds($new_entries[$obj_id]['obj_id'],
232  $new_entries[$obj_id]['child']);
233  }
234  }
235  }
236 
243  function intersectEntries(&$result_obj)
244  {
245  $new_entries = $this->getEntries();
246  $this->entries = array();
247 
248  foreach($result_obj->getEntries() as $entry)
249  {
250  $obj_id = $entry['obj_id'];
251  if(isset($new_entries[$obj_id]))
252  {
253  $this->addEntry($new_entries[$obj_id]['obj_id'],
254  $new_entries[$obj_id]['type'],
255  $new_entries[$obj_id]['found']);
256 
257  $this->__updateEntryChilds($new_entries[$obj_id]['obj_id'],
258  $new_entries[$obj_id]['child']);
259  }
260  }
261  }
262 
263 
273  function addResult($a_ref_id,$a_obj_id,$a_type)
274  {
275  $this->results[$a_ref_id]['ref_id'] = $a_ref_id;
276  $this->results[$a_ref_id]['obj_id'] = $a_obj_id;
277  $this->results[$a_ref_id]['type'] = $a_type;
278  }
279 
280  function getResults()
281  {
282  return $this->results ? $this->results : array();
283  }
284 
291  public function getResultIds()
292  {
293  foreach($this->getResults() as $id => $tmp)
294  {
295  $ids[] = $id;
296  }
297  return $ids ? $ids : array();
298  }
299 
300  function getResultsByObjId()
301  {
302  $tmp_res = array();
303  foreach($this->getResults() as $ref_id => $res_data)
304  {
305  $tmp_res[$res_data['obj_id']][] = $ref_id;
306  }
307  return $tmp_res ? $tmp_res : array();
308  }
309 
310 
317  function getUniqueResults()
318  {
319  $obj_ids = array();
320  foreach($this->results as $result)
321  {
322  if(in_array($result['obj_id'],$obj_ids))
323  {
324  continue;
325  }
326  $obj_ids[] = $result['obj_id'];
327  $objects[] = $result;
328  }
329  return $objects ? $objects : array();
330  }
331 
333  {
334  $res = array();
335 
336  foreach($this->getResults() as $result)
337  {
338  $res[$result['ref_id']] = $result['obj_id'];
339  }
340  return $res;
341  }
342 
343  public function getSubitemIds()
344  {
345  $res = array();
346  foreach($this->getResults() as $row)
347  {
348  $res[$row['obj_id']] = $row['child'];
349  }
350  return $res ? $res : array();
351  }
352 
353 
354 
367  public function filter($a_root_node,$check_and)
368  {
369  global $tree;
370 
371  // get ref_ids and check access
372  $counter = 0;
373  $offset_counter = 0;
374  foreach($this->getEntries() as $entry)
375  {
376  // boolean and failed continue
377  if($check_and and in_array(0,$entry['found']))
378  {
379  continue;
380  }
381  // Types like role, rolt, user do not need rbac checks
382  $type = ilObject::_lookupType($entry['obj_id']);
383  if($type == 'rolt' or $type == 'usr' or $type == 'role')
384  {
385  if($this->callListeners($entry['obj_id'],$entry))
386  {
387  $this->addResult($entry['obj_id'],$entry['obj_id'],$type);
388  $counter += count($entry['child']);
389  // Stop if maximum of hits is reached
390  if(++$counter > $this->getMaxHits())
391  {
392  $this->limit_reached = true;
393  return true;
394  }
395  }
396  continue;
397  }
398  // Check referenced objects
399  foreach(ilObject::_getAllReferences($entry['obj_id']) as $ref_id)
400  {
401  // Failed check: if ref id check is failed by previous search
402  if($this->search_cache->isFailed($ref_id))
403  {
404  continue;
405  }
406  // Offset check
407  if($this->search_cache->isChecked($ref_id) and !$this->isOffsetReached($offset_counter))
408  {
409  ++$offset_counter;
410  continue;
411  }
412 
413  if(!$this->callListeners($ref_id, $entry))
414  {
415  continue;
416  }
417 
418 
419 
420  // RBAC check
421  $type = ilObject::_lookupType($ref_id, true);
422  if($this->ilAccess->checkAccessOfUser($this->getUserId(),
423  $this->getRequiredPermission(),
424  '',
425  $ref_id,
426  $type,
427  $entry['obj_id']))
428  {
429  if($a_root_node == ROOT_FOLDER_ID or $tree->isGrandChild($a_root_node,$ref_id))
430  {
431  // Call listeners
432  #if($this->callListeners($ref_id,$entry))
433  if(1)
434  {
435  $this->addResult($ref_id,$entry['obj_id'],$type);
436  $this->search_cache->appendToChecked($ref_id,$entry['obj_id']);
437  $this->__updateResultChilds($ref_id,$entry['child']);
438 
439  $counter++;
440  $offset_counter++;
441  // Stop if maximum of hits is reached
442 
443  if($counter >= $this->getMaxHits())
444  {
445  $this->limit_reached = true;
446  $this->search_cache->setResults($this->results);
447  return true;
448  }
449  }
450  }
451  continue;
452  }
453  $this->search_cache->appendToFailed($ref_id);
454  }
455  }
456  $this->search_cache->setResults($this->results);
457  return false;
458  }
459 
465  function filterResults($a_root_node)
466  {
467  global $tree;
468 
469  $tmp_results = $this->getResults();
470  $this->results = array();
471  foreach($tmp_results as $result)
472  {
473  if($tree->isGrandChild($a_root_node,$result['ref_id']) and $tree->isInTree($result['ref_id']))
474  {
475  $this->addResult($result['ref_id'],$result['obj_id'],$result['type']);
476  $this->__updateResultChilds($result['ref_id'],$result['child']);
477  }
478  }
479 
480  return true;
481  }
482 
483 
491  {
492  $this->search_cache->save();
493  return false;
494  }
502  {
503  $this->results = $this->search_cache->getResults();
504  }
505 
506  // PRIVATE
514  function __updateEntryChilds($a_obj_id,$a_childs)
515  {
516  if($this->entries[$a_obj_id] and is_array($a_childs))
517  {
518  foreach($a_childs as $child_id)
519  {
520  if($child_id)
521  {
522  $this->entries[$a_obj_id]['child'][$child_id] = $child_id;
523  }
524  }
525  return true;
526  }
527  return false;
528  }
536  function __updateResultChilds($a_ref_id,$a_childs)
537  {
538  if($this->results[$a_ref_id] and is_array($a_childs))
539  {
540  foreach($a_childs as $child_id)
541  {
542  $this->results[$a_ref_id]['child'][$child_id] = $child_id;
543  }
544  return true;
545  }
546  return false;
547  }
548 
549 
550 
552  {
553  include_once 'Services/Search/classes/class.ilSearchSettings.php';
554 
555  $this->search_settings = new ilSearchSettings();
556  if(!$this->preventOverwritingMaxhits())
557  $this->setMaxHits($this->search_settings->getMaxHits());
558  }
559 
566  protected function initUserSearchCache()
567  {
568  include_once('Services/Search/classes/class.ilUserSearchCache.php');
569  $this->search_cache = ilUserSearchCache::_getInstance($this->getUserId());
570  $this->offset = $this->getMaxHits() * ($this->search_cache->getResultPageNumber() - 1) ;
571  }
572 
582  public function preventOverwritingMaxhits($a_flag = null)
583  {
584  if(null === $a_flag)
585  {
587  }
588 
589  $this->preventOverwritingMaxhits = $a_flag;
590 
591  return $this;
592  }
593 
603  function addObserver(&$a_class,$a_method)
604  {
605  $this->observers[] = array('class' => $a_class,
606  'method' => $a_method);
607  return true;
608  }
609  function callListeners($a_ref_id,&$a_data)
610  {
611  foreach($this->observers as $observer)
612  {
613  $class =& $observer['class'];
614  $method = $observer['method'];
615 
616  if(!$class->$method($a_ref_id,$a_data))
617  {
618  return false;
619  }
620  }
621  return true;
622  }
623 } // END class.Search
624 ?>
read($a_type=DEFAULT_SEARCH)
read search results
isOffsetReached($a_counter)
Check if offset is reached.
const DEFAULT_SEARCH
getResultIds()
get result ids
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.
initUserSearchCache()
Init user search cache.
addObserver(&$a_class, $a_method)
The observer is used to call functions for filtering result.
getUniqueResults()
Get unique results.
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 ...
$counter
$a_type
Definition: workflow.php:93
static _getInstance($a_usr_id)
Get singleton instance.
$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.
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
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;.
$ref_id
Definition: sahs_server.php: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...