OSDN Git Service

Merge branch 'skinnable-master'
[nucleus-jp/nucleus-next.git] / nucleus / libs / SEARCH.php
index 4420c09..81edfb5 100644 (file)
@@ -1,3 +1,226 @@
+<<<<<<< HEAD
+<?php\r
+\r
+/*\r
+ * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/)\r
+ * Copyright (C) 2003-2009 The Nucleus Group\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ * (see nucleus/documentation/index.html#license for more info)\r
+ */\r
+/**\r
+ * SEARCH(querystring) offers different functionality to create an\r
+ * SQL query to find certain items. (and comments)\r
+ *\r
+ * based on code by David Altherr:\r
+ * http://www.evolt.org/article/Boolean_Fulltext_Searching_with_PHP_and_MySQL/18/15665/\r
+ * http://davidaltherr.net/web/php_functions/boolean/funcs.mysql.boolean.txt\r
+ *\r
+ * @license http://nucleuscms.org/license.txt GNU General Public License\r
+ * @copyright Copyright (C) 2002-2012 The Nucleus Group\r
+ * @version $Id: SEARCH.php 1556 2011-07-11 14:18:48Z ftruscot $\r
+ */\r
+\r
+\r
+\r
+class Search\r
+{\r
+       var $querystring;\r
+       var $marked;\r
+       var $inclusive;\r
+       var $blogs;\r
+\r
+\r
+       function SEARCH($text) {\r
+               global $blogid;\r
+               $text = preg_replace ("/[<,>,=,?,!,#,^,(,),[,\],:,;,\\\,%]/","",$text);\r
+               $this->querystring      = $text;\r
+               $this->marked           = $this->boolean_mark_atoms($text);\r
+               $this->inclusive        = $this->boolean_inclusive_atoms($text);\r
+               $this->blogs            = array();\r
+\r
+               // get all public searchable blogs, no matter what, include the current blog allways.\r
+               $res = DB::getResult('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');\r
+               foreach ( $res as $row )\r
+                       $this->blogs[] = intval($row['bnumber']);\r
+       }\r
+\r
+       function  boolean_sql_select($match){\r
+               if (i18n::strlen($this->inclusive) > 0) {\r
+                  /* build sql for determining score for each record */\r
+                  $result=preg_split("# #",$this->inclusive);\r
+                  for($cth=0;$cth<count($result);$cth++){\r
+                          if(i18n::strlen($result[$cth])>=4){\r
+                                  $stringsum_long .=  " $result[$cth] ";\r
+                          }else{\r
+                                  $stringsum_a[] = ' '.$this->boolean_sql_select_short($result[$cth],$match).' ';\r
+                          }\r
+                  }\r
+\r
+                  if(i18n::strlen($stringsum_long)>0){\r
+                               $stringsum_long = DB::quoteValue($stringsum_long);\r
+                               $stringsum_a[] = " match ({$match}) against ({$stringsum_long}) ";\r
+                  }\r
+\r
+                  $stringsum .= implode("+",$stringsum_a);\r
+                  return $stringsum;\r
+               }\r
+       }\r
+\r
+       function boolean_inclusive_atoms($string){\r
+               $result = trim($string);\r
+               $result = preg_replace("#([[:space:]]{2,})#", ' ', $result);\r
+\r
+               # replaced eregi_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0\r
+               # just added delimiters to regex and the 'i' for case-insensitive matching\r
+\r
+               /* convert normal boolean operators to shortened syntax */\r
+               $result = preg_replace('# not #i', ' -', $result);\r
+               $result = preg_replace('# and #i', ' ', $result);\r
+               $result = preg_replace('# or #i', ',', $result);\r
+\r
+               /* drop unnecessary spaces */\r
+               $result = str_replace(' ,', ',', $result);\r
+               $result = str_replace(', ', ',', $result);\r
+               $result = str_replace('- ', '-', $result);\r
+               $result = str_replace('+', '', $result);\r
+\r
+               /* strip exlusive atoms */\r
+               $result = preg_replace(\r
+                       "#\-\([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_\,]{0,}\)#",\r
+                       '',\r
+                       $result);\r
+\r
+               $result = str_replace('(', ' ', $result);\r
+               $result = str_replace(')', ' ', $result);\r
+               $result = str_replace(',', ' ', $result);\r
+\r
+               return $result;\r
+       }\r
+\r
+    function boolean_sql_where($match){\r
+\r
+        $result = $this->marked;\r
+\r
+        $this->boolean_sql_where_cb1($match); // set the static $match\r
+\r
+        $result = preg_replace_callback(\r
+\r
+            "/foo\[\(\'([^\)]{4,})\'\)\]bar/",\r
+\r
+            array($this,'boolean_sql_where_cb1'),\r
+\r
+            $result);\r
+\r
+        $this->boolean_sql_where_cb2($match); // set the static $match\r
+\r
+        $result = preg_replace_callback(\r
+\r
+            "/foo\[\(\'([^\)]{1,3})\'\)\]bar/",\r
+\r
+            array($this,'boolean_sql_where_cb2'),\r
+\r
+            $result);\r
+\r
+        return $result;\r
+\r
+    }\r
+\r
+    function boolean_sql_where_cb1($matches){\r
+\r
+        static $match;\r
+\r
+        if (!is_array($matches)) $match=$matches;\r
+\r
+        else return ' match ('.$match.') against ('.DB::quoteValue($matches[1]).') > 0 ';\r
+\r
+    }\r
+\r
+    function boolean_sql_where_cb2($matches){\r
+\r
+        static $match;\r
+\r
+        if (!is_array($matches)) $match=$matches;\r
+\r
+        else return ' ('.$this->boolean_sql_where_short($matches[1], $match).') ';\r
+\r
+    }  \r
+\r
+       function boolean_mark_atoms($string){\r
+               $result = trim($string);\r
+               $result = preg_replace("/([[:space:]]{2,})/",' ',$result);\r
+\r
+               # replaced eregi_replace() below with preg_replace(). ereg* functions are deprecated in PHP 5.3.0\r
+               # just added delimiters to regex and the 'i' for case-insensitive matching\r
+\r
+               /* convert normal boolean operators to shortened syntax */\r
+               $result = preg_replace('# not #i', ' -', $result);\r
+               $result = preg_replace('# and #i', ' ', $result);\r
+               $result = preg_replace('# or #i', ',', $result);\r
+\r
+               /* strip excessive whitespace */\r
+               $result = str_replace('( ', '(', $result);\r
+               $result = str_replace(' )', ')', $result);\r
+               $result = str_replace(', ', ',', $result);\r
+               $result = str_replace(' ,', ',', $result);\r
+               $result = str_replace('- ', '-', $result);\r
+               $result = str_replace('+', '', $result);\r
+\r
+               // remove double spaces (we might have introduced some new ones above)\r
+               $result = trim($result);\r
+               $result = preg_replace("#([[:space:]]{2,})#", ' ', $result);\r
+\r
+               /* apply arbitrary function to all 'word' atoms */\r
+\r
+               $result_a = preg_split('# #', $result);\r
+\r
+               for($word = 0;$word<count($result_a);$word++)\r
+               {\r
+                       $result_a[$word] = "foo[('" . $result_a[$word] . "')]bar";\r
+               }\r
+\r
+               $result = implode(' ', $result_a);\r
+\r
+               /* dispatch ' ' to ' AND ' */\r
+               $result = str_replace(' ', ' AND ', $result);\r
+\r
+               /* dispatch ',' to ' OR ' */\r
+               $result = str_replace(',', ' OR ', $result);\r
+\r
+               /* dispatch '-' to ' NOT ' */\r
+               $result = str_replace(' -', ' NOT ', $result);\r
+               return $result;\r
+       }\r
+\r
+       function boolean_sql_where_short($string,$match){\r
+               $match_a = preg_split('#,#',$match);\r
+               for($ith=0;$ith<count($match_a);$ith++){\r
+                       $like_a[$ith] = ' $match_a[$ith] LIKE ' . DB::quoteValue("% {$string} %") . ' ';\r
+               }\r
+               $like = implode(" OR ",$like_a);\r
+\r
+               return $like;\r
+       }\r
+       function boolean_sql_select_short($string,$match){\r
+               $match_a = preg_split('#,#',$match);\r
+               $score_unit_weight = .2;\r
+               for($ith=0;$ith<count($match_a);$ith++){\r
+                       $score_a[$ith] =\r
+                                                  " $score_unit_weight*(\r
+                                                  LENGTH(" . DB::quoteValue($match_a[$ith]) . ") -\r
+                                                  LENGTH(REPLACE(LOWER(" . DB::quoteValue($match_a[$ith]) . "),LOWER(" . DB::quoteValue($string) . "),'')))\r
+                                                  /LENGTH(" . DB::quoteValue($string) . ") ";\r
+               }\r
+               $score = implode(" + ",$score_a);\r
+\r
+               return $score;\r
+       }\r
+}\r
+?>\r
+=======
 <?php
 
 /*
  *
  * @license http://nucleuscms.org/license.txt GNU General Public License
  * @copyright Copyright (C) 2002-2009 The Nucleus Group
- * @version $Id: SEARCH.php 1556 2011-07-11 14:18:48Z ftruscot $
+ * @version $Id: SEARCH.php 1886 2012-06-17 08:27:27Z sakamocchi $
  */
 
 
 
-class SEARCH {
-
+class Search
+{
        var $querystring;
        var $marked;
        var $inclusive;
@@ -42,15 +265,15 @@ class SEARCH {
                $this->blogs            = array();
 
                // get all public searchable blogs, no matter what, include the current blog allways.
-               $res = sql_query('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');
-               while ($obj = sql_fetch_object($res))
-                       $this->blogs[] = intval($obj->bnumber);
+               $res = DB::getResult('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');
+               foreach ( $res as $row )
+                       $this->blogs[] = intval($row['bnumber']);
        }
 
        function  boolean_sql_select($match){
                if (i18n::strlen($this->inclusive) > 0) {
                   /* build sql for determining score for each record */
-                  $result=i18n::explode(" ",$this->inclusive);
+                  $result=preg_split("# #",$this->inclusive);
                   for($cth=0;$cth<count($result);$cth++){
                           if(i18n::strlen($result[$cth])>=4){
                                   $stringsum_long .=  " $result[$cth] ";
@@ -60,8 +283,8 @@ class SEARCH {
                   }
 
                   if(i18n::strlen($stringsum_long)>0){
-                               $stringsum_long = sql_real_escape_string($stringsum_long);
-                               $stringsum_a[] = " match ($match) against ('$stringsum_long') ";
+                               $stringsum_long = DB::quoteValue($stringsum_long);
+                               $stringsum_a[] = " match ({$match}) against ({$stringsum_long}) ";
                   }
 
                   $stringsum .= implode("+",$stringsum_a);
@@ -134,7 +357,7 @@ class SEARCH {
 
         if (!is_array($matches)) $match=$matches;
 
-        else return ' match ('.$match.') against (\''.sql_real_escape_string($matches[1]).'\') > 0 ';
+        else return ' match ('.$match.') against ('.DB::quoteValue($matches[1]).') > 0 ';
 
     }
 
@@ -144,7 +367,7 @@ class SEARCH {
 
         if (!is_array($matches)) $match=$matches;
 
-        else return ' ('.$this->boolean_sql_where_short(sql_real_escape_string($matches[1]),$match).') ';
+        else return ' ('.$this->boolean_sql_where_short($matches[1], $match).') ';
 
     }  
 
@@ -174,7 +397,7 @@ class SEARCH {
 
                /* apply arbitrary function to all 'word' atoms */
 
-               $result_a = i18n::explode(' ', $result);
+               $result_a = preg_split('# #', $result);
 
                for($word = 0;$word<count($result_a);$word++)
                {
@@ -195,23 +418,23 @@ class SEARCH {
        }
 
        function boolean_sql_where_short($string,$match){
-               $match_a = i18n::explode(',',$match);
+               $match_a = preg_split('#,#',$match);
                for($ith=0;$ith<count($match_a);$ith++){
-                       $like_a[$ith] = " $match_a[$ith] LIKE '% $string %' ";
+                       $like_a[$ith] = ' $match_a[$ith] LIKE ' . DB::quoteValue("% {$string} %") . ' ';
                }
                $like = implode(" OR ",$like_a);
 
                return $like;
        }
        function boolean_sql_select_short($string,$match){
-               $match_a = i18n::explode(',',$match);
+               $match_a = preg_split('#,#',$match);
                $score_unit_weight = .2;
                for($ith=0;$ith<count($match_a);$ith++){
                        $score_a[$ith] =
                                                   " $score_unit_weight*(
-                                                  LENGTH(" . sql_real_escape_string($match_a[$ith]) . ") -
-                                                  LENGTH(REPLACE(LOWER(" . sql_real_escape_string($match_a[$ith]) . "),LOWER('" . sql_real_escape_string($string) . "'),'')))
-                                                  /LENGTH('" . sql_real_escape_string($string) . "') ";
+                                                  LENGTH(" . DB::quoteValue($match_a[$ith]) . ") -
+                                                  LENGTH(REPLACE(LOWER(" . DB::quoteValue($match_a[$ith]) . "),LOWER(" . DB::quoteValue($string) . "),'')))
+                                                  /LENGTH(" . DB::quoteValue($string) . ") ";
                }
                $score = implode(" + ",$score_a);
 
@@ -219,3 +442,4 @@ class SEARCH {
        }
 }
 ?>
+>>>>>>> skinnable-master