/*
Standard functions for Wiki functionality
GeneratePage($template, $content, $name, $hash)
LinkExistingWikiWord($wikiword)
LinkUnknownWikiWord($wikiword)
LinkURL($url)
RenderQuickSearch()
RenderFullSearch()
RenderMostPopular()
CookSpaces($pagearray)
class Stack
SetHTMLOutputMode($newmode, $depth)
UpdateRecentChanges($dbi, $pagename, $isnewpage)
SaveCopyToArchive($pagename, $pagehash)
ParseAndLink($bracketlink)
*/
function GeneratePage($template, $content, $name, $hash)
{
global $ScriptUrl, $AllowedProtocols, $templates;
global $datetimeformat, $dbi, $logo;
if (!is_array($hash))
unset($hash);
$page = join('', file($templates[$template]));
$page = str_replace('###', "#$FieldSeparator#", $page);
// valid for all pagetypes
$page = str_replace("#$FieldSeparator#SCRIPTURL#$FieldSeparator#",
$ScriptUrl, $page);
$page = str_replace("#$FieldSeparator#PAGE#$FieldSeparator#",
htmlspecialchars($name), $page);
$page = str_replace("#$FieldSeparator#ALLOWEDPROTOCOLS#$FieldSeparator#",
$AllowedProtocols, $page);
$page = str_replace("#$FieldSeparator#LOGO#$FieldSeparator#",
$logo, $page);
// invalid for messages (search results, error messages)
if ($template != 'MESSAGE') {
$page = str_replace("#$FieldSeparator#PAGEURL#$FieldSeparator#",
rawurlencode($name), $page);
$page = str_replace("#$FieldSeparator#LASTMODIFIED#$FieldSeparator#",
date($datetimeformat, $hash['lastmodified']), $page);
$page = str_replace("#$FieldSeparator#LASTAUTHOR#$FieldSeparator#",
$hash['author'], $page);
$page = str_replace("#$FieldSeparator#VERSION#$FieldSeparator#",
$hash['version'], $page);
if (strstr($page, "#$FieldSeparator#HITS#$FieldSeparator#")) {
$page = str_replace("#$FieldSeparator#HITS#$FieldSeparator#",
GetHitCount($dbi, $name), $page);
}
}
// valid only for EditLinks
if ($template == 'EDITLINKS') {
for ($i = 1; $i <= NUM_LINKS; $i++)
$page = str_replace("#$FieldSeparator#R$i#$FieldSeparator#",
$hash['refs'][$i], $page);
}
if ($hash['copy']) {
$page = str_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#",
'', $page);
} else {
$page = ereg_replace("#$FieldSeparator#IFCOPY#$FieldSeparator#[^\n]*",
'', $page);
}
$page = str_replace("#$FieldSeparator#CONTENT#$FieldSeparator#",
$content, $page);
print $page;
}
function LinkExistingWikiWord($wikiword) {
global $ScriptUrl;
$enc_word = rawurlencode($wikiword);
$wikiword = htmlspecialchars($wikiword);
return "$wikiword";
}
function LinkUnknownWikiWord($wikiword) {
global $ScriptUrl;
$enc_word = rawurlencode($wikiword);
$wikiword = htmlspecialchars($wikiword);
return "$wikiword?";
}
function LinkURL($url) {
global $ScriptUrl;
if(ereg("[<>\"]", $url)) {
return "BAD URL -- remove all of <, >, "";
}
$enc_url = htmlspecialchars($url);
return "$enc_url";
}
function RenderQuickSearch() {
global $value, $ScriptUrl;
$formtext = "
\n";
return $formtext;
}
function RenderFullSearch() {
global $value, $ScriptUrl;
$formtext = "\n";
return $formtext;
}
function RenderMostPopular() {
global $ScriptUrl, $dbi;
$query = InitMostPopular($dbi, 20);
$result = "\n";
while ($qhash = MostPopularNextMatch($dbi, $query)) {
$result .= "- $qhash[hits] ... " . LinkExistingWikiWord($qhash['pagename']) . "\n";
}
$result .= "
\n";
return $result;
}
// converts spaces to tabs
function CookSpaces($pagearray) {
return preg_replace("/ {3,8}/", "\t", $pagearray);
}
class Stack {
var $items;
var $size = 0;
function push($item) {
$this->items[$this->size] = $item;
$this->size++;
return true;
}
function pop() {
if ($this->size == 0) {
return false; // stack is empty
}
$this->size--;
return $this->items[$this->size];
}
function cnt() {
return $this->size;
}
function top() {
return $this->items[$this->size - 1];
}
}
// end class definition
// I couldn't move this to wiki_config.php3 because it
// wasn't declared yet.
$stack = new Stack;
/*
Wiki HTML output can, at any given time, be in only one mode.
It will be something like Unordered List, Preformatted Text,
plain text etc. When we change modes we have to issue close tags
for one mode and start tags for another.
*/
function SetHTMLOutputMode($tag, $tagdepth, $tabcount) {
global $stack;
$retvar = "";
if ($tagdepth == SINGLE_DEPTH) {
if ($tabcount < $stack->cnt()) {
// there are fewer tabs than stack,
// reduce stack to that tab count
while ($stack->cnt() > $tabcount) {
$closetag = $stack->pop();
if ($closetag == false) {
//echo "bounds error in tag stack";
break;
}
$retvar .= "$closetag>\n";
}
// if list type isn't the same,
// back up one more and push new tag
if ($tag != $stack->top()) {
$closetag = $stack->pop();
$retvar .= "$closetag><$tag>\n";
$stack->push($tag);
}
} elseif ($tabcount > $stack->cnt()) {
// we add the diff to the stack
// stack might be zero
while ($stack->cnt() < $tabcount) {
#echo "<$tag>\n";
$retvar .= "<$tag>\n";
$stack->push($tag);
if ($stack->cnt() > 10) {
// arbitrarily limit tag nesting
echo "Stack bounds exceeded in SetHTMLOutputMode\n";
exit();
}
}
} else {
if ($tag == $stack->top()) {
return;
} else {
$closetag = $stack->pop();
#echo "$closetag>\n";
#echo "<$tag>\n";
$retvar .= "$closetag>\n";
$retvar .= "<$tag>\n";
$stack->push($tag);
}
}
} elseif ($tagdepth == ZERO_DEPTH) {
// empty the stack for $depth == 0;
// what if the stack is empty?
if ($tag == $stack->top()) {
return;
}
while ($stack->cnt() > 0) {
$closetag = $stack->pop();
#echo "$closetag>\n";
$retvar .= "$closetag>\n";
}
if ($tag) {
#echo "<$tag>\n";
$retvar .= "<$tag>\n";
$stack->push($tag);
}
} else {
// error
echo "Passed bad tag depth value in SetHTMLOutputMode\n";
exit();
}
return $retvar;
}
// end SetHTMLOutputMode
// The Recent Changes file is solely handled here
function UpdateRecentChanges($dbi, $pagename, $isnewpage) {
global $remoteuser; // this is set in the config
global $dateformat;
$recentchanges = RetrievePage($dbi, "RecentChanges");
// this shouldn't be necessary, since PhpWiki loads
// default pages if this is a new baby Wiki
if ($recentchanges == -1) {
$recentchanges = array();
}
$now = time();
$today = date($dateformat, $now);
if (date($dateformat, $recentchanges["lastmodified"]) != $today) {
$isNewDay = TRUE;
$recentchanges["lastmodified"] = $now;
} else {
$isNewDay = FALSE;
}
$numlines = sizeof($recentchanges["content"]);
$newpage = array();
$k = 0;
// scroll through the page to the first date and break
// dates are marked with "____" at the beginning of the line
for ($i = 0; $i < ($numlines + 1); $i++) {
if (preg_match("/^____/",
$recentchanges["content"][$i])) {
break;
} else {
$newpage[$k++] = $recentchanges["content"][$i];
}
}
// if it's a new date, insert it, else add the updated page's
// name to the array
if ($isNewDay) {
$newpage[$k++] = "____$today\r";
} else {
$newpage[$k++] = $recentchanges["content"][$i++];
}
if($isnewpage) {
$newpage[$k++] = "\t* [$pagename] (new) ..... $remoteuser\r";
} else {
$newpage[$k++] = "\t* [$pagename] ..... $remoteuser\r";
}
// copy the rest of the page into the new array
$pagename = preg_quote($pagename);
for (; $i < ($numlines + 1); $i++) {
// skip previous entry for $pagename
if (preg_match("/\[$pagename\]/", $recentchanges["content"][$i])) {
continue;
} else {
$newpage[$k++] = $recentchanges["content"][$i];
}
}
$recentchanges["content"] = $newpage;
InsertPage($dbi, "RecentChanges", $recentchanges);
}
// for archiving pages to a seperate dbm
function SaveCopyToArchive($pagename, $pagehash) {
global $ArchiveDataBase;
$adbi = OpenDataBase($ArchiveDataBase);
$newpagename = $pagename;
InsertPage($adbi, $newpagename, $pagehash);
}
function ParseAndLink($bracketlink) {
global $dbi, $AllowedProtocols;
// $bracketlink will start and end with brackets; in between
// will be either a page name, a URL or both seperated by a pipe.
// strip brackets and leading space
preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match);
$linkdata = $match[2];
// send back links that are only numbers (they are references)
if (preg_match("/^\d+$/", $linkdata)) {
return $bracketlink;
}
// send back escaped ([[) bracket sets
if (preg_match("/^\[/", $linkdata)) {
return htmlspecialchars(substr($bracketlink, 1));
}
// match the contents
preg_match("/([^|]+)(\|)?([^|]+)?/", $linkdata, $matches);
if (isset($matches[3])) {
$URL = trim($matches[3]);
$linkname = htmlspecialchars(trim($matches[1]));
// assert proper URL's
if (preg_match("#^($AllowedProtocols):#", $URL)) {
return "$linkname";
} else {
return "BAD URL -- links have to start with one of " . "$AllowedProtocols followed by ':'";
}
}
if (isset($matches[1])) {
$linkname = trim($matches[1]);
if (IsWikiPage($dbi, $linkname)) {
return LinkExistingWikiWord($linkname);
} elseif (preg_match("#^($AllowedProtocols):#", $linkname)) {
return LinkURL($linkname);
} else {
return LinkUnknownWikiWord($linkname);
}
}
return $bracketlink;
}
?>