ILIAS  release_4-3 Revision
 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  $res = array();
337 
338  foreach($this->getResults() as $result)
339  {
340  $res[$result['ref_id']] = $result['obj_id'];
341  }
342  return $res;
343  }
344 
345  public function getSubitemIds()
346  {
347  $res = array();
348  foreach($this->getResults() as $row)
349  {
350  $res[$row['obj_id']] = $row['child'];
351  }
352  return $res ? $res : array();
353  }
354 
355 
356 
369  public function filter($a_root_node,$check_and)
370  {
371  global $tree;
372 
373  // get ref_ids and check access
374  $counter = 0;
375  $offset_counter = 0;
376  foreach($this->getEntries() as $entry)
377  {
378  // boolean and failed continue
379  if($check_and and in_array(0,$entry['found']))
380  {
381  continue;
382  }
383  // Types like role, rolt, user do not need rbac checks
384  $type = ilObject::_lookupType($entry['obj_id']);
385  if($type == 'rolt' or $type == 'usr' or $type == 'role')
386  {
387  if($this->callListeners($entry['obj_id'],$entry))
388  {
389  $this->addResult($entry['obj_id'],$entry['obj_id'],$type);
390  $counter += count($entry['child']);
391  // Stop if maximum of hits is reached
392  if(++$counter > $this->getMaxHits())
393  {
394  $this->limit_reached = true;
395  return true;
396  }
397  }
398  continue;
399  }
400  // Check referenced objects
401  foreach(ilObject::_getAllReferences($entry['obj_id']) as $ref_id)
402  {
403  // Failed check: if ref id check is failed by previous search
404  if($this->search_cache->isFailed($ref_id))
405  {
406  continue;
407  }
408  // Offset check
409  if($this->search_cache->isChecked($ref_id) and !$this->isOffsetReached($offset_counter))
410  {
411  ++$offset_counter;
412  continue;
413  }
414 
415  if(!$this->callListeners($ref_id, $entry))
416  {
417  continue;
418  }
419 
420 
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  if(1)
436  {
437  $this->addResult($ref_id,$entry['obj_id'],$type);
438  $this->search_cache->appendToChecked($ref_id,$entry['obj_id']);
439  $this->__updateResultChilds($ref_id,$entry['child']);
440 
441  $counter++;
442  $offset_counter++;
443  // Stop if maximum of hits is reached
444 
445  if($counter >= $this->getMaxHits())
446  {
447  $this->limit_reached = true;
448  $this->search_cache->setResults($this->results);
449  return true;
450  }
451  }
452  }
453  continue;
454  }
455  $this->search_cache->appendToFailed($ref_id);
456  }
457  }
458  $this->search_cache->setResults($this->results);
459  return false;
460  }
461 
467  function filterResults($a_root_node)
468  {
469  global $tree;
470 
471  $tmp_results = $this->getResults();
472  $this->results = array();
473  foreach($tmp_results as $result)
474  {
475  if($tree->isGrandChild($a_root_node,$result['ref_id']) and $tree->isInTree($result['ref_id']))
476  {
477  $this->addResult($result['ref_id'],$result['obj_id'],$result['type']);
478  $this->__updateResultChilds($result['ref_id'],$result['child']);
479  }
480  }
481 
482  return true;
483  }
484 
485 
492  function save($a_type = DEFAULT_SEARCH)
493  {
494  $this->search_cache->save();
495  return false;
496  }
503  function read($a_type = DEFAULT_SEARCH)
504  {
505  $this->results = $this->search_cache->getResults();
506  }
507 
508  // PRIVATE
516  function __updateEntryChilds($a_obj_id,$a_childs)
517  {
518  if($this->entries[$a_obj_id] and is_array($a_childs))
519  {
520  foreach($a_childs as $child_id)
521  {
522  if($child_id)
523  {
524  $this->entries[$a_obj_id]['child'][$child_id] = $child_id;
525  }
526  }
527  return true;
528  }
529  return false;
530  }
538  function __updateResultChilds($a_ref_id,$a_childs)
539  {
540  if($this->results[$a_ref_id] and is_array($a_childs))
541  {
542  foreach($a_childs as $child_id)
543  {
544  $this->results[$a_ref_id]['child'][$child_id] = $child_id;
545  }
546  return true;
547  }
548  return false;
549  }
550 
551 
552 
554  {
555  include_once 'Services/Search/classes/class.ilSearchSettings.php';
556 
557  $this->search_settings = new ilSearchSettings();
558  if(!$this->preventOverwritingMaxhits())
559  $this->setMaxHits($this->search_settings->getMaxHits());
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 ?>