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")) + count($this->getResultByType("role"));
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
00260 #$result["role"] = $this->__checkAccess($result["role"],'role');
00261 break;
00262 }
00263 }
00264
00265 $this->setResult($result);
00266 $this->__validateResults();
00267
00268 if ($this->getPerformUpdate())
00269 {
00270 $this->__updateDBResult();
00271 }
00272
00273 $ilBench->stop("Search", "performSearch");
00274
00275 return true;
00276 }
00277
00278 function getWhereCondition($a_type,$a_fields)
00279 {
00280 switch ($a_type)
00281 {
00282 case "like":
00283 $where = $this->__createLikeCondition($a_fields);
00284 break;
00285
00286 case "fulltext":
00287 $where = $this->__createFulltextCondition($a_fields);
00288 break;
00289 }
00290
00291 return $where;
00292 }
00293
00294 function getInStatement($a_primary)
00295 {
00296 $in = '';
00297
00298 switch ($this->getSearchType())
00299 {
00300 case "new":
00301 $in .= "";
00302 break;
00303
00304 case "result":
00305 # if(count($this->__getResultIdsByActualType()))
00306 # {
00307 $in .= "AND $a_primary IN('".implode("','",$this->__getResultIdsByActualType())."') ";
00308 # }
00309 break;
00310
00311 }
00312
00313 return $in;
00314 }
00315
00316
00317 function __createLikeCondition($a_fields)
00318 {
00319 $where = "WHERE (";
00320 $concat = "CONCAT(";
00321 $concat .= implode(",\" \",",$a_fields);
00322 $concat .= ") ";
00323
00324 $where .= "1 ";
00325
00326
00327 foreach ($this->parsed_str["and"] as $and)
00328 {
00329 $where .= "AND ";
00330 $where .= $concat;
00331 $where .= "LIKE(\"%".$and."%\") ";
00332 }
00333
00334
00335 foreach ($this->parsed_str["not"] as $not)
00336 {
00337 $where .= "AND ";
00338 $where .= $concat;
00339 $where .= "NOT LIKE(\"%".$not."%\") ";
00340 }
00341
00342 if (count($this->parsed_str["or"]) and
00343 !count($this->parsed_str["and"]) and
00344 !count($this->parsed_str["not"]))
00345 {
00346 $where .= "AND ( ";
00347
00348 foreach ($this->parsed_str["all"] as $or)
00349 {
00350 $where .= $concat;
00351 $where .= "LIKE(\"%".$or."%\") ";
00352 $where .= "OR ";
00353 }
00354
00355 $where .= "0) ";
00356 }
00357
00358 $where .= ") ";
00359
00360 return $where;
00361 }
00362 function __createFulltextCondition($a_fields)
00363 {
00364 $where = "WHERE (";
00365 $match = " MATCH(".implode(",",$a_fields).") ";
00366
00367 $where .= "1 ";
00368
00369 if (count($this->parsed_str["or"]))
00370 {
00371 $where .= "AND ";
00372 $where .= $match;
00373 $where .= " AGAINST('".implode(" ",$this->parsed_str["all"])."') ";
00374 }
00375
00376 foreach ($this->parsed_str["and"] as $and)
00377 {
00378 $where .= "AND ";
00379 $where .= $match;
00380 $where .= "AGAINST('".$and."') ";
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 $where .= ") ";
00392
00393 return $where;
00394 }
00395
00396 function __parseSearchString()
00397 {
00398 $tmp_arr = explode(" ",$this->getSearchString());
00399 $this->parsed_str["and"] = $this->parsed_str["or"] = $this->parsed_str["not"] = array();
00400
00401 foreach ($tmp_arr as $word)
00402 {
00403 $word = trim($word);
00404
00405 if ($word)
00406 {
00407 if (substr($word,0,1) == '+')
00408 {
00409 $this->parsed_str["all"][] = substr($word,1);
00410 $this->parsed_str["and"][] = substr($word,1);
00411 continue;
00412 }
00413
00414 if (substr($word,0,1) == '-')
00415 {
00416
00417 #$this->parsed_str["all"][] = substr($word,1);
00418 $this->parsed_str["not"][] = substr($word,1);
00419 continue;
00420 }
00421
00422 if ($this->getCombination() == 'and')
00423 {
00424 $this->parsed_str["all"][] = $word;
00425 $this->parsed_str["and"][] = $word;
00426 continue;
00427 }
00428
00429 if ($this->getCombination() == 'or')
00430 {
00431 $this->parsed_str["all"][] = $word;
00432 $this->parsed_str["or"][] = $word;
00433 continue;
00434 }
00435 }
00436 }
00437 }
00438
00439 function __validateParsedString(&$message)
00440 {
00441 foreach ($this->parsed_str as $type)
00442 {
00443 foreach ($type as $word)
00444 {
00445 if (strlen($word) < 3)
00446 {
00447 $to_short = true;
00448 }
00449 }
00450 }
00451
00452 if ($to_short)
00453 {
00454 $message .= $this->lng->txt("search_minimum_three")."<br/>";
00455 return false;
00456 }
00457
00458 return true;
00459 }
00460
00461 function __updateDBResult()
00462 {
00463 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID)
00464 {
00465 $query = "REPLACE INTO usr_search ".
00466 "VALUES('".$this->getUserId()."','".addslashes(serialize($this->getResults()))."','0')";
00467
00468 $res = $this->ilias->db->query($query);
00469
00470 return true;
00471 }
00472
00473 return false;
00474 }
00475
00476 function __readDBResult()
00477 {
00478 if ($this->getUserId() != 0 and $this->getUserId() != ANONYMOUS_USER_ID and $this->read_db_result)
00479 {
00480 $query = "SELECT search_result FROM usr_search ".
00481 "WHERE usr_id = '".$this->getUserId()."'";
00482
00483 $res = $this->ilias->db->query($query);
00484
00485 if ($res->numRows())
00486 {
00487 $row = $res->fetchRow(DB_FETCHMODE_OBJECT);
00488 $this->setResult(unserialize(stripslashes($row->search_result)));
00489 }
00490 else
00491 {
00492 $this->setResult(array("usr" => array(),
00493 "grp" => array(),
00494 "lm" => array(),
00495 "dbk" => array()));
00496 }
00497 }
00498 else
00499 {
00500 $this->setResult(array("usr" => array(),
00501 "grp" => array(),
00502 "lm" => array(),
00503 "dbk" => array()));
00504 }
00505
00506 $this->__validateResults();
00507 $this->__updateDBResult();
00508 return true;
00509 }
00510
00511 function __getResultIdsByActualType()
00512 {
00513 $results = $this->getResultByType($this->act_type);
00514
00515
00516 switch ($this->act_type)
00517 {
00518
00519 case "lm":
00520 case "dbk":
00521 $results = $results[$this->getSearchInByType($this->act_type)];
00522 break;
00523 }
00524
00525 if(is_array($results))
00526 {
00527 foreach ($results as $result)
00528 {
00529 $ids[] = $result["id"];
00530 }
00531 }
00532 return $ids ? $ids : array();
00533 }
00534
00535 function __checkAccess($a_results,$a_type)
00536 {
00537 include_once './classes/class.ilRepositoryExplorer.php';
00538
00539 if (is_array($a_results))
00540 {
00541
00542 foreach ($a_results as $result)
00543 {
00544 $obj_id = ilObject::_lookupObjId($result['id']);
00545
00546 if(!$this->_checkParentConditions($result['id']))
00547 {
00548 continue;
00549 }
00550
00551 if(ilRepositoryExplorer::isClickable($a_type,$result['id'],$obj_id) and
00552 ilRepositoryExplorer::isVisible($result['id'],$a_type))
00553 {
00554 $checked_result[] = $result;
00555 }
00556 }
00557
00558 return $checked_result ? $checked_result : array();
00559 }
00560
00561 return false;
00562 }
00563
00564
00565 function _checkParentConditions($a_ref_id)
00566 {
00567 include_once './payment/classes/class.ilPaymentObject.php';
00568 include_once './course/classes/class.ilObjCourse.php';
00569
00570 global $tree,$ilias;
00571
00572 if(!$tree->isInTree($a_ref_id))
00573 {
00574 return false;
00575 }
00576 foreach($tree->getPathFull($a_ref_id) as $node_data)
00577 {
00578 if(!ilPaymentObject::_hasAccess($node_data['child']))
00579 {
00580 return false;
00581 }
00582 if($node_data['type'] == 'crs')
00583 {
00584 $tmp_obj =& ilObjectFactory::getInstanceByRefId($node_data['child']);
00585
00586 $tmp_obj->initCourseMemberObject();
00587
00588 if(!$tmp_obj->members_obj->hasAccess($ilias->account->getId()))
00589 {
00590 return false;
00591 }
00592 }
00593 }
00594 return true;
00595 }
00596
00597 function __validateResults()
00598 {
00599 global $tree;
00600
00601 $new_result = array();
00602
00603
00604
00605
00606 $this->result['lm']['meta'] = $this->__checkAccess($this->result['lm']['meta'],'lm');
00607 if(is_array($this->result['lm']['meta']))
00608 {
00609 foreach($this->result['lm']['meta'] as $data)
00610 {
00611 if($tree->isInTree($data['id']))
00612 {
00613 $new_result['lm']['meta'][] = $data;
00614 }
00615 }
00616 }
00617 $this->result['lm']['content'] = $this->__checkAccess($this->result['lm']['content'],'lm');
00618 if(is_array($this->result['lm']['content']))
00619 {
00620 foreach($this->result['lm']['content'] as $data)
00621 {
00622 if($tree->isInTree($data['id']))
00623 {
00624 $new_result['lm']['content'][] = $data;
00625 }
00626 }
00627 }
00628 $this->result['dbk']['meta'] = $this->__checkAccess($this->result['dbk']['meta'],'dbk');
00629 if(is_array($this->result['dbk']['meta']))
00630 {
00631 foreach($this->result['dbk']['meta'] as $data)
00632 {
00633 if($tree->isInTree($data['id']))
00634 {
00635 $new_result['dbk']['meta'][] = $data;
00636 }
00637 }
00638 }
00639 $this->result['dbk']['content'] = $this->__checkAccess($this->result['dbk']['content'],'dbk');
00640 if(is_array($this->result['dbk']['content']))
00641 {
00642 foreach($this->result['dbk']['content'] as $data)
00643 {
00644 if($tree->isInTree($data['id']))
00645 {
00646 $new_result['dbk']['content'][] = $data;
00647 }
00648 }
00649 }
00650 $this->result['grp'] = $this->__checkAccess($this->result['grp'],'grp');
00651 if(is_array($this->result['grp']))
00652 {
00653 foreach($this->result['grp'] as $data)
00654 {
00655 if($tree->isInTree($data['id']))
00656 {
00657 $new_result['grp'][] = $data;
00658 }
00659 }
00660 }
00661 if(is_array($this->result['usr']))
00662 {
00663 foreach($this->result['usr'] as $user)
00664 {
00665 if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
00666 {
00667 $new_result['usr'][] = $user;
00668 }
00669 }
00670 }
00671 if(is_array($this->result['role']))
00672 {
00673 foreach($this->result['role'] as $user)
00674 {
00675 if($tmp_obj =& ilObjectFactory::getInstanceByObjId($user['id'],false))
00676 {
00677 $new_result['role'][] = $user;
00678 }
00679 }
00680 }
00681 $this->setResult($new_result);
00682
00683 return true;
00684 }
00685 }
00686 ?>