ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
5 include_once './Services/Search/classes/class.ilQueryParser.php';
6 
14 class ilSearch
15 {
16  protected $qp = null;
17 
23  var $ilias;
24  var $lng;
26  var $user_id; // INTEGER USED FOR SAVED RESULTS
27  var $search_string; // INPUT FROM SEARCH FORM
28  var $parsed_str; // PARSED INPUT
29  var $combination; // STRING 'and' or 'or'
30  var $min_word_length = 3; // Define minimum character length for queries
31  var $search_for; // OBJECT TYPE 'usr','grp','lm','dbk'
32  var $search_in; // STRING SEARCH IN 'content' OR 'meta'
33  var $search_type; // STRING 'new' or 'result'
34  var $result; // RESULT SET array['object_type']['counter']
35  var $perform_update; // UPDATE USER SEARCH HISTORY default is true SEE function setPerformUpdate()
36  var $read_db_result; // READ db result true/false
37 
38  var $allow_empty_search; // ALLOW EMPTY SEARCH TERM use setEmtySearch(true | false) TO SET THIS VALUE DEFAULT (FALSE)
43  function ilSearch($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  function setSearchString($a_search_str)
64  {
65  $this->search_string = trim($a_search_str);
66  }
67  function setCombination($a_combination)
68  {
69  // 'and' or 'or'
70  $this->combination = $a_combination;
71  }
72  function setSearchFor($a_search_for)
73  {
74  $this->search_for = $a_search_for;
75  }
76  function setSearchIn($a_search_in)
77  {
78  $this->search_in = $a_search_in;
79  }
80  function setResult($a_result)
81  {
82  $this->result = $a_result;
83  }
84  function setSearchType($a_type)
85  {
86  $this->search_type = $a_type;
87  }
88  function setPerformUpdate($a_value)
89  {
90  $this->perform_update = $a_value;
91  }
92  function setEmptySearch($a_value)
93  {
94  $this->allow_empty_search = $a_value;
95  }
96 
97  function setMinWordLength($a_min_word_length)
98  {
99  $this->min_word_length = $a_min_word_length;
100  }
101  function getMinWordLength()
102  {
103  return $this->min_word_length;
104  }
105 
106  // GET MEHODS
107  function getUserId()
108  {
109  return $this->user_id;
110  }
111  function getSearchString()
112  {
113  return $this->search_string;
114  }
115  function getCombination()
116  {
117  return $this->combination ? $this->combination : "or";
118  }
119  function getSearchFor()
120  {
121  return $this->search_for ? $this->search_for : array();
122  }
123  function getSearchIn()
124  {
125  return $this->search_in ? $this->search_in : array();
126  }
127  function getSearchInByType($a_type)
128  {
129  if($a_type == 'lm' or $a_type == 'dbk')
130  {
131  return $this->search_in[$a_type];
132  }
133  else
134  {
135  return false;
136  }
137  }
138  function getResults()
139  {
140  return $this->result ? $this->result : array();
141  }
142  function getResultByType($a_type)
143  {
144  return $this->result[$a_type] ? $this->result[$a_type] : array();
145  }
146  function getSearchType()
147  {
148  return $this->search_type;
149  }
150  function getPerformUpdate()
151  {
152  return $this->perform_update;
153  }
154  function getEmptySearch()
155  {
157  }
158 
159 
160  // PUBLIC
162  {
163  $number = count($this->getResultByType("usr")) + count($this->getResultByType("grp")) + count($this->getResultByType("role"));
164 
165  $tmp_res = $this->getResultByType("dbk");
166  $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
167 
168  $tmp_res = $this->getResultByType("lm");
169  $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
170 
171  return $number;
172  }
173 
174  function validate(&$message)
175  {
176  $this->initQueryParser();
177 
178  if(!$this->qp->validate())
179  {
180  $message = $this->qp->getMessage();
181  return false;
182  }
183  return true;
184  }
185 
186  function performSearch()
187  {
188  global $objDefinition, $ilBench;
189 
190  $ilBench->start("Search", "performSearch");
191 
192  $this->initQueryParser();
193 
194  $result = array("usr" => array(),
195  "grp" => array(),
196  "lm" => array(),
197  "dbk" => array(),
198  "role"=> array());
199 
200  foreach($this->getSearchFor() as $obj_type)
201  {
202  switch($obj_type)
203  {
204  case "usr":
205  $result['usr'] = $this->performUserSearch();
206  break;
207 
208  case "grp":
209  $result['grp'] = $this->performObjectSearch('grp');
210  break;
211 
212  case "lm":
213  $result['lm'] = $this->performObjectSearch('lm');
214  break;
215 
216  case "dbk":
217  $result['dbk'] = $this->performObjectSearch('dbk');
218  break;
219 
220  case "role":
221  $result['role'] = $this->performRoleSearch();
222  break;
223  }
224  }
225 
226  $this->setResult($result);
227  $this->__validateResults();
228 
229  if ($this->getPerformUpdate())
230  {
231  $this->__updateDBResult();
232  }
233 
234  $ilBench->stop("Search", "performSearch");
235 
236  return true;
237  }
238 
239 
240  // PRIVATE METHODS
241 
243  {
244  $tmp_arr = explode(" ",$this->getSearchString());
245  $this->parsed_str["and"] = $this->parsed_str["or"] = $this->parsed_str["not"] = array();
246 
247  foreach ($tmp_arr as $word)
248  {
249  #$word = trim($word);
250  $word = $this->__prepareWord($word);
251  if ($word)
252  {
253  if (substr($word,0,1) == '+')
254  {
255  $this->parsed_str["all"][] = substr($word,1);
256  $this->parsed_str["and"][] = substr($word,1);
257  continue;
258  }
259 
260  if (substr($word,0,1) == '-')
261  {
262  // better parsed_str["allmost_all"] ;-)
263  #$this->parsed_str["all"][] = substr($word,1);
264  $this->parsed_str["not"][] = substr($word,1);
265  continue;
266  }
267 
268  if ($this->getCombination() == 'and')
269  {
270  $this->parsed_str["all"][] = $word;
271  $this->parsed_str["and"][] = $word;
272  continue;
273  }
274 
275  if ($this->getCombination() == 'or')
276  {
277  $this->parsed_str["all"][] = $word;
278  $this->parsed_str["or"][] = $word;
279  continue;
280  }
281  }
282  }
283  }
284 
285  function __updateDBResult()
286  {
287  global $ilDB;
288 
289  if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID)
290  {
291  $ilDB->manipulate("DELETE FROM usr_search ".
292  "WHERE usr_id = ".$ilDB->quote($this->getUserId() ,'integer')." ".
293  "AND search_type = 0 ");
294 
295  $ilDB->insert('usr_search',array(
296  'usr_id' => array('integer',$this->getUserId()),
297  'search_result' => array('clob',serialize($this->getResults())),
298  'checked' => array('clob',serialize(array())),
299  'failed' => array('clob',serialize(array())),
300  'page' => array('integer',0),
301  'search_type' => array('integer',0),
302  'query' => array('text',''),
303  'root' => array('integer',ROOT_FOLDER_ID)));
304 
305  return true;
306  }
307 
308  return false;
309  }
310 
311  function __readDBResult()
312  {
313  global $ilDB;
314 
315  if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID and $this->read_db_result)
316  {
317  $query = "SELECT search_result FROM usr_search ".
318  "WHERE usr_id = ".$ilDB->quote($this->getUserId() ,'integer');
319 
320 
321  $res = $ilDB->query($query);
322  if ($res->numRows())
323  {
324  $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
325  $this->setResult(unserialize(stripslashes($row->search_result)));
326  }
327  else
328  {
329  $this->setResult(array("usr" => array(),
330  "grp" => array(),
331  "lm" => array(),
332  "dbk" => array()));
333  }
334  }
335  else
336  {
337  $this->setResult(array("usr" => array(),
338  "grp" => array(),
339  "lm" => array(),
340  "dbk" => array()));
341  }
342 
343  $this->__validateResults();
344  $this->__updateDBResult();
345  return true;
346  }
347 
348 
349  function __checkAccess($a_results,$a_type)
350  {
351  global $ilAccess;
352 
353  if (is_array($a_results))
354  {
355  foreach ($a_results as $result)
356  {
357  if($ilAccess->checkAccess('read','',$result['id']))
358  {
359  $checked_result[] = $result;
360  break;
361  }
362  }
363  }
364  return $checked_result ? $checked_result : array();
365  }
366 
367 
368  function __validateResults()
369  {
370  global $tree;
371 
372  $new_result = array();
373 
374 
375  // check lm meta
376 
377  $this->result['lm']['meta'] = $this->__checkAccess($this->result['lm']['meta'],'lm');
378  if(is_array($this->result['lm']['meta']))
379  {
380  foreach($this->result['lm']['meta'] as $data)
381  {
382  if($tree->isInTree($data['id']))
383  {
384  $new_result['lm']['meta'][] = $data;
385  }
386  }
387  }
388  $this->result['lm']['content'] = $this->__checkAccess($this->result['lm']['content'],'lm');
389  if(is_array($this->result['lm']['content']))
390  {
391  foreach($this->result['lm']['content'] as $data)
392  {
393  if($tree->isInTree($data['id']))
394  {
395  $new_result['lm']['content'][] = $data;
396  }
397  }
398  }
399  $this->result['dbk']['meta'] = $this->__checkAccess($this->result['dbk']['meta'],'dbk');
400  if(is_array($this->result['dbk']['meta']))
401  {
402  foreach($this->result['dbk']['meta'] as $data)
403  {
404  if($tree->isInTree($data['id']))
405  {
406  $new_result['dbk']['meta'][] = $data;
407  }
408  }
409  }
410  $this->result['dbk']['content'] = $this->__checkAccess($this->result['dbk']['content'],'dbk');
411  if(is_array($this->result['dbk']['content']))
412  {
413  foreach($this->result['dbk']['content'] as $data)
414  {
415  if($tree->isInTree($data['id']))
416  {
417  $new_result['dbk']['content'][] = $data;
418  }
419  }
420  }
421  $this->result['grp'] = $this->__checkAccess($this->result['grp'],'grp');
422  if(is_array($this->result['grp']))
423  {
424  foreach($this->result['grp'] as $data)
425  {
426  if($tree->isInTree($data['id']))
427  {
428  $new_result['grp'][] = $data;
429  }
430  }
431  }
432  if(is_array($this->result['usr']))
433  {
434  foreach($this->result['usr'] as $user)
435  {
436  if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
437  {
438  $new_result['usr'][] = $user;
439  }
440  }
441  }
442  if(is_array($this->result['role']))
443  {
444  foreach($this->result['role'] as $user)
445  {
446  if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
447  {
448  $new_result['role'][] = $user;
449  }
450  }
451  }
452  $this->setResult($new_result);
453 
454  return true;
455  }
456 
457  function __prepareWord($a_word)
458  {
459  $word = trim($a_word);
460 
461  if(!preg_match('/\*/',$word))
462  {
463  return '%'.$word.'%';
464  }
465  if(preg_match('/^\*/',$word))
466  {
467  return str_replace('*','%',$word);
468  }
469  else
470  {
471  return '% '.str_replace('*','%',$word);
472  }
473  }
474 
479  protected function performUserSearch()
480  {
481  include_once 'Services/Search/classes/class.ilObjectSearchFactory.php';
482 
483  $user_search = ilObjectSearchFactory::_getUserSearchInstance($this->qp);
484  $res = new ilSearchResult($this->getUserId());
485 
486  foreach(array("login","firstname","lastname","title",
487  "email","institution","street","city","zipcode","country","phone_home","fax") as $field)
488  {
489  $user_search->setFields(array($field));
490  $tmp_res = $user_search->performSearch();
491 
492  $res->mergeEntries($tmp_res);
493  }
494 
495  foreach($res->getEntries() as $id => $data)
496  {
497  $tmp['id'] = $id;
498  $users[] = $tmp;
499  }
500  return $users ? $users : array();
501  }
502 
507  protected function performObjectSearch($a_type)
508  {
509  include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php';
510  $object_search = new ilLikeObjectSearch($this->qp);
511  $object_search->setFilter(array($a_type));
512  $res = $object_search->performSearch();
513  $res->filter(ROOT_FOLDER_ID,$this->getCombination());
514 
515  $counter = 0;
516  foreach($res->getResultIds() as $id)
517  {
518  $objs[$counter++]['id'] = $id;
519  }
520  return $objs ? $objs : array();
521  }
522 
528  protected function performRoleSearch()
529  {
530  // Perform like search
531  include_once 'Services/Search/classes/Like/class.ilLikeObjectSearch.php';
532  $object_search = new ilLikeObjectSearch($this->qp);
533  $object_search->setFilter(array('role'));
534 
535  $res = $object_search->performSearch();
536  foreach($res->getEntries() as $id => $data)
537  {
538  $tmp['id'] = $id;
539  $roles[] = $tmp;
540  }
541  return $roles ? $roles : array();
542  }
543 
548  protected function initQueryParser()
549  {
550  if($this->qp)
551  {
552  return true;
553  }
554 
555  $this->qp = new ilQueryParser($this->getSearchString());
556  $this->qp->setCombination($this->getCombination() == 'and' ? QP_COMBINATION_AND : QP_COMBINATION_OR);
557  $this->qp->setMinWordLength($this->getMinWordLength());
558  $this->qp->parse();
559  }
560 
561 
562 } // END class.ilSearch
563 ?>