"; } define('NO_END_TAG_PAT', '/^' . join('|', array('area', 'base', 'basefont', 'br', 'col', 'frame', 'hr', 'image', 'input', 'isindex', 'link', 'meta', 'param')) . '$/i'); function Element($tag, $args = '', $content = '') { $html = "<$tag"; if (!is_array($args)) { $content = $args; $args = false; } $html = StartTag($tag, $args); if (!preg_match(NO_END_TAG_PAT, $tag)) { $html .= $content; $html .= "";//FIXME: newline might not always be desired. } return $html; } function QElement($tag, $args = '', $content = '') { if (is_array($args)) return Element($tag, $args, htmlspecialchars($content)); else { $content = $args; return Element($tag, htmlspecialchars($content)); } } function LinkURL($url, $linktext='') { // FIXME: Is this needed (or sufficient?) if(ereg("[<>\"]", $url)) { return "BAD URL -- remove all of <, >, ""; } if (empty($linktext)) $linktext = QElement('span', array('class' => 'rawurl'), $url); else $linktext = htmlspecialchars($linktext); return Element('a', array('href' => $url, 'class' => 'linkurl'), $linktext); } function LinkExistingWikiWord($wikiword, $linktext='') { if (empty($linktext)) $linktext = QElement('span', array('class' => 'wikiword'), $wikiword); else $linktext = htmlspecialchars($linktext); return Element('a', array('href' => WikiURL($wikiword), 'class' => 'wikilink'), $linktext); } function LinkUnknownWikiWord($wikiword, $linktext='') { if (empty($linktext)) $linktext = QElement('span', array('class' => 'wikiword'), $wikiword); else $linktext = htmlspecialchars($linktext); return Element('span', array('class' => 'wikiunknown'), Element('u', $linktext) . QElement('a', array('href' => WikiURL($wikiword, array('action' => 'edit')), 'class' => 'wikiunknown'), '?')); } function LinkImage($url, $alt='[External Image]') { // FIXME: Is this needed (or sufficient?) // As long as the src in htmlspecialchars()ed I think it's safe. if(ereg('[<>"]', $url)) { return "BAD URL -- remove all of <, >, ""; } return Element('img', array('src' => $url, 'alt' => $alt)); } // converts spaces to tabs function CookSpaces($pagearray) { return preg_replace("/ {3,8}/", "\t", $pagearray); } class Stack { var $items = array(); 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() { if($this->size) return $this->items[$this->size - 1]; else return ''; } } // end class definition function MakeWikiForm ($pagename, $args, $class, $button_text = '') { $formargs['action'] = USE_PATH_INFO ? WikiURL($pagename) : SCRIPT_NAME; $formargs['method'] = 'post'; $formargs['class'] = $class; $contents = ''; $input_seen = 0; while (list($key, $val) = each($args)) { $a = array('name' => $key, 'value' => $val, 'type' => 'hidden'); if (preg_match('/^ (\d*) \( (.*) \) ((upload)?) $/xi', $val, $m)) { $input_seen++; $a['type'] = 'text'; $a['size'] = $m[1] ? $m[1] : 30; $a['value'] = $m[2]; if ($m[3]) { $a['type'] = 'file'; $formargs['enctype'] = 'multipart/form-data'; $contents .= Element('input', array('name' => 'MAX_FILE_SIZE', 'value' => MAX_UPLOAD_SIZE, 'type' => 'hidden')); } } $contents .= Element('input', $a); } $row = Element('td', $contents); if (!empty($button_text)) { $row .= Element('td', Element('input', array('type' => 'submit', 'value' => $button_text))); } return Element('form', $formargs, Element('table', array('cellspacing' => 0, 'cellpadding' => 2, 'border' => 0), Element('tr', $row))); } function SplitQueryArgs ($query_args = '') { $split_args = split('&', $query_args); $args = array(); while (list($key, $val) = each($split_args)) if (preg_match('/^ ([^=]+) =? (.*) /x', $val, $m)) $args[$m[1]] = $m[2]; return $args; } function LinkPhpwikiURL($url, $text = '') { global $pagename; $args = array(); $page = $pagename; if (!preg_match('/^ phpwiki: ([^?]*) [?]? (.*) $/x', $url, $m)) return "BAD phpwiki: URL"; if ($m[1]) $page = urldecode($m[1]); $qargs = $m[2]; if (!$page && preg_match('/^(diff|edit|links|info|diff)=([^&]+)$/', $qargs, $m)) { // Convert old style links (to not break diff links in RecentChanges). $page = urldecode($m[2]); $args = array("action" => $m[1]); } else { $args = SplitQueryArgs($qargs); } if (isset($args['action']) && $args['action'] == 'browse') unset($args['action']); if (empty($args['action'])) $class = 'wikilink'; else if (IsSafeAction($args['action'])) $class = 'wikiaction'; else { // Don't allow administrative links on unlocked pages. // FIXME: Ugh: don't like this... global $pagehash; if (($pagehash['flags'] & FLAG_PAGE_LOCKED) == 0) return QElement('u', array('class' => 'wikiunsafe'), gettext('Lock page to enable link')); $class = 'wikiadmin'; } // FIXME: ug, don't like this if (preg_match('/=\d*\(/', $qargs)) return MakeWikiForm($page, $args, $class, $text); else { if ($text) $text = htmlspecialchars($text); else $text = QElement('span', array('class' => 'rawurl'), $url); return Element('a', array('href' => WikiURL($page, $args), 'class' => $class), $text); } } function ParseAndLink($bracketlink) { global $dbi, $AllowedProtocols, $InlineImages; global $InterWikiLinkRegexp; // $bracketlink will start and end with brackets; in between // will be either a page name, a URL or both separated by a pipe. // strip brackets and leading space preg_match("/(\[\s*)(.+?)(\s*\])/", $bracketlink, $match); // match the contents preg_match("/([^|]+)(\|)?([^|]+)?/", $match[2], $matches); if (isset($matches[3])) { // named link of the form "[some link name | http://blippy.com/]" $URL = trim($matches[3]); $linkname = trim($matches[1]); $linktype = 'named'; } else { // unnamed link of the form "[http://blippy.com/] or [wiki page]" $URL = trim($matches[1]); $linkname = ''; $linktype = 'simple'; } if (IsWikiPage($dbi, $URL)) { $link['type'] = "wiki-$linktype"; $link['link'] = LinkExistingWikiWord($URL, $linkname); } elseif (preg_match("#^($AllowedProtocols):#", $URL)) { // if it's an image, embed it; otherwise, it's a regular link if (preg_match("/($InlineImages)$/i", $URL)) { $link['type'] = "image-$linktype"; $link['link'] = LinkImage($URL, $linkname); } else { $link['type'] = "url-$linktype"; $link['link'] = LinkURL($URL, $linkname); } } elseif (preg_match("#^phpwiki:(.*)#", $URL, $match)) { $link['type'] = "url-wiki-$linktype"; $link['link'] = LinkPhpwikiURL($URL, $linkname); } elseif (preg_match("#^\d+$#", $URL)) { $link['type'] = "footnote-$linktype"; $link['link'] = $URL; } elseif (function_exists('LinkInterWikiLink') && preg_match("#^$InterWikiLinkRegexp:#", $URL)) { $link['type'] = "interwiki-$linktype"; $link['link'] = LinkInterWikiLink($URL, $linkname); } else { $link['type'] = "wiki-unknown-$linktype"; $link['link'] = LinkUnknownWikiWord($URL, $linkname); } return $link; } function ExtractWikiPageLinks($content) { global $WikiNameRegexp; $wikilinks = array(); $numlines = count($content); for($l = 0; $l < $numlines; $l++) { // remove escaped '[' $line = str_replace('[[', ' ', $content[$l]); // bracket links (only type wiki-* is of interest) $numBracketLinks = preg_match_all("/\[\s*([^\]|]+\|)?\s*(.+?)\s*\]/", $line, $brktlinks); for ($i = 0; $i < $numBracketLinks; $i++) { $link = ParseAndLink($brktlinks[0][$i]); if (preg_match("#^wiki#", $link['type'])) $wikilinks[$brktlinks[2][$i]] = 1; $brktlink = preg_quote($brktlinks[0][$i]); $line = preg_replace("|$brktlink|", '', $line); } // BumpyText old-style wiki links if (preg_match_all("/!?$WikiNameRegexp/", $line, $link)) { for ($i = 0; isset($link[0][$i]); $i++) { if($link[0][$i][0] <> '!') $wikilinks[$link[0][$i]] = 1; } } } return $wikilinks; } function LinkRelatedPages($dbi, $pagename) { // currently not supported everywhere if(!function_exists('GetWikiPageLinks')) return ''; $links = GetWikiPageLinks($dbi, $pagename); $txt = ""; $txt .= sprintf (gettext ("%d best incoming links:"), NUM_RELATED_PAGES); $txt .= "\n"; for($i = 0; $i < NUM_RELATED_PAGES; $i++) { if(isset($links['in'][$i])) { list($name, $score) = $links['in'][$i]; $txt .= LinkExistingWikiWord($name) . " ($score), "; } } $txt .= "\n
"; $txt .= sprintf (gettext ("%d best outgoing links:"), NUM_RELATED_PAGES); $txt .= "\n"; for($i = 0; $i < NUM_RELATED_PAGES; $i++) { if(isset($links['out'][$i])) { list($name, $score) = $links['out'][$i]; if(IsWikiPage($dbi, $name)) $txt .= LinkExistingWikiWord($name) . " ($score), "; } } $txt .= "\n
"; $txt .= sprintf (gettext ("%d most popular nearby:"), NUM_RELATED_PAGES); $txt .= "\n"; for($i = 0; $i < NUM_RELATED_PAGES; $i++) { if(isset($links['popular'][$i])) { list($name, $score) = $links['popular'][$i]; $txt .= LinkExistingWikiWord($name) . " ($score), "; } } return $txt; } # GeneratePage() -- takes $content and puts it in the template $template # this function contains all the template logic # # $template ... name of the template (see config.php for list of names) # $content ... html content to put into the page # $name ... page title # $hash ... if called while creating a wiki page, $hash points to # the $pagehash array of that wiki page. function GeneratePage($template, $content, $name, $hash) { global $templates; global $datetimeformat, $dbi, $logo, $FieldSeparator; global $user, $pagename; if (!is_array($hash)) unset($hash); function _dotoken ($id, $val, &$page) { global $FieldSeparator; $page = str_replace("$FieldSeparator#$id$FieldSeparator#", $val, $page); } function _iftoken ($id, $condition, &$page) { global $FieldSeparator; // line based IF directive $lineyes = "$FieldSeparator#IF $id$FieldSeparator#"; $lineno = "$FieldSeparator#IF !$id$FieldSeparator#"; // block based IF directive $blockyes = "$FieldSeparator#IF:$id$FieldSeparator#"; $blockyesend = "$FieldSeparator#ENDIF:$id$FieldSeparator#"; $blockno = "$FieldSeparator#IF:!$id$FieldSeparator#"; $blocknoend = "$FieldSeparator#ENDIF:!$id$FieldSeparator#"; if ($condition) { $page = str_replace($lineyes, '', $page); $page = str_replace($blockyes, '', $page); $page = str_replace($blockyesend, '', $page); $page = preg_replace("/$blockno(.*?)$blocknoend/s", '', $page); $page = ereg_replace("${lineno}[^\n]*\n", '', $page); } else { $page = str_replace($lineno, '', $page); $page = str_replace($blockno, '', $page); $page = str_replace($blocknoend, '', $page); $page = preg_replace("/$blockyes(.*?)$blockyesend/s", '', $page); $page = ereg_replace("${lineyes}[^\n]*\n", '', $page); } } $page = join('', file(FindLocalizedFile($templates[$template]))); $page = str_replace('###', "$FieldSeparator#", $page); // valid for all pagetypes _iftoken('COPY', isset($hash['copy']), $page); _iftoken('LOCK', (isset($hash['flags']) && ($hash['flags'] & FLAG_PAGE_LOCKED)), $page); _iftoken('ADMIN', $user->is_admin(), $page); _iftoken('ANONYMOUS', !$user->is_authenticated(), $page); if (empty($hash['minor_edit_checkbox'])) $hash['minor_edit_checkbox'] = ''; _iftoken('MINOR_EDIT_CHECKBOX', $hash['minor_edit_checkbox'], $page); _dotoken('MINOR_EDIT_CHECKBOX', $hash['minor_edit_checkbox'], $page); _dotoken('USERID', htmlspecialchars($user->id()), $page); _dotoken('PAGE', htmlspecialchars($name), $page); _dotoken('SPLIT_PAGE', htmlspecialchars( preg_replace('/([[:lower:]])([[:upper:]])/', '\\1 \\2', $name)), $page); _dotoken('LOGO', htmlspecialchars(DataURL($logo)), $page); _dotoken('CSS_URL', htmlspecialchars(DataURL(CSS_URL)), $page); _dotoken('RCS_IDS', $GLOBALS['RCS_IDS'], $page); $prefs = $user->getPreferences(); _dotoken('EDIT_AREA_WIDTH', $prefs['edit_area.width'], $page); _dotoken('EDIT_AREA_HEIGHT', $prefs['edit_area.height'], $page); // FIXME: Clean up this stuff _dotoken('BROWSE', WikiURL(''), $page); if (USE_PATH_INFO) _dotoken('BASE_URL', SERVER_URL . VIRTUAL_PATH . "/" . WikiURL($pagename), $page); else _dotoken('BASE_URL', SERVER_URL . SCRIPT_NAME, $page); if ($GLOBALS['action'] != 'browse') _dotoken('ROBOTS_META', Element('meta', array('name' => 'robots', 'content' => 'noindex, nofollow')), $page); else _dotoken('ROBOTS_META', '', $page); // invalid for messages (search results, error messages) if ($template != 'MESSAGE') { $browse_page = WikiURL($name); _dotoken('BROWSE_PAGE', $browse_page, $page); $arg_sep = strstr($browse_page, '?') ? '&' : '?'; _dotoken('ACTION', $browse_page . $arg_sep . "action=", $page); _dotoken('PAGEURL', rawurlencode($name), $page); if (!empty($hash['lastmodified'])) _dotoken('LASTMODIFIED', strftime($datetimeformat, $hash['lastmodified']), $page); if (!empty($hash['author'])) _dotoken('LASTAUTHOR', $hash['author'], $page); if (!empty($hash['version'])) _dotoken('VERSION', $hash['version'], $page); if (strstr($page, "$FieldSeparator#HITS$FieldSeparator#")) { _dotoken('HITS', GetHitCount($dbi, $name), $page); } if (strstr($page, "$FieldSeparator#RELATEDPAGES$FieldSeparator#")) { _dotoken('RELATEDPAGES', LinkRelatedPages($dbi, $name), $page); } } _dotoken('CONTENT', $content, $page); return $page; } function UpdateRecentChanges($dbi, $pagename, $isnewpage) { global $user; global $dateformat; global $WikiPageStore; $recentchanges = RetrievePage($dbi, gettext ("RecentChanges"), $WikiPageStore); // this shouldn't be necessary, since PhpWiki loads // default pages if this is a new baby Wiki $now = time(); $today = strftime($dateformat, $now); if (is_array($recentchanges)) { $isNewDay = strftime($dateformat, $recentchanges['lastmodified']) != $today; } else { $recentchanges = array('version' => 1, 'created' => $now, 'flags' => FLAG_PAGE_LOCKED, 'author' => $GLOBALS['user']->id()); $recentchanges['content'] = array(gettext("The most recently changed pages are listed below."), '', "____$today " . gettext("(first day for this Wiki)"), '', gettext("Quick title search:"), '[phpwiki:?action=search&searchterm=()]', '----'); $isNewDay = 0; } $recentchanges['lastmodified'] = $now; $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; $i++) { if (preg_match("/^____/", $recentchanges['content'][$i])) { break; } else { $newpage[$k++] = $recentchanges['content'][$i]; } } // if it's a new date, insert it $newpage[$k++] = $isNewDay ? "____$today\r" : $recentchanges['content'][$i++]; $userid = $user->id(); // add the updated page's name to the array if($isnewpage) { $newpage[$k++] = "* [$pagename] " . gettext("(new)") . " ..... $userid\r"; } else { $diffurl = "phpwiki:" . rawurlencode($pagename) . "?action=diff"; $newpage[$k++] = "* [$pagename] ([diff|$diffurl]) ..... $userid\r"; } if ($isNewDay) $newpage[$k++] = "\r"; // copy the rest of the page into the new array // and skip previous entry for $pagename $pagename = preg_quote($pagename); for (; $i < $numlines; $i++) { if (!preg_match("|\[$pagename\]|", $recentchanges['content'][$i])) { $newpage[$k++] = $recentchanges['content'][$i]; } } $recentchanges['content'] = $newpage; InsertPage($dbi, gettext ("RecentChanges"), $recentchanges); } // For emacs users // Local Variables: // mode: php // c-file-style: "ellemtel" // End: ?>