OSDN Git Service

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