1 <!-- $Id: wiki_stdlib.php3,v 1.22 2000-07-05 14:52:04 ahollosi 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, $logo;
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);
39 $page = str_replace("#$FieldSeparator#LOGO#$FieldSeparator#",
42 // invalid for messages (search results, error messages)
43 if ($template != 'MESSAGE') {
44 $page = str_replace("#$FieldSeparator#PAGEURL#$FieldSeparator#",
45 rawurlencode($name), $page);
46 $page = str_replace("#$FieldSeparator#LASTMODIFIED#$FieldSeparator#",
47 date($datetimeformat, $hash['lastmodified']), $page);
48 $page = str_replace("#$FieldSeparator#LASTAUTHOR#$FieldSeparator#",
49 $hash['author'], $page);
50 $page = str_replace("#$FieldSeparator#VERSION#$FieldSeparator#",
51 $hash['version'], $page);
52 if (strstr($page, "#$FieldSeparator#HITS#$FieldSeparator#")) {
53 $page = str_replace("#$FieldSeparator#HITS#$FieldSeparator#",
54 GetHitCount($dbi, $name), $page);
58 // valid only for EditLinks
59 if ($template == 'EDITLINKS') {
60 for ($i = 1; $i <= NUM_LINKS; $i++)
61 $page = str_replace("#$FieldSeparator#R$i#$FieldSeparator#",
62 $hash['refs'][$i], $page);
66 $page = str_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#",
69 $page = ereg_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#[^\n]*",
73 $page = str_replace("#$FieldSeparator#CONTENT#$FieldSeparator#",
79 function LinkExistingWikiWord($wikiword) {
81 $enc_word = rawurlencode($wikiword);
82 $wikiword = htmlspecialchars($wikiword);
83 return "<a href=\"$ScriptUrl?$enc_word\">$wikiword</a>";
86 function LinkUnknownWikiWord($wikiword) {
88 $enc_word = rawurlencode($wikiword);
89 $wikiword = htmlspecialchars($wikiword);
90 return "<u>$wikiword</u><a href=\"$ScriptUrl?edit=$enc_word\">?</a>";
93 function LinkURL($url) {
95 if(ereg("[<>\"]", $url)) {
96 return "<b><u>BAD URL -- remove all of <, >, "</u></b>";
98 $enc_url = htmlspecialchars($url);
99 return "<a href=\"$url\">$enc_url</a>";
103 function RenderQuickSearch() {
104 global $value, $ScriptUrl;
105 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='search' value='$value'>\n</form>\n";
109 function RenderFullSearch() {
110 global $value, $ScriptUrl;
111 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='full' value='$value'>\n</form>\n";
115 function RenderMostPopular() {
116 global $ScriptUrl, $dbi;
118 $query = InitMostPopular($dbi, 20);
120 while ($qhash = MostPopularNextMatch($dbi, $query)) {
121 $result .= "<DD>$qhash[hits] ... " . LinkExistingWikiWord($qhash['pagename']) . "\n";
123 $result .= "</DL>\n";
128 // converts spaces to tabs
129 function CookSpaces($pagearray) {
130 return preg_replace("/ {3,8}/", "\t", $pagearray);
138 function push($item) {
139 $this->items[$this->size] = $item;
145 if ($this->size == 0) {
146 return false; // stack is empty
149 return $this->items[$this->size];
157 return $this->items[$this->size - 1];
161 // end class definition
164 // I couldn't move this to wiki_config.php3 because it
165 // wasn't declared yet.
169 Wiki HTML output can, at any given time, be in only one mode.
170 It will be something like Unordered List, Preformatted Text,
171 plain text etc. When we change modes we have to issue close tags
172 for one mode and start tags for another.
175 function SetHTMLOutputMode($tag, $tagdepth, $tabcount) {
179 if ($tagdepth == SINGLE_DEPTH) {
180 if ($tabcount < $stack->cnt()) {
181 // there are fewer tabs than stack,
182 // reduce stack to that tab count
183 while ($stack->cnt() > $tabcount) {
184 $closetag = $stack->pop();
185 if ($closetag == false) {
186 //echo "bounds error in tag stack";
189 $retvar .= "</$closetag>\n";
192 // if list type isn't the same,
193 // back up one more and push new tag
194 if ($tag != $stack->top()) {
195 $closetag = $stack->pop();
196 $retvar .= "</$closetag><$tag>\n";
200 } elseif ($tabcount > $stack->cnt()) {
201 // we add the diff to the stack
202 // stack might be zero
203 while ($stack->cnt() < $tabcount) {
205 $retvar .= "<$tag>\n";
207 if ($stack->cnt() > 10) {
208 // arbitrarily limit tag nesting
209 echo "Stack bounds exceeded in SetHTMLOutputMode\n";
215 if ($tag == $stack->top()) {
218 $closetag = $stack->pop();
219 #echo "</$closetag>\n";
221 $retvar .= "</$closetag>\n";
222 $retvar .= "<$tag>\n";
227 } elseif ($tagdepth == ZERO_DEPTH) {
228 // empty the stack for $depth == 0;
229 // what if the stack is empty?
230 if ($tag == $stack->top()) {
233 while ($stack->cnt() > 0) {
234 $closetag = $stack->pop();
235 #echo "</$closetag>\n";
236 $retvar .= "</$closetag>\n";
241 $retvar .= "<$tag>\n";
247 echo "Passed bad tag depth value in SetHTMLOutputMode\n";
254 // end SetHTMLOutputMode
258 // The Recent Changes file is solely handled here
259 function UpdateRecentChanges($dbi, $pagename, $isnewpage) {
261 global $remoteuser; // this is set in the config
264 $recentchanges = RetrievePage($dbi, "RecentChanges");
266 // this shouldn't be necessary, since PhpWiki loads
267 // default pages if this is a new baby Wiki
268 if ($recentchanges == -1) {
269 $recentchanges = array();
273 $today = date($dateformat, $now);
275 if (date($dateformat, $recentchanges["lastmodified"]) != $today) {
277 $recentchanges["lastmodified"] = $now;
282 $numlines = sizeof($recentchanges["content"]);
286 // scroll through the page to the first date and break
287 // dates are marked with "____" at the beginning of the line
288 for ($i = 0; $i < ($numlines + 1); $i++) {
289 if (preg_match("/^____/",
290 $recentchanges["content"][$i])) {
293 $newpage[$k++] = $recentchanges["content"][$i];
297 // if it's a new date, insert it, else add the updated page's
301 $newpage[$k++] = "____$today\r";
302 $newpage[$k++] = "\r";
304 $newpage[$k++] = $recentchanges["content"][$i++];
307 $newpage[$k++] = "\t* [$pagename] (new) ..... $remoteuser\r";
309 $newpage[$k++] = "\t* [$pagename] ..... $remoteuser\r";
312 // copy the rest of the page into the new array
313 $pagename = preg_quote($pagename);
314 for (; $i < ($numlines + 1); $i++) {
315 // skip previous entry for $pagename
316 if (preg_match("|\[$pagename\]|", $recentchanges["content"][$i])) {
319 $newpage[$k++] = $recentchanges["content"][$i];
323 $recentchanges["content"] = $newpage;
325 InsertPage($dbi, "RecentChanges", $recentchanges);
329 // for archiving pages to a seperate dbm
330 function SaveCopyToArchive($pagename, $pagehash) {
331 global $ArchiveDataBase;
333 $adbi = OpenDataBase($ArchiveDataBase);
334 $newpagename = $pagename;
335 InsertPage($adbi, $newpagename, $pagehash);
339 function ParseAndLink($bracketlink) {
340 global $dbi, $AllowedProtocols;
342 // $bracketlink will start and end with brackets; in between
343 // will be either a page name, a URL or both seperated by a pipe.
345 // strip brackets and leading space
346 preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match);
347 $linkdata = $match[2];
349 // send back links that are only numbers (they are references)
350 if (preg_match("/^\d+$/", $linkdata)) {
354 // send back escaped ([[) bracket sets
355 if (preg_match("/^\[/", $linkdata)) {
356 return htmlspecialchars(substr($bracketlink, 1));
359 // match the contents
360 preg_match("/([^|]+)(\|)?([^|]+)?/", $linkdata, $matches);
362 if (isset($matches[3])) {
363 $URL = trim($matches[3]);
364 $linkname = htmlspecialchars(trim($matches[1]));
365 // assert proper URL's
366 if (preg_match("#^($AllowedProtocols):#", $URL)) {
367 return "<a href=\"$URL\">$linkname</a>";
369 return "<b><u>BAD URL -- links have to start with one of " . "$AllowedProtocols followed by ':'</u></b>";
373 if (isset($matches[1])) {
374 $linkname = trim($matches[1]);
375 if (IsWikiPage($dbi, $linkname)) {
376 return LinkExistingWikiWord($linkname);
377 } elseif (preg_match("#^($AllowedProtocols):#", $linkname)) {
378 return LinkURL($linkname);
380 return LinkUnknownWikiWord($linkname);