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