/** Set the cache control headers in the HTTP response. */ function cacheControl($strategy = CACHE_CONTROL, $max_age = CACHE_CONTROL_MAX_AGE) { if ($strategy == 'NO_CACHE') { $cache_control = "no-cache"; // better set private. See Pear HTTP_Header $max_age = -20; } elseif ($strategy == 'ALLOW_STALE' && $max_age > 0) { $cache_control = sprintf("max-age=%d", $max_age); } else { $cache_control = "must-revalidate"; $max_age = -20; } header("Cache-Control: {$cache_control}"); header("Expires: " . Rfc1123DateTime(time() + $max_age)); header("Vary: Cookie"); // FIXME: add more here? }
function displayPage(&$request, $template = false) { global $WikiTheme; global $robots; $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 */ $robots = "noindex,nofollow"; $toks['ROBOTS_META'] = $robots; } else { $revision = $page->getCurrentRevision(); } $format = $request->getArg('format'); if ($format == 'xml') { // fast ajax: include page content asynchronously global $charset; header("Content-Type: text/xml"); echo "<", "?xml version=\"1.0\" encoding=\"{$charset}\"?", ">\n"; // DOCTYPE html needed to allow unencoded entities like without !CDATA[] echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">', "\n"; if ($page->exists()) { header("Last-Modified: " . Rfc1123DateTime($revision->get('mtime'))); $request->cacheControl(); $request->setArg('format', ''); $page_content = $revision->getTransformedContent(); $page_content->printXML(); $request->_is_buffering_output = false; // avoid wrong Content-Length with errors $request->finish(); } else { $request->cacheControl(); echo '<div style="display:none;" />'; $request->_is_buffering_output = false; // avoid wrong Content-Length with errors $request->finish(); exit; } } 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']); } */ $toks['TITLE'] = $pagetitle; // <title> tag $toks['HEADER'] = $pageheader; // h1 with backlink $toks['revision'] = $revision; // On external searchengine (google) referrer, highlight the searchterm and // pass through the Searchhighlight actionpage. if ($result = isExternalReferrer($request)) { if (!empty($result['query'])) { if (ENABLE_SEARCHHIGHLIGHT) { $request->_searchhighlight = $result; $request->appendValidators(array('%mtime' => time())); // force no cache(?) // Should be changed to check the engine and search term only // $request->setArg('nocache', 1); $page_content = new TransformedText($revision->getPage(), $revision->getPackedContent(), $revision->getMetaData()); /* Now add the SearchHighlight plugin to the top of the page, in memory only. You can parametrize this by changing the SearchHighlight action page. */ if ($actionpage = $request->findActionPage('SearchHighlight')) { $actionpage = $request->getPage($actionpage); $actionrev = $actionpage->getCurrentRevision(); $pagetitle = HTML(fmt("%s: %s", $actionpage->getName(), $WikiTheme->linkExistingWikiWord($pagename, false, $version))); $request->appendValidators(array('actionpagerev' => $actionrev->getVersion(), '%mtime' => $actionrev->get('mtime'))); $toks['SEARCH_ENGINE'] = $result['engine']; $toks['SEARCH_ENGINE_URL'] = $result['engine_url']; $toks['SEARCH_TERM'] = $result['query']; //$toks['HEADER'] = HTML($actionpage->getName(),": ",$pageheader); // h1 with backlink $actioncontent = new TransformedText($actionrev->getPage(), $actionrev->getPackedContent(), $actionrev->getMetaData()); // prepend the actionpage in front of the hightlighted content $toks['CONTENT'] = HTML($actioncontent, $page_content); } } } else { $page_content = $revision->getTransformedContent(); } } else { $page_content = $revision->getTransformedContent(); } /* Check for special pagenames, which are no actionpages. */ /* if ( $pagename == _("RecentVisitors")) { $robots = "noindex,follow"; $toks['ROBOTS_META'] = $robots; } else */ if ($pagename == _("SandBox")) { $robots = "noindex,nofollow"; $toks['ROBOTS_META'] = $robots; } else { if (isActionPage($pagename)) { // AllPages must not be indexed, but must be followed to get all pages $robots = "noindex,follow"; $toks['ROBOTS_META'] = $robots; } else { if (!isset($toks['ROBOTS_META'])) { $robots = "index,follow"; $toks['ROBOTS_META'] = $robots; } } } if (!isset($toks['CONTENT'])) { $toks['CONTENT'] = new Template('browse', $request, $page_content); } if (!empty($redirect_message)) { $toks['redirected'] = $redirect_message; } // Massive performance problem parsing at run-time into all xml objects // looking for p's. Should be optional, if not removed at all. //$toks['PAGE_DESCRIPTION'] = $page_content->getDescription(); $toks['PAGE_KEYWORDS'] = GleanKeywords($page); if (!$template) { $template = new Template('html', $request); } // 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, owl, kbmodel, daml, ... are handled by SemanticWeb. /* Only single page versions. rss only if not already handled by RecentChanges. */ if (!$format or $format == 'html' or $format == 'sidebar' or $format == 'contribs') { $template->printExpansion($toks); } else { // No pagelist here. Single page version only require_once "lib/PageList.php"; $pagelist = new PageList(); $pagelist->addPage($page); if ($format == 'pdf') { require_once "lib/pdf.php"; $request->setArg('format', ''); ConvertAndDisplayPdfPageList($request, $pagelist); // time-sorted rdf a la RecentChanges } elseif (in_array($format, array("rss91", "rss2", "rss", "atom"))) { //$request->setArg('format',''); if ($pagename == _("RecentChanges")) { $template->printExpansion($toks); } else { require_once "lib/plugin/RecentChanges.php"; $plugin = new WikiPlugin_RecentChanges(); $args = $request->getArgs(); return $plugin->format($plugin->getChanges($request->_dbi, $args), $args); } } elseif ($format == 'rdf') { // all semantic relations and attributes require_once "lib/SemanticWeb.php"; $rdf = new RdfWriter($request, $pagelist); $rdf->format(); } elseif ($format == 'owl') { // or daml? require_once "lib/SemanticWeb.php"; $rdf = new OwlWriter($request, $pagelist); $rdf->format(); } elseif ($format == 'json') { // include page content asynchronously $request->setArg('format', ''); if ($page->exists()) { $content = $page_content->asXML(); } else { $content = ''; } $req_args = $request->args; unset($req_args['format']); // no meta-data so far, just the content $json = array('content' => $content, '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); } else { if (!in_array($pagename, array(_("LinkDatabase")))) { trigger_error(sprintf(_("Unsupported argument: %s=%s"), "format", $format), E_USER_WARNING); } $template->printExpansion($toks); } } $page->increaseHitCount(); if ($request->getArg('action') != 'pdf') { $request->checkValidators(); flush(); } return ''; }