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
34include_once('Services/Search/classes/class.ilUserSearchCache.php');
35
36define('DEFAULT_SEARCH',0);
37define('ADVANCED_SEARCH',1);
38define('ADVANCED_MD_SEARCH',4);
39
41{
42 var $permission = 'visible';
43
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;
55
56 // Stores info if MAX HITS is reached or not
57 var $limit_reached = false;
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
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
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?>
An exception for terminatinating execution or to throw for unit testing.
const DEFAULT_SEARCH
static _getAllReferences($a_id)
get all reference ids of object
static _lookupType($a_id, $a_reference=false)
lookup object type
addObserver(&$a_class, $a_method)
The observer is used to call functions for filtering result.
setRequiredPermission($a_permission)
Set the required permission for the rbac checks in function 'filter()'.
__construct($a_user_id=0)
Constructor @access public.
getUniqueResults()
Get unique results.
mergeEntries(&$result_obj)
merge entries of this instance and another result object
save($a_type=DEFAULT_SEARCH)
Save search results.
isOffsetReached($a_counter)
Check if offset is reached.
initUserSearchCache()
Init user search cache.
filterResults($a_root_node)
Filter search area of result set @access public.
diffEntriesFromResult(&$result_obj)
diff entries of this instance and another result object Used for search in results
filter($a_root_node, $check_and)
Filter search result.
numEntries()
Check number of entries @access public.
callListeners($a_ref_id, &$a_data)
addEntry($a_obj_id, $a_type, $found, $a_child_id=0)
add search result entry Entries are stored with 'obj_id'.
getResultIds()
get result ids
addResult($a_ref_id, $a_obj_id, $a_type)
add search result Results are stored with 'ref_id'.
__updateResultChilds($a_ref_id, $a_childs)
Update childs for a specific result.
read($a_type=DEFAULT_SEARCH)
read search results
__updateEntryChilds($a_obj_id, $a_childs)
Update childs for a specific entry.
preventOverwritingMaxhits($a_flag=null)
If you call this function and pass "true" the maxhits setting will not be overwritten in __initSearch...
intersectEntries(&$result_obj)
Build intersection of entries (all entries that are present in both result sets)
static _getInstance($a_usr_id)
Get singleton instance.
$counter
$ref_id
Definition: sahs_server.php:39
global $ilDB
$ilUser
Definition: imgupload.php:18
$a_type
Definition: workflow.php:93