Esempio n. 1
0
 function _printPlugin($pi)
 {
     include_once "lib/WikiPlugin.php";
     static $loader;
     if (empty($loader)) {
         $loader = new WikiPluginLoader();
     }
     $this->_print($loader->expandPI($pi, $this->_request, $this, $this->_basepage));
 }
Esempio n. 2
0
 function PluginSidebarBox($name, $args = false, $basepage = false)
 {
     $loader = new WikiPluginLoader();
     $plugin = $loader->getPlugin($name);
     if (!$plugin) {
         return $loader->_error(sprintf(_("Plugin %s: undefined"), $name));
     }
     /*
             if (!method_exists($plugin, 'box')) {
                 return $loader->_error(sprintf(_("%s: has no box method"),
                                                get_class($plugin)));
             }*/
     $this->_plugin =& $plugin;
     $this->_args = $args ? $args : array();
     $this->_basepage = $basepage;
 }
Esempio n. 3
0
 function _doautocomplete(&$form, $inputtype, &$input, &$values)
 {
     global $request;
     $input['class'] = "dropdown";
     $input['acdropdown'] = "true";
     //$input['autocomplete'] = "OFF";
     $input['autocomplete_complete'] = "true";
     // only match begin: autocomplete_matchbegin, or
     $input['autocomplete_matchsubstring'] = "true";
     if (empty($values)) {
         if ($input['method']) {
             if (empty($input['args'])) {
                 if (preg_match("/^(.*?) (.*)\$/", $input['method'], $m)) {
                     $input['method'] = $m[1];
                     $input['args'] = $m[2];
                 } else {
                     $input['args'] = null;
                 }
             }
             static $tmpArray = 'tmpArray00';
             // deferred remote xmlrpc call
             if (string_starts_with($input['method'], "dynxmlrpc:")) {
                 // how is server + method + args encoding parsed by acdropdown?
                 $input['autocomplete_list'] = substr($input['method'], 3);
                 if ($input['args']) {
                     $input['autocomplete_list'] .= " " . $input['args'];
                 }
                 // static xmlrpc call, local only
             } elseif (string_starts_with($input['method'], "xmlrpc:")) {
                 include_once "lib/XmlRpcClient.php";
                 $values = wiki_xmlrpc_post(substr($input['method'], 7), $input['args']);
             } elseif (string_starts_with($input['method'], "url:")) {
                 include_once "lib/HttpClient.php";
                 $html = HttpClient::quickGet(substr($input['method'], 4));
                 //TODO: how to parse the HTML result into a list?
             } elseif (string_starts_with($input['method'], "dynurl:")) {
                 $input['autocomplete_list'] = substr($input['method'], 3);
             } elseif (string_starts_with($input['method'], "plugin:")) {
                 $dbi = $request->getDbh();
                 $pluginName = substr($input['method'], 7);
                 $basepage = '';
                 require_once "lib/WikiPlugin.php";
                 $w = new WikiPluginLoader();
                 $p = $w->getPlugin($pluginName, false);
                 // second arg?
                 if (!is_object($p)) {
                     trigger_error("invalid input['method'] " . $input['method'], E_USER_WARNING);
                 }
                 $pagelist = $p->run($dbi, @$input['args'], $request, $basepage);
                 $values = array();
                 if (is_object($pagelist) and isa($pagelist, 'PageList')) {
                     foreach ($pagelist->_pages as $page) {
                         if (is_object($page)) {
                             $values[] = $page->getName();
                         } else {
                             $values[] = (string) $page;
                         }
                     }
                 }
             } elseif (string_starts_with($input['method'], "array:")) {
                 // some predefined values (e.g. in a template or themeinfo.php)
                 $input['autocomplete_list'] = $input['method'];
             } else {
                 trigger_error("invalid input['method'] " . $input['method'], E_USER_WARNING);
             }
             if (empty($input['autocomplete_list'])) {
                 $tmpArray++;
                 $input['autocomplete_list'] = "array:" . $tmpArray;
                 $svalues = empty($values) ? "" : join("','", $values);
                 $form->pushContent(JavaScript("var {$tmpArray} = new Array('" . $svalues . "')"));
             }
             if (count($values) == 1) {
                 $input['value'] = $values[0];
             } else {
                 $input['value'] = "";
             }
             unset($input['method']);
             unset($input['args']);
             //unset($input['autocomplete']);
         } elseif ($s = $request->getArg($input['name'])) {
             $input['value'] = $s;
         }
     }
     return true;
 }
Esempio n. 4
0
function callPlugin($pluginname, $pluginargs, $credentials = false)
{
    global $server;
    checkCredentials($server, $credentials, 'change', "Help/" . $pluginname . "Plugin");
    $basepage = '';
    require_once "lib/WikiPlugin.php";
    $w = new WikiPluginLoader();
    $p = $w->getPlugin($pluginName, false);
    // second arg?
    $pagelist = $p->run($dbi, $pluginargs, $request, $basepage);
    $pages = array();
    if (is_object($pagelist) and isa($pagelist, 'PageList')) {
        foreach ($pagelist->pageNames() as $name) {
            $pages[] = array('pagename' => $name);
        }
    }
    return $pages;
}
Esempio n. 5
0
function displayPage(&$request, $template = false)
{
    global $WikiTheme, $pv;
    $pagename = $request->getArg('pagename');
    $version = $request->getArg('version');
    $page = $request->getPage();
    if ($version) {
        $revision = $page->getRevision($version);
        if (!$revision) {
            NoSuchRevision($request, $page, $version);
        }
    } else {
        $revision = $page->getCurrentRevision();
    }
    if (isSubPage($pagename)) {
        $pages = explode(SUBPAGE_SEPARATOR, $pagename);
        $last_page = array_pop($pages);
        // deletes last element from array as side-effect
        $pageheader = HTML::span(HTML::a(array('href' => WikiURL($pages[0]), 'class' => 'pagetitle'), $WikiTheme->maybeSplitWikiWord($pages[0] . SUBPAGE_SEPARATOR)));
        $first_pages = $pages[0] . SUBPAGE_SEPARATOR;
        array_shift($pages);
        foreach ($pages as $p) {
            if ($pv != 2) {
                //Add the Backlink in page title
                $pageheader->pushContent(HTML::a(array('href' => WikiURL($first_pages . $p), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($p . SUBPAGE_SEPARATOR)));
            } else {
                // Remove Backlinks
                $pageheader->pushContent(HTML::h1($pagename));
            }
            $first_pages .= $p . SUBPAGE_SEPARATOR;
        }
        if ($pv != 2) {
            $backlink = HTML::a(array('href' => WikiURL($pagename, array('action' => _("BackLinks"))), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($last_page));
            $backlink->addTooltip(sprintf(_("BackLinks for %s"), $pagename));
        } else {
            $backlink = HTML::h1($pagename);
        }
        $pageheader->pushContent($backlink);
    } else {
        if ($pv != 2) {
            $pageheader = HTML::a(array('href' => WikiURL($pagename, array('action' => _("BackLinks"))), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($pagename));
            $pageheader->addTooltip(sprintf(_("BackLinks for %s"), $pagename));
        } else {
            $pageheader = HTML::h1($pagename);
            //Remove Backlinks
        }
        if ($request->getArg('frame')) {
            $pageheader->setAttr('target', '_top');
        }
    }
    // {{{ Codendi hook to insert stuff between navbar and header
    $eM =& EventManager::instance();
    $ref_html = '';
    $crossref_fact = new CrossReferenceFactory($pagename, ReferenceManager::REFERENCE_NATURE_WIKIPAGE, GROUP_ID);
    $crossref_fact->fetchDatas();
    if ($crossref_fact->getNbReferences() > 0) {
        $ref_html .= '<h3>' . $GLOBALS['Language']->getText('cross_ref_fact_include', 'references') . '</h3>';
        $ref_html .= $crossref_fact->getHTMLDisplayCrossRefs();
    }
    $additional_html = false;
    $eM->processEvent('wiki_before_content', array('html' => &$additional_html, 'group_id' => GROUP_ID, 'wiki_page' => $pagename));
    if ($additional_html) {
        $beforeHeader = HTML();
        $beforeHeader->pushContent($additional_html);
        $beforeHeader->pushContent(HTML::raw($ref_html));
        $toks['BEFORE_HEADER'] = $beforeHeader;
    } else {
        $beforeHeader = HTML();
        $beforeHeader->pushContent(HTML::raw($ref_html));
        $toks['BEFORE_HEADER'] = $beforeHeader;
    }
    // }}} /Codendi hook
    $pagetitle = SplitPagename($pagename);
    if ($redirect_from = $request->getArg('redirectfrom')) {
        $redirect_message = HTML::span(array('class' => 'redirectfrom'), fmt("(Redirected from %s)", RedirectorLink($redirect_from)));
        // abuse the $redirected template var for some status update notice
    } elseif ($request->getArg('errormsg')) {
        $redirect_message = $request->getArg('errormsg');
        $request->setArg('errormsg', false);
    }
    $request->appendValidators(array('pagerev' => $revision->getVersion(), '%mtime' => $revision->get('mtime')));
    /*
        // FIXME: This is also in the template...
        if ($request->getArg('action') != 'pdf' and !headers_sent()) {
          // FIXME: enable MathML/SVG/... support
          if (ENABLE_XHTML_XML
                 and (!isBrowserIE()
                      and strstr($request->get('HTTP_ACCEPT'),'application/xhtml+xml')))
                header("Content-Type: application/xhtml+xml; charset=" . $GLOBALS['charset']);
            else
                header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
        }
    */
    $page_content = $revision->getTransformedContent();
    // if external searchengine (google) referrer, highlight the searchterm
    // FIXME: move that to the transformer?
    // OR: add the searchhightplugin line to the content?
    if ($result = isExternalReferrer($request)) {
        if (DEBUG and !empty($result['query'])) {
            //$GLOBALS['SearchHighlightQuery'] = $result['query'];
            /* simply add the SearchHighlight plugin to the top of the page. 
               This just parses the wikitext, and doesn't highlight the markup */
            include_once 'lib/WikiPlugin.php';
            $loader = new WikiPluginLoader();
            $xml = $loader->expandPI('<' . '?plugin SearchHighlight s="' . $result['query'] . '"?' . '>', $request, $markup);
            if ($xml and is_array($xml)) {
                foreach (array_reverse($xml) as $line) {
                    array_unshift($page_content->_content, $line);
                }
                array_unshift($page_content->_content, HTML::div(_("You searched for: "), HTML::strong($result['query'])));
            }
            if (0) {
                /* Parse the transformed (mixed HTML links + strings) lines?
                     This looks like overkill.
                   */
                require_once "lib/TextSearchQuery.php";
                $query = new TextSearchQuery($result['query']);
                $hilight_re = $query->getHighlightRegexp();
                //$matches = preg_grep("/$hilight_re/i", $revision->getContent());
                // FIXME!
                for ($i = 0; $i < count($page_content->_content); $i++) {
                    $found = false;
                    $line = $page_content->_content[$i];
                    if (is_string($line)) {
                        while (preg_match("/^(.*?)({$hilight_re})/i", $line, $m)) {
                            $found = true;
                            $line = substr($line, strlen($m[0]));
                            $html[] = $m[1];
                            // prematch
                            $html[] = HTML::strong(array('class' => 'search-term'), $m[2]);
                            // match
                        }
                    }
                    if ($found) {
                        $html[] = $line;
                        // postmatch
                        $page_content->_content[$i] = HTML::span(array('class' => 'search-context'), $html);
                    }
                }
            }
        }
    }
    $toks['CONTENT'] = new Template('browse', $request, $page_content);
    $toks['TITLE'] = $pagetitle;
    // <title> tag
    $toks['HEADER'] = $pageheader;
    // h1 with backlink
    $toks['revision'] = $revision;
    if (!empty($redirect_message)) {
        $toks['redirected'] = $redirect_message;
    }
    $toks['ROBOTS_META'] = 'index,follow';
    $toks['PAGE_DESCRIPTION'] = $page_content->getDescription();
    $toks['PAGE_KEYWORDS'] = GleanKeywords($page);
    if (!$template) {
        $template = new Template('html', $request);
    }
    $template->printExpansion($toks);
    $page->increaseHitCount();
    if ($request->getArg('action') != 'pdf') {
        $request->checkValidators();
    }
    flush();
}
Esempio n. 6
0
 /** A higher-level interface to createRevision.
  *
  * This takes care of computing the links, and storing
  * a cached version of the transformed wiki-text.
  *
  * @param string $wikitext  The page content.
  *
  * @param int $version Version number for new revision.  
  * To ensure proper serialization of edits, $version must be
  * exactly one higher than the current latest version.
  * (You can defeat this check by setting $version to
  * {@link WIKIDB_FORCE_CREATE} --- not usually recommended.)
  *
  * @param hash $meta  Meta-data for new revision.
  */
 function save($wikitext, $version, $meta, $formatted = null)
 {
     if ($this->_wikidb->readonly) {
         trigger_error("readonly database", E_USER_WARNING);
         return;
     }
     if (is_null($formatted)) {
         $formatted = new TransformedText($this, $wikitext, $meta);
     }
     $type = $formatted->getType();
     $meta['pagetype'] = $type->getName();
     $links = $formatted->getWikiPageLinks();
     // linkto => relation
     $attributes = array();
     foreach ($links as $link) {
         if ($link['linkto'] === "" and !empty($link['relation'])) {
             $attributes[$link['relation']] = $this->getAttribute($link['relation']);
         }
     }
     $meta['attribute'] = $attributes;
     $backend =& $this->_wikidb->_backend;
     $newrevision = $this->createRevision($version, $wikitext, $meta, $links);
     if ($newrevision and !WIKIDB_NOCACHE_MARKUP) {
         $this->set('_cached_html', $formatted->pack());
     }
     // FIXME: probably should have some global state information
     // in the backend to control when to optimize.
     //
     // We're doing this here rather than in createRevision because
     // postgresql can't optimize while locked.
     if ((int) DEBUG & _DEBUG_SQL or DATABASE_OPTIMISE_FREQUENCY > 0 and time() % DATABASE_OPTIMISE_FREQUENCY == 0) {
         if ($backend->optimize()) {
             if ((int) DEBUG) {
                 trigger_error(_("Optimizing database"), E_USER_NOTICE);
             }
         }
     }
     /* Generate notification emails? */
     if (ENABLE_MAILNOTIFY and isa($newrevision, 'WikiDB_PageRevision')) {
         // Save didn't fail because of concurrent updates.
         $notify = $this->_wikidb->get('notify');
         if (!empty($notify) and is_array($notify) and !isa($GLOBALS['request'], 'MockRequest')) {
             include_once "lib/MailNotify.php";
             $MailNotify = new MailNotify($newrevision->getName());
             $MailNotify->onChangePage($this->_wikidb, $wikitext, $version, $meta);
         }
         $newrevision->_transformedContent = $formatted;
     }
     // more pagechange callbacks: (in a hackish manner for now)
     if (ENABLE_RECENTCHANGESBOX and empty($meta['is_minor_edit']) and !in_array($GLOBALS['request']->getArg('action'), array('loadfile', 'upgrade'))) {
         require_once "lib/WikiPlugin.php";
         $w = new WikiPluginLoader();
         $p = $w->getPlugin("RecentChangesCached", false);
         $p->box_update(false, $GLOBALS['request'], $this->_pagename);
     }
     return $newrevision;
 }
Esempio n. 7
0
 /** 
  * Main function for obtaining images from cache or generating on-the-fly
  * from parameters sent by url or session vars.
  *
  * @access static public
  * @param  dbi     WikiDB            handle to database
  * @param  request Request           ???
  * @param  errorformat string        outputs errors in 'png', 'gif', 'jpeg' or 'html'
  */
 function fetchImageFromCache($dbi, $request, $errorformat = 'png')
 {
     $cache = $this->newCache();
     $errorformat = $this->decideImgType($errorformat);
     // get id
     if (!$this->checkCall1($id, $plugincall, $cache, $request, $errorformat)) {
         return false;
     }
     // check cache
     $content = $cache->get($id, 'imagecache');
     if (!empty($content['image'])) {
         $this->writeHeader($content['imagetype']);
         print $content['image'];
         return true;
     }
     if (!empty($content['html'])) {
         print $content['html'];
         return true;
     }
     // static version?
     if (!empty($content['file']) && !empty($content['url']) && file_exists($content['file'])) {
         print $this->embedImg($content['url'], $dbi, array(), $request);
         return true;
     }
     // re-produce image. At first, we need the plugincall parameters.
     // Cached args with matching id override given args to shorten getimg.php?id=md5
     if (!empty($content['args'])) {
         $plugincall['arguments'] = $content['args'];
     }
     if (!$this->checkCall2($plugincall, $request)) {
         return false;
     }
     $pluginname = $plugincall['pluginname'];
     $argarray = $plugincall['arguments'];
     $loader = new WikiPluginLoader();
     $plugin = $loader->getPlugin($pluginname);
     // cache empty, but image maps have to be created _inline_
     // so ask user to reload wiki page instead
     if ($plugin->getPluginType() & PLUGIN_CACHED_MAP && PLUGIN_CACHED_FORCE_SYNCMAP) {
         $errortext = _("Image map expired. Reload wiki page to recreate its html part.");
         $this->printError($errorformat, $errortext);
     }
     if (!$this->produceImage($content, $plugin, $dbi, $argarray, $request, $errorformat)) {
         return false;
     }
     $expire = $plugin->getExpire($dbi, $argarray, $request);
     if ($content['image']) {
         $cache->save($id, $content, $expire, 'imagecache');
         $this->writeHeader($content['imagetype']);
         print $content['image'];
         return true;
     }
     $errortext = "Could not create image file from imagehandle.";
     $this->printError($errorformat, $errortext);
     return false;
 }
Esempio n. 8
0
 function run($dbi, $argstr, &$request, $basepage)
 {
     include_once 'lib/BlockParser.php';
     $args = $this->getArgs($argstr, $request, false);
     extract($args);
     if (!$page) {
         return '';
     }
     $this->_pagename = $page;
     $out = '';
     // get rid of this
     $html = HTML();
     if (empty($exclude)) {
         $exclude = array();
     }
     if (!$include_self) {
         $exclude[] = $page;
     }
     $this->ExcludedPages = empty($exclude) ? "" : "^(?:" . join("|", $exclude) . ")";
     $this->_default_limit = str_pad('', 3, '*');
     if (is_numeric($reclimit)) {
         if ($reclimit < 0) {
             $reclimit = 0;
         }
         if ($reclimit > 10) {
             $reclimit = 10;
         }
         $limit = str_pad('', $reclimit + 2, '*');
     } else {
         $limit = '***';
     }
     //Fixme:  override given arg
     $description = $this->getDescription();
     if (!$noheader) {
         $out = $this->getDescription() . " " . sprintf(_("(max. recursion level: %d)"), $reclimit) . ":\n\n";
         $html->pushContent(TransformText($out, 1.0, $page));
     }
     $pagelist = new PageList($info, $exclude);
     $p = $dbi->getPage($page);
     $pagearr = array();
     if ($direction == 'back') {
         $pagearr = $this->recursivelyGetBackLinks($p, $pagearr, "*", $limit);
     } else {
         $this->dbi = $dbi;
         $this->initialpage = $page;
         $this->firstreversed = $firstreversed;
         $this->excludeunknown = $excludeunknown;
         $pagearr = $this->recursivelyGetLinks($p, $pagearr, "*", $limit);
     }
     reset($pagearr);
     if (!empty($includepages)) {
         // disallow direct usage, only via child class IncludeSiteMap
         if (!isa($this, "WikiPlugin_IncludeSiteMap")) {
             $includepages = '';
         }
         if (!is_string($includepages)) {
             $includepages = ' ';
         }
         // avoid plugin loader problems
         $loader = new WikiPluginLoader();
         $plugin = $loader->getPlugin('IncludePage', false);
         $nothing = '';
     }
     while (list($key, $link) = each($pagearr)) {
         if (!empty($includepages)) {
             $a = substr_count($key, '*');
             $indenter = str_pad($nothing, $a);
             //$request->setArg('IncludePage', 1);
             // quote linkname, by Stefan Schorn
             $plugin_args = 'page=\'' . $link->getName() . '\' ' . $includepages;
             $pagehtml = $plugin->run($dbi, $plugin_args, $request, $basepage);
             $html->pushContent($pagehtml);
             //$html->pushContent( HTML(TransformText($indenter, 1.0, $page), $pagehtml));
             //$out .= $indenter . $pagehtml . "\n";
         } else {
             $out .= $key . "\n";
         }
     }
     if (empty($includepages)) {
         return TransformText($out, 2.0, $page);
     } else {
         return $html;
     }
 }
Esempio n. 9
0
 /**
  * Get the side-wide ModeratedPage status, reading the action-page args.
  * Who are the moderators? What actions should be moderated?
  */
 function getSiteStatus(&$request, &$action_page)
 {
     $loader = new WikiPluginLoader();
     $rev = $action_page->getCurrentRevision();
     $content = $rev->getPackedContent();
     list($pi) = explode("\n", $content, 2);
     // plugin ModeratedPage must be first line!
     if ($parsed = $loader->parsePI($pi)) {
         $plugin =& $parsed[1];
         if ($plugin->getName() != _("ModeratedPage")) {
             return $this->error(sprintf(_("<?plugin ModeratedPage ... ?> not found in first line of %s"), $action_page->getName()));
         }
         if (!$action_page->get('locked')) {
             return $this->error(sprintf(_("%s is not locked!"), $action_page->getName()));
         }
         return $plugin->resolve_argstr($request, $parsed[2]);
     } else {
         return $this->error(sprintf(_("<?plugin ModeratedPage ... ?> not found in first line of %s"), $action_page->getName()));
     }
 }
Esempio n. 10
0
 function parseArgStr($argstr)
 {
     $args = array();
     $defaults = array();
     if (empty($argstr)) {
         return array($args, $defaults);
     }
     $arg_p = '\\w+';
     $op_p = '(?:\\|\\|)?=';
     $word_p = '\\S+';
     $opt_ws = '\\s*';
     $qq_p = '" ( (?:[^"\\\\]|\\\\.)* ) "';
     //"<--kludge for brain-dead syntax coloring
     $q_p = "' ( (?:[^'\\\\]|\\\\.)* ) '";
     $gt_p = "_\\( {$opt_ws} {$qq_p} {$opt_ws} \\)";
     $argspec_p = "({$arg_p}) {$opt_ws} ({$op_p}) {$opt_ws} (?: {$qq_p}|{$q_p}|{$gt_p}|({$word_p}))";
     // handle plugin-list arguments seperately
     $plugin_p = '<!plugin-list\\s+\\w+.*?!>';
     while (preg_match("/^({$arg_p}) {$opt_ws} ({$op_p}) {$opt_ws} ({$plugin_p}) {$opt_ws}/x", $argstr, $m)) {
         @(list(, $arg, $op, $plugin_val) = $m);
         $argstr = substr($argstr, strlen($m[0]));
         $loader = new WikiPluginLoader();
         $markup = null;
         $basepage = null;
         $plugin_val = preg_replace(array("/^<!/", "/!>\$/"), array("<?", "?>"), $plugin_val);
         $val = $loader->expandPI($plugin_val, $GLOBALS['request'], $markup, $basepage);
         if ($op == '=') {
             $args[$arg] = $val;
             // comma delimited pagenames or array()?
         } else {
             assert($op == '||=');
             $defaults[$arg] = $val;
         }
     }
     while (preg_match("/^{$opt_ws} {$argspec_p} {$opt_ws}/x", $argstr, $m)) {
         @(list(, $arg, $op, $qq_val, $q_val, $gt_val, $word_val) = $m);
         $argstr = substr($argstr, strlen($m[0]));
         // Remove quotes from string values.
         if ($qq_val) {
             $val = stripslashes($qq_val);
         } elseif ($q_val) {
             $val = stripslashes($q_val);
         } elseif ($gt_val) {
             $val = _(stripslashes($gt_val));
         } else {
             $val = $word_val;
         }
         if ($op == '=') {
             $args[$arg] = $val;
         } else {
             // NOTE: This does work for multiple args. Use the
             // separator character defined in your webserver
             // configuration, usually & or &amp; (See
             // http://www.htmlhelp.com/faq/cgifaq.4.html)
             // e.g. <plugin RecentChanges days||=1 show_all||=0 show_minor||=0>
             // url: RecentChanges?days=1&show_all=1&show_minor=0
             assert($op == '||=');
             $defaults[$arg] = $val;
         }
     }
     if ($argstr) {
         $this->handle_plugin_args_cruft($argstr, $args);
     }
     return array($args, $defaults);
 }
Esempio n. 11
0
function getPluginSynopsis($params)
{
    $ParamPlugin = $params->getParam(0);
    $pluginName = short_string_decode($ParamPlugin->scalarval());
    require_once "lib/WikiPlugin.php";
    $w = new WikiPluginLoader();
    $synopsis = '';
    $p = $w->getPlugin($pluginName, false);
    // second arg?
    // trap php files which aren't WikiPlugin~s: wikiplugin + wikiplugin_cached only
    if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
        $plugin_args = '';
        $desc = $p->getArgumentsDescription();
        $src = array("\n", '"', "'", '|', '[', ']', '\\');
        $replace = array('%0A', '%22', '%27', '%7C', '%5B', '%5D', '%5C');
        $desc = str_replace("<br />", ' ', $desc->asXML());
        if ($desc) {
            $plugin_args = '\\n' . str_replace($src, $replace, $desc);
        }
        $synopsis = "<?plugin " . $pluginName . $plugin_args . "?>";
        // args?
    }
    return new xmlrpcresp(short_string($synopsis));
}
Esempio n. 12
0
function actionPage(&$request, $action)
{
    global $WikiTheme;
    global $robots;
    $pagename = $request->getArg('pagename');
    $version = $request->getArg('version');
    $page = $request->getPage();
    $revision = $page->getCurrentRevision();
    $dbi = $request->getDbh();
    $actionpage = $dbi->getPage($action);
    $actionrev = $actionpage->getCurrentRevision();
    $pagetitle = HTML(fmt("%s: %s", $actionpage->getName(), $WikiTheme->linkExistingWikiWord($pagename, false, $version)));
    $request->setValidators(array('pageversion' => $revision->getVersion(), '%mtime' => $revision->get('mtime')));
    $request->appendValidators(array('pagerev' => $revision->getVersion(), '%mtime' => $revision->get('mtime')));
    $request->appendValidators(array('actionpagerev' => $actionrev->getVersion(), '%mtime' => $actionrev->get('mtime')));
    $transformedContent = $actionrev->getTransformedContent();
    /* Optionally tell google (and others) not to take notice of action pages.
          RecentChanges or AllPages might be an exception.
       */
    $args = array();
    if (GOOGLE_LINKS_NOFOLLOW) {
        $robots = "noindex,nofollow";
        $args = array('ROBOTS_META' => $robots);
    }
    /* Handle other formats: So far we had html only.
          xml is requested by loaddump, rss is handled by recentchanges,
          pdf is a special action, but should be a format to dump multiple pages
          if the actionpage plugin returns a pagelist.
          rdf and owl are handled by SemanticWeb.
       */
    $format = $request->getArg('format');
    /* At first the single page formats: html, xml */
    if ($pagename == _("LinkDatabase")) {
        $template = Template('browse', array('CONTENT' => $transformedContent));
        GeneratePage($template, $pagetitle, $revision, $args);
    } elseif (!$format or $format == 'html' or $format == 'sidebar' or $format == 'contribs') {
        $template = Template('browse', array('CONTENT' => $transformedContent));
        GeneratePage($template, $pagetitle, $revision, $args);
    } elseif ($format == 'xml') {
        $request->setArg('format', '');
        $template = new Template('browse', $request, array('revision' => $revision, 'CONTENT' => $transformedContent));
        $html = GeneratePageAsXML($template, $pagename, $revision);
        header("Content-Type: application/xhtml+xml; charset=" . $GLOBALS['charset']);
        echo $html;
    } else {
        $pagelist = null;
        require_once 'lib/WikiPlugin.php';
        // Then the multi-page formats
        // rss (if not already handled by RecentChanges)
        // Need the pagelist from the first plugin
        foreach ($transformedContent->_content as $cached_element) {
            if (is_a($cached_element, "Cached_PluginInvocation")) {
                $loader = new WikiPluginLoader();
                $markup = null;
                // return the first found pagelist
                $pagelist = $loader->expandPI($cached_element->_pi, $request, $markup, $pagename);
                if (is_a($pagelist, 'PageList')) {
                    break;
                }
            }
        }
        if (!$pagelist or !is_a($pagelist, 'PageList')) {
            if (!in_array($format, array("rss91", "rss2", "rss", "atom", "rdf"))) {
                trigger_error(sprintf("Format %s requires an actionpage returning a pagelist.", $format) . "\n" . "Fall back to single page mode", E_USER_WARNING);
            }
            require_once 'lib/PageList.php';
            $pagelist = new PageList();
            if ($format == 'pdf') {
                $pagelist->addPage($page);
            }
        } else {
            foreach ($pagelist->_pages as $page) {
                $name = $page->getName();
                if ($name != $pagename and $page->exists()) {
                    $args['VALID_LINKS'][] = $name;
                }
            }
        }
        if ($format == 'pdf') {
            require_once "lib/pdf.php";
            array_unshift($args['VALID_LINKS'], $pagename);
            ConvertAndDisplayPdfPageList($request, $pagelist, $args);
        } elseif ($format == 'ziphtml') {
            // need to fix links
            require_once 'lib/loadsave.php';
            array_unshift($args['VALID_LINKS'], $pagename);
            $request->setArg('zipname', FilenameForPage($pagename) . ".zip");
            $request->setArg('pages', $args['VALID_LINKS']);
            $request->setArg('format', '');
            MakeWikiZipHtml($request);
        } elseif (in_array($format, array("rss91", "rss2", "rss", "atom"))) {
            $args = $request->getArgs();
            //$request->setArg('format','');
            if ($pagename == _("RecentChanges")) {
                $template->printExpansion($args);
            } else {
                require_once "lib/plugin/RecentChanges.php";
                $plugin = new WikiPlugin_RecentChanges();
                return $plugin->format($plugin->getChanges($request->_dbi, $args), $args);
            }
        } elseif ($format == 'json') {
            // for faster autocompletion on searches
            $req_args =& $request->args;
            unset($req_args['format']);
            $json = array('count' => count($pagelist->_pages), 'list' => $args['VALID_LINKS'], 'args' => $req_args, 'phpwiki-version' => PHPWIKI_VERSION);
            if (loadPhpExtension('json')) {
                $json_enc = json_encode($json);
            } else {
                require_once "lib/pear/JSON.php";
                $j = new Services_JSON();
                $json_enc = $j->encode($json);
            }
            header("Content-Type: application/json");
            die($json_enc);
        } elseif ($format == 'rdf') {
            // all semantic relations and attributes
            require_once "lib/SemanticWeb.php";
            $rdf = new RdfWriter($request, $pagelist);
            $rdf->format();
        } elseif ($format == 'rdfs') {
            require_once "lib/SemanticWeb.php";
            $rdf = new RdfsWriter($request, $pagelist);
            $rdf->format();
        } elseif ($format == 'owl') {
            // or daml?
            require_once "lib/SemanticWeb.php";
            $rdf = new OwlWriter($request, $pagelist);
            $rdf->format();
        } else {
            if (!in_array($pagename, array(_("LinkDatabase")))) {
                trigger_error(sprintf(_("Unsupported argument: %s=%s"), "format", $format), E_USER_WARNING);
            }
            $template = Template('browse', array('CONTENT' => $transformedContent));
            GeneratePage($template, $pagetitle, $revision, $args);
        }
    }
    $request->checkValidators();
    flush();
    return '';
}
Esempio n. 13
0
function callPlugin($params)
{
    global $request;
    $dbi = $request->getDbh();
    $ParamPlugin = $params->getParam(0);
    $pluginName = short_string_decode($ParamPlugin->scalarval());
    $ParamArgs = $params->getParam(1);
    $plugin_args = short_string_decode($ParamArgs->scalarval());
    $basepage = '';
    //$pluginName;
    require_once "lib/WikiPlugin.php";
    $w = new WikiPluginLoader();
    $p = $w->getPlugin($pluginName, false);
    // second arg?
    $pagelist = $p->run($dbi, $plugin_args, $request, $basepage);
    $list = array();
    if (is_object($pagelist) and isa($pagelist, 'PageList')) {
        foreach ($pagelist->_pages as $page) {
            $list[] = $page->getName();
        }
    }
    return new xmlrpcresp(new xmlrpcval($list, "array"));
}
Esempio n. 14
0
 function pluginPulldown()
 {
     global $WikiTheme;
     global $AllAllowedPlugins;
     $plugin_dir = 'lib/plugin';
     if (defined('PHPWIKI_DIR')) {
         $plugin_dir = PHPWIKI_DIR . "/{$plugin_dir}";
     }
     $pd = new fileSet($plugin_dir, '*.php');
     $plugins = $pd->getFiles();
     unset($pd);
     sort($plugins);
     if (!empty($plugins)) {
         $plugin_js = '';
         require_once "lib/WikiPlugin.php";
         $w = new WikiPluginLoader();
         foreach ($plugins as $plugin) {
             $pluginName = str_replace(".php", "", $plugin);
             if (in_array($pluginName, $AllAllowedPlugins)) {
                 $p = $w->getPlugin($pluginName, false);
                 // second arg?
                 // trap php files which aren't WikiPlugin~s
                 if (strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
                     $plugin_args = '';
                     $desc = $p->getArgumentsDescription();
                     $src = array("\n", '"', "'", '|', '[', ']', '\\');
                     $replace = array('%0A', '%22', '%27', '%7C', '%5B', '%5D', '%5C');
                     $desc = str_replace("<br />", ' ', $desc->asXML());
                     if ($desc) {
                         $plugin_args = ' ' . str_replace($src, $replace, $desc);
                     }
                     $toinsert = "%0A<<" . $pluginName . $plugin_args . ">>";
                     // args?
                     $plugin_js .= ",['{$pluginName}','{$toinsert}']";
                 }
             }
         }
         $plugin_js = substr($plugin_js, 1);
         $more_buttons = HTML::img(array('class' => "toolbar", 'id' => 'tb-plugins', 'src' => $WikiTheme->getImageURL("ed_plugins.png"), 'title' => _("AddPlugin"), 'alt' => _("AddPlugin"), 'onclick' => "showPulldown('" . _("Insert Plugin") . "',[" . $plugin_js . "],'" . _("Insert") . "','" . _("Close") . "','tb-plugins')"));
         return HTML("\n", $more_buttons);
     }
     return '';
 }
Esempio n. 15
0
 function getHtml($dbi, $argarray, $request, $basepage)
 {
     $loader = new WikiPluginLoader();
     return $loader->expandPI('<?plugin RecentChanges ' . WikiPluginCached::glueArgs($argarray) . ' ?>', $request, $this, $basepage);
 }
Esempio n. 16
0
 function run($dbi, $argstr, &$request, $basepage)
 {
     //if ($request->getArg('action') != 'browse')
     //    return $this->disabled("(action != 'browse')");
     $args = $this->getArgs($argstr, $request);
     $this->_args = $args;
     extract($args);
     $this->preSelectS($args, $request);
     $info = $args['info'];
     $this->debug = $args['debug'];
     // array_multisort($this->_list, SORT_NUMERIC, SORT_DESC);
     $pagename = $request->getArg('pagename');
     // GetUrlToSelf() with all given params
     //$uri = $GLOBALS['HTTP_SERVER_VARS']['REQUEST_URI']; // without s would be better.
     //$uri = $request->getURLtoSelf();//false, array('verify'));
     $form = HTML::form(array('action' => $request->getPostURL(), 'method' => 'POST'));
     if ($request->getArg('WikiAdminSelect') == _("Go")) {
         $p = false;
     } else {
         $p = $request->getArg('p');
     }
     //$p = @$GLOBALS['HTTP_POST_VARS']['p'];
     $form->pushContent(HTML::p(array('class' => 'wikitext'), _("Select: "), HTML::input(array('type' => 'text', 'name' => 's', 'value' => $args['s'])), HTML::input(array('type' => 'submit', 'name' => 'WikiAdminSelect', 'value' => _("Go")))));
     if ($request->isPost() && !$request->getArg('wikiadmin') && !empty($p)) {
         $this->_list = array();
         // List all selected pages again.
         foreach ($p as $page => $name) {
             $this->_list[$name] = 1;
         }
     } elseif ($request->isPost() and $request->_user->isAdmin() and !empty($p) and $request->getArg('action') == 'WikiAdminSelect' and $request->getArg('wikiadmin')) {
         // handle external plugin
         $loader = new WikiPluginLoader();
         $a = array_keys($request->getArg('wikiadmin'));
         $plugin_action = $a[0];
         $single_arg_plugins = array("Remove");
         if (in_array($plugin_action, $single_arg_plugins)) {
             $plugin = $loader->getPlugin($plugin_action);
             $ul = HTML::ul();
             foreach ($p as $page => $name) {
                 $plugin_args = "run_page={$name}";
                 $request->setArg($plugin_action, 1);
                 $request->setArg('p', array($page => $name));
                 // if the plugin requires more args than the pagename,
                 // then this plugin will not return. (Rename, SearchReplace, ...)
                 $action_result = $plugin->run($dbi, $plugin_args, $request, $basepage);
                 $ul->pushContent(HTML::li(fmt("Selected page '%s' passed to '%s'.", $name, $select)));
                 $ul->pushContent(HTML::ul(HTML::li($action_result)));
             }
         } else {
             // redirect to the plugin page.
             // in which page is this plugin?
             $plugin_action = preg_replace("/^WikiAdmin/", "", $plugin_action);
             $args = array();
             foreach ($p as $page => $x) {
                 $args["p[{$page}]"] = 1;
             }
             header("Location: " . WikiURL(_("PhpWikiAdministration") . "/" . _($plugin_action), $args, 1));
             exit;
         }
     } elseif (empty($args['s'])) {
         // List all pages to select from.
         $this->_list = $this->collectPages($this->_list, $dbi, $args['sortby'], $args['limit']);
     }
     $pagelist = new PageList_Selectable($info, $args['exclude'], $args);
     $pagelist->addPageList($this->_list);
     $form->pushContent($pagelist->getContent());
     foreach ($args as $k => $v) {
         if (!in_array($k, array('s', 'WikiAdminSelect', 'action', 'verify'))) {
             $form->pushContent(HiddenInputs(array($k => $v)));
         }
         // plugin params
     }
     /*
     foreach ($_GET as $k => $v) {
         if (!in_array($k,array('s','WikiAdminSelect','action')))
             $form->pushContent(HiddenInputs(array($k => $v))); // debugging params, ...
     }
     */
     if (!$request->getArg('verify')) {
         $form->pushContent(HTML::input(array('type' => 'hidden', 'name' => 'action', 'value' => 'verify')));
         $form->pushContent(Button('submit:verify', _("Select pages"), 'wikiadmin'), Button('submit:cancel', _("Cancel"), 'button'));
     } else {
         global $WikiTheme;
         $form->pushContent(HTML::input(array('type' => 'hidden', 'name' => 'action', 'value' => 'WikiAdminSelect')));
         // Add the Buttons for all registered WikiAdmin plugins
         $plugin_dir = 'lib/plugin';
         if (defined('PHPWIKI_DIR')) {
             $plugin_dir = PHPWIKI_DIR . "/{$plugin_dir}";
         }
         $fs = new fileSet($plugin_dir, 'WikiAdmin*.php');
         $actions = $fs->getFiles();
         foreach ($actions as $f) {
             $f = preg_replace('/.php$/', '', $f);
             $s = preg_replace('/^WikiAdmin/', '', $f);
             if (!in_array($s, array("Select", "Utils"))) {
                 // disable Select and Utils
                 $form->pushContent(Button("submit:wikiadmin[{$f}]", _($s), "wikiadmin"));
                 $form->pushContent($WikiTheme->getButtonSeparator());
             }
         }
         $form->pushContent(Button('submit:cancel', _("Cancel"), 'button'));
     }
     if (!$request->getArg('select')) {
         return $form;
     } else {
         //return $action_result;
     }
 }
Esempio n. 17
0
 function _generateTableBody(&$info, &$dbi, &$request, &$table)
 {
     $plugin_dir = 'lib/plugin';
     if (defined('PHPWIKI_DIR')) {
         $plugin_dir = PHPWIKI_DIR . "/{$plugin_dir}";
     }
     $pd = new fileSet($plugin_dir, '*.php');
     $plugins = $pd->getFiles();
     unset($pd);
     sort($plugins);
     // table body
     $tbody = HTML::tbody();
     $row_no = 0;
     $w = new WikiPluginLoader();
     foreach ($plugins as $pluginName) {
         // instantiate a plugin
         $pluginName = str_replace(".php", "", $pluginName);
         $temppluginclass = "<? plugin {$pluginName} ?>";
         // hackish
         $p = $w->getPlugin($pluginName, false);
         // second arg?
         // trap php files which aren't WikiPlugin~s
         if (!strtolower(substr(get_parent_class($p), 0, 10)) == 'wikiplugin') {
             // Security: Hide names of extraneous files within
             // plugin dir from non-admins.
             if ($request->_user->isAdmin()) {
                 trigger_error(sprintf(_("%s does not appear to be a WikiPlugin."), $pluginName . ".php"));
             }
             continue;
             // skip this non WikiPlugin file
         }
         $desc = $p->getDescription();
         $ver = $p->getVersion();
         $arguments = $p->getArgumentsDescription();
         unset($p);
         //done querying plugin object, release from memory
         // This section was largely improved by Pierrick Meignen:
         // make a link if an actionpage exists
         $pluginNamelink = $pluginName;
         $pluginDocPageName = $pluginName . "Plugin";
         $pluginDocPageNamelink = false;
         $localizedPluginName = '';
         $localizedPluginDocPageName = '';
         if ($GLOBALS['LANG'] != "en") {
             if (_($pluginName) != $pluginName) {
                 $localizedPluginName = _($pluginName);
             }
             if ($localizedPluginName && $dbi->isWikiPage($localizedPluginName)) {
                 $pluginDocPageNamelink = WikiLink($localizedPluginName, 'if_known');
             }
             if (_($pluginDocPageName) != $pluginDocPageName) {
                 $localizedPluginDocPageName = _($pluginDocPageName);
             }
             if ($localizedPluginDocPageName && $dbi->isWikiPage($localizedPluginDocPageName)) {
                 $pluginDocPageNamelink = WikiLink($localizedPluginDocPageName, 'if_known');
             }
         } else {
             $pluginNamelink = WikiLink($pluginName, 'if_known');
             if ($dbi->isWikiPage($pluginDocPageName)) {
                 $pluginDocPageNamelink = WikiLink($pluginDocPageName, 'if_known');
             }
         }
         // highlight alternate rows
         $row_no++;
         $group = (int) ($row_no / 1);
         //_group_rows
         $class = $group % 2 ? 'evenrow' : 'oddrow';
         // generate table row
         $tr = HTML::tr(array('class' => $class));
         if ($pluginDocPageNamelink) {
             // plugin has a description page 'PluginName' . 'Plugin'
             $tr->pushContent(HTML::td($pluginNamelink, HTML::br(), $pluginDocPageNamelink));
             $pluginDocPageNamelink = false;
         } else {
             // plugin just has an actionpage
             $tr->pushContent(HTML::td($pluginNamelink));
         }
         $tr->pushContent(HTML::td($ver), HTML::td($desc));
         if ($info == 'args') {
             // add Arguments column
             $style = array('style' => 'font-family:monospace;font-size:smaller');
             $tr->pushContent(HTML::td($style, $arguments));
         }
         $tbody->pushContent($tr);
     }
     $table->pushContent($tbody);
 }
Esempio n. 18
0
 function handle_plugin_args_cruft($argstr, $args)
 {
     $allowed = array("editbox", "hidden", "checkbox", "radiobutton", "radio", "pulldown", "submit", "reset", "combobox");
     // no editbox[] = array(...) allowed (space)
     $arg_array = preg_split("/\n/", $argstr);
     // for security we should check this better
     $arg = '';
     for ($i = 0; $i < count($arg_array); $i++) {
         //TODO: we require an name=value pair here, but submit may go without also.
         if (preg_match("/^\\s*(" . join("|", $allowed) . ")\\[\\](.*)\$/", $arg_array[$i], $m)) {
             $name = $m[1];
             // one of the allowed input types
             $this->inputbox[][$name] = array();
             $j = count($this->inputbox) - 1;
             $curargs = trim($m[2]);
             // must match name=NAME and also value=<!plugin-list name !>
             while (preg_match("/^(\\w+)=((?:\".*\")|(?:\\w+)|(?:\"?<!plugin-list.+!>\"?))\\s*/", $curargs, $m)) {
                 $attr = $m[1];
                 $value = $m[2];
                 $curargs = substr($curargs, strlen($m[0]));
                 if (preg_match("/^\"(.*)\"\$/", $value, $m)) {
                     $value = $m[1];
                 }
                 if (in_array($name, array("pulldown", "checkbox", "radio", "radiobutton", "combobox")) and preg_match('/^<!plugin-list.+!>$/', $value, $m)) {
                     $loader = new WikiPluginLoader();
                     $markup = null;
                     $basepage = null;
                     $plugin_str = preg_replace(array("/^<!/", "/!>\$/"), array("<?", "?>"), $value);
                     // will return a pagelist object! pulldown,checkbox,radiobutton
                     $value = $loader->expandPI($plugin_str, $GLOBALS['request'], $markup, $basepage);
                     if (isa($value, 'PageList')) {
                         $value = $value->_pages;
                     } elseif (!is_array($value)) {
                         trigger_error(sprintf("Invalid argument %s ignored", htmlentities($arg_array[$i])), E_USER_WARNING);
                     }
                 } elseif (defined($value)) {
                     $value = constant($value);
                 }
                 $this->inputbox[$j][$name][$attr] = $value;
             }
             //trigger_error("not yet finished");
             //eval('$this->inputbox[]["'.$m[1].'"]='.$m[2].';');
         } else {
             trigger_error(sprintf("Invalid argument %s ignored", htmlentities($arg_array[$i])), E_USER_WARNING);
         }
     }
     return;
 }
Esempio n. 19
0
 function _arrayToTable($array, &$request)
 {
     $thead = HTML::thead();
     $label[0] = _("Wiki Name");
     $label[1] = _("Search");
     $thead->pushContent(HTML::tr(HTML::th($label[0]), HTML::th($label[1])));
     $tbody = HTML::tbody();
     $dbi = $request->getDbh();
     if ($array) {
         foreach ($array as $moniker => $interurl) {
             $monikertd = HTML::td(array('class' => 'interwiki-moniker'), $dbi->isWikiPage($moniker) ? WikiLink($moniker) : $moniker);
             $w = new WikiPluginLoader();
             $p = $w->getPlugin('ExternalSearch');
             $argstr = sprintf('url="%s"', addslashes($interurl));
             $searchtd = HTML::td($p->run($dbi, $argstr, $request, $basepage));
             $tbody->pushContent(HTML::tr($monikertd, $searchtd));
         }
     }
     $table = HTML::table();
     $table->setAttr('class', 'interwiki-map');
     $table->pushContent($thead);
     $table->pushContent($tbody);
     return $table;
 }
Esempio n. 20
0
 function action_lock()
 {
     $page = $this->getPage();
     $page->set('locked', true);
     $this->_dbi->touch();
     // check ModeratedPage hook
     if ($moderated = $page->get('moderated')) {
         require_once "lib/WikiPlugin.php";
         $plugin = WikiPluginLoader::getPlugin("ModeratedPage");
         if ($retval = $plugin->lock_check($this, $page, $moderated)) {
             $this->setArg('errormsg', $retval);
         }
     } elseif ($action_page = $page->existLink(_("ModeratedPage"))) {
         require_once "lib/WikiPlugin.php";
         $plugin = WikiPluginLoader::getPlugin("ModeratedPage");
         if ($retval = $plugin->lock_add($this, $page, $action_page)) {
             $this->setArg('errormsg', $retval);
         }
     }
     $this->action_browse();
 }
Esempio n. 21
0
function displayPage(&$request, $template = false)
{
    global $WikiTheme;
    $pagename = $request->getArg('pagename');
    $version = $request->getArg('version');
    $page = $request->getPage();
    if ($version) {
        $revision = $page->getRevision($version);
        if (!$revision) {
            NoSuchRevision($request, $page, $version);
        }
        /* Tell Google (and others) to ignore old versions of pages */
        $toks['ROBOTS_META'] = "noindex,nofollow";
    } else {
        $revision = $page->getCurrentRevision();
    }
    if (isSubPage($pagename)) {
        $pages = explode(SUBPAGE_SEPARATOR, $pagename);
        $last_page = array_pop($pages);
        // deletes last element from array as side-effect
        $pageheader = HTML::span(HTML::a(array('href' => WikiURL($pages[0]), 'class' => 'pagetitle'), $WikiTheme->maybeSplitWikiWord($pages[0] . SUBPAGE_SEPARATOR)));
        $first_pages = $pages[0] . SUBPAGE_SEPARATOR;
        array_shift($pages);
        foreach ($pages as $p) {
            $pageheader->pushContent(HTML::a(array('href' => WikiURL($first_pages . $p), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($p . SUBPAGE_SEPARATOR)));
            $first_pages .= $p . SUBPAGE_SEPARATOR;
        }
        $backlink = HTML::a(array('href' => WikiURL($pagename, array('action' => _("BackLinks"))), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($last_page));
        $backlink->addTooltip(sprintf(_("BackLinks for %s"), $pagename));
        $pageheader->pushContent($backlink);
    } else {
        $pageheader = HTML::a(array('href' => WikiURL($pagename, array('action' => _("BackLinks"))), 'class' => 'backlinks'), $WikiTheme->maybeSplitWikiWord($pagename));
        $pageheader->addTooltip(sprintf(_("BackLinks for %s"), $pagename));
        if ($request->getArg('frame')) {
            $pageheader->setAttr('target', '_top');
        }
    }
    $pagetitle = SplitPagename($pagename);
    if ($redirect_from = $request->getArg('redirectfrom')) {
        $redirect_message = HTML::span(array('class' => 'redirectfrom'), fmt("(Redirected from %s)", RedirectorLink($redirect_from)));
        // abuse the $redirected template var for some status update notice
    } elseif ($request->getArg('errormsg')) {
        $redirect_message = $request->getArg('errormsg');
        $request->setArg('errormsg', false);
    }
    $request->appendValidators(array('pagerev' => $revision->getVersion(), '%mtime' => $revision->get('mtime')));
    /*
        // FIXME: This is also in the template...
        if ($request->getArg('action') != 'pdf' and !headers_sent()) {
          // FIXME: enable MathML/SVG/... support
          if (ENABLE_XHTML_XML
                 and (!isBrowserIE()
                      and strstr($request->get('HTTP_ACCEPT'),'application/xhtml+xml')))
                header("Content-Type: application/xhtml+xml; charset=" . $GLOBALS['charset']);
            else
                header("Content-Type: text/html; charset=" . $GLOBALS['charset']);
        }
    */
    $page_content = $revision->getTransformedContent();
    // if external searchengine (google) referrer, highlight the searchterm
    // FIXME: move that to the transformer?
    // OR: add the searchhightplugin line to the content?
    if ($result = isExternalReferrer($request)) {
        if (DEBUG and !empty($result['query'])) {
            //$GLOBALS['SearchHighlightQuery'] = $result['query'];
            /* simply add the SearchHighlight plugin to the top of the page. 
               This just parses the wikitext, and doesn't highlight the markup */
            include_once 'lib/WikiPlugin.php';
            $loader = new WikiPluginLoader();
            $xml = $loader->expandPI('<' . '?plugin SearchHighlight s="' . $result['query'] . '"?' . '>', $request, $markup);
            if ($xml and is_array($xml)) {
                foreach (array_reverse($xml) as $line) {
                    array_unshift($page_content->_content, $line);
                }
                array_unshift($page_content->_content, HTML::div(_("You searched for: "), HTML::strong($result['query'])));
            }
            if (0) {
                /* Parse the transformed (mixed HTML links + strings) lines?
                     This looks like overkill.
                   */
                require_once "lib/TextSearchQuery.php";
                $query = new TextSearchQuery($result['query']);
                $hilight_re = $query->getHighlightRegexp();
                //$matches = preg_grep("/$hilight_re/i", $revision->getContent());
                // FIXME!
                for ($i = 0; $i < count($page_content->_content); $i++) {
                    $found = false;
                    $line = $page_content->_content[$i];
                    if (is_string($line)) {
                        while (preg_match("/^(.*?)({$hilight_re})/i", $line, $m)) {
                            $found = true;
                            $line = substr($line, strlen($m[0]));
                            $html[] = $m[1];
                            // prematch
                            $html[] = HTML::strong(array('class' => 'search-term'), $m[2]);
                            // match
                        }
                    }
                    if ($found) {
                        $html[] = $line;
                        // postmatch
                        $page_content->_content[$i] = HTML::span(array('class' => 'search-context'), $html);
                    }
                }
            }
        }
    }
    /* Check for special pagenames */
    /*
    if ( $pagename == _("RecentChanges") 
         || $pagename == _("RecentEdits")
         || $pagename == _("RecentVisitors")) {
        $toks['ROBOTS_META']="noindex,follow";
    } else
    */
    if ($pagename == _("SandBox")) {
        $toks['ROBOTS_META'] = "noindex,nofollow";
    } else {
        if (!isset($toks['ROBOTS_META'])) {
            $toks['ROBOTS_META'] = "index,follow";
        }
    }
    $toks['CONTENT'] = new Template('browse', $request, $page_content);
    $toks['TITLE'] = $pagetitle;
    // <title> tag
    $toks['HEADER'] = $pageheader;
    // h1 with backlink
    $toks['revision'] = $revision;
    if (!empty($redirect_message)) {
        $toks['redirected'] = $redirect_message;
    }
    $toks['PAGE_DESCRIPTION'] = $page_content->getDescription();
    $toks['PAGE_KEYWORDS'] = GleanKeywords($page);
    if (!$template) {
        $template = new Template('html', $request);
    }
    $template->printExpansion($toks);
    $page->increaseHitCount();
    if ($request->getArg('action') != 'pdf') {
        $request->checkValidators();
    }
    flush();
}