7656762f81960e6b5ccf20520232e44c44eb36d1
[atutor.git] / mods / wiki / plugins / page / powersearch.php
1 <?php
2
3 /*
4    This plugins provides the internal page PowerSearch, which allows
5    to search in page contents and/or titles (or for author names, if any),
6    it tries to guess how good the database match matches the requested
7    search strings and orders results.
8    The top 10 results are printed more verbosely.
9 */
10
11
12 define("EWIKI_PAGE_POWERSEARCH", "PowerSearch");
13 $ewiki_plugins["page"][EWIKI_PAGE_POWERSEARCH] = "ewiki_page_powersearch";
14 $ewiki_plugins["action"]["search"] = "ewiki_action_powersearch";
15
16
17 function ewiki_action_powersearch(&$id, &$data, &$action) {
18     $o = ewiki_make_title(EWIKI_PAGE_POWERSEARCH, EWIKI_PAGE_POWERSEARCH, 2);        
19     $o.= ewiki_powersearch($id);
20     return ($o);
21 }
22
23
24 function ewiki_page_powersearch($id, &$data, $action) {
25     $q = @$_REQUEST["q"];
26
27     ($where = preg_replace('/[^a-z]/', '', @$_REQUEST["where"]))
28     or ($where = "content");
29
30     $o = ewiki_make_title($id, $id, 2);
31     
32     if (empty($q)) {        
33         $o .= '<div class="search-form">
34         <form name="powersearch" action="' . ewiki_script("", $id) . '" method="GET">
35         <input type="hidden" name="id" value="'.$id.'">
36         <input type="text" id="q" name="q" size="30">
37         in <select name="where"><option value="content">page texts</option><option value="id">titles</option><option value="author">author names</option></select>
38         <br /><br />
39         <input type="submit" value=" &nbsp; &nbsp; S E A R C H &nbsp; &nbsp; ">
40         </form></div>
41         <script type="text/javascript"><!--
42         document.powersearch.q.focus();
43         //--></script>';
44         
45         return($o);
46     }
47     else { 
48         $o .= ewiki_powersearch($q, $where);
49         return ($o);
50     }
51
52     return('');
53 }
54
55
56 function ewiki_powersearch($q, $where='content'){
57     $q = ewiki_lowercase(preg_replace('/\s*[\000-\040]+\s*/', ' ', $q));
58     
59     $found = array(); 
60     $scored = array(); 
61     
62     #-- initial scan
63     foreach (explode(" ", $q) as $search) {
64     
65      if (empty($search)) {
66         continue;
67      }
68     
69      $result = ewiki_db::SEARCH($where, $search);
70     
71         while ($row = $result->get()) {        
72             if (($row["flags"] & EWIKI_DB_F_TYPE) == EWIKI_DB_F_TEXT) {
73                 
74                 $id = $row["id"];
75                 $content = strtolower($row[$where]);
76                 unset($row);
77                 
78                 #-- have a closer look
79                 $len1 = strlen($content) + 1;
80                 
81                 if (!isset($scored[$id])) {
82                     $scored[$id] = 1;
83                 }
84                 $scored[$id] += 800 * (strlen($search) / $len1);
85                 $scored[$id] += 65 * (count(explode($search, $content)) - 2);
86                 $p = -1;
87                 while (($p = strpos($content, $search, $p+1)) !== false) {
88                     $scored[$id] += 80 * (1 - $p / $len1);
89                 }
90             
91             }#if-TXT
92         }
93     }
94     
95     
96     #-- output results
97     arsort($scored);
98     
99     $o = "<ol>\n";
100     $n = 0;
101     foreach ($scored as $id => $score) {
102     
103      #-- refetch page for top 10 entries (still cached by OS or DB)
104      $row = ($n < 10) ? ewiki_db::GET($id) : NULL;
105     
106      #-- check access rights in protected mode
107      if (EWIKI_PROTECTED_MODE && !ewiki_auth($id, $row, "view", $ring=false, $force=0)) {
108         if (EWIKI_PROTECTED_MODE_HIDING) {
109             continue;
110         } else {
111            $row["content"] = ewiki_t("FORBIDDEN");
112         }
113     }   
114     
115      $o .= "<li>\n";
116      $o .= '<div class="search-result '.($oe^=1?"odd":"even").'">'
117          . '<a href="' . ewiki_script("", $id) . '">' . $id . "</a> "
118     #<off>#      . "<small><small>(#$score)</small></small>"
119          . "\n";
120     
121      #-- top 10 results are printed more verbosely
122     
123      if ($n++ < 10) {
124     
125      preg_match_all('/([_-\w]+)/', $row["content"], $uu);
126         $text = htmlentities(substr(implode(" ", $uu[1]), 0, 200));
127         $o .= "<br />\n<small>$text\n"
128             . "<br />" . strftime(ewiki_t("LASTCHANGED"), $row["lastmodified"])
129             . "<br /><br /></small>\n";
130      }
131     
132      $o .= "</div>\n";
133     
134      $o .= "</li>\n";
135     
136     }
137     
138     $o .= "</ol>\n";
139     return($o); 
140     
141 }
142
143
144 ?>