]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/db_filesystem.php
Added real back-link searches.
[SourceForge/phpwiki.git] / lib / db_filesystem.php
1 <?php  rcs_id('$Id: db_filesystem.php,v 1.4.2.1 2001-08-18 00:35:10 dairiki Exp $');
2    /*
3       Database functions:
4
5       OpenDataBase($table)
6       CloseDataBase($dbi)
7       RetrievePage($dbi, $pagename, $pagestore)
8       InsertPage($dbi, $pagename, $pagehash)
9       SaveCopyToArchive($dbi, $pagename, $pagehash) 
10       IsWikiPage($dbi, $pagename)
11       InitTitleSearch($dbi, $search)
12       TitleSearchNextMatch($dbi, $res)
13       InitFullSearch($dbi, $search)
14       FullSearchNextMatch($dbi, $res)
15       MakeBackLinkSearchRegexp($pagename)
16       InitBackLinkSearch($dbi, $pagename) 
17       BackLinkSearchNextMatch($dbi, &$pos) 
18       IncreaseHitCount($dbi, $pagename)
19       GetHitCount($dbi, $pagename)
20       InitMostPopular($dbi, $limit)
21       MostPopularNextMatch($dbi, $res)
22    */
23
24
25    // open a database and return the handle
26    // loop until we get a handle; php has its own
27    // locking mechanism, thank god.
28    // Suppress ugly error message with @.
29
30    function OpenDataBase($dbname) {
31       global $WikiDB;
32
33       ksort($WikiDB);
34       reset($WikiDB);
35
36       return $WikiDB;
37    }
38
39
40    function CloseDataBase($dbi) {
41       return;
42    }
43
44    
45    // Return hash of page + attributes or default
46    function RetrievePage($dbi, $pagename, $pagestore) {
47       $filename = $dbi[$pagestore] . "/" . $pagename;
48       if ($fd = @fopen($filename, "r")) {
49          $locked = flock($fd, 1); # Read lock
50          if (!$locked) { 
51             ExitWiki("Timeout while obtaining lock. Please try again"); 
52          }
53          if ($data = file($filename)) {
54             // unserialize $data into a hash
55             $pagehash = unserialize(join("\n", $data));
56                  }      
57                  fclose($fd);
58                  if($data) {
59                     return $pagehash;
60                  }
61       } else {
62          return -1;
63       }
64    }
65
66
67    // Either insert or replace a key/value (a page)
68    function Filesystem_WritePage($dbi, $pagename, $pagehash) {
69       global $WikiPageStore;
70       $pagedata = serialize($pagehash);
71
72       if (!file_exists($dbi)) {
73              $d = split("/", $dbi);
74                  $dt = "";
75                  while(list($key, $val) = each($d)) {
76                         $dt = $dt.$val."/";
77                     @mkdir($dt, 0755);
78                  }
79           }
80
81       $filename = $dbi . "/" . $pagename;
82       if($fd = fopen($filename, 'a')) { 
83          $locked = flock($fd,2); #Exclusive blocking lock 
84          if (!$locked) { 
85             ExitWiki("Timeout while obtaining lock. Please try again"); 
86          } 
87
88          #Second (actually used) filehandle 
89          $fdsafe = fopen($filename, 'w'); 
90          fwrite($fdsafe, $pagedata); 
91          fclose($fdsafe); 
92          fclose($fd);
93       } else {
94          ExitWiki("Error while writing page '$pagename'");
95       }
96    }
97
98    function InsertPage($dbi, $pagename, $pagehash) {
99       return Filesystem_WritePage($dbi['wiki'], $pagename, $pagehash);
100    }
101
102    // for archiving pages to a seperate dbm
103    function SaveCopyToArchive($dbi, $pagename, $pagehash) {
104       global $ArchivePageStore;
105       return Filesystem_WritePage($dbi[$ArchivePageStore], $pagename, $pagehash);
106    }
107
108
109    function IsWikiPage($dbi, $pagename) {
110       return file_exists($dbi['wiki'] . "/" . $pagename);
111    }
112
113
114    function IsInArchive($dbi, $pagename) {
115       return file_exists($dbi['archive'] . "/" . $pagename);
116    }
117
118
119    // setup for title-search
120    function InitTitleSearch($dbi, $search) { 
121       $pos['search'] = $search;
122       $pos['data'] = GetAllWikiPageNames($dbi['wiki']);
123
124       return $pos;
125    }
126
127    // iterating through database
128    function TitleSearchNextMatch($dbi, &$pos) { 
129       while (list($key, $page) = each($pos['data'])) {
130          if (eregi($pos['search'], $page)) {
131             return $page;
132          }
133       }
134       return 0;
135    }
136
137    // setup for full-text search
138    function InitFullSearch($dbi, $search) { 
139       return InitTitleSearch($dbi, $search);
140    }
141
142    //iterating through database
143    function FullSearchNextMatch($dbi, &$pos) { 
144       global $WikiPageStore;
145       while (list($key, $page) = each($pos['data'])) {
146          $pagedata = RetrievePage($dbi, $page, $WikiPageStore);
147          if (eregi($pos['search'], serialize($pagedata))) {
148                 return $pagedata;
149                  }
150           }
151       return 0;
152    }
153
154    ////////////////////////
155    // new database features
156
157    // Compute PCRE suitable for searching for links to the given page.
158    function MakeBackLinkSearchRegexp($pagename) {
159       global $WikiNameRegexp;
160
161       // Note that in (at least some) PHP 3.x's, preg_quote only takes
162       // (at most) one argument.  Also it doesn't quote '/'s.
163       // It does quote '='s, so we'll use that for the delimeter.
164       $quoted_pagename = preg_quote($pagename);
165       if (preg_match("/^$WikiNameRegexp\$/", $pagename)) {
166          # FIXME: This may need modification for non-standard (non-english) $WikiNameRegexp.
167          return "=(?<![A-Za-z0-9!])$quoted_pagename(?![A-Za-z0-9])=";
168       }
169       else {
170          // Note from author: Sorry. :-/
171          return ( '='
172                   . '(?<!\[)\[(?!\[)' // Single, isolated '['
173                   . '([^]|]*\|)?'     // Optional stuff followed by '|'
174                   . '\s*'             // Optional space
175                   . $quoted_pagename  // Pagename
176                   . '\s*\]=' );       // Optional space, followed by ']'
177          // FIXME: the above regexp is still not quite right.
178          // Consider the text: " [ [ test page ]".  This is a link to a page
179          // named '[ test page'.  The above regexp will recognize this
180          // as a link either to '[ test page' (good) or to 'test page' (wrong).
181       } 
182    }
183
184    // setup for back-link search
185    function InitBackLinkSearch($dbi, $pagename) {
186       return InitTitleSearch($dbi, MakeBackLinkSearchRegexp($pagename));
187    }
188
189    // iterating through back-links
190    function BackLinkSearchNextMatch($dbi, &$pos) {
191       global $WikiPageStore;
192       while (list($key, $page) = each($pos['data'])) {
193          $pagedata = RetrievePage($dbi, $page, $WikiPageStore);
194          printf("Page: '%s' => '%s'<br>\n",
195                 htmlspecialchars($page),
196                 htmlspecialchars($pagedata));
197          
198          while (list($i, $line) = each($pagedata['content'])) {
199             if (preg_match($pos['search'], $line))
200                return $page;
201          }
202       }
203       return 0;
204    }
205
206    function IncreaseHitCount($dbi, $pagename) {
207       return;
208 return;
209       // kluge: we ignore the $dbi for hit counting
210       global $WikiDB;
211
212       $hcdb = OpenDataBase($WikiDB['hitcount']);
213
214       if (dbmexists($hcdb['active'], $pagename)) {
215          // increase the hit count
216          $count = dbmfetch($hcdb['active'], $pagename);
217          $count++;
218          dbmreplace($hcdb['active'], $pagename, $count);
219       } else {
220          // add it, set the hit count to one
221          $count = 1;
222          dbminsert($hcdb['active'], $pagename, $count);
223       }
224
225       CloseDataBase($hcdb);
226    }
227
228    function GetHitCount($dbi, $pagename) {
229       return;
230       // kluge: we ignore the $dbi for hit counting
231       global $WikiDB;
232
233       $hcdb = OpenDataBase($WikiDB['hitcount']);
234       if (dbmexists($hcdb['active'], $pagename)) {
235          // increase the hit count
236          $count = dbmfetch($hcdb['active'], $pagename);
237          return $count;
238       } else {
239          return 0;
240       }
241
242       CloseDataBase($hcdb);
243    }
244
245
246    function InitMostPopular($dbi, $limit) {
247      return;
248       $pagename = dbmfirstkey($dbi['hitcount']);
249       $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
250       while ($pagename = dbmnextkey($dbi['hitcount'], $pagename)) {
251          $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
252          echo "got $pagename with value " . $res[$pagename] . "<br>\n";
253       }
254
255       rsort($res);
256       reset($res);
257       return($res);
258    }
259
260    function MostPopularNextMatch($dbi, $res) {
261       return;
262       // the return result is a two element array with 'hits'
263       // and 'pagename' as the keys
264
265       if (list($index1, $index2, $pagename, $hits) = each($res)) {
266          echo "most popular next match called<br>\n";
267          echo "got $pagename, $hits back<br>\n";
268          $nextpage = array(
269             "hits" => $hits,
270             "pagename" => $pagename
271          );
272          return $nextpage;
273       } else {
274          return 0;
275       }
276    } 
277
278    function GetAllWikiPagenames($dbi) {
279       $namelist = array();
280       $d = opendir($dbi);
281       while($entry = readdir($d)) {
282          if ($entry != '.' && $entry != '..')
283             $namelist[] = $entry;
284       }
285
286       return $namelist;
287    }
288 ?>