• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

classes/class.ilSearch.php

Go to the documentation of this file.
00001 <?php
00002 /*
00003         +-----------------------------------------------------------------------------+
00004         | ILIAS open source                                                           |
00005         +-----------------------------------------------------------------------------+
00006         | Copyright (c) 1998-2001 ILIAS open source, University of Cologne            |
00007         |                                                                             |
00008         | This program is free software; you can redistribute it and/or               |
00009         | modify it under the terms of the GNU General Public License                 |
00010         | as published by the Free Software Foundation; either version 2              |
00011         | of the License, or (at your option) any later version.                      |
00012         |                                                                             |
00013         | This program is distributed in the hope that it will be useful,             |
00014         | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
00015         | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
00016         | GNU General Public License for more details.                                |
00017         |                                                                             |
00018         | You should have received a copy of the GNU General Public License           |
00019         | along with this program; if not, write to the Free Software                 |
00020         | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. |
00021         +-----------------------------------------------------------------------------+
00022 */
00023 
00024 
00033 class ilSearch
00034 {
00040         var $ilias;
00041         var $lng;
00042         var $rbacsystem;
00043         var $user_id;                           // INTEGER USED FOR SAVED RESULTS
00044         var $search_string;                     // INPUT FROM SEARCH FORM
00045         var $parsed_str;                        // PARSED INPUT
00046         var $combination;                       // STRING 'and' or 'or'
00047         var $search_for;                        // OBJECT TYPE 'usr','grp','lm','dbk'
00048         var $search_in;                         // STRING SEARCH IN 'content' OR 'meta'
00049         var $search_type;                       // STRING 'new' or 'result'
00050         var $result;                            // RESULT SET array['object_type']['counter']
00051         var $perform_update;            // UPDATE USER SEARCH HISTORY default is true SEE function setPerformUpdate()
00052         var $read_db_result;            // READ db result true/false
00053 
00054         var $allow_empty_search;                // ALLOW EMPTY SEARCH TERM use setEmtySearch(true | false) TO SET THIS VALUE DEFAULT (FALSE)
00059         function ilSearch($a_user_id = 0,$a_read = false)
00060         {
00061                 global $ilias,$rbacsystem,$lng;
00062                 
00063                 // Initiate variables
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                 // READ OLD SEARCH RESULTS FROM DATABASE
00075                 $this->__readDBResult();
00076         }
00077 
00078         // SET METHODS
00079         function setSearchString($a_search_str)
00080         {
00081                 $this->search_string = trim($a_search_str);
00082         }
00083         function setCombination($a_combination)
00084         {
00085                 // 'and' or 'or'
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         // GET MEHODS
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         // PUBLIC
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                                         // TODO: NOT NICE BUT USEFUL
00225                                         // THIS VAR IS USED IN __getResultIdsByType()
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         // PRIVATE METHODS
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                 // AND
00326                 foreach ($this->parsed_str["and"] as $and)
00327                 {
00328                         $where .= "AND ";
00329                         $where .= $concat;
00330                         $where .= "LIKE(\"%".$and."%\") ";
00331                 }
00332                 
00333                 // AND NOT
00334                 foreach ($this->parsed_str["not"] as $not)
00335                 {
00336                         $where .= "AND ";
00337                         $where .= $concat;
00338                         $where .= "NOT LIKE(\"%".$not."%\") ";
00339                 }
00340                 // OR
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                 // OR
00368                 if (count($this->parsed_str["or"]))
00369                 {
00370                         $where .= "AND ";
00371                         $where .= $match;
00372                         $where .= " AGAINST('".implode(" ",$this->parsed_str["all"])."') ";
00373                 }
00374                 // AND  
00375                 foreach ($this->parsed_str["and"] as $and)
00376                 {
00377                         $where .= "AND ";
00378                         $where .= $match;
00379                         $where .= "AGAINST('".$and."') ";
00380                 }
00381                 // AND NOT
00382                 /*
00383                 foreach($this->parsed_str["not"] as $and)
00384                 {
00385                         $where .= "AND NOT ";
00386                         $where .= $match;
00387                         $where .= "AGAINST('".$and."') ";
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                                         // better parsed_str["allmost_all"] ;-)
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                 // GET 'content' or 'meta' array
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         // STATIC
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                 // check lm meta
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 } // END class.ilSearch
00685 ?>

Generated on Fri Dec 13 2013 09:06:35 for ILIAS Release_3_4_x_branch .rev 46804 by  doxygen 1.7.1