1 <!-- $Id: wiki_stdlib.php3,v 1.19 2000-06-29 03:25:17 wainstead Exp $ -->
4 Standard functions for Wiki functionality
5 GeneratePage($template, $content, $name, $hash)
6 LinkExistingWikiWord($wikiword)
7 LinkUnknownWikiWord($wikiword)
12 CookSpaces($pagearray)
14 SetHTMLOutputMode($newmode, $depth)
15 UpdateRecentChanges($dbi, $pagename, $isnewpage)
16 SaveCopyToArchive($pagename, $pagehash)
17 ParseAndLink($bracketlink)
21 function GeneratePage($template, $content, $name, $hash)
23 global $ScriptUrl, $AllowedProtocols, $templates;
24 global $datetimeformat, $dbi;
29 $page = join('', file($templates[$template]));
30 $page = str_replace('###', "#$FieldSeparator#", $page);
32 // valid for all pagetypes
33 $page = str_replace("#$FieldSeparator#SCRIPTURL#$FieldSeparator#",
35 $page = str_replace("#$FieldSeparator#PAGE#$FieldSeparator#",
36 htmlspecialchars($name), $page);
37 $page = str_replace("#$FieldSeparator#ALLOWEDPROTOCOLS#$FieldSeparator#",
38 $AllowedProtocols, $page);
40 // invalid for messages (search results, error messages)
41 if ($template != 'MESSAGE') {
42 $page = str_replace("#$FieldSeparator#PAGEURL#$FieldSeparator#",
43 rawurlencode($name), $page);
44 $page = str_replace("#$FieldSeparator#LASTMODIFIED#$FieldSeparator#",
45 date($datetimeformat, $hash['lastmodified']), $page);
46 $page = str_replace("#$FieldSeparator#LASTAUTHOR#$FieldSeparator#",
47 $hash['author'], $page);
48 $page = str_replace("#$FieldSeparator#VERSION#$FieldSeparator#",
49 $hash['version'], $page);
50 if (strstr($page, "#$FieldSeparator#HITS#$FieldSeparator#")) {
51 $page = str_replace("#$FieldSeparator#HITS#$FieldSeparator#",
52 GetHitCount($dbi, $name), $page);
56 // valid only for EditLinks
57 if ($template == 'EDITLINKS') {
58 for ($i = 1; $i <= NUM_LINKS; $i++)
59 $page = str_replace("#$FieldSeparator#R$i#$FieldSeparator#",
60 $hash['refs'][$i], $page);
64 $page = str_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#",
67 $page = ereg_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#[^\n]*",
71 $page = str_replace("#$FieldSeparator#CONTENT#$FieldSeparator#",
77 function LinkExistingWikiWord($wikiword) {
79 $enc_word = rawurlencode($wikiword);
80 $wikiword = htmlspecialchars($wikiword);
81 return "<a href=\"$ScriptUrl?$enc_word\">$wikiword</a>";
84 function LinkUnknownWikiWord($wikiword) {
86 $enc_word = rawurlencode($wikiword);
87 $wikiword = htmlspecialchars($wikiword);
88 return "<u>$wikiword</u><a href=\"$ScriptUrl?edit=$enc_word\">?</a>";
91 function LinkURL($url) {
93 if(ereg("[<>\"]", $url)) {
94 return "<b><u>BAD URL -- remove all of <, >, "</u></b>";
96 $enc_url = htmlspecialchars($url);
97 return "<a href=\"$url\">$enc_url</a>";
101 function RenderQuickSearch() {
102 global $value, $ScriptUrl;
103 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='search' value='$value'>\n</form>\n";
107 function RenderFullSearch() {
108 global $value, $ScriptUrl;
109 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='full' value='$value'>\n</form>\n";
113 function RenderMostPopular() {
114 global $ScriptUrl, $dbi;
116 $query = InitMostPopular($dbi, 20);
118 while ($qhash = MostPopularNextMatch($dbi, $query)) {
119 $result .= "<DD>$qhash[hits] ... " . LinkExistingWikiWord($qhash['pagename']) . "\n";
121 $result .= "</DL>\n";
126 // converts spaces to tabs
127 function CookSpaces($pagearray) {
128 return preg_replace("/ {3,8}/", "\t", $pagearray);
136 function push($item) {
137 $this->items[$this->size] = $item;
143 if ($this->size == 0) {
144 return false; // stack is empty
147 return $this->items[$this->size];
155 return $this->items[$this->size - 1];
159 // end class definition
162 // I couldn't move this to wiki_config.php3 because it
163 // wasn't declared yet.
167 Wiki HTML output can, at any given time, be in only one mode.
168 It will be something like Unordered List, Preformatted Text,
169 plain text etc. When we change modes we have to issue close tags
170 for one mode and start tags for another.
173 function SetHTMLOutputMode($tag, $tagdepth, $tabcount) {
177 if ($tagdepth == SINGLE_DEPTH) {
178 if ($tabcount < $stack->cnt()) {
179 // there are fewer tabs than stack,
180 // reduce stack to that tab count
181 while ($stack->cnt() > $tabcount) {
182 $closetag = $stack->pop();
183 if ($closetag == false) {
184 //echo "bounds error in tag stack";
187 $retvar .= "</$closetag>\n";
190 // if list type isn't the same,
191 // back up one more and push new tag
192 if ($tag != $stack->top()) {
193 $closetag = $stack->pop();
194 $retvar .= "</$closetag><$tag>\n";
198 } elseif ($tabcount > $stack->cnt()) {
199 // we add the diff to the stack
200 // stack might be zero
201 while ($stack->cnt() < $tabcount) {
203 $retvar .= "<$tag>\n";
205 if ($stack->cnt() > 10) {
206 // arbitrarily limit tag nesting
207 echo "Stack bounds exceeded in SetHTMLOutputMode\n";
213 if ($tag == $stack->top()) {
216 $closetag = $stack->pop();
217 #echo "</$closetag>\n";
219 $retvar .= "</$closetag>\n";
220 $retvar .= "<$tag>\n";
225 } elseif ($tagdepth == ZERO_DEPTH) {
226 // empty the stack for $depth == 0;
227 // what if the stack is empty?
228 if ($tag == $stack->top()) {
231 while ($stack->cnt() > 0) {
232 $closetag = $stack->pop();
233 #echo "</$closetag>\n";
234 $retvar .= "</$closetag>\n";
239 $retvar .= "<$tag>\n";
245 echo "Passed bad tag depth value in SetHTMLOutputMode\n";
252 // end SetHTMLOutputMode
256 // The Recent Changes file is solely handled here
257 function UpdateRecentChanges($dbi, $pagename, $isnewpage) {
259 global $remoteuser; // this is set in the config
262 $recentchanges = RetrievePage($dbi, "RecentChanges");
264 // this shouldn't be necessary, since PhpWiki loads
265 // default pages if this is a new baby Wiki
266 if ($recentchanges == -1) {
267 $recentchanges = array();
271 $today = date($dateformat, $now);
273 if (date($dateformat, $recentchanges["lastmodified"]) != $today) {
275 $recentchanges["lastmodified"] = $now;
280 $numlines = sizeof($recentchanges["content"]);
284 // scroll through the page to the first date and break
285 // dates are marked with "____" at the beginning of the line
286 for ($i = 0; $i < ($numlines + 1); $i++) {
287 if (preg_match("/^____/",
288 $recentchanges["content"][$i])) {
291 $newpage[$k++] = $recentchanges["content"][$i];
295 // if it's a new date, insert it, else add the updated page's
299 $newpage[$k++] = "____$today\r";
301 $newpage[$k++] = $recentchanges["content"][$i++];
304 $newpage[$k++] = "\t* [$pagename] (new) ..... $remoteuser\r";
306 $newpage[$k++] = "\t* [$pagename] ..... $remoteuser\r";
309 // copy the rest of the page into the new array
310 $pagename = preg_quote($pagename);
311 for (; $i < ($numlines + 1); $i++) {
312 // skip previous entry for $pagename
313 if (preg_match("/\[$pagename\]/", $recentchanges["content"][$i])) {
316 $newpage[$k++] = $recentchanges["content"][$i];
320 $recentchanges["content"] = $newpage;
322 InsertPage($dbi, "RecentChanges", $recentchanges);
326 // for archiving pages to a seperate dbm
327 function SaveCopyToArchive($pagename, $pagehash) {
328 global $ArchiveDataBase;
330 $adbi = OpenDataBase($ArchiveDataBase);
331 $newpagename = $pagename;
332 InsertPage($adbi, $newpagename, $pagehash);
336 function ParseAndLink($bracketlink) {
337 global $dbi, $AllowedProtocols;
339 // $bracketlink will start and end with brackets; in between
340 // will be either a page name, a URL or both seperated by a pipe.
342 // strip brackets and leading space
343 preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match);
344 $linkdata = $match[2];
346 // send back links that are only numbers (they are references)
347 if (preg_match("/^\d+$/", $linkdata)) {
351 // send back escaped ([[) bracket sets
352 if (preg_match("/^\[/", $linkdata)) {
353 return htmlspecialchars(substr($bracketlink, 1));
356 // match the contents
357 preg_match("/([^|]+)(\|)?([^|]+)?/", $linkdata, $matches);
359 if (isset($matches[3])) {
360 $URL = trim($matches[3]);
361 $linkname = htmlspecialchars(trim($matches[1]));
362 // assert proper URL's
363 if (preg_match("#^($AllowedProtocols):#", $URL)) {
364 return "<a href=\"$URL\">$linkname</a>";
366 return "<b><u>BAD URL -- links have to start with one of " . "$AllowedProtocols followed by ':'</u></b>";
370 if (isset($matches[1])) {
371 $linkname = trim($matches[1]);
372 if (IsWikiPage($dbi, $linkname)) {
373 return LinkExistingWikiWord($linkname);
374 } elseif (preg_match("#^($AllowedProtocols):#", $linkname)) {
375 return LinkURL($linkname);
377 return LinkUnknownWikiWord($linkname);