1 <?php rcs_id('$Id: db_filesystem.php,v 1.4.2.2 2001-08-18 02:05:28 dairiki Exp $');
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)
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 @.
30 function OpenDataBase($dbname) {
40 function CloseDataBase($dbi) {
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
51 ExitWiki("Timeout while obtaining lock. Please try again");
53 if ($data = file($filename)) {
54 // unserialize $data into a hash
55 $pagehash = unserialize(join("\n", $data));
67 // Either insert or replace a key/value (a page)
68 function Filesystem_WritePage($dbi, $pagename, $pagehash) {
69 global $WikiPageStore;
70 $pagedata = serialize($pagehash);
72 if (!file_exists($dbi)) {
73 $d = split("/", $dbi);
75 while(list($key, $val) = each($d)) {
81 $filename = $dbi . "/" . $pagename;
82 if($fd = fopen($filename, 'a')) {
83 $locked = flock($fd,2); #Exclusive blocking lock
85 ExitWiki("Timeout while obtaining lock. Please try again");
88 #Second (actually used) filehandle
89 $fdsafe = fopen($filename, 'w');
90 fwrite($fdsafe, $pagedata);
94 ExitWiki("Error while writing page '$pagename'");
98 function InsertPage($dbi, $pagename, $pagehash) {
99 return Filesystem_WritePage($dbi['wiki'], $pagename, $pagehash);
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);
109 function IsWikiPage($dbi, $pagename) {
110 return file_exists($dbi['wiki'] . "/" . $pagename);
114 function IsInArchive($dbi, $pagename) {
115 return file_exists($dbi['archive'] . "/" . $pagename);
119 // setup for title-search
120 function InitTitleSearch($dbi, $search) {
121 $pos['search'] = $search;
122 $pos['data'] = GetAllWikiPageNames($dbi['wiki']);
127 // iterating through database
128 function TitleSearchNextMatch($dbi, &$pos) {
129 while (list($key, $page) = each($pos['data'])) {
130 if (eregi($pos['search'], $page)) {
137 // setup for full-text search
138 function InitFullSearch($dbi, $search) {
139 return InitTitleSearch($dbi, $search);
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))) {
154 ////////////////////////
155 // new database features
157 // Compute PCRE suitable for searching for links to the given page.
158 function MakeBackLinkSearchRegexp($pagename) {
159 global $WikiNameRegexp;
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])=";
170 // Note from author: Sorry. :-/
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).
184 // setup for back-link search
185 function InitBackLinkSearch($dbi, $pagename) {
186 return InitTitleSearch($dbi, MakeBackLinkSearchRegexp($pagename));
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);
195 while (list($i, $line) = each($pagedata['content'])) {
196 if (preg_match($pos['search'], $line))
203 function IncreaseHitCount($dbi, $pagename) {
206 // kluge: we ignore the $dbi for hit counting
209 $hcdb = OpenDataBase($WikiDB['hitcount']);
211 if (dbmexists($hcdb['active'], $pagename)) {
212 // increase the hit count
213 $count = dbmfetch($hcdb['active'], $pagename);
215 dbmreplace($hcdb['active'], $pagename, $count);
217 // add it, set the hit count to one
219 dbminsert($hcdb['active'], $pagename, $count);
222 CloseDataBase($hcdb);
225 function GetHitCount($dbi, $pagename) {
227 // kluge: we ignore the $dbi for hit counting
230 $hcdb = OpenDataBase($WikiDB['hitcount']);
231 if (dbmexists($hcdb['active'], $pagename)) {
232 // increase the hit count
233 $count = dbmfetch($hcdb['active'], $pagename);
239 CloseDataBase($hcdb);
243 function InitMostPopular($dbi, $limit) {
245 $pagename = dbmfirstkey($dbi['hitcount']);
246 $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
247 while ($pagename = dbmnextkey($dbi['hitcount'], $pagename)) {
248 $res[$pagename] = dbmfetch($dbi['hitcount'], $pagename);
249 echo "got $pagename with value " . $res[$pagename] . "<br>\n";
257 function MostPopularNextMatch($dbi, $res) {
259 // the return result is a two element array with 'hits'
260 // and 'pagename' as the keys
262 if (list($index1, $index2, $pagename, $hits) = each($res)) {
263 echo "most popular next match called<br>\n";
264 echo "got $pagename, $hits back<br>\n";
267 "pagename" => $pagename
275 function GetAllWikiPagenames($dbi) {
278 while($entry = readdir($d)) {
279 if ($entry != '.' && $entry != '..')
280 $namelist[] = $entry;