ILIAS  Release_3_10_x_branch Revision 61812
 All Data Structures Namespaces Files Functions Variables Groups Pages
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('SHOP_CONTENT',2);
39 define('SHOP_ADVANCED_SEARCH',3);
40 define('ADVANCED_MD_SEARCH',4);
41 
43 {
44  var $permission = 'visible';
45 
46  var $user_id;
47  var $entries = array();
48  var $results = array();
49  var $observers = array();
50 
51  protected $search_cache = null;
52  protected $offset = 0;
53 
54  // OBJECT VARIABLES
55  var $ilias;
56  var $ilAccess;
57 
58  // Stores info if MAX HITS is reached or not
59  var $limit_reached = false;
60  var $result;
61 
62  protected $preventOverwritingMaxhits = false;
63 
68  function ilSearchResult($a_user_id = 0)
69  {
70  global $ilias,$ilAccess,$ilDB,$ilUser;
71 
72  $this->ilAccess =& $ilAccess;
73  if($a_user_id)
74  {
75  $this->user_id = $a_user_id;
76  }
77  else
78  {
79  $this->user_id = $ilUser->getId();
80  }
82  $this->initUserSearchCache();
83 
84  $this->db =& $ilDB;
85  }
86 
90  function setRequiredPermission($a_permission)
91  {
92  $this->permission = $a_permission;
93  }
94 
96  {
97  return $this->permission;
98  }
99 
100 
101  function setUserId($a_user_id)
102  {
103  $this->user_id = $a_user_id;
104  }
105  function getUserId()
106  {
107  return $this->user_id;
108  }
109 
110  function getEntries()
111  {
112  return $this->entries ? $this->entries : array();
113  }
114 
115  function isLimitReached()
116  {
117  return $this->limit_reached ? true : false;
118  }
119 
120  function setMaxHits($a_max_hits)
121  {
122  $this->max_hits = $a_max_hits;
123  }
124  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  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  {
156  $this->entries[$a_obj_id]['obj_id'] = $a_obj_id;
157  $this->entries[$a_obj_id]['type'] = $a_type;
158  $this->entries[$a_obj_id]['found'] = $found;
159 
160  if($a_child_id and $a_child_id != $a_obj_id)
161  {
162  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
163  }
164  }
165  else
166  {
167  // replace or add child ('pg','st') id
168  if($a_child_id and $a_child_id != $a_obj_id)
169  {
170  $this->entries[$a_obj_id]['child'][$a_child_id] = $a_child_id;
171  }
172 
173  // UPDATE FOUND
174  $counter = 0;
175  foreach($found as $position)
176  {
177  if($position)
178  {
179  $this->entries[$a_obj_id]['found'][$counter] = $position;
180  }
181  $counter++;
182  }
183  }
184  return true;
185  }
186 
192  function numEntries()
193  {
194  return count($this->getEntries());
195  }
196 
203  function mergeEntries(&$result_obj)
204  {
205  foreach($result_obj->getEntries() as $entry)
206  {
207  $this->addEntry($entry['obj_id'],$entry['type'],$entry['found']);
208  $this->__updateEntryChilds($entry['obj_id'],$entry['child']);
209  }
210  return true;
211  }
212 
220  function diffEntriesFromResult(&$result_obj)
221  {
222  $new_entries = $this->getEntries();
223  $this->entries = array();
224 
225  // Get all checked objects
226  foreach($this->search_cache->getCheckedItems() as $ref_id => $obj_id)
227  {
228  if(isset($new_entries[$obj_id]))
229  {
230  $this->addEntry($new_entries[$obj_id]['obj_id'],
231  $new_entries[$obj_id]['type'],
232  $new_entries[$obj_id]['found']);
233  $this->__updateEntryChilds($new_entries[$obj_id]['obj_id'],
234  $new_entries[$obj_id]['child']);
235  }
236  }
237  }
238 
245  function intersectEntries(&$result_obj)
246  {
247  $new_entries = $this->getEntries();
248  $this->entries = array();
249 
250  foreach($result_obj->getEntries() as $entry)
251  {
252  $obj_id = $entry['obj_id'];
253  if(isset($new_entries[$obj_id]))
254  {
255  $this->addEntry($new_entries[$obj_id]['obj_id'],
256  $new_entries[$obj_id]['type'],
257  $new_entries[$obj_id]['found']);
258 
259  $this->__updateEntryChilds($new_entries[$obj_id]['obj_id'],
260  $new_entries[$obj_id]['child']);
261  }
262  }
263  }
264 
265 
275  function addResult($a_ref_id,$a_obj_id,$a_type)
276  {
277  $this->results[$a_ref_id]['ref_id'] = $a_ref_id;
278  $this->results[$a_ref_id]['obj_id'] = $a_obj_id;
279  $this->results[$a_ref_id]['type'] = $a_type;
280  }
281 
282  function getResults()
283  {
284  return $this->results ? $this->results : array();
285  }
286 
293  public function getResultIds()
294  {
295  foreach($this->getResults() as $id => $tmp)
296  {
297  $ids[] = $id;
298  }
299  return $ids ? $ids : array();
300  }
301 
302  function getResultsByObjId()
303  {
304  $tmp_res = array();
305  foreach($this->getResults() as $ref_id => $res_data)
306  {
307  $tmp_res[$res_data['obj_id']][] = $ref_id;
308  }
309  return $tmp_res ? $tmp_res : array();
310  }
311 
312 
319  function getUniqueResults()
320  {
321  $obj_ids = array();
322  foreach($this->results as $result)
323  {
324  if(in_array($result['obj_id'],$obj_ids))
325  {
326  continue;
327  }
328  $obj_ids[] = $result['obj_id'];
329  $objects[] = $result;
330  }
331  return $objects ? $objects : array();
332  }
333 
335  {
336  foreach($this->getResults() as $result)
337  {
338  switch($result['type'])
339  {
340  // learning material
341  case "sahs":
342  case "lm":
343  case "dbk":
344  case "htlm":
345  $type = "lres";
346  break;
347 
348  default:
349  $type = $result['type'];
350  break;
351  }
352  $title = ilObject::_lookupTitle($result['obj_id']);
353  $description = ilObject::_lookupDescription($result['obj_id']);
354 
355  $presentation_result[$type][] = array('ref_id' => $result['ref_id'],
356  'title' => $title,
357  'description' => $description,
358  'type' => $result['type'],
359  'obj_id' => $result['obj_id'],
360  'child' => $result['child']);
361  }
362  return $presentation_result ? $presentation_result : array();
363  }
364 
377  public function filter($a_root_node,$check_and)
378  {
379  global $tree;
380 
381  // get ref_ids and check access
382  $counter = 0;
383  $offset_counter = 0;
384  foreach($this->getEntries() as $entry)
385  {
386  // boolean and failed continue
387  if($check_and and in_array(0,$entry['found']))
388  {
389  continue;
390  }
391  // Types like role, rolt, user do not need rbac checks
392  $type = ilObject::_lookupType($entry['obj_id']);
393  if($type == 'rolt' or $type == 'usr' or $type == 'role')
394  {
395  if($this->callListeners($entry['obj_id'],$entry))
396  {
397  $this->addResult($entry['obj_id'],$entry['obj_id'],$type);
398  $counter += count($entry['child']);
399  // Stop if maximum of hits is reached
400  if(++$counter > $this->getMaxHits())
401  {
402  $this->limit_reached = true;
403  return true;
404  }
405  }
406  continue;
407  }
408  // Check referenced objects
409  foreach(ilObject::_getAllReferences($entry['obj_id']) as $ref_id)
410  {
411  // Failed check: if ref id check is failed by previous search
412  if($this->search_cache->isFailed($ref_id))
413  {
414  continue;
415  }
416  // Offset check
417  if($this->search_cache->isChecked($ref_id) and !$this->isOffsetReached($offset_counter))
418  {
419  ++$offset_counter;
420  continue;
421  }
422  // RBAC check
423  $type = ilObject::_lookupType($ref_id, true);
424  if($this->ilAccess->checkAccessOfUser($this->getUserId(),
425  $this->getRequiredPermission(),
426  '',
427  $ref_id,
428  $type,
429  $entry['obj_id']))
430  {
431  if($a_root_node == ROOT_FOLDER_ID or $tree->isGrandChild($a_root_node,$ref_id))
432  {
433  // Call listeners
434  if($this->callListeners($ref_id,$entry))
435  {
436  $this->addResult($ref_id,$entry['obj_id'],$type);
437  $this->search_cache->appendToChecked($ref_id,$entry['obj_id']);
438  $this->__updateResultChilds($ref_id,$entry['child']);
439 
440  $counter++;
441  $offset_counter++;
442  // Stop if maximum of hits is reached
443 
444  if($counter >= $this->getMaxHits())
445  {
446  $this->limit_reached = true;
447  $this->search_cache->setResults($this->results);
448  return true;
449  }
450  }
451  }
452  continue;
453  }
454  $this->search_cache->appendToFailed($ref_id);
455  }
456  }
457  $this->search_cache->setResults($this->results);
458  return false;
459  }
460 
466  function filterResults($a_root_node)
467  {
468  global $tree;
469 
470  $tmp_results = $this->getResults();
471  $this->results = array();
472  foreach($tmp_results as $result)
473  {
474  if($tree->isGrandChild($a_root_node,$result['ref_id']) and $tree->isInTree($result['ref_id']))
475  {
476  $this->addResult($result['ref_id'],$result['obj_id'],$result['type']);
477  $this->__updateResultChilds($result['ref_id'],$result['child']);
478  }
479  }
480 
481  return true;
482  }
483 
484 
491  function save($a_type = DEFAULT_SEARCH)
492  {
493  $this->search_cache->save();
494  return false;
495  }
502  function read($a_type = DEFAULT_SEARCH)
503  {
504  $this->results = $this->search_cache->getResults();
505  }
506 
507  // PRIVATE
515  function __updateEntryChilds($a_obj_id,$a_childs)
516  {
517  if($this->entries[$a_obj_id] and is_array($a_childs))
518  {
519  foreach($a_childs as $child_id)
520  {
521  if($child_id)
522  {
523  $this->entries[$a_obj_id]['child'][$child_id] = $child_id;
524  }
525  }
526  return true;
527  }
528  return false;
529  }
537  function __updateResultChilds($a_ref_id,$a_childs)
538  {
539  if($this->results[$a_ref_id] and is_array($a_childs))
540  {
541  foreach($a_childs as $child_id)
542  {
543  $this->results[$a_ref_id]['child'][$child_id] = $child_id;
544  }
545  return true;
546  }
547  return false;
548  }
549 
550 
551 
553  {
554  include_once 'Services/Search/classes/class.ilSearchSettings.php';
555 
556  $this->search_settings = new ilSearchSettings();
557  if(!$this->preventOverwritingMaxhits())
558  $this->setMaxHits($this->search_settings->getMaxHits());
559  #$this->setMaxHits(2);
560  }
561 
568  protected function initUserSearchCache()
569  {
570  include_once('Services/Search/classes/class.ilUserSearchCache.php');
571  $this->search_cache = ilUserSearchCache::_getInstance($this->getUserId());
572  $this->offset = $this->getMaxHits() * ($this->search_cache->getResultPageNumber() - 1) ;
573  }
574 
584  public function preventOverwritingMaxhits($a_flag = null)
585  {
586  if(null === $a_flag)
587  {
589  }
590 
591  $this->preventOverwritingMaxhits = $a_flag;
592 
593  return $this;
594  }
595 
605  function addObserver(&$a_class,$a_method)
606  {
607  $this->observers[] = array('class' => $a_class,
608  'method' => $a_method);
609  return true;
610  }
611  function callListeners($a_ref_id,&$a_data)
612  {
613  foreach($this->observers as $observer)
614  {
615  $class =& $observer['class'];
616  $method = $observer['method'];
617 
618  if(!$class->$method($a_ref_id,$a_data))
619  {
620  return false;
621  }
622  }
623  return true;
624  }
625 } // END class.Search
626 ?>