]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/stdlib.php
Added "Minor edit, do not archive" checkbox on the edit form.
[SourceForge/phpwiki.git] / lib / stdlib.php
1 <?php rcs_id('$Id: stdlib.php,v 1.24 2001-02-07 22:14:35 dairiki Exp $');
2
3    /*
4       Standard functions for Wiki functionality
5          ExitWiki($errormsg)
6          LinkExistingWikiWord($wikiword) 
7          LinkUnknownWikiWord($wikiword) 
8          LinkURL($url, $linktext)
9          LinkImage($url, $alt)
10          RenderQuickSearch($value)
11          RenderFullSearch($value)
12          RenderMostPopular()
13          CookSpaces($pagearray) 
14          class Stack (push(), pop(), cnt(), top())
15          SetHTMLOutputMode($newmode, $depth)
16          UpdateRecentChanges($dbi, $pagename, $isnewpage) 
17          ParseAndLink($bracketlink)
18          ExtractWikiPageLinks($content)
19          LinkRelatedPages($dbi, $pagename)
20          GeneratePage($template, $content, $name, $hash)
21    */
22
23
24    function ExitWiki($errormsg)
25    {
26       static $exitwiki = 0;
27       global $dbi;
28
29       if($exitwiki)             // just in case CloseDataBase calls us
30          exit();
31       $exitwiki = 1;
32
33       CloseDataBase($dbi);
34
35       if($errormsg <> '') {
36          print "<P><hr noshade><h2>" . gettext("WikiFatalError") . "</h2>\n";
37          print $errormsg;
38          print "\n</BODY></HTML>";
39       }
40       exit;
41    }
42
43
44    function LinkExistingWikiWord($wikiword, $linktext='') {
45       global $ScriptUrl;
46       $enc_word = rawurlencode($wikiword);
47       if(empty($linktext))
48          $linktext = htmlspecialchars($wikiword);
49       return "<a href=\"$ScriptUrl?$enc_word\">$linktext</a>";
50    }
51
52    function LinkUnknownWikiWord($wikiword, $linktext='') {
53       global $ScriptUrl;
54       $enc_word = rawurlencode($wikiword);
55       if(empty($linktext))
56          $linktext = htmlspecialchars($wikiword);
57       return "<u>$linktext</u><a href=\"$ScriptUrl?edit=$enc_word\">?</a>";
58    }
59
60    function LinkURL($url, $linktext='') {
61       global $ScriptUrl;
62       if(ereg("[<>\"]", $url)) {
63          return "<b><u>BAD URL -- remove all of &lt;, &gt;, &quot;</u></b>";
64       }
65       if(empty($linktext))
66          $linktext = htmlspecialchars($url);
67       return "<a href=\"$url\">$linktext</a>";
68    }
69
70    function LinkImage($url, $alt='[External Image]') {
71       global $ScriptUrl;
72       if(ereg('[<>"]', $url)) {
73          return "<b><u>BAD URL -- remove all of &lt;, &gt;, &quot;</u></b>";
74       }
75       return "<img src=\"$url\" ALT=\"$alt\">";
76    }
77
78    function ParseAdminTokens($line) {
79       global $ScriptUrl;
80       
81       while (preg_match("/%%ADMIN-INPUT-(.*?)-(\w+)%%/", $line, $matches)) {
82          $head = str_replace('_', ' ', $matches[2]);
83          $form = "<FORM ACTION=\"$ScriptUrl\" METHOD=POST>"
84                 ."$head: <INPUT NAME=$matches[1] SIZE=20> "
85                 ."<INPUT TYPE=SUBMIT VALUE=\"" . gettext("Go") . "\">"
86                 ."</FORM>";
87          $line = str_replace($matches[0], $form, $line);
88       }
89       return $line;
90    }
91
92    // converts spaces to tabs
93    function CookSpaces($pagearray) {
94       return preg_replace("/ {3,8}/", "\t", $pagearray);
95    }
96
97
98    class Stack {
99       var $items = array();
100       var $size = 0;
101
102       function push($item) {
103          $this->items[$this->size] = $item;
104          $this->size++;
105          return true;
106       }  
107    
108       function pop() {
109          if ($this->size == 0) {
110             return false; // stack is empty
111          }  
112          $this->size--;
113          return $this->items[$this->size];
114       }  
115    
116       function cnt() {
117          return $this->size;
118       }  
119
120       function top() {
121          if($this->size)
122             return $this->items[$this->size - 1];
123          else
124             return '';
125       }  
126
127    }  
128    // end class definition
129
130
131    function ParseAndLink($bracketlink) {
132       global $dbi, $ScriptUrl, $AllowedProtocols, $InlineImages;
133
134       // $bracketlink will start and end with brackets; in between
135       // will be either a page name, a URL or both separated by a pipe.
136
137       // strip brackets and leading space
138       preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match);
139       // match the contents 
140       preg_match("/([^|]+)(\|)?([^|]+)?/", $match[2], $matches);
141
142       if (isset($matches[3])) {
143          // named link of the form  "[some link name | http://blippy.com/]"
144          $URL = trim($matches[3]);
145          $linkname = htmlspecialchars(trim($matches[1]));
146          $linktype = 'named';
147       } else {
148          // unnamed link of the form "[http://blippy.com/] or [wiki page]"
149          $URL = trim($matches[1]);
150          $linkname = '';
151          $linktype = 'simple';
152       }
153
154       if (IsWikiPage($dbi, $URL)) {
155          $link['type'] = "wiki-$linktype";
156          $link['link'] = LinkExistingWikiWord($URL, $linkname);
157       } elseif (preg_match("#^($AllowedProtocols):#", $URL)) {
158         // if it's an image, embed it; otherwise, it's a regular link
159          if (preg_match("/($InlineImages)$/i", $URL)) {
160             $link['type'] = "image-$linktype";
161             $link['link'] = LinkImage($URL, $linkname);
162          } else {
163             $link['type'] = "url-$linktype";
164             $link['link'] = LinkURL($URL, $linkname);
165          }
166       } elseif (preg_match("#^phpwiki:(.*)#", $URL, $match)) {
167          $link['type'] = "url-wiki-$linktype";
168          if(empty($linkname))
169             $linkname = htmlspecialchars($URL);
170          $link['link'] = "<a href=\"$ScriptUrl$match[1]\">$linkname</a>";
171       } elseif (preg_match("#^\d+$#", $URL)) {
172          $link['type'] = "footnote-$linktype";
173          $link['link'] = $URL;
174       } else {
175          $link['type'] = "wiki-unknown-$linktype";
176          $link['link'] = LinkUnknownWikiWord($URL, $linkname);
177       }
178
179       return $link;
180    }
181
182
183    function ExtractWikiPageLinks($content)
184    {
185       global $WikiNameRegexp;
186
187       $wikilinks = array();
188       $numlines = count($content);
189       for($l = 0; $l < $numlines; $l++)
190       {
191          // remove escaped '['
192          $line = str_replace('[[', ' ', $content[$l]);
193
194          // bracket links (only type wiki-* is of interest)
195          $numBracketLinks = preg_match_all("/\[\s*([^\]|]+\|)?\s*(.+?)\s*\]/", $line, $brktlinks);
196          for ($i = 0; $i < $numBracketLinks; $i++) {
197             $link = ParseAndLink($brktlinks[0][$i]);
198             if (preg_match("#^wiki#", $link['type']))
199                $wikilinks[$brktlinks[2][$i]] = 1;
200
201             $brktlink = preg_quote($brktlinks[0][$i]);
202             $line = preg_replace("|$brktlink|", '', $line);
203          }
204
205          // BumpyText old-style wiki links
206          if (preg_match_all("/!?$WikiNameRegexp/", $line, $link)) {
207             for ($i = 0; isset($link[0][$i]); $i++) {
208                if($link[0][$i][0] <> '!')
209                   $wikilinks[$link[0][$i]] = 1;
210             }
211          }
212       }
213       return $wikilinks;
214    }      
215
216
217    function LinkRelatedPages($dbi, $pagename)
218    {
219       // currently not supported everywhere
220       if(!function_exists('GetWikiPageLinks'))
221          return '';
222
223       $links = GetWikiPageLinks($dbi, $pagename);
224
225       $txt = "<b>";
226       $txt .= sprintf (gettext ("%d best incoming links:"), NUM_RELATED_PAGES);
227       $txt .= "</b>\n";
228       for($i = 0; $i < NUM_RELATED_PAGES; $i++) {
229          if(isset($links['in'][$i])) {
230             list($name, $score) = $links['in'][$i];
231             $txt .= LinkExistingWikiWord($name) . " ($score), ";
232          }
233       }
234
235       $txt .= "\n<br><b>";
236       $txt .= sprintf (gettext ("%d best outgoing links:"), NUM_RELATED_PAGES);
237       $txt .= "</b>\n";
238       for($i = 0; $i < NUM_RELATED_PAGES; $i++) {
239          if(isset($links['out'][$i])) {
240             list($name, $score) = $links['out'][$i];
241             if(IsWikiPage($dbi, $name))
242                $txt .= LinkExistingWikiWord($name) . " ($score), ";
243          }
244       }
245
246       $txt .= "\n<br><b>";
247       $txt .= sprintf (gettext ("%d most popular nearby:"), NUM_RELATED_PAGES);
248       $txt .= "</b>\n";
249       for($i = 0; $i < NUM_RELATED_PAGES; $i++) {
250          if(isset($links['popular'][$i])) {
251             list($name, $score) = $links['popular'][$i];
252             $txt .= LinkExistingWikiWord($name) . " ($score), ";
253          }
254       }
255       
256       return $txt;
257    }
258
259    
260    # GeneratePage() -- takes $content and puts it in the template $template
261    # this function contains all the template logic
262    #
263    # $template ... name of the template (see config.php for list of names)
264    # $content ... html content to put into the page
265    # $name ... page title
266    # $hash ... if called while creating a wiki page, $hash points to
267    #           the $pagehash array of that wiki page.
268
269    function GeneratePage($template, $content, $name, $hash)
270    {
271       global $ScriptUrl, $AllowedProtocols, $templates;
272       global $datetimeformat, $dbi, $logo, $FieldSeparator;
273
274       if (!is_array($hash))
275          unset($hash);
276
277       function _dotoken ($id, $val, &$page) {
278          global $FieldSeparator;
279          $page = str_replace("$FieldSeparator#$id$FieldSeparator#",
280                                 $val, $page);
281       }
282
283       function _iftoken ($id, $condition, &$page) {
284          global $FieldSeparator;
285
286          // line based IF directive
287          $lineyes = "$FieldSeparator#IF $id$FieldSeparator#";
288          $lineno = "$FieldSeparator#IF !$id$FieldSeparator#";
289          // block based IF directive
290          $blockyes = "$FieldSeparator#IF:$id$FieldSeparator#";
291          $blockyesend = "$FieldSeparator#ENDIF:$id$FieldSeparator#";
292          $blockno = "$FieldSeparator#IF:!$id$FieldSeparator#";
293          $blocknoend = "$FieldSeparator#ENDIF:!$id$FieldSeparator#";
294
295          if ($condition) {
296             $page = str_replace($lineyes, '', $page);
297             $page = str_replace($blockyes, '', $page);
298             $page = str_replace($blockyesend, '', $page);
299             $page = preg_replace("/$blockno(.*?)$blocknoend/s", '', $page);
300             $page = ereg_replace("${lineno}[^\n]*\n", '', $page);
301          } else {
302             $page = str_replace($lineno, '', $page);
303             $page = str_replace($blockno, '', $page);
304             $page = str_replace($blocknoend, '', $page);
305             $page = preg_replace("/$blockyes(.*?)$blockyesend/s", '', $page);
306             $page = ereg_replace("${lineyes}[^\n]*\n", '', $page);
307          }
308       }
309
310       $page = join('', file($templates[$template]));
311       $page = str_replace('###', "$FieldSeparator#", $page);
312
313       // valid for all pagetypes
314       _iftoken('COPY', isset($hash['copy']), $page);
315       _iftoken('LOCK',  (isset($hash['flags']) &&
316                         ($hash['flags'] & FLAG_PAGE_LOCKED)), $page);
317       _iftoken('ADMIN', defined('WIKI_ADMIN'), $page);
318       _iftoken('MINOR_EDIT', isset($hash['minor_edit']), $page);        
319
320       _dotoken('SCRIPTURL', $ScriptUrl, $page);
321       _dotoken('PAGE', htmlspecialchars($name), $page);
322       _dotoken('ALLOWEDPROTOCOLS', $AllowedProtocols, $page);
323       _dotoken('LOGO', $logo, $page);
324       
325       // invalid for messages (search results, error messages)
326       if ($template != 'MESSAGE') {
327          _dotoken('PAGEURL', rawurlencode($name), $page);
328          _dotoken('LASTMODIFIED',
329                         date($datetimeformat, $hash['lastmodified']), $page);
330          _dotoken('LASTAUTHOR', $hash['author'], $page);
331          _dotoken('VERSION', $hash['version'], $page);
332          if (strstr($page, "$FieldSeparator#HITS$FieldSeparator#")) {
333             _dotoken('HITS', GetHitCount($dbi, $name), $page);
334          }
335          if (strstr($page, "$FieldSeparator#RELATEDPAGES$FieldSeparator#")) {
336             _dotoken('RELATEDPAGES', LinkRelatedPages($dbi, $name), $page);
337          }
338       }
339
340       // valid only for EditLinks
341       if ($template == 'EDITLINKS') {
342          for ($i = 1; $i <= NUM_LINKS; $i++) {
343             $ref = isset($hash['refs'][$i]) ? $hash['refs'][$i] : '';
344             _dotoken("R$i", $ref, $page);
345          }
346       }
347
348       _dotoken('CONTENT', $content, $page);
349       print $page;
350    }
351 ?>