OSDN Git Service

fe2571fa96b330c0eb0dbdc6b64f4bab07186e10
[nucleus-jp/nucleus-jp-ancient.git] / euc / 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 //        $text = preg_replace ("/[<,>,=,?,!,#,^,(,),[,\],:,;,\\\,%]/","",$text);\r
34 \r
35      /* * * for jp * * * * * * * * * * */\r
36         $text = $this->zenspace_replace($text);\r
37         $text = preg_replace ("/[<>=?!#^()[\]:;\\%]/","",$text);\r
38 \r
39         $this->ascii = '[\x00-\x7F]';\r
40         $this->two = '[\x8E\xA1-\xFE][\xA1-\xFE]';\r
41         $this->three = '\x8F[\xA1-\xFE][\xA1-\xFE]';\r
42 \r
43         $this->jpmarked      = $this->boolean_mark_atoms_jp($text);\r
44      /* * * * * * * * * * * * * * * * */\r
45 \r
46         $this->querystring      = $text;\r
47 //        $this->marked         = $this->boolean_mark_atoms($text);\r
48         $this->inclusive        = $this->boolean_inclusive_atoms($text);\r
49         $this->blogs            = array();\r
50 \r
51         // get all public searchable blogs, no matter what, include the current blog allways.\r
52                 $res = sql_query('SELECT bnumber FROM '.sql_table('blog').' WHERE bincludesearch=1 ');\r
53                 while ($obj = mysql_fetch_object($res)) \r
54                     $this->blogs[] = intval($obj->bnumber);\r
55         }\r
56 /***********************************************\r
57   zenkaku space to space\r
58 ***********************************************/\r
59 \r
60     function zenspace_replace($text){\r
61         $ta = unpack("C*",$text);\r
62         $len = count($ta);\r
63         $temp = '';\r
64         for($i=1; $i<=$len; $i++){\r
65                 if($ta[$i]>= 0x8e){ // ja\r
66                         if($ta[$i]>0xa0 || $ta[$i]<0x8f){ // 2byte\r
67                                 $char = chr($ta[$i]).chr($ta[$i+1]);\r
68                                 if($char == "\xA1\xA1") $char = "\x20";\r
69                                 $temp .= $char;\r
70                                 $i ++;\r
71                         }else{ // 3byte\r
72                                 $temp .= chr($ta[$i]).chr($ta[$i+1]).chr($ta[$i+2]);\r
73                                 $i += 2;\r
74                         }\r
75                 }else{ //ascii\r
76                         $temp .= chr($ta[$i]);\r
77                 }\r
78         }\r
79       return $temp;\r
80    }\r
81 /***********************************************/\r
82 \r
83     function  boolean_sql_select($match){\r
84 //        if (strlen($this->inclusive) > 0) {\r
85            /* build sql for determining score for each record */\r
86 /*             $result=explode(" ",$this->inclusive);\r
87            $result = $result[0];\r
88                  for($cth=0;$cth<count($result);$cth++){\r
89              if(strlen($result[$cth])>=4){\r
90                    $stringsum_long .=  " $result[$cth] ";\r
91                      }else{\r
92                        $stringsum_a[] = ' '.$this->boolean_sql_select_short($result[$cth],$match).' ';\r
93                      }\r
94                  }\r
95              if(strlen($stringsum_long)>0){\r
96                         $stringsum_long = addslashes($stringsum_long);\r
97                         $stringsum_a[] = " match ($match) against ('$stringsum_long') ";\r
98              }\r
99                  $stringsum .= implode("+",$stringsum_a);\r
100              return $stringsum;\r
101             }\r
102 */\r
103     }\r
104     \r
105     function boolean_inclusive_atoms($string){\r
106         $result=trim($string);\r
107         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
108 \r
109         /* convert normal boolean operators to shortened syntax */\r
110         $result=eregi_replace(' not ',' -',$result);\r
111         $result=eregi_replace(' and ',' ',$result);\r
112         $result=eregi_replace(' or ',',',$result);\r
113 \r
114         /* drop unnecessary spaces */\r
115         $result=str_replace(' ,',',',$result);\r
116         $result=str_replace(', ',',',$result);\r
117         $result=str_replace('- ','-',$result);\r
118         $result=str_replace('+','',$result);\r
119 \r
120         /* strip exlusive atoms */\r
121         $result=preg_replace(\r
122 //              "(\-\([A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_\,]{0,}\))",\r
123                 "(\-\(([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,}\))",\r
124                 '',\r
125                 $result);\r
126         $result=preg_replace(\r
127 //              "(\-[A-Za-z0-9]{1,}[A-Za-z0-9\-\.\_]{0,})",\r
128                 "(\-([A-Za-z0-9]|$this->two|$this->three){1,}([A-Za-z0-9\-\.\_\,]|$this->two|$this->three){0,})",\r
129                 '',\r
130                 $result);\r
131         $result=str_replace('(',' ',$result);\r
132         $result=str_replace(')',' ',$result);\r
133         $result=str_replace(',',' ',$result);\r
134 \r
135         return $result;\r
136     }\r
137     \r
138     function boolean_sql_where($match){\r
139 /*        $result = $this->marked;\r
140         $result = preg_replace(\r
141                 "/foo\[\(\'([^\)]{4,})\'\)\]bar/e",\r
142                 " 'match ('.\$match.') against (\''.\$this->copyvalue(\"$1\").'\') > 0 ' ",\r
143                 $result);\r
144 \r
145         $result = preg_replace(                 \r
146             "/foo\[\(\'([^\)]{1,3})\'\)\]bar/e",\r
147             " '('.\$this->boolean_sql_where_short(\"$1\",\"$match\").')' ",             \r
148             $result);*/\r
149       $result = $this->jpmarked; /* for jp */\r
150         $result = $this->boolean_sql_where_jp_short($result,$match);/* for jp */\r
151         return $result;\r
152     }\r
153     \r
154     // there must be a simple way to simply copy a value with backslashes in it through\r
155     // the preg_replace, but I cannot currently find it (karma 2003-12-30)\r
156     function copyvalue($foo) {\r
157         return $foo;\r
158     }\r
159 \r
160 /***********************************************\r
161   Make "WHERE" (jp)\r
162 ***********************************************/\r
163 \r
164     function boolean_mark_atoms_jp($string){\r
165 \r
166         $result=trim($string);\r
167         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
168 \r
169         /* convert normal boolean operators to shortened syntax */\r
170         $result=eregi_replace(' not ',' -',$result);\r
171         $result=eregi_replace(' and ',' ',$result);\r
172         $result=eregi_replace(' or ',',',$result);\r
173 \r
174         /* strip excessive whitespace */\r
175         $result=str_replace(', ',',',$result);\r
176         $result=str_replace(' ,',',',$result);\r
177         $result=str_replace('- ','-',$result);\r
178         $result=str_replace('+','',$result);\r
179         \r
180         $result=str_replace(',',' ,',$result);\r
181 \r
182         return $result;\r
183     }\r
184     \r
185 \r
186     function boolean_sql_where_jp_short($string,$match){\r
187         $match_a = explode(',',$match);\r
188                         $key_a = explode(' ',$string);\r
189                         \r
190         for($ith=0;$ith<count($match_a);$ith++){\r
191                 $temp_a[$ith] = "(i.$match_a[$ith] LIKE '%" . addslashes($key_a[0]) . "%') ";\r
192         }\r
193         $like = '('.implode(' or ',$temp_a).')';\r
194 \r
195                         for($kn=1; $kn<count($key_a); $kn++){\r
196                 if(substr($key_a[$kn],0,1) == ","){\r
197                         for($ith=0;$ith<count($match_a);$ith++){\r
198                                 $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
199                         }\r
200                         $like .=' OR ('. implode(' or ',$temp_a).')';\r
201                 }elseif(substr($key_a[$kn],0,1) != '-'){\r
202                         for($ith=0;$ith<count($match_a);$ith++){\r
203                                 $temp_a[$ith] = " (i.$match_a[$ith] LIKE '%" . addslashes($key_a[$kn]) . "%') ";\r
204                         }\r
205                         $like .=' AND ('. implode(' or ',$temp_a).')';\r
206                 }else{\r
207                         for($ith=0;$ith<count($match_a);$ith++){\r
208                                 $temp_a[$ith] = " NOT(i.$match_a[$ith] LIKE '%" . addslashes(substr($key_a[$kn],1)) . "%') ";\r
209                         }\r
210                         $like .=' AND ('. implode(' and ',$temp_a).')';\r
211                 }\r
212         }\r
213         \r
214         $like = '('.$like.')';\r
215         return $like;\r
216     }\r
217 \r
218 /***********************************************/\r
219 \r
220 /*    function boolean_mark_atoms($string){\r
221         $result=trim($string);\r
222         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
223 \r
224         // convert normal boolean operators to shortened syntax \r
225         $result=eregi_replace(' not ',' -',$result);\r
226         $result=eregi_replace(' and ',' ',$result);\r
227         $result=eregi_replace(' or ',',',$result);\r
228 \r
229         // strip excessive whitespace \r
230         $result=str_replace('( ','(',$result);\r
231         $result=str_replace(' )',')',$result);\r
232         $result=str_replace(', ',',',$result);\r
233         $result=str_replace(' ,',',',$result);\r
234         $result=str_replace('- ','-',$result);\r
235         $result=str_replace('+','',$result);\r
236 \r
237         // remove double spaces (we might have introduced some new ones above)\r
238         $result=trim($result);\r
239         $result=preg_replace("/([[:space:]]{2,})/",' ',$result);\r
240 \r
241         // apply arbitrary function to all 'word' atoms \r
242 \r
243         $result_a = explode(" ",$result);\r
244         for($word=0;$word<count($result_a);$word++){\r
245             $result_a[$word] = "foo[('".$result_a[$word]."')]bar";\r
246         }\r
247         $result = implode(" ",$result_a);\r
248         \r
249         // dispatch ' ' to ' AND ' \r
250         $result=str_replace(' ',' AND ',$result);\r
251 \r
252         // dispatch ',' to ' OR ' \r
253         $result=str_replace(',',' OR ',$result);\r
254 \r
255         // dispatch '-' to ' NOT ' \r
256         $result=str_replace(' -',' NOT ',$result);\r
257         return $result;\r
258     }\r
259     \r
260     function boolean_sql_where_short($string,$match){\r
261         $match_a = explode(',',$match);\r
262         for($ith=0;$ith<count($match_a);$ith++){\r
263                 $like_a[$ith] = " $match_a[$ith] LIKE '% $string %' ";\r
264         }\r
265         $like = implode(" or ",$like_a);\r
266 \r
267         return $like;\r
268     }\r
269     function boolean_sql_select_short($string,$match){\r
270         $match_a = explode(',',$match);\r
271         $score_unit_weight = .2;\r
272         for($ith=0;$ith<count($match_a);$ith++){\r
273             $score_a[$ith] =\r
274                            " $score_unit_weight*(\r
275                            LENGTH(" . addslashes($match_a[$ith]) . ") -\r
276                            LENGTH(REPLACE(LOWER(" . addslashes($match_a[$ith]) . "),LOWER('" . addslashes($string) . "'),'')))\r
277                                        /LENGTH('" . addslashes($string) . "') ";\r
278         }\r
279             $score = implode(" + ",$score_a);\r
280 \r
281         return $score;\r
282     } */\r
283   }\r
284 ?>\r