Jeff PHP framework  0.99
Modular, extensible, OOP, MVC, lightweight php framework designed to ease the programmers in the development of web applications.
search.class.php
Go to the documentation of this file.
00001 <?php
00039 class search {
00040 
00044         private $_registry;
00045         
00049         private $_table;
00050 
00060         function __construct($table, $opts=null) {
00061         
00062                 $this->_registry = registry::instance();
00063                 $this->_table = $table;
00064                 $this->_highlight_range = gOpt($opts, 'highlight_range', 120);
00065 
00066         }
00067 
00076         private function clearSearchString($search_string) {
00077 
00078                 $unconsidered = array("lo", "l", "il", "la", "i", "gli", "le", "uno", "un", "una", "un", "su", "sul", "sulla", "sullo", "sull", "in", "nel", "nello", "nella", "nell", "con", "di", "da", "dei", "d",  "della", "dello", "del", "dell", "che", "a", "dal", "รจ", "e", "per", "non", "si", "al", "ai", "allo", "all", "al", "o", "the", "a", "an", "on", "in", "with", "of", "which", "that", "is", "for", "to");
00079 
00080                 $clean_string = strtolower($search_string);
00081 
00082                 $clean_string = preg_replace("#\b(".preg_quote(implode("|", $unconsidered)).")\b#", "", $clean_string);
00083                 $clean_string = preg_replace("#\W|(\s+)#", " ", $clean_string);
00084 
00085                 $clean_string = preg_quote($clean_string);
00086         
00087                 return $clean_string;
00088 
00089         }
00090 
00097         private function getKeywords($search_string) {
00098                 
00099                 $clean_string = $this->clearSearchString($search_string);
00100 
00101                 $empty_array = array(""," ");
00102 
00103                 return  array_diff(array_unique(explode(" ", $clean_string)), $empty_array);
00104 
00105         }
00106 
00128         public function makeQuery($selected_fields, $required_clauses, $weight_clauses){
00129         
00130                 $final_keywords = 0;
00131 
00132                 $selected = array();
00133                 foreach($selected_fields as $f) {
00134                         $selected[] = is_array($f) ? $f['field'] : $f;
00135                 }
00136                 $relevance = "(";
00137                 $occurrences = "(";
00138                 $sqlwhere_r = "";
00139                 $sqlwhere_w = "";
00140                 $sql_where = '';
00141                 foreach($required_clauses as $f=>$fp) {
00142                         if(is_array($fp)) {
00143                                 if(isset($fp['inside']) && $fp['inside']) $sqlwhere_r .= "$f LIKE '%".$fp['value']."%' AND ";
00144                                 elseif(isset($fp['begin']) && $fp['begin']) $sqlwhere_r .= "$f LIKE '".$fp['value']."%' AND ";
00145                                 elseif(isset($fp['end']) && $fp['end']) $sqlwhere_r .= "$f LIKE '%".$fp['value']."' AND ";
00146                                 elseif(isset($fp['field']) && $fp['field']) $sqlwhere_r .= "$f=".$fp['value']." AND ";
00147                                 else $sqlwhere_r .= "$f='".$fp['value']."' AND ";
00148                         }
00149                         else {
00150                                 $sqlwhere_r .= "$f='$fp' AND ";
00151                         }
00152                 }
00153                 foreach($weight_clauses as $f=>$fp) {
00154                         $search_keywords = $this->getKeywords($fp['value']);
00155                         $final_keywords += count($search_keywords);
00156 
00157                         foreach($search_keywords as $keyw) {
00158                                 $occurrences .= "IFNULL(((LENGTH($f)-LENGTH(replace_ci($f,'$keyw','')))/LENGTH('$keyw')), 0) + ";
00159                                 if(isset($fp['inside']) && $fp['inside']) {
00160                                         $relevance .= "(INSTR(`$f`, '".$keyw."')>0)*".$fp['weight']." + ";
00161                                         $sqlwhere_w .= "`$f` LIKE '%".$keyw."%' OR ";
00162                                 }
00163                                 else {
00164                                         $relevance .= "IFNULL(((`$f` REGEXP '[[:<:]]".$keyw."[[:>:]]')>0)*".$fp['weight'].", 0) + ";
00165                                         $sqlwhere_w .= "`$f` REGEXP '[[:<:]]".$keyw."[[:>:]]' OR ";
00166                                 }
00167                         }
00168                 }
00169                 if($final_keywords) $sqlwhere_w = substr($sqlwhere_w, 0, strlen($sqlwhere_w)-4);
00170                 $relevance .= "0)";
00171                 $occurrences .= "0)";
00172                 if($sqlwhere_r || $sqlwhere_w) {
00173                         $sqlwhere = "WHERE ";
00174                         if($sqlwhere_r) $sqlwhere .= $sqlwhere_r;
00175                         if($sqlwhere_w) $sqlwhere .= "(".$sqlwhere_w.")";
00176                         else $sqlwhere = substr($sqlwhere, 0, strlen($sqlwhere)-5);
00177                 }
00178                 $query = "SELECT ".implode(",", $selected).", $relevance AS relevance, $occurrences AS occurrences FROM $this->_table $sqlwhere ORDER BY relevance DESC, occurrences DESC";
00179                         
00180                 return $final_keywords ? $query : false;
00181 
00182         }
00183 
00214         public function getSearchResults($selected_fields, $required_clauses, $weight_clauses) {
00215         
00216                 $res = array();
00217 
00218                 $query = $this->makeQuery($selected_fields, $required_clauses, $weight_clauses);
00219 
00220                 if($query===false) return array();
00221                 $rows = $this->_registry->db->queryResult($query);
00222                 if(sizeof($rows)>0) {
00223                         $i = 0;
00224                         foreach($rows as $row) {
00225                                 $res[$i] = array(); 
00226                                 foreach($selected_fields as $f) {
00227                                         $res[$i]['relevance'] = $row['relevance'];
00228                                         $res[$i]['occurrences'] = $row['occurrences'];
00229                                         if(is_array($f) && isset($f['highlight']) && $f['highlight']) {
00230                                                 $fp = $weight_clauses[$f['field']];
00231                                                 $get_search_keywords = $this->getKeywords($fp['value']);
00232                                                 $search_keywords = array();
00233                                                 foreach($get_search_keywords as $kw) {
00234                                                         $search_keywords[] = preg_quote($kw);
00235                                                 }
00236                                                 $rexp = (isset($fp['inside']) && $fp['inside']) 
00237                                                         ? implode("|", $search_keywords) 
00238                                                         : "\b".implode("\b|\b", $search_keywords)."\b";
00239                                                 if(preg_match("#(.){0,$this->_highlight_range}($rexp)(.){0,$this->_highlight_range}#sui", cutHtmlText($row[preg_replace("#.*?\.#", "", $f['field'])], 50000000, '', true, false, true), $matches)) {
00240                                                         $res[$i][$f['field']] = preg_replace("#".$rexp."#i", "<span class=\"evidence\">$0</span>", $matches[0]);
00241                                                 }
00242                                                 else $res[$i][$f['field']] = '';
00243                                         }
00244                                         else $res[$i][$f] = $row[preg_replace("#.*?\.#", "", $f)];
00245                                 }
00246                                 $i++;
00247                         }
00248                 }
00249 
00250                 return $res;
00251         
00252         }
00253 
00254 
00255 }
00256 
00257 ?>