function view($usecache = true) { global $wgUser, $wgOut; $fname = 'NewsFeedPage::view'; wfDebug("{$fname}: start\n"); $note = ''; $ims = @$_SERVER['HTTP_IF_MODIFIED_SINCE']; //TODO: cache control! if ($ims && $usecache) { $lastchange = wfTimestamp(TS_UNIX, NewsRenderer::getLastChangeTime()); wfDebug("{$fname}: checking cache-ok: IMS {$ims} vs. changed {$lastchange} \n"); if ($wgOut->checkLastModified($lastchange)) { wfDebug("{$fname}: HTTP cache ok, 304 header sent \n"); return; // done, 304 header sent. } } //NOTE: do caching for anon users only, because of user-specific // rendering of textual content if ($wgUser->isAnon() && $usecache) { $cachekey = $this->getCacheKey(); $ocache = wfGetParserCacheStorage(); $e = $ocache ? $ocache->get($cachekey) : null; $note .= ' anon;'; $debug = $e ? "got cached" : "no cached"; wfDebug("{$fname}: ({$debug}) \n"); } else { if (!$usecache) { wfDebug("{$fname}: purge, ignoring cache \n"); $note .= ' purged;'; } else { wfDebug("{$fname}: logged in, ignoring cache \n"); $note .= ' user;'; } $cachekey = null; $ocache = null; $e = null; $note .= ' user;'; } $wgOut->disable(); if ($e) { if (!isset($lastchange)) { $lastchange = wfTimestamp(TS_UNIX, NewsRenderer::getLastChangeTime()); } $last = wfTimestamp(TS_UNIX, $lastchange); if ($last < $e['timestamp']) { wfDebug("{$fname}: outputting cached copy ({$cacheKey}): {$last} < " . $e['timestamp'] . " \n"); header('Content-Type: application/' . $this->mFeedFormat . '+xml; charset=UTF-8'); print $e['xml']; print "\n<!-- cached: {$note} -->\n"; return; //done } else { wfDebug("{$fname}: found stale cached copy ({$cacheKey}): {$last} <= " . $e['timestamp'] . " \n"); $note .= " stale: {$last} >= {$e['timestamp']};"; } } //TODO: fetch actual news data and check the newest item. re-apply cache checks. // this would still save the cost of rendering if the data didn't change global $wgParser; //evil global $wgParser->startExternalParse($this->mTitle, new ParserOptions(), Parser::OT_HTML, true); //FIXME: an EXTREMELY ugly hack to force generation of absolute links. // this is needed because Title::getLocalUrl check wgRequest to see // if absolute urls are requested, instead of it being a parser option. $_REQUEST['action'] = 'render'; $renderer = NewsRenderer::newFromArticle($this, $wgParser); if (!$renderer) { wfDebug("{$fname}: no feed found on page: " . $this->mTitle->getPrefixedText() . "\n"); wfHttpError(404, "Not Found", "no feed found on page: " . $this->mTitle->getPrefixedText()); //TODO: better code & text return; } $description = ''; //TODO: grab from article content... but what? and how? $ts = time(); //this also sends the right headers $xml = $renderer->renderFeed($this->mFeedFormat, $description); wfDebug("{$fname}: rendered feed \n"); $e = array('xml' => $xml, 'timestamp' => $ts); if ($ocache) { wfDebug("{$fname}: caching feed ({$cachekey}) \n"); $ocache->set($cachekey, $e, $ts + 24 * 60 * 60); //cache for max 24 hours; cached record is discarded when anything turns up in RC anyway. $note .= ' updated;'; } wfDebug("{$fname}: outputting fresh feed \n"); header('Content-Type: application/' . $this->mFeedFormat . '+xml; charset=UTF-8'); print $xml; print "\n<!-- fresh: {$note} -->\n"; }
function wfNewsSkinTemplateOutputPageBeforeExec($skin, $tpl) { $feeds = $tpl->data['feeds']; if (!$feeds) { return true; } $title = $skin->getTitle(); //hack... foreach ($feeds as $format => $e) { $e['href'] = NewsRenderer::getFeedURL($title, $format); $feeds[$format] = $e; } $tpl->setRef('feeds', $feeds); return true; }