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 
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 $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  {
103  return $this->min_word_length;
104  }
105 
106  // GET MEHODS
107  public function getUserId()
108  {
109  return $this->user_id;
110  }
111  public function getSearchString()
112  {
113  return $this->search_string;
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  {
149  return $this->perform_update;
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
setSearchString($a_search_str)
setMinWordLength($a_min_word_length)
__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
$counter
$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
static getInstanceByObjId($a_obj_id, $stop_on_error=true)
get an instance of an Ilias object by object id
Create styles array
The data for the language used.
$users
Definition: authpage.php:44
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