]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/mysql.php
Fix SF bug #462168: hit count broken for pages with apostrophes in their names.
[SourceForge/phpwiki.git] / lib / mysql.php
1 <?php rcs_id('$Id: mysql.php,v 1.10.2.3 2001-11-07 18:54:07 dairiki Exp $');
2
3    /*
4       Database functions:
5       OpenDataBase($dbname)
6       CloseDataBase($dbi)
7       MakeDBHash($pagename, $pagehash)
8       MakePageHash($dbhash)
9       RetrievePage($dbi, $pagename, $pagestore)
10       InsertPage($dbi, $pagename, $pagehash)
11       SaveCopyToArchive($dbi, $pagename, $pagehash)
12       IsWikiPage($dbi, $pagename)
13       IsInArchive($dbi, $pagename)
14       RemovePage($dbi, $pagename)
15       IncreaseHitCount($dbi, $pagename)
16       GetHitCount($dbi, $pagename)
17       MakeSQLSearchClause($search, $column)
18       InitTitleSearch($dbi, $search)
19       TitleSearchNextMatch($dbi, $res)
20       InitFullSearch($dbi, $search)
21       FullSearchNextMatch($dbi, $res)
22       InitBackLinkSearch($dbi, $pagename) 
23       BackLinkSearchNextMatch($dbi, &$pos) 
24       InitMostPopular($dbi, $limit)
25       MostPopularNextMatch($dbi, $res)
26       GetAllWikiPageNames($dbi)
27       GetWikiPageLinks($dbi, $pagename)
28       SetWikiPageLinks($dbi, $pagename, $linklist)
29    */
30
31    // open a database and return the handle
32    // ignores MAX_DBM_ATTEMPTS
33
34    function OpenDataBase($dbname) {
35       global $mysql_server, $mysql_user, $mysql_pwd, $mysql_db;
36
37       if (!($dbc = mysql_pconnect($mysql_server, $mysql_user, $mysql_pwd))) {
38          $msg = gettext ("Cannot establish connection to database, giving up.");
39          $msg .= "<BR>";
40          $msg .= sprintf(gettext ("MySQL error: %s"), mysql_error());
41          ExitWiki($msg);
42       }
43       if (!mysql_select_db($mysql_db, $dbc)) {
44          $msg =  sprintf(gettext ("Cannot open database %s, giving up."), $mysql_db);
45          $msg .= "<BR>";
46          $msg .= sprintf(gettext ("MySQL error: %s"), mysql_error());
47          ExitWiki($msg);
48       }
49       $dbi['dbc'] = $dbc;
50       $dbi['table'] = $dbname;
51       return $dbi;
52    }
53
54
55    function CloseDataBase($dbi) {
56       // NOP function
57       // mysql connections are established as persistant
58       // they cannot be closed through mysql_close()
59    }
60
61
62    // prepare $pagehash for storing in mysql
63    function MakeDBHash($pagename, $pagehash)
64    {
65       $pagehash["pagename"] = addslashes($pagename);
66       if (!isset($pagehash["flags"]))
67          $pagehash["flags"] = 0;
68       $pagehash["author"] = addslashes($pagehash["author"]);
69       $pagehash["content"] = implode("\n", $pagehash["content"]);
70       $pagehash["content"] = addslashes($pagehash["content"]);
71       if (!isset($pagehash["refs"]))
72          $pagehash["refs"] = array();
73       $pagehash["refs"] = serialize($pagehash["refs"]);
74  
75       return $pagehash;
76    }
77
78
79    // convert mysql result $dbhash to $pagehash
80    function MakePageHash($dbhash)
81    {
82       // unserialize/explode content
83       $dbhash['refs'] = unserialize($dbhash['refs']);
84       $dbhash['content'] = explode("\n", $dbhash['content']);
85       return $dbhash;
86    }
87
88
89    // Return hash of page + attributes or default
90    function RetrievePage($dbi, $pagename, $pagestore) {
91       $pagename = addslashes($pagename);
92       if ($res = mysql_query("select * from $pagestore where pagename='$pagename'", $dbi['dbc'])) {
93          if ($dbhash = mysql_fetch_array($res)) {
94             return MakePageHash($dbhash);
95          }
96       }
97       return -1;
98    }
99
100
101    // Either insert or replace a key/value (a page)
102    function InsertPage($dbi, $pagename, $pagehash)
103    {
104       global $WikiPageStore; // ugly hack
105
106       if ($dbi['table'] == $WikiPageStore) { // HACK
107          $linklist = ExtractWikiPageLinks($pagehash['content']);
108          SetWikiPageLinks($dbi, $pagename, $linklist);
109       }
110
111       $pagehash = MakeDBHash($pagename, $pagehash);
112
113       $COLUMNS = "author, content, created, flags, " .
114                  "lastmodified, pagename, refs, version";
115
116       $VALUES =  "'$pagehash[author]', '$pagehash[content]', " .
117                  "$pagehash[created], $pagehash[flags], " .
118                  "$pagehash[lastmodified], '$pagehash[pagename]', " .
119                  "'$pagehash[refs]', $pagehash[version]";
120
121       if (!mysql_query("replace into $dbi[table] ($COLUMNS) values ($VALUES)",
122                         $dbi['dbc'])) {
123             $msg = sprintf(gettext ("Error writing page '%s'"), $pagename);
124             $msg .= "<BR>";
125             $msg .= sprintf(gettext ("MySQL error: %s"), mysql_error());
126             ExitWiki($msg);
127       }
128    }
129
130
131    // for archiving pages to a seperate dbm
132    function SaveCopyToArchive($dbi, $pagename, $pagehash) {
133       global $ArchivePageStore;
134       $adbi = OpenDataBase($ArchivePageStore);
135       InsertPage($adbi, $pagename, $pagehash);
136    }
137
138
139    function IsWikiPage($dbi, $pagename) {
140       $pagename = addslashes($pagename);
141       if ($res = mysql_query("select count(*) from $dbi[table] where pagename='$pagename'", $dbi['dbc'])) {
142          return(mysql_result($res, 0));
143       }
144       return 0;
145    }
146
147    function IsInArchive($dbi, $pagename) {
148       global $ArchivePageStore;
149
150       $pagename = addslashes($pagename);
151       if ($res = mysql_query("select count(*) from $ArchivePageStore where pagename='$pagename'", $dbi['dbc'])) {
152          return(mysql_result($res, 0));
153       }
154       return 0;
155    }
156
157
158    function RemovePage($dbi, $pagename) {
159       global $WikiPageStore, $ArchivePageStore;
160       global $WikiLinksStore, $HitCountStore, $WikiScoreStore;
161
162       $pagename = addslashes($pagename);
163       $msg = gettext ("Cannot delete '%s' from table '%s'");
164       $msg .= "<br>\n";
165       $msg .= gettext ("MySQL error: %s");
166
167       if (!mysql_query("delete from $WikiPageStore where pagename='$pagename'", $dbi['dbc']))
168          ExitWiki(sprintf($msg, $pagename, $WikiPageStore, mysql_error()));
169
170       if (!mysql_query("delete from $ArchivePageStore where pagename='$pagename'", $dbi['dbc']))
171          ExitWiki(sprintf($msg, $pagename, $ArchivePageStore, mysql_error()));
172
173       if (!mysql_query("delete from $WikiLinksStore where frompage='$pagename'", $dbi['dbc']))
174          ExitWiki(sprintf($msg, $pagename, $WikiLinksStore, mysql_error()));
175
176       if (!mysql_query("delete from $HitCountStore where pagename='$pagename'", $dbi['dbc']))
177          ExitWiki(sprintf($msg, $pagename, $HitCountStore, mysql_error()));
178
179       if (!mysql_query("delete from $WikiScoreStore where pagename='$pagename'", $dbi['dbc']))
180          ExitWiki(sprintf($msg, $pagename, $WikiScoreStore, mysql_error()));
181    }
182
183
184    function IncreaseHitCount($dbi, $pagename)
185    {
186       global $HitCountStore;
187
188       $qpagename = addslashes($pagename);
189       $res = mysql_query("update $HitCountStore set hits=hits+1"
190                          . " where pagename='$qpagename'",
191                          $dbi['dbc']);
192
193       if (!mysql_affected_rows($dbi['dbc'])) {
194          $res = mysql_query("insert into $HitCountStore (pagename, hits)"
195                             . " values ('$qpagename', 1)",
196                             $dbi['dbc']);
197       }
198
199       return $res;
200    }
201
202    function GetHitCount($dbi, $pagename)
203    {
204       global $HitCountStore;
205
206       $qpagename = addslashes($pagename);
207       $res = mysql_query("select hits from $HitCountStore"
208                          . " where pagename='$qpagename'",
209                          $dbi['dbc']);
210       if (mysql_num_rows($res))
211          $hits = mysql_result($res, 0);
212       else
213          $hits = "0";
214
215       return $hits;
216    }
217
218    function MakeSQLSearchClause($search, $column)
219    {
220       $search = addslashes(preg_replace("/\s+/", " ", $search));
221       $term = strtok($search, ' ');
222       $clause = '';
223       while($term) {
224          $word = strtolower("$term");
225          if ($word[0] == '-') {
226             $word = substr($word, 1);
227             $clause .= "not (LCASE($column) like '%$word%') ";
228          } else {
229             $clause .= "(LCASE($column) like '%$word%') ";
230          }
231          if ($term = strtok(' '))
232             $clause .= 'AND ';
233       }
234       return $clause;
235    }
236
237    // setup for title-search
238    function InitTitleSearch($dbi, $search) {
239       $clause = MakeSQLSearchClause($search, 'pagename');
240       $res = mysql_query("select pagename from $dbi[table] where $clause order by pagename", $dbi["dbc"]);
241
242       return $res;
243    }
244
245
246    // iterating through database
247    function TitleSearchNextMatch($dbi, $res) {
248       if($o = mysql_fetch_object($res)) {
249          return $o->pagename;
250       }
251       else {
252          return 0;
253       }
254    }
255
256
257    // setup for full-text search
258    function InitFullSearch($dbi, $search) {
259       $clause = MakeSQLSearchClause($search, 'content');
260       $res = mysql_query("select * from $dbi[table] where $clause", $dbi["dbc"]);
261
262       return $res;
263    }
264
265    // iterating through database
266    function FullSearchNextMatch($dbi, $res) {
267       if($hash = mysql_fetch_array($res)) {
268          return MakePageHash($hash);
269       }
270       else {
271          return 0;
272       }
273    }
274
275    // setup for back-link search
276    function InitBackLinkSearch($dbi, $pagename) {
277       global $WikiLinksStore;
278      
279       $topage = addslashes($pagename);
280       $res = mysql_query( "SELECT DISTINCT frompage FROM $WikiLinksStore"
281                           . " WHERE topage='$topage'"
282                           . " ORDER BY frompage",
283                           $dbi["dbc"]);
284       return $res;
285    }
286
287
288    // iterating through database
289    function BackLinkSearchNextMatch($dbi, $res) {
290       if($a = mysql_fetch_row($res)) {
291          return $a[0];
292       }
293       else {
294          return 0;
295       }
296    }
297
298
299    function InitMostPopular($dbi, $limit) {
300       global $HitCountStore;
301       $res = mysql_query("select * from $HitCountStore order by hits desc, pagename limit $limit", $dbi["dbc"]);
302       
303       return $res;
304    }
305
306    function MostPopularNextMatch($dbi, $res) {
307       if ($hits = mysql_fetch_array($res))
308          return $hits;
309       else
310          return 0;
311    }
312
313    function GetAllWikiPageNames($dbi) {
314       global $WikiPageStore;
315       $res = mysql_query("select pagename from $WikiPageStore", $dbi["dbc"]);
316       $rows = mysql_num_rows($res);
317       for ($i = 0; $i < $rows; $i++) {
318          $pages[$i] = mysql_result($res, $i);
319       }
320       return $pages;
321    }
322    
323    
324    ////////////////////////////////////////
325    // functionality for the wikilinks table
326
327    // takes a page name, returns array of scored incoming and outgoing links
328    function GetWikiPageLinks($dbi, $pagename) {
329       global $WikiLinksStore, $WikiScoreStore, $HitCountStore;
330
331       $pagename = addslashes($pagename);
332       $res = mysql_query("select topage, score from $WikiLinksStore, $WikiScoreStore where topage=pagename and frompage='$pagename' order by score desc, topage");
333       $rows = mysql_num_rows($res);
334       for ($i = 0; $i < $rows; $i++) {
335          $out = mysql_fetch_array($res);
336          $links['out'][] = array($out['topage'], $out['score']);
337       }
338
339       $res = mysql_query("select frompage, score from $WikiLinksStore, $WikiScoreStore where frompage=pagename and topage='$pagename' order by score desc, frompage");
340       $rows = mysql_num_rows($res);
341       for ($i = 0; $i < $rows; $i++) {
342          $out = mysql_fetch_array($res);
343          $links['in'][] = array($out['frompage'], $out['score']);
344       }
345
346       $res = mysql_query("select distinct pagename, hits from $WikiLinksStore, $HitCountStore where (frompage=pagename and topage='$pagename') or (topage=pagename and frompage='$pagename') order by hits desc, pagename");
347       $rows = mysql_num_rows($res);
348       for ($i = 0; $i < $rows; $i++) {
349          $out = mysql_fetch_array($res);
350          $links['popular'][] = array($out['pagename'], $out['hits']);
351       }
352
353       return $links;
354    }
355
356
357    // takes page name, list of links it contains
358    // the $linklist is an array where the keys are the page names
359    function SetWikiPageLinks($dbi, $pagename, $linklist) {
360       global $WikiLinksStore, $WikiScoreStore;
361
362       $frompage = addslashes($pagename);
363
364       // first delete the old list of links
365       mysql_query("delete from $WikiLinksStore where frompage='$frompage'",
366                 $dbi["dbc"]);
367
368       // the page may not have links, return if not
369       if (! count($linklist))
370          return;
371       // now insert the new list of links
372       while (list($topage, $count) = each($linklist)) {
373          $topage = addslashes($topage);
374          if($topage != $frompage) {
375             mysql_query("insert into $WikiLinksStore (frompage, topage) " .
376                      "values ('$frompage', '$topage')", $dbi["dbc"]);
377          }
378       }
379
380       // update pagescore
381       mysql_query("delete from $WikiScoreStore", $dbi["dbc"]);
382       mysql_query("insert into $WikiScoreStore select w1.topage, count(*) from $WikiLinksStore as w1, $WikiLinksStore as w2 where w2.topage=w1.frompage group by w1.topage", $dbi["dbc"]);
383    }
384
385 /* more mysql queries:
386
387 orphans:
388 select pagename from wiki left join wikilinks on pagename=topage where topage is NULL;
389 */
390 ?>