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

Generated on Fri Dec 13 2013 11:57:55 for ILIAS Release_3_6_x_branch .rev 46809 by  doxygen 1.7.1