1 <script language="PHP">
2 require_once "search-config.php";
4 function end_form($value)
8 if ($config['DISABLE_INDEX'] == false)
10 echo " <input type=\"text\" id=\"MSearchField\" name=\"query\" value=\"$value\" size=\"20\" accesskey=\"S\" onfocus=\"searchBox.OnSearchFieldFocus(true)\" onblur=\"searchBox.OnSearchFieldFocus(false)\"/>\n </form>\n </div><div class=\"right\"></div>\n </div>\n </li>\n </ul>\n </div>\n</div>\n";
12 if ($config['GENERATE_TREEVIEW'])
14 echo $translator['split_bar'];
22 //if ($config['GENERATE_TREEVIEW'])
24 // echo "</div>\n<div id=\"nav-path\" class=\"navpath\">\n <ul>\n <li class=\"footer\">";
25 // echo $translator['logo'];
26 // echo "</li>\n </ul>\n</div>";
28 echo "</body></html>";
31 function search_results()
34 return $translator['search_results_title'];
37 function matches_text($num)
40 $string = $translator['search_results'][($num>2)?2:$num];
41 // The eval is used so that translator strings can contain $num.
42 eval("\$result = \"$string\";");
46 function report_matches()
49 return $translator['search_matches'];
52 function readInt($file)
54 $b1 = ord(fgetc($file)); $b2 = ord(fgetc($file));
55 $b3 = ord(fgetc($file)); $b4 = ord(fgetc($file));
56 return ($b1<<24)|($b2<<16)|($b3<<8)|$b4;
59 function readString($file)
62 while (ord($c=fgetc($file))) $result.=$c;
66 function readHeader($file)
68 $header =fgetc($file); $header.=fgetc($file);
69 $header.=fgetc($file); $header.=fgetc($file);
73 function computeIndex($word)
75 // Simple hashing that allows for substring search
76 if (strlen($word)<2) return -1;
77 // high char of the index
79 if ($hi==0) return -1;
80 // low char of the index
82 if ($lo==0) return -1;
87 function search($file,$word,&$statsList)
89 $index = computeIndex($word);
90 if ($index!=-1) // found a valid index
92 fseek($file,$index*4+4); // 4 bytes per entry, skip header
93 $index = readInt($file);
94 if ($index) // found words matching the hash key
96 $start=sizeof($statsList);
99 $w = readString($file);
102 $statIdx = readInt($file);
103 if ($word==substr($w,0,strlen($word)))
104 { // found word that matches (as substring)
105 $statsList[$count++]=array(
109 "full"=>strlen($w)==strlen($word),
113 $w = readString($file);
118 for ($count=$start;$count<sizeof($statsList);$count++)
120 $statInfo = &$statsList[$count];
122 // whole word matches have a double weight
123 if ($statInfo["full"]) $multiplier=2;
124 fseek($file,$statInfo["index"]);
125 $numDocs = readInt($file);
127 // read docs info + occurrence frequency of the word
128 for ($i=0;$i<$numDocs;$i++)
131 $freq=readInt($file);
132 $docInfo[$i]=array("idx" => $idx,
137 if ($freq&1) // word occurs in high priority doc
140 $totalFreqHi+=$freq*$multiplier;
142 else // word occurs in low priority doc
144 $totalFreqLo+=$freq*$multiplier;
147 // read name and url info for the doc
148 for ($i=0;$i<$numDocs;$i++)
150 fseek($file,$docInfo[$i]["idx"]);
151 $docInfo[$i]["name"]=readString($file);
152 $docInfo[$i]["url"]=readString($file);
154 $statInfo["docs"]=$docInfo;
156 $totalFreq=($totalHi+1)*$totalFreqLo + $totalFreqHi;
157 for ($count=$start;$count<sizeof($statsList);$count++)
159 $statInfo = &$statsList[$count];
161 // whole word matches have a double weight
162 if ($statInfo["full"]) $multiplier=2;
163 for ($i=0;$i<sizeof($statInfo["docs"]);$i++)
165 $docInfo = &$statInfo["docs"];
166 // compute frequency rank of the word in each doc
167 $freq=$docInfo[$i]["freq"];
168 if ($docInfo[$i]["hi"])
170 $statInfo["docs"][$i]["rank"]=
171 (float)($freq*$multiplier+$totalFreqLo)/$totalFreq;
175 $statInfo["docs"][$i]["rank"]=
176 (float)($freq*$multiplier)/$totalFreq;
185 function combine_results($results,&$docs)
187 foreach ($results as $wordInfo)
189 $docsList = &$wordInfo["docs"];
190 foreach ($docsList as $di)
194 if (isset($docs[$key]))
196 $docs[$key]["rank"]+=$rank;
200 $docs[$key] = array("url"=>$key,
205 $docs[$key]["words"][] = array(
206 "word"=>$wordInfo["word"],
207 "match"=>$wordInfo["match"],
215 function filter_results($docs,&$requiredWords,&$forbiddenWords)
217 $filteredDocs=array();
218 while (list ($key, $val) = each ($docs))
220 $words = &$docs[$key]["words"];
221 $copy=1; // copy entry by default
222 if (sizeof($requiredWords)>0)
224 foreach ($requiredWords as $reqWord)
227 foreach ($words as $wordInfo)
229 $found = $wordInfo["word"]==$reqWord;
234 $copy=0; // document contains none of the required words
239 if (sizeof($forbiddenWords)>0)
241 foreach ($words as $wordInfo)
243 if (in_array($wordInfo["word"],$forbiddenWords))
245 $copy=0; // document contains a forbidden word
250 if ($copy) $filteredDocs[$key]=$docs[$key];
252 return $filteredDocs;
255 function compare_rank($a,$b)
257 if ($a["rank"] == $b["rank"])
261 return ($a["rank"]>$b["rank"]) ? -1 : 1;
264 function sort_results($docs,&$sorted)
267 usort($sorted,"compare_rank");
271 function report_results(&$docs)
273 echo "<div class=\"header\">";
274 echo " <div class=\"headertitle\">\n";
275 echo " <h1>".search_results()."</h1>\n";
278 echo "<div class=\"searchresults\">\n";
279 echo "<table cellspacing=\"2\">\n";
280 $numDocs = sizeof($docs);
284 echo " <td colspan=\"2\">".matches_text(0)."</td>\n";
290 echo " <td colspan=\"2\">".matches_text($numDocs);
295 foreach ($docs as $doc)
298 echo " <td align=\"right\">$num.</td>";
299 echo "<td><a class=\"el\" href=\"".$doc["url"]."\">".$doc["name"]."</a></td>\n";
301 echo " <td></td><td class=\"tiny\">".report_matches()." ";
302 foreach ($doc["words"] as $wordInfo)
304 $word = $wordInfo["word"];
305 $matchRight = substr($wordInfo["match"],strlen($word));
306 echo "<b>$word</b>$matchRight(".$wordInfo["freq"].") ";
317 function run_query($query)
319 if(strcmp('4.1.0', phpversion()) > 0)
321 die("Error: PHP version 4.1.0 or above required!");
323 if (!($file=fopen("search/search.idx","rb")))
325 die("Error: Search index file could NOT be opened!");
327 if (readHeader($file)!="DOXS")
329 die("Error: Header of index file is invalid!");
332 $requiredWords = array();
333 $forbiddenWords = array();
334 $foundWords = array();
335 $word=strtok($query," ");
336 while ($word) // for each word in the search query
338 if (($word{0}=='+')) { $word=substr($word,1); $requiredWords[]=$word; }
339 if (($word{0}=='-')) { $word=substr($word,1); $forbiddenWords[]=$word; }
340 if (!in_array($word,$foundWords))
343 search($file,strtolower($word),$results);
349 combine_results($results,$docs);
350 // filter out documents with forbidden word or that do not contain
352 $filteredDocs = filter_results($docs,$requiredWords,$forbiddenWords);
353 // sort the results based on rank
355 sort_results($filteredDocs,$sorted);
362 if (array_key_exists("query", $_GET))
364 $query=$_GET["query"];
366 $sorted = run_query($query);
367 // Now output the HTML stuff...
369 end_form(preg_replace("/[^a-zA-Z0-9\-\_\.]/i", " ", $query ));
370 // report results to the user
371 report_results($sorted);