1 <!-- $Id: wiki_stdlib.php3,v 1.16 2000-06-26 20:05:22 ahollosi Exp $ -->
4 Standard functions for Wiki functionality
5 GeneratePage($template, $content, $name, $hash)
6 LinkExistingWikiWord($wikiword)
7 LinkUnknownWikiWord($wikiword)
11 CookSpaces($pagearray)
13 SetHTMLOutputMode($newmode, $depth)
14 UpdateRecentChanges($dbi, $pagename, $isnewpage)
15 SaveCopyToArchive($pagename, $pagehash)
16 ParseAndLink($bracketlink)
20 function GeneratePage($template, $content, $name, $hash)
22 global $ScriptUrl, $AllowedProtocols, $templates;
23 global $datetimeformat;
28 $page = join('', file($templates[$template]));
29 $page = str_replace('###', "#$FieldSeparator#", $page);
31 // valid for all pagetypes
32 $page = str_replace("#$FieldSeparator#SCRIPTURL#$FieldSeparator#",
34 $page = str_replace("#$FieldSeparator#PAGE#$FieldSeparator#",
35 htmlspecialchars($name), $page);
36 $page = str_replace("#$FieldSeparator#ALLOWEDPROTOCOLS#$FieldSeparator#",
37 $AllowedProtocols, $page);
39 // invalid for messages (search results, error messages)
40 if ($template != 'MESSAGE') {
41 $page = str_replace("#$FieldSeparator#PAGEURL#$FieldSeparator#",
42 rawurlencode($name), $page);
43 $page = str_replace("#$FieldSeparator#LASTMODIFIED#$FieldSeparator#",
44 date($datetimeformat, $hash['lastmodified']), $page);
45 $page = str_replace("#$FieldSeparator#LASTAUTHOR#$FieldSeparator#",
46 $hash['author'], $page);
47 $page = str_replace("#$FieldSeparator#VERSION#$FieldSeparator#",
48 $hash['version'], $page);
51 // valid only for EditLinks
52 if ($template == 'EDITLINKS') {
53 for ($i = 1; $i <= NUM_LINKS; $i++)
54 $page = str_replace("#$FieldSeparator#R$i#$FieldSeparator#",
55 $hash['refs'][$i], $page);
59 $page = str_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#",
62 $page = ereg_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#[^\n]*",
66 $page = str_replace("#$FieldSeparator#CONTENT#$FieldSeparator#",
72 function LinkExistingWikiWord($wikiword) {
74 $enc_word = rawurlencode($wikiword);
75 $wikiword = htmlspecialchars($wikiword);
76 return "<a href=\"$ScriptUrl?$enc_word\">$wikiword</a>";
79 function LinkUnknownWikiWord($wikiword) {
81 $enc_word = rawurlencode($wikiword);
82 $wikiword = htmlspecialchars($wikiword);
83 return "<u>$wikiword</u><a href=\"$ScriptUrl?edit=$enc_word\">?</a>";
86 function LinkURL($url) {
88 if(ereg("[<>\"]", $url)) {
89 return "<b><u>BAD URL -- remove all of <, >, "</u></b>";
91 $enc_url = htmlspecialchars($url);
92 return "<a href=\"$url\">$enc_url</a>";
96 function RenderQuickSearch() {
97 global $value, $ScriptUrl;
98 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='search' value='$value'>\n</form>\n";
102 function RenderFullSearch() {
103 global $value, $ScriptUrl;
104 $formtext = "<form action='$ScriptUrl'>\n<input type='text' size='40' name='full' value='$value'>\n</form>\n";
108 // converts spaces to tabs
109 function CookSpaces($pagearray) {
110 return preg_replace("/ {3,8}/", "\t", $pagearray);
118 function push($item) {
119 $this->items[$this->size] = $item;
125 if ($this->size == 0) {
126 return false; // stack is empty
129 return $this->items[$this->size];
137 return $this->items[$this->size - 1];
141 // end class definition
144 // I couldn't move this to wiki_config.php3 because it
145 // wasn't declared yet.
149 Wiki HTML output can, at any given time, be in only one mode.
150 It will be something like Unordered List, Preformatted Text,
151 plain text etc. When we change modes we have to issue close tags
152 for one mode and start tags for another.
155 function SetHTMLOutputMode($tag, $tagdepth, $tabcount) {
159 if ($tagdepth == SINGLE_DEPTH) {
160 if ($tabcount < $stack->cnt()) {
161 // there are fewer tabs than stack,
162 // reduce stack to that tab count
163 while ($stack->cnt() > $tabcount) {
164 $closetag = $stack->pop();
165 if ($closetag == false) {
166 //echo "bounds error in tag stack";
169 $retvar .= "</$closetag>\n";
172 // if list type isn't the same,
173 // back up one more and push new tag
174 if ($tag != $stack->top()) {
175 $closetag = $stack->pop();
176 $retvar .= "</$closetag><$tag>\n";
180 } elseif ($tabcount > $stack->cnt()) {
181 // we add the diff to the stack
182 // stack might be zero
183 while ($stack->cnt() < $tabcount) {
185 $retvar .= "<$tag>\n";
187 if ($stack->cnt() > 10) {
188 // arbitrarily limit tag nesting
189 echo "Stack bounds exceeded in SetHTMLOutputMode\n";
195 if ($tag == $stack->top()) {
198 $closetag = $stack->pop();
199 #echo "</$closetag>\n";
201 $retvar .= "</$closetag>\n";
202 $retvar .= "<$tag>\n";
207 } elseif ($tagdepth == ZERO_DEPTH) {
208 // empty the stack for $depth == 0;
209 // what if the stack is empty?
210 if ($tag == $stack->top()) {
213 while ($stack->cnt() > 0) {
214 $closetag = $stack->pop();
215 #echo "</$closetag>\n";
216 $retvar .= "</$closetag>\n";
221 $retvar .= "<$tag>\n";
227 echo "Passed bad tag depth value in SetHTMLOutputMode\n";
234 // end SetHTMLOutputMode
238 // The Recent Changes file is solely handled here
239 function UpdateRecentChanges($dbi, $pagename, $isnewpage) {
241 global $remoteuser; // this is set in the config
244 $recentchanges = RetrievePage($dbi, "RecentChanges");
246 // this shouldn't be necessary, since PhpWiki loads
247 // default pages if this is a new baby Wiki
248 if ($recentchanges == -1) {
249 $recentchanges = array();
253 $today = date($dateformat, $now);
255 if (date($dateformat, $recentchanges["lastmodified"]) != $today) {
257 $recentchanges["lastmodified"] = $now;
262 $numlines = sizeof($recentchanges["content"]);
266 // scroll through the page to the first date and break
267 // dates are marked with "____" at the beginning of the line
268 for ($i = 0; $i < ($numlines + 1); $i++) {
269 if (preg_match("/^____/",
270 $recentchanges["content"][$i])) {
273 $newpage[$k++] = $recentchanges["content"][$i];
277 // if it's a new date, insert it, else add the updated page's
281 $newpage[$k++] = "____$today\r";
283 $newpage[$k++] = $recentchanges["content"][$i++];
286 $newpage[$k++] = "\t* [$pagename] (new) ..... $remoteuser\r";
288 $newpage[$k++] = "\t* [$pagename] ..... $remoteuser\r";
291 // copy the rest of the page into the new array
292 $pagename = preg_quote($pagename);
293 for (; $i < ($numlines + 1); $i++) {
294 // skip previous entry for $pagename
295 if (preg_match("/\[$pagename\]/", $recentchanges["content"][$i])) {
298 $newpage[$k++] = $recentchanges["content"][$i];
302 $recentchanges["content"] = $newpage;
304 InsertPage($dbi, "RecentChanges", $recentchanges);
308 // for archiving pages to a seperate dbm
309 function SaveCopyToArchive($pagename, $pagehash) {
310 global $ArchiveDataBase;
312 $adbi = OpenDataBase($ArchiveDataBase);
313 $newpagename = $pagename;
314 InsertPage($adbi, $newpagename, $pagehash);
318 function ParseAndLink($bracketlink) {
319 global $dbi, $AllowedProtocols;
321 // $bracketlink will start and end with brackets; in between
322 // will be either a page name, a URL or both seperated by a pipe.
324 // strip brackets and leading space
325 preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match);
326 $linkdata = $match[2];
328 // send back links that are only numbers (they are references)
329 if (preg_match("/^\d+$/", $linkdata)) {
333 // send back escaped ([[) bracket sets
334 if (preg_match("/^\[/", $linkdata)) {
335 return htmlspecialchars(substr($bracketlink, 1));
338 // match the contents
339 preg_match("/([^|]+)(\|)?([^|]+)?/", $linkdata, $matches);
341 if (isset($matches[3])) {
342 $URL = trim($matches[3]);
343 $linkname = htmlspecialchars(trim($matches[1]));
344 // assert proper URL's
345 if (preg_match("#^($AllowedProtocols):#", $URL)) {
346 return "<a href=\"$URL\">$linkname</a>";
348 return "<b><u>BAD URL -- links have to start with one of " . "$AllowedProtocols followed by ':'</u></b>";
352 if (isset($matches[1])) {
353 $linkname = trim($matches[1]);
354 if (IsWikiPage($dbi, $linkname)) {
355 return LinkExistingWikiWord($linkname);
356 } elseif (preg_match("#^($AllowedProtocols):#", $linkname)) {
357 return LinkURL($linkname);
358 } elseif ($linkname == 'Search') {
359 return RenderQuickSearch();
360 } elseif ($linkname == 'Fullsearch') {
361 return RenderFullSearch();
363 return LinkUnknownWikiWord($linkname);