00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00033 class ilSearch
00034 {
00040 var $ilias;
00041 var $lng;
00042 var $rbacsystem;
00043 var $user_id;
00044 var $search_string;
00045 var $parsed_str;
00046 var $combination;
00047 var $search_for;
00048 var $search_in;
00049 var $search_type;
00050 var $result;
00051 var $perform_update;
00052 var $read_db_result;
00053
00054 var $allow_empty_search;
00059 function ilSearch($a_user_id = 0,$a_read = false)
00060 {
00061 global $ilias,$rbacsystem,$lng;
00062
00063
00064 $this->ilias =& $ilias;
00065 $this->lng =& $lng;
00066 $this->lng->loadLanguageModule("search");
00067 $this->rbacsystem =& $rbacsystem;
00068 $this->user_id = $a_user_id;
00069
00070 $this->setPerformUpdate(true);
00071 $this->setEmptySearch(false);
00072 $this->read_db_result = $a_read;
00073
00074
00075 $this->__readDBResult();
00076 }
00077
00078
00079 function setSearchString($a_search_str)
00080 {
00081 $this->search_string = trim($a_search_str);
00082 }
00083 function setCombination($a_combination)
00084 {
00085
00086 $this->combination = $a_combination;
00087 }
00088 function setSearchFor($a_search_for)
00089 {
00090 $this->search_for = $a_search_for;
00091 }
00092 function setSearchIn($a_search_in)
00093 {
00094 $this->search_in = $a_search_in;
00095 }
00096 function setResult($a_result)
00097 {
00098 $this->result = $a_result;
00099 }
00100 function setSearchType($a_type)
00101 {
00102 $this->search_type = $a_type;
00103 }
00104 function setPerformUpdate($a_value)
00105 {
00106 $this->perform_update = $a_value;
00107 }
00108 function setEmptySearch($a_value)
00109 {
00110 $this->allow_empty_search = $a_value;
00111 }
00112
00113
00114 function getUserId()
00115 {
00116 return $this->user_id;
00117 }
00118 function getSearchString()
00119 {
00120 return $this->search_string;
00121 }
00122 function getCombination()
00123 {
00124 return $this->combination ? $this->combination : "or";
00125 }
00126 function getSearchFor()
00127 {
00128 return $this->search_for ? $this->search_for : array();
00129 }
00130 function getSearchIn()
00131 {
00132 return $this->search_in ? $this->search_in : array();
00133 }
00134 function getSearchInByType($a_type)
00135 {
00136 if($a_type == 'lm' or $a_type == 'dbk')
00137 {
00138 return $this->search_in[$a_type];
00139 }
00140 else
00141 {
00142 return false;
00143 }
00144 }
00145 function getResults()
00146 {
00147 return $this->result ? $this->result : array();
00148 }
00149 function getResultByType($a_type)
00150 {
00151 return $this->result[$a_type] ? $this->result[$a_type] : array();
00152 }
00153 function getSearchType()
00154 {
00155 return $this->search_type;
00156 }
00157 function getPerformUpdate()
00158 {
00159 return $this->perform_update;
00160 }
00161 function getEmptySearch()
00162 {
00163 return $this->allow_empty_search;
00164 }
00165
00166
00167
00168 function getNumberOfResults()
00169 {
00170 $number = count($this->getResultByType("usr")) + count($this->getResultByType("grp"));
00171
00172 $tmp_res = $this->getResultByType("dbk");
00173 $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
00174
00175 $tmp_res = $this->getResultByType("lm");
00176 $number += count($tmp_res["meta"]) + count($tmp_res["content"]);
00177
00178 return $number;
00179 }
00180
00181 function validate(&$message)
00182 {
00183 $ok = true;
00184
00185 if(!$this->getEmptySearch())
00186 {
00187 if(!$this->getSearchString())
00188 {
00189 $message .= $this->lng->txt("search_no_search_term")."<br/>";
00190 $ok = false;
00191 }
00192 $this->__parseSearchString();
00193
00194 if(!$this->__validateParsedString($message))
00195 {
00196 $ok = false;
00197 }
00198 if(!$this->getSearchFor())
00199 {
00200 $message .= $this->lng->txt("search_no_category")."<br/>";
00201 $ok = false;
00202 }
00203 }
00204 return $ok;
00205 }
00206
00207 function performSearch()
00208 {
00209 global $objDefinition, $ilBench;
00210
00211 $ilBench->start("Search", "performSearch");
00212
00213 $result = array("usr" => array(),
00214 "grp" => array(),
00215 "lm" => array(),
00216 "dbk" => array(),
00217 "role"=> array());
00218
00219 foreach($this->getSearchFor() as $obj_type)
00220 {
00221 switch($obj_type)
00222 {
00223 case "usr":
00224
00225
00226 $this->act_type = 'usr';
00227 $result["usr"] = ilObjUser::_search($this);
00228 break;
00229
00230 case "grp":
00231 include_once "./classes/class.ilObjGroup.php";
00232
00233 $this->act_type = 'grp';
00234 $result["grp"] = ilObjGroup::_search($this);
00235 $result["grp"] = $this->__checkAccess($result["grp"],'grp');
00236 break;
00237
00238 case "lm":
00239 include_once "./content/classes/class.ilObjContentObject.php";
00240 $this->act_type = 'lm';
00241 $result["lm"][$this->getSearchInByType("lm")] = ilObjContentObject::_search($this,$this->getSearchInByType("lm"));
00242 $result["lm"][$this->getSearchInByType("lm")]
00243 = $this->__checkAccess($result["lm"][$this->getSearchInByType("lm")],'lm');
00244 break;
00245
00246 case "dbk":
00247 include_once "./content/classes/class.ilObjDlBook.php";
00248 $this->act_type = 'dbk';
00249 $result["dbk"][$this->getSearchInByType("dbk")] = ilObjDlBook::_search($this,$this->getSearchInByType("dbk"));
00250 $result["dbk"][$this->getSearchInByType("dbk")]
00251 = $this->__checkAccess($result["dbk"][$this->getSearchInByType("dbk")],'dbk');
00252 break;
00253
00254 case "role":
00255 include_once "./classes/class.ilObjRole.php";
00256
00257 $this->act_type = 'role';
00258 $result["role"] = ilObjRole::_search($this);
00259 #$result["role"] = $this->__checkAccess($result["role"],'role');
00260 break;
00261 }
00262 }
00263
00264 $this->setResult($result);
00265 $this->__validateResults();
00266
00267 if ($this->getPerformUpdate())
00268 {
00269 $this->__updateDBResult();
00270 }
00271
00272 $ilBench->stop("Search", "performSearch");
00273
00274 return true;
00275 }
00276
00277 function getWhereCondition($a_type,$a_fields)
00278 {
00279 switch ($a_type)
00280 {
00281 case "like":
00282 $where = $this->__createLikeCondition($a_fields);
00283 break;
00284
00285 case "fulltext":
00286 $where = $this->__createFulltextCondition($a_fields);
00287 break;
00288 }
00289
00290 return $where;
00291 }
00292
00293 function getInStatement($a_primary)
00294 {
00295 $in = '';
00296
00297 switch ($this->getSearchType())
00298 {
00299 case "new":
00300 $in .= "";
00301 break;
00302
00303 case "result":
00304 # if(count($this->__getResultIdsByActualType()))
00305 # {
00306 $in .= "AND $a_primary IN('".implode("','",$this->__getResultIdsByActualType())."') ";
00307 # }
00308 break;
00309
00310 }
00311
00312 return $in;
00313 }
00314
00315
00316 function __createLikeCondition($a_fields)
00317 {
00318 $where = "WHERE (";
00319 $concat = "CONCAT(";
00320 $concat .= implode(",\" \",",$a_fields);
00321 $concat .= ") ";
00322
00323 $where .= "1 ";
00324
00325
00326 foreach ($this->parsed_str["and"] as $and)
00327 {
00328 $where .= "AND ";
00329 $where .= $concat;
00330 $where .= "LIKE(\"%".$and."%\") ";
00331 }
00332
00333
00334 foreach ($this->parsed_str["not"] as $not)
00335 {
00336 $where .= "AND ";
00337 $where .= $concat;
00338 $where .= "NOT LIKE(\"%".$not."%\") ";
00339 }
00340
00341 if (count($this->parsed_str["or"]) and
00342 !count($this->parsed_str["and"]) and
00343 !count($this->parsed_str["not"]))
00344 {
00345 $where .= "AND ( ";
00346
00347 foreach ($this->parsed_str["all"] as $or)
00348 {
00349 $where .= $concat;
00350 $where .= "LIKE(\"%".$or."%\") ";
00351 $where .= "OR ";
00352 }
00353
00354 $where .= "0) ";
00355 }
00356
00357 $where .= ") ";
00358
00359 return $where;
00360 }
00361 function __createFulltextCondition($a_fields)
00362 {
00363 $where = "WHERE (";
00364 $match = " MATCH(".implode(",",$a_fields).") ";
00365
00366 $where .= "1 ";
00367
00368 if (count($this->parsed_str["or"]))
00369 {
00370 $where .= "AND ";
00371 $where .= $match;
00372 $where .= " AGAINST('".implode(" ",$this->parsed_str["all"])."') ";
00373 }
00374
00375 foreach ($this->parsed_str["and"] as $and)
00376 {
00377 $where .= "AND ";
00378 $where .= $match;
00379 $where .= "AGAINST('".$and."') ";
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 $where .= ") ";
00391
00392 return $where;
00393 }
00394
00395 function __parseSearchString()
00396 {
00397 $tmp_arr = explode(" ",$this->getSearchString());
00398 $this->parsed_str["and"] = $this->parsed_str["or"] = $this->parsed_str["not"] = array();
00399
00400 foreach ($tmp_arr as $word)
00401 {
00402 $word = trim($word);
00403
00404 if ($word)
00405 {
00406 if (substr($word,0,1) == '+')
00407 {
00408 $this->parsed_str["all"][] = substr($word,1);
00409 $this->parsed_str["and"][] = substr($word,1);
00410 continue;
00411 }
00412
00413 if (substr($word,0,1) == '-')
00414 {
00415
00416 #$this->parsed_str["all"][] = substr($word,1);
00417 $this->parsed_str["not"][] = substr($word,1);
00418 continue;
00419 }
00420
00421 if ($this->getCombination() == 'and')
00422 {
00423 $this->parsed_str["all"][] = $word;
00424 $this->parsed_str["and"][] = $word;
00425 continue;
00426 }
00427
00428 if ($this->getCombination() == 'or')
00429 {
00430 $this->parsed_str["all"][] = $word;
00431 $this->parsed_str["or"][] = $word;
00432 continue;
00433 }
00434 }
00435 }
00436 }
00437
00438 function __validateParsedString(&$message)
00439 {
00440 foreach ($this->parsed_str as $type)
00441 {
00442 foreach ($type as $word)
00443 {
00444 if (strlen($word) < 3)
00445 {
00446 $to_short = true;
00447 }
00448 }
00449 }
00450
00451 if ($to_short)
00452 {
00453 $message .= $this->lng->txt("search_minimum_three")."<br/>";
00454 return false;
00455 }
00456
00457 return true;
00458 }
00459
00460 function __updateDBResult()
00461 {
00462 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID)
00463 {
00464 $query = "REPLACE INTO usr_search ".
00465 "VALUES('".$this->getUserId()."','".addslashes(serialize($this->getResults()))."')";
00466
00467 $res = $this->ilias->db->query($query);
00468
00469 return true;
00470 }
00471
00472 return false;
00473 }
00474
00475 function __readDBResult()
00476 {
00477 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID and $this->read_db_result)
00478 {
00479 $query = "SELECT search_result FROM usr_search ".
00480 "WHERE usr_id = '".$this->getUserId()."'";
00481
00482 $res = $this->ilias->db->query($query);
00483
00484 if ($res->numRows())
00485 {
00486 $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
00487 $this->setResult(unserialize(stripslashes($row->search_result)));
00488 }
00489 else
00490 {
00491 $this->setResult(array("usr" => array(),
00492 "grp" => array(),
00493 "lm" => array(),
00494 "dbk" => array()));
00495 }
00496 }
00497 else
00498 {
00499 $this->setResult(array("usr" => array(),
00500 "grp" => array(),
00501 "lm" => array(),
00502 "dbk" => array()));
00503 }
00504
00505 $this->__validateResults();
00506 $this->__updateDBResult();
00507 return true;
00508 }
00509
00510 function __getResultIdsByActualType()
00511 {
00512 $results = $this->getResultByType($this->act_type);
00513
00514
00515 switch ($this->act_type)
00516 {
00517
00518 case "lm":
00519 case "dbk":
00520 $results = $results[$this->getSearchInByType($this->act_type)];
00521 break;
00522 }
00523
00524 if(is_array($results))
00525 {
00526 foreach ($results as $result)
00527 {
00528 $ids[] = $result["id"];
00529 }
00530 }
00531 return $ids ? $ids : array();
00532 }
00533
00534 function __checkAccess($a_results,$a_type)
00535 {
00536 include_once './classes/class.ilRepositoryExplorer.php';
00537
00538 if (is_array($a_results))
00539 {
00540
00541 foreach ($a_results as $result)
00542 {
00543 $obj_id = ilObject::_lookupObjId($result['id']);
00544
00545 if(!$this->_checkParentConditions($result['id']))
00546 {
00547 continue;
00548 }
00549
00550 if(ilRepositoryExplorer::isClickable($a_type,$result['id'],$obj_id) and
00551 ilRepositoryExplorer::isVisible($result['id'],$a_type))
00552 {
00553 $checked_result[] = $result;
00554 }
00555 }
00556
00557 return $checked_result ? $checked_result : array();
00558 }
00559
00560 return false;
00561 }
00562
00563
00564 function _checkParentConditions($a_ref_id)
00565 {
00566 include_once './payment/classes/class.ilPaymentObject.php';
00567 include_once './course/classes/class.ilObjCourse.php';
00568
00569 global $tree,$ilias;
00570
00571 if(!$tree->isInTree($a_ref_id))
00572 {
00573 return false;
00574 }
00575 foreach($tree->getPathFull($a_ref_id) as $node_data)
00576 {
00577 if(!ilPaymentObject::_hasAccess($node_data['child']))
00578 {
00579 return false;
00580 }
00581 if($node_data['type'] == 'crs')
00582 {
00583 $tmp_obj =& ilObjectFactory::getInstanceByRefId($node_data['child']);
00584
00585 $tmp_obj->initCourseMemberObject();
00586
00587 if(!$tmp_obj->members_obj->hasAccess($ilias->account->getId()))
00588 {
00589 return false;
00590 }
00591 }
00592 }
00593 return true;
00594 }
00595
00596 function __validateResults()
00597 {
00598 global $tree;
00599
00600 $new_result = array();
00601
00602
00603
00604
00605 $this->result['lm']['meta'] = $this->__checkAccess($this->result['lm']['meta'],'lm');
00606 if(is_array($this->result['lm']['meta']))
00607 {
00608 foreach($this->result['lm']['meta'] as $data)
00609 {
00610 if($tree->isInTree($data['id']))
00611 {
00612 $new_result['lm']['meta'][] = $data;
00613 }
00614 }
00615 }
00616 $this->result['lm']['content'] = $this->__checkAccess($this->result['lm']['content'],'lm');
00617 if(is_array($this->result['lm']['content']))
00618 {
00619 foreach($this->result['lm']['content'] as $data)
00620 {
00621 if($tree->isInTree($data['id']))
00622 {
00623 $new_result['lm']['content'][] = $data;
00624 }
00625 }
00626 }
00627 $this->result['dbk']['meta'] = $this->__checkAccess($this->result['dbk']['meta'],'dbk');
00628 if(is_array($this->result['dbk']['meta']))
00629 {
00630 foreach($this->result['dbk']['meta'] as $data)
00631 {
00632 if($tree->isInTree($data['id']))
00633 {
00634 $new_result['dbk']['meta'][] = $data;
00635 }
00636 }
00637 }
00638 $this->result['dbk']['content'] = $this->__checkAccess($this->result['dbk']['content'],'dbk');
00639 if(is_array($this->result['dbk']['content']))
00640 {
00641 foreach($this->result['dbk']['content'] as $data)
00642 {
00643 if($tree->isInTree($data['id']))
00644 {
00645 $new_result['dbk']['content'][] = $data;
00646 }
00647 }
00648 }
00649 $this->result['grp'] = $this->__checkAccess($this->result['grp'],'grp');
00650 if(is_array($this->result['grp']))
00651 {
00652 foreach($this->result['grp'] as $data)
00653 {
00654 if($tree->isInTree($data['id']))
00655 {
00656 $new_result['grp'][] = $data;
00657 }
00658 }
00659 }
00660 if(is_array($this->result['usr']))
00661 {
00662 foreach($this->result['usr'] as $user)
00663 {
00664 if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
00665 {
00666 $new_result['usr'][] = $user;
00667 }
00668 }
00669 }
00670 if(is_array($this->result['role']))
00671 {
00672 foreach($this->result['role'] as $user)
00673 {
00674 if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
00675 {
00676 $new_result['role'][] = $user;
00677 }
00678 }
00679 }
00680 $this->setResult($new_result);
00681
00682 return true;
00683 }
00684 }
00685 ?>