ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilSearch.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
5include_once './Services/Search/classes/class.ilQueryParser.php';
6
15{
16 protected $qp = null;
17
23 public $ilias;
24 public $lng;
26 public $user_id; // INTEGER USED FOR SAVED RESULTS
27 public $search_string; // INPUT FROM SEARCH FORM
28 public $parsed_str; // PARSED INPUT
29 public $combination; // STRING 'and' or 'or'
30 public $min_word_length = 3; // Define minimum character length for queries
31 public $search_for; // OBJECT TYPE 'usr','grp','lm','dbk'
32 public $search_in; // STRING SEARCH IN 'content' OR 'meta'
33 public $search_type; // STRING 'new' or 'result'
34 public $result; // RESULT SET array['object_type']['counter']
35 public $perform_update; // UPDATE USER SEARCH HISTORY default is true SEE function setPerformUpdate()
36 public $read_db_result; // READ db result true/false
37
38 public $allow_empty_search; // ALLOW EMPTY SEARCH TERM use setEmtySearch(true | false) TO SET THIS VALUE DEFAULT (FALSE)
43 public function __construct($a_user_id = 0, $a_read = false)
44 {
45 global $ilias,$rbacsystem,$lng;
46
47 // Initiate variables
48 $this->ilias =&$ilias;
49 $this->lng =&$lng;
50 $this->lng->loadLanguageModule("search");
51 $this->rbacsystem =&$rbacsystem;
52 $this->user_id = $a_user_id;
53
54 $this->setPerformUpdate(true);
55 $this->setEmptySearch(false);
56 $this->read_db_result = $a_read;
57
58 // READ OLD SEARCH RESULTS FROM DATABASE
59 #$this->__readDBResult();
60 }
61
62 // SET METHODS
63 public function setSearchString($a_search_str)
64 {
65 $this->search_string = trim($a_search_str);
66 }
67 public function setCombination($a_combination)
68 {
69 // 'and' or 'or'
70 $this->combination = $a_combination;
71 }
72 public function setSearchFor($a_search_for)
73 {
74 $this->search_for = $a_search_for;
75 }
76 public function setSearchIn($a_search_in)
77 {
78 $this->search_in = $a_search_in;
79 }
80 public function setResult($a_result)
81 {
82 $this->result = $a_result;
83 }
84 public function setSearchType($a_type)
85 {
86 $this->search_type = $a_type;
87 }
88 public function setPerformUpdate($a_value)
89 {
90 $this->perform_update = $a_value;
91 }
92 public function setEmptySearch($a_value)
93 {
94 $this->allow_empty_search = $a_value;
95 }
96
97 public function setMinWordLength($a_min_word_length)
98 {
99 $this->min_word_length = $a_min_word_length;
100 }
101 public function getMinWordLength()
102 {
104 }
105
106 // GET MEHODS
107 public function getUserId()
108 {
109 return $this->user_id;
110 }
111 public function getSearchString()
112 {
114 }
115 public function getCombination()
116 {
117 return $this->combination ? $this->combination : "or";
118 }
119 public function getSearchFor()
120 {
121 return $this->search_for ? $this->search_for : array();
122 }
123 public function getSearchIn()
124 {
125 return $this->search_in ? $this->search_in : array();
126 }
127 public function getSearchInByType($a_type)
128 {
129 if ($a_type == 'lm' or $a_type == 'dbk') {
130 return $this->search_in[$a_type];
131 } else {
132 return false;
133 }
134 }
135 public function getResults()
136 {
137 return $this->result ? $this->result : array();
138 }
139 public function getResultByType($a_type)
140 {
141 return $this->result[$a_type] ? $this->result[$a_type] : array();
142 }
143 public function getSearchType()
144 {
145 return $this->search_type;
146 }
147 public function getPerformUpdate()
148 {
150 }
151 public function getEmptySearch()
152 {
154 }
155
156
157 // PUBLIC
158 public function getNumberOfResults()
159 {
160 $number = count($this->getResultByType("usr")) + count($this->getResultByType("grp")) + count($this->getResultByType("role"));
161
162 $tmp_res = $this->getResultByType("dbk");
163 $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
164
165 $tmp_res = $this->getResultByType("lm");
166 $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
167
168 return $number;
169 }
170
171 public function validate(&$message)
172 {
173 $this->initQueryParser();
174
175 if (!$this->qp->validate()) {
176 $message = $this->qp->getMessage();
177 return false;
178 }
179 return true;
180 }
181
182 public function performSearch()
183 {
184 global $objDefinition, $ilBench;
185
186 $ilBench->start("Search", "performSearch");
187
188 $this->initQueryParser();
189
190 $result = array("usr" => array(),
191 "grp" => array(),
192 "lm" => array(),
193 "dbk" => array(),
194 "role"=> array());
195
196 foreach ($this->getSearchFor() as $obj_type) {
197 switch ($obj_type) {
198 case "usr":
199 $result['usr'] = $this->performUserSearch();
200 break;
201
202 case "grp":
203 $result['grp'] = $this->performObjectSearch('grp');
204 break;
205
206 case "lm":
207 $result['lm'] = $this->performObjectSearch('lm');
208 break;
209
210 case "dbk":
211 $result['dbk'] = $this->performObjectSearch('dbk');
212 break;
213
214 case "role":
215 $result['role'] = $this->performRoleSearch();
216 break;
217 }
218 }
219
220 $this->setResult($result);
221 $this->__validateResults();
222
223 if ($this->getPerformUpdate()) {
224 $this->__updateDBResult();
225 }
226
227 $ilBench->stop("Search", "performSearch");
228
229 return true;
230 }
231
232
233 // PRIVATE METHODS
234
235 public function __parseSearchString()
236 {
237 $tmp_arr = explode(" ", $this->getSearchString());
238 $this->parsed_str["and"] = $this->parsed_str["or"] = $this->parsed_str["not"] = array();
239
240 foreach ($tmp_arr as $word) {
241 #$word = trim($word);
242 $word = $this->__prepareWord($word);
243 if ($word) {
244 if (substr($word, 0, 1) == '+') {
245 $this->parsed_str["all"][] = substr($word, 1);
246 $this->parsed_str["and"][] = substr($word, 1);
247 continue;
248 }
249
250 if (substr($word, 0, 1) == '-') {
251 // better parsed_str["allmost_all"] ;-)
252 #$this->parsed_str["all"][] = substr($word,1);
253 $this->parsed_str["not"][] = substr($word, 1);
254 continue;
255 }
256
257 if ($this->getCombination() == 'and') {
258 $this->parsed_str["all"][] = $word;
259 $this->parsed_str["and"][] = $word;
260 continue;
261 }
262
263 if ($this->getCombination() == 'or') {
264 $this->parsed_str["all"][] = $word;
265 $this->parsed_str["or"][] = $word;
266 continue;
267 }
268 }
269 }
270 }
271
272 public function __updateDBResult()
273 {
274 global $ilDB;
275
276 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID) {
277 $ilDB->manipulate("DELETE FROM usr_search " .
278 "WHERE usr_id = " . $ilDB->quote($this->getUserId(), 'integer') . " " .
279 "AND search_type = 0 ");
280
281 $ilDB->insert('usr_search', array(
282 'usr_id' => array('integer',$this->getUserId()),
283 'search_result' => array('clob',serialize($this->getResults())),
284 'checked' => array('clob',serialize(array())),
285 'failed' => array('clob',serialize(array())),
286 'page' => array('integer',0),
287 'search_type' => array('integer',0),
288 'query' => array('text',''),
289 'root' => array('integer',ROOT_FOLDER_ID)));
290
291 return true;
292 }
293
294 return false;
295 }
296
297 public function __readDBResult()
298 {
299 global $ilDB;
300
301 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID and $this->read_db_result) {
302 $query = "SELECT search_result FROM usr_search " .
303 "WHERE usr_id = " . $ilDB->quote($this->getUserId(), 'integer');
304
305
306 $res = $ilDB->query($query);
307 if ($res->numRows()) {
309 $this->setResult(unserialize(stripslashes($row->search_result)));
310 } else {
311 $this->setResult(array("usr" => array(),
312 "grp" => array(),
313 "lm" => array(),
314 "dbk" => array()));
315 }
316 } else {
317 $this->setResult(array("usr" => array(),
318 "grp" => array(),
319 "lm" => array(),
320 "dbk" => array()));
321 }
322
323 $this->__validateResults();
324 $this->__updateDBResult();
325 return true;
326 }
327
328
329 public function __checkAccess($a_results, $a_type)
330 {
331 global $ilAccess;
332
333 if (is_array($a_results)) {
334 foreach ($a_results as $result) {
335 if ($ilAccess->checkAccess('read', '', $result['id'])) {
336 $checked_result[] = $result;
337 break;
338 }
339 }
340 }
341 return $checked_result ? $checked_result : array();
342 }
343
344
345 public function __validateResults()
346 {
347 global $tree;
348
349 $new_result = array();
350
351
352 // check lm meta
353
354 $this->result['lm']['meta'] = $this->__checkAccess($this->result['lm']['meta'], 'lm');
355 if (is_array($this->result['lm']['meta'])) {
356 foreach ($this->result['lm']['meta'] as $data) {
357 if ($tree->isInTree($data['id'])) {
358 $new_result['lm']['meta'][] = $data;
359 }
360 }
361 }
362 $this->result['lm']['content'] = $this->__checkAccess($this->result['lm']['content'], 'lm');
363 if (is_array($this->result['lm']['content'])) {
364 foreach ($this->result['lm']['content'] as $data) {
365 if ($tree->isInTree($data['id'])) {
366 $new_result['lm']['content'][] = $data;
367 }
368 }
369 }
370 $this->result['dbk']['meta'] = $this->__checkAccess($this->result['dbk']['meta'], 'dbk');
371 if (is_array($this->result['dbk']['meta'])) {
372 foreach ($this->result['dbk']['meta'] as $data) {
373 if ($tree->isInTree($data['id'])) {
374 $new_result['dbk']['meta'][] = $data;
375 }
376 }
377 }
378 $this->result['dbk']['content'] = $this->__checkAccess($this->result['dbk']['content'], 'dbk');
379 if (is_array($this->result['dbk']['content'])) {
380 foreach ($this->result['dbk']['content'] as $data) {
381 if ($tree->isInTree($data['id'])) {
382 $new_result['dbk']['content'][] = $data;
383 }
384 }
385 }
386 $this->result['grp'] = $this->__checkAccess($this->result['grp'], 'grp');
387 if (is_array($this->result['grp'])) {
388 foreach ($this->result['grp'] as $data) {
389 if ($tree->isInTree($data['id'])) {
390 $new_result['grp'][] = $data;
391 }
392 }
393 }
394 if (is_array($this->result['usr'])) {
395 foreach ($this->result['usr'] as $user) {
396 if ($tmp_obj =&ilObjectFactory::getInstanceByObjId($user['id'], false)) {
397 $new_result['usr'][] = $user;
398 }
399 }
400 }
401 if (is_array($this->result['role'])) {
402 foreach ($this->result['role'] as $user) {
403 if ($tmp_obj =&ilObjectFactory::getInstanceByObjId($user['id'], false)) {
404 $new_result['role'][] = $user;
405 }
406 }
407 }
408 $this->setResult($new_result);
409
410 return true;
411 }
412
413 public function __prepareWord($a_word)
414 {
415 $word = trim($a_word);
416
417 if (!preg_match('/\*/', $word)) {
418 return '%' . $word . '%';
419 }
420 if (preg_match('/^\*/', $word)) {
421 return str_replace('*', '%', $word);
422 } else {
423 return '% ' . str_replace('*', '%', $word);
424 }
425 }
426
431 protected function performUserSearch()
432 {
433 include_once 'Services/Search/classes/class.ilObjectSearchFactory.php';
434
435 $user_search = ilObjectSearchFactory::_getUserSearchInstance($this->qp);
436 $res = new ilSearchResult($this->getUserId());
437
438 foreach (array("login","firstname","lastname","title",
439 "email","institution","street","city","zipcode","country","phone_home","fax") as $field) {
440 $user_search->setFields(array($field));
441 $tmp_res = $user_search->performSearch();
442
443 $res->mergeEntries($tmp_res);
444 }
445
446 foreach ($res->getEntries() as $id => $data) {
447 $tmp['id'] = $id;
448 $users[] = $tmp;
449 }
450 return $users ? $users : array();
451 }
452
457 protected function performObjectSearch($a_type)
458 {
459 include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php';
460 $object_search = new ilLikeObjectSearch($this->qp);
461 $object_search->setFilter(array($a_type));
462 $res = $object_search->performSearch();
463 $res->filter(ROOT_FOLDER_ID, $this->getCombination());
464
465 $counter = 0;
466 foreach ($res->getResultIds() as $id) {
467 $objs[$counter++]['id'] = $id;
468 }
469 return $objs ? $objs : array();
470 }
471
477 protected function performRoleSearch()
478 {
479 // Perform like search
480 include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php';
481 $object_search = new ilLikeObjectSearch($this->qp);
482 $object_search->setFilter(array('role'));
483
484 $res = $object_search->performSearch();
485 foreach ($res->getEntries() as $id => $data) {
486 $tmp['id'] = $id;
487 $roles[] = $tmp;
488 }
489 return $roles ? $roles : array();
490 }
491
496 protected function initQueryParser()
497 {
498 if ($this->qp) {
499 return true;
500 }
501
502 $this->qp = new ilQueryParser($this->getSearchString());
503 $this->qp->setCombination($this->getCombination() == 'and' ? QP_COMBINATION_AND : QP_COMBINATION_OR);
504 $this->qp->setMinWordLength($this->getMinWordLength());
505 $this->qp->parse();
506 }
507} // END class.ilSearch
$users
Definition: authpage.php:44
An exception for terminatinating execution or to throw for unit testing.
const QP_COMBINATION_OR
const QP_COMBINATION_AND
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
static _getUserSearchInstance($query_parser)
get reference of ilLikeUserSearch
initQueryParser()
init query parser
performObjectSearch($a_type)
perform object search
setEmptySearch($a_value)
setSearchString($a_search_str)
getResultByType($a_type)
setSearchIn($a_search_in)
setCombination($a_combination)
setSearchType($a_type)
setSearchFor($a_search_for)
__prepareWord($a_word)
setResult($a_result)
getSearchInByType($a_type)
__checkAccess($a_results, $a_type)
__construct($a_user_id=0, $a_read=false)
Constructor @access public.
setMinWordLength($a_min_word_length)
performUserSearch()
perform a search for users
validate(&$message)
setPerformUpdate($a_value)
$counter
if(!array_key_exists('StateId', $_REQUEST)) $id
global $ilBench
Definition: ilias.php:18
catch(Exception $e) $message
redirection script todo: (a better solution should control the processing via a xml file)
$query
foreach($_POST as $key=> $value) $res
global $ilDB
$a_type
Definition: workflow.php:92