OSDN Git Service

applied some bug fixes
[nucleus-jp/nucleus-jp-ancient.git] / utf8 / nucleus / libs / SEARCH.php
1 <?php\r
2 \r
3 /**\r
4   * Nucleus: PHP/MySQL Weblog CMS (http://nucleuscms.org/) \r
5   * Copyright (C) 2003-2004 The Nucleus Group\r
6   *\r
7   * This program is free software; you can redistribute it and/or\r
8   * modify it under the terms of the GNU General Public License\r
9   * as published by the Free Software Foundation; either version 2\r
10   * of the License, or (at your option) any later version.\r
11   * (see nucleus/documentation/index.html#license for more info)\r
12   *\r
13   * SEARCH(querystring) offers different functionality to create an\r
14   * SQL query to find certain items. (and comments)\r
15   *\r
16   * based on code by David Altherr:\r
17   * http://www.evolt.org/article/Boolean_Fulltext_Searching_with_PHP_and_MySQL/18/15665/\r
18   * http://davidaltherr.net/web/php_functions/boolean/funcs.mysql.boolean.txt\r
19   * \r
20   */\r
21 \r
22 \r
23 class SEARCH {\r
24         \r
25         var $querystring;\r
26         var $marked;\r
27         var $inclusive;\r
28         var $blogs;\r
29 \r
30 \r
31     function SEARCH($text) {\r
32         global $blogid;\r
33 \r
34 //       $text = preg_replace ("/[<,>,=,?,!,#,^,(,),[,\],:,;,\\\,%]/","",$text);\r
35 \r
36      /* * * for jp * * * * * * * * * * */\r
37         $text = str_replace ("\xE3\x80\x80",' ',$text);\r
38         $text = preg_replace ("/[<>=?!#^()[\]:;\\%]/","",$text);\r
39 \r
40         $this->ascii = '[\x00-\x7F]';\r
41         $this->two = '[\xC0-\xDF][\x80-\xBF]';\r
42         $this->three = '[\xE0-\xEF][\x80-\xBF][\x80-\xBF]';\r
43 \r
44         $this->jpmarked      = $this->boolean_mark_atoms_jp($text);\r
45      /* * * * * * * * * * * * * * * * */\r
46 \r
47         $this->querystring      = $text;\r
48 //        $this->marked         = $this->boolean_mark_atoms($text);\r
49         $this->inclusive        = $this->boolean_inclusive_atoms($text);\r
50         $this->blogs            = array();\r
51 \r
52         // get all public searchable blogs, no matter what, include the current blog allways.\r
53                 $res = sql_query('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');\r
54                 while ($obj = mysql_fetch_object($res)) \r
55                     $this->blogs[] = intval($obj->bnumber);\r
56         }\r
57 \r
58     function  boolean_sql_select($match){\r
59 //        $string = $this->inclusive;\r
60 //        if (strlen($string) > 0) {\r
61            /* build sql for determining score for each record */\r
62 /*\r
63                preg_match_all(\r
64                                    "([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",\r
65                                $string,\r
66                                $result);\r
67            $result = $result[0];\r
68                  for($cth=0;$cth<count($result);$cth++){\r
69              if(strlen($result[$cth])>=4){\r
70                    $stringsum_long .=  " $result[$cth] ";\r
71                      }else{\r
72                        $stringsum_a[] = ' '.$this->boolean_sql_select_short($result[$cth],$match).' ';\r
73                      }\r
74                  }\r
75              if(strlen($stringsum_long)>0){\r
76                                 $stringsum_long = addslashes($stringsum_long);\r
77                         $stringsum_a[] = " match ($match) against ('$stringsum_long') ";\r
78              }\r
79                  $stringsum .= implode("+",$stringsum_a);\r
80              return $stringsum;\r
81             }\r
82 */\r
83     }\r
84 \r
85     \r
86 \r
87     function boolean_inclusive_atoms($string){\r
88         $result=trim($string);\r
89         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
90 \r
91         /* convert normal boolean operators to shortened syntax */\r
92         $result=eregi_replace(' not ',' -',$result);\r
93         $result=eregi_replace(' and ',' ',$result);\r
94         $result=eregi_replace(' or ',',',$result);\r
95 \r
96         /* drop unnecessary spaces */\r
97         $result=str_replace(' ,',',',$result);\r
98         $result=str_replace(', ',',',$result);\r
99         $result=str_replace('- ','-',$result);\r
100         $result=str_replace('+','',$result);\r
101 \r
102         /* strip exlusive atoms */\r
103         $result=preg_replace(\r
104 //              "(\-\([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_\,]{0,}\))",\r
105                 "(\-\(([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,}\))",\r
106                 '',\r
107                 $result);\r
108 \r
109         $result=preg_replace(\r
110 //              "(\-[A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",\r
111                 "(\-([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,})",\r
112                 '',\r
113                 $result);\r
114 \r
115         $result=str_replace('(',' ',$result);\r
116         $result=str_replace(')',' ',$result);\r
117         $result=str_replace(',',' ',$result);\r
118 \r
119         return $result;\r
120     }\r
121 \r
122     function boolean_sql_where($match){\r
123 /*\r
124         $result = $this->marked;\r
125         $result = preg_replace(\r
126                 "/foo\[\(\'([^\)]{4,})\'\)\]bar/e",\r
127                 " 'match ('.\$match.') against (\''.\$this->copyvalue(\"$1\").'\') > 0 ' ",\r
128                 $result);\r
129 \r
130         $result = preg_replace(                 \r
131             "/foo\[\(\'([^\)]{1,3})\'\)\]bar/e",\r
132             " '('.\$this->boolean_sql_where_short(\"$1\",\"$match\").')' ",             \r
133             $result);\r
134 */\r
135       $result = $this->jpmarked; /* for jp */\r
136         $result = $this->boolean_sql_where_jp_short($result,$match);/* for jp */\r
137         return $result;\r
138     }\r
139 \r
140     // there must be a simple way to simply copy a value with backslashes in it through\r
141     // the preg_replace, but I cannot currently find it (karma 2003-12-30)\r
142     function copyvalue($foo) {\r
143         return $foo;\r
144     }\r
145 \r
146 /***********************************************\r
147   Make "WHERE" (jp)\r
148 ***********************************************/\r
149 \r
150     function boolean_mark_atoms_jp($string){\r
151 \r
152         $result=trim($string);\r
153         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
154         \r
155         /* convert normal boolean operators to shortened syntax */\r
156         $result=eregi_replace(' not ',' -',$result);\r
157         $result=eregi_replace(' and ',' ',$result);\r
158         $result=eregi_replace(' or ',',',$result);\r
159 \r
160         /* strip excessive whitespace */\r
161         $result=str_replace(', ',',',$result);\r
162         $result=str_replace(' ,',',',$result);\r
163         $result=str_replace('- ','-',$result);\r
164         $result=str_replace('+','',$result);\r
165         \r
166         $result=str_replace(',',' ,',$result);\r
167 \r
168         return $result;\r
169     }\r
170     \r
171 \r
172     function boolean_sql_where_jp_short($string,$match){\r
173         $match_a = explode(',',$match);\r
174                         $key_a = explode(' ',$string);\r
175                         \r
176         for($ith=0;$ith<count($match_a);$ith++){\r
177                 $temp_a[$ith] = "(i.$match_a[$ith] LIKE '%" . addslashes($key_a[0]) . "%') ";\r
178         }\r
179         $like = '('.implode(' or ',$temp_a).')';\r
180 \r
181                         for($kn=1; $kn<count($key_a); $kn++){\r
182                 if(substr($key_a[$kn],0,1) == ","){\r
183                         for($ith=0;$ith<count($match_a);$ith++){\r
184                                 $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
185                         }\r
186                         $like .=' OR ('. implode(' or ',$temp_a).')';\r
187                 }elseif(substr($key_a[$kn],0,1) != '-'){\r
188                         for($ith=0;$ith<count($match_a);$ith++){\r
189                                 $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes($key_a[$kn]) . "%') ";\r
190                         }\r
191                         $like .=' AND ('. implode(' or ',$temp_a).')';\r
192                 }else{\r
193                         for($ith=0;$ith<count($match_a);$ith++){\r
194                                 $temp_a[$ith] = " NOT(i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
195                         }\r
196                         $like .=' AND ('. implode(' and ',$temp_a).')';\r
197                 }\r
198         }\r
199         \r
200         $like = '('.$like.')';\r
201         return $like;\r
202     }\r
203 \r
204 /***********************************************/\r
205 \r
206 \r
207 /*\r
208     function boolean_mark_atoms($string){\r
209         $result=trim($string);\r
210         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
211 \r
212         //convert normal boolean operators to shortened syntax\r
213         $result=eregi_replace(' not ',' -',$result);\r
214         $result=eregi_replace(' and ',' ',$result);\r
215         $result=eregi_replace(' or ',',',$result);\r
216 \r
217 \r
218         //strip excessive whitespace\r
219         $result=str_replace('( ','(',$result);\r
220         $result=str_replace(' )',')',$result);\r
221         $result=str_replace(', ',',',$result);\r
222         $result=str_replace(' ,',',',$result);\r
223         $result=str_replace('- ','-',$result);\r
224         $result=str_replace('+','',$result);\r
225 \r
226         // remove double spaces (we might have introduced some new ones above)\r
227         $result=trim($result);\r
228         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
229 \r
230         // apply arbitrary function to all 'word' atoms\r
231 \r
232         $result_a = explode(" ",$result);\r
233         for($word=0;$word<count($result_a);$word++){\r
234             $result_a[$word] = "foo[('".$result_a[$word]."')]bar";\r
235         }\r
236         $result = implode(" ",$result_a);\r
237         \r
238         // dispatch ' ' to ' AND '\r
239         $result=str_replace(' ',' AND ',$result);\r
240 \r
241         // dispatch ',' to ' OR '\r
242         $result=str_replace(',',' OR ',$result);\r
243 \r
244         // dispatch '-' to ' NOT '\r
245         $result=str_replace(' -',' NOT ',$result);\r
246         return $result;\r
247     }\r
248     \r
249     function boolean_sql_where_short($string,$match){\r
250         $match_a = explode(',',$match);\r
251         for($ith=0;$ith<count($match_a);$ith++){\r
252                 $like_a[$ith] = " $match_a[$ith] LIKE '% $string %' ";\r
253         }\r
254         $like = implode(" OR ",$like_a);\r
255 \r
256         return $like;\r
257     }\r
258     function boolean_sql_select_short($string,$match){\r
259         $match_a = explode(',',$match);\r
260         $score_unit_weight = .2;\r
261         for($ith=0;$ith<count($match_a);$ith++){\r
262             $score_a[$ith] =\r
263                            " $score_unit_weight*(\r
264                            LENGTH(" . addslashes($match_a[$ith]) . ") -\r
265                            LENGTH(REPLACE(LOWER(" . addslashes($match_a[$ith]) . "),LOWER('" . addslashes($string) . "'),'')))\r
266                                        /LENGTH('" . addslashes($string) . "') ";\r
267         }\r
268             $score = implode(" + ",$score_a);\r
269 \r
270         return $score;\r
271     }\r
272 */\r
273 \r
274 }\r
275 ?>\r