private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); if ($request->getCookie('forceHTTPS') && $request->detectProtocol() == 'http' && $request->getMethod() == 'GET') { $redirUrl = $request->getFullRequestURL(); $redirUrl = str_replace('http://', 'https://', $redirUrl); // Setup dummy Title, otherwise OutputPage::redirect will fail $title = Title::newFromText(NS_MAIN, 'REDIR'); $this->context->setTitle($title); $output = $this->context->getOutput(); $output->redirect($redirUrl); $output->output(); wfProfileOut(__METHOD__); return; } // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things $title = Title::makeTitle(NS_MAIN, 'AJAX'); $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } $this->performRequest(); // Now commit any transactions, so that unreported errors after // output() don't roll back the whole DB transaction wfGetLBFactory()->commitMasterChanges(); // Output everything! $this->context->getOutput()->output(); wfProfileOut(__METHOD__); }
/** * checkLastModified returns true if it has taken care of all * output to the client that is necessary for this request. * (that is, it has sent a cached version of the page) * * @return boolean true if cached version send, false otherwise */ protected function tryFileCache() { static $called = false; if ($called) { wfDebug("Article::tryFileCache(): called twice!?\n"); return false; } $called = true; if ($this->isFileCacheable()) { $cache = HTMLFileCache::newFromTitle($this->getTitle(), 'view'); if ($cache->isCacheGood($this->mPage->getTouched())) { wfDebug("Article::tryFileCache(): about to load file\n"); $cache->loadFromFileCache($this->getContext()); return true; } else { wfDebug("Article::tryFileCache(): starting buffer\n"); ob_start(array(&$cache, 'saveToFileCache')); } } else { wfDebug("Article::tryFileCache(): not cacheable\n"); } return false; }
/** * Print the history page for an article. */ function onView() { $out = $this->getOutput(); $request = $this->getRequest(); /** * Allow client caching. */ if ($out->checkLastModified($this->page->getTouched())) { return; // Client cache fresh and headers sent, nothing more to do. } wfProfileIn(__METHOD__); $this->preCacheMessages(); $config = $this->context->getConfig(); # Fill in the file cache if not set already $useFileCache = $config->get('UseFileCache'); if ($useFileCache && HTMLFileCache::useFileCache($this->getContext())) { $cache = HTMLFileCache::newFromTitle($this->getTitle(), 'history'); if (!$cache->isCacheGood()) { ob_start(array(&$cache, 'saveToFileCache')); } } // Setup page variables. $out->setFeedAppendQuery('action=history'); $out->addModules('mediawiki.action.history'); if ($config->get('UseMediaWikiUIEverywhere')) { $out = $this->getOutput(); $out->addModuleStyles(array('mediawiki.ui.input', 'mediawiki.ui.checkbox')); } // Handle atom/RSS feeds. $feedType = $request->getVal('feed'); if ($feedType) { $this->feed($feedType); wfProfileOut(__METHOD__); return; } // Fail nicely if article doesn't exist. if (!$this->page->exists()) { $out->addWikiMsg('nohistory'); # show deletion/move log if there is an entry LogEventsList::showLogExtract($out, array('delete', 'move'), $this->getTitle(), '', array('lim' => 10, 'conds' => array("log_action != 'revision'"), 'showIfEmpty' => false, 'msgKey' => array('moveddeleted-notice'))); wfProfileOut(__METHOD__); return; } /** * Add date selector to quickly get to a certain time */ $year = $request->getInt('year'); $month = $request->getInt('month'); $tagFilter = $request->getVal('tagfilter'); $tagSelector = ChangeTags::buildTagFilterSelector($tagFilter); /** * Option to show only revisions that have been (partially) hidden via RevisionDelete */ if ($request->getBool('deleted')) { $conds = array('rev_deleted != 0'); } else { $conds = array(); } if ($this->getUser()->isAllowed('deletedhistory')) { $checkDeleted = Xml::checkLabel($this->msg('history-show-deleted')->text(), 'deleted', 'mw-show-deleted-only', $request->getBool('deleted')) . "\n"; } else { $checkDeleted = ''; } // Add the general form $action = htmlspecialchars(wfScript()); $out->addHTML("<form action=\"{$action}\" method=\"get\" id=\"mw-history-searchform\">" . Xml::fieldset($this->msg('history-fieldset-title')->text(), false, array('id' => 'mw-history-search')) . Html::hidden('title', $this->getTitle()->getPrefixedDBkey()) . "\n" . Html::hidden('action', 'history') . "\n" . Xml::dateMenu($year == null ? MWTimestamp::getLocalInstance()->format('Y') : $year, $month) . ' ' . ($tagSelector ? implode(' ', $tagSelector) . ' ' : '') . $checkDeleted . Xml::submitButton($this->msg('allpagessubmit')->text()) . "\n" . '</fieldset></form>'); wfRunHooks('PageHistoryBeforeList', array(&$this->page, $this->getContext())); // Create and output the list. $pager = new HistoryPager($this, $year, $month, $tagFilter, $conds); $out->addHTML($pager->getNavigationBar() . $pager->getBody() . $pager->getNavigationBar()); $out->preventClickjacking($pager->getPreventClickjacking()); wfProfileOut(__METHOD__); }
private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things $title = Title::makeTitle(NS_MAIN, 'AJAX'); $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; // If the user has forceHTTPS set to true, or if the user // is in a group requiring HTTPS, or if they have the HTTPS // preference set, redirect them to HTTPS. // Note: Do this after $wgTitle is setup, otherwise the hooks run from // isLoggedIn() will do all sorts of weird stuff. if (($request->getCookie('forceHTTPS', '') || $request->getCookie('forceHTTPS') || $this->context->getUser()->isLoggedIn() && $this->context->getUser()->requiresHTTPS()) && $request->getProtocol() == 'http') { $oldUrl = $request->getFullRequestURL(); $redirUrl = str_replace('http://', 'https://', $oldUrl); if ($request->wasPosted()) { // This is weird and we'd hope it almost never happens. This // means that a POST came in via HTTP and policy requires us // redirecting to HTTPS. It's likely such a request is going // to fail due to post data being lost, but let's try anyway // and just log the instance. // // @todo @fixme See if we could issue a 307 or 308 here, need // to see how clients (automated & browser) behave when we do wfDebugLog('RedirectedPosts', "Redirected from HTTP to HTTPS: {$oldUrl}"); } // Setup dummy Title, otherwise OutputPage::redirect will fail $title = Title::newFromText(NS_MAIN, 'REDIR'); $this->context->setTitle($title); $output = $this->context->getOutput(); // Since we only do this redir to change proto, always send a vary header $output->addVaryHeader('X-Forwarded-Proto'); $output->redirect($redirUrl); $output->output(); wfProfileOut(__METHOD__); return; } if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff // Assume we're viewing the latest revision (this should always be the case with file cache) $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } // Actually do the work of the request and build up any output $this->performRequest(); // Either all DB and deferred updates should happen or none. // The later should not be cancelled due to client disconnect. ignore_user_abort(true); // Now commit any transactions, so that unreported errors after // output() don't roll back the whole DB transaction wfGetLBFactory()->commitMasterChanges(); // Output everything! $this->context->getOutput()->output(); wfProfileOut(__METHOD__); }
public function execute() { global $wgUseFileCache, $wgReadOnly, $wgContentNamespaces, $wgRequestTime; global $wgOut; if (!$wgUseFileCache) { $this->error("Nothing to do -- \$wgUseFileCache is disabled.", true); } $wgReadOnly = 'Building cache'; // avoid DB writes (like enotif/counters) $start = $this->getOption('start', "0"); if (!ctype_digit($start)) { $this->error("Invalid value for start parameter.", true); } $start = intval($start); $end = $this->getOption('end', "0"); if (!ctype_digit($end)) { $this->error("Invalid value for end parameter.", true); } $end = intval($end); $this->output("Building content page file cache from page {$start}!\n"); $dbr = $this->getDB(DB_SLAVE); $overwrite = $this->getOption('overwrite', false); $start = $start > 0 ? $start : $dbr->selectField('page', 'MIN(page_id)', false, __FUNCTION__); $end = $end > 0 ? $end : $dbr->selectField('page', 'MAX(page_id)', false, __FUNCTION__); if (!$start) { $this->error("Nothing to do.", true); } $_SERVER['HTTP_ACCEPT_ENCODING'] = 'bgzip'; // hack, no real client # Do remaining chunk $end += $this->mBatchSize - 1; $blockStart = $start; $blockEnd = $start + $this->mBatchSize - 1; $dbw = $this->getDB(DB_MASTER); // Go through each page and save the output while ($blockEnd <= $end) { // Get the pages $res = $dbr->select('page', array('page_namespace', 'page_title', 'page_id'), array('page_namespace' => $wgContentNamespaces, "page_id BETWEEN {$blockStart} AND {$blockEnd}"), array('ORDER BY' => 'page_id ASC', 'USE INDEX' => 'PRIMARY')); $this->beginTransaction($dbw, __METHOD__); // for any changes foreach ($res as $row) { $rebuilt = false; $wgRequestTime = microtime(true); # bug 22852 $title = Title::makeTitleSafe($row->page_namespace, $row->page_title); if (null == $title) { $this->output("Page {$row->page_id} has bad title\n"); continue; // broken title? } $context = new RequestContext(); $context->setTitle($title); $article = Article::newFromTitle($title, $context); $context->setWikiPage($article->getPage()); $wgOut = $context->getOutput(); // set display title // If the article is cacheable, then load it if ($article->isFileCacheable()) { $cache = HTMLFileCache::newFromTitle($title, 'view'); if ($cache->isCacheGood()) { if ($overwrite) { $rebuilt = true; } else { $this->output("Page {$row->page_id} already cached\n"); continue; // done already! } } ob_start(array(&$cache, 'saveToFileCache')); // save on ob_end_clean() $wgUseFileCache = false; // hack, we don't want $article fiddling with filecache $article->view(); MediaWiki\suppressWarnings(); // header notices $wgOut->output(); MediaWiki\restoreWarnings(); $wgUseFileCache = true; ob_end_clean(); // clear buffer if ($rebuilt) { $this->output("Re-cached page {$row->page_id}\n"); } else { $this->output("Cached page {$row->page_id}\n"); } } else { $this->output("Page {$row->page_id} not cacheable\n"); } } $this->commitTransaction($dbw, __METHOD__); // commit any changes (just for sanity) $blockStart += $this->mBatchSize; $blockEnd += $this->mBatchSize; } $this->output("Done!\n"); }
/** * @return string */ private function fileCachedPage() { $context = RequestContext::getMain(); if ($context->getOutput()->isDisabled()) { // Done already? return ''; } if ($context->getTitle()) { // Use the main context's title if we managed to set it $t = $context->getTitle()->getPrefixedDBkey(); } else { // Fallback to the raw title URL param. We can't use the Title // class is it may hit the interwiki table and give a DB error. // We may get a cache miss due to not sanitizing the title though. $t = str_replace(' ', '_', $context->getRequest()->getVal('title')); if ($t == '') { // fallback to main page $t = Title::newFromText($this->msg('mainpage', 'Main Page'))->getPrefixedDBkey(); } } $cache = HTMLFileCache::newFromTitle($t, 'view'); if ($cache->isCached()) { return $cache->fetchText(); } else { return ''; } }
/** * @return string */ private function fileCachedPage() { global $wgTitle, $wgOut, $wgRequest; if ($wgOut->isDisabled()) { return ''; // Done already? } if ($wgTitle) { // use $wgTitle if we managed to set it $t = $wgTitle->getPrefixedDBkey(); } else { # Fallback to the raw title URL param. We can't use the Title # class is it may hit the interwiki table and give a DB error. # We may get a cache miss due to not sanitizing the title though. $t = str_replace(' ', '_', $wgRequest->getVal('title')); if ($t == '') { // fallback to main page $t = Title::newFromText($this->msg('mainpage', 'Main Page'))->getPrefixedDBkey(); } } $cache = HTMLFileCache::newFromTitle($t, 'view'); if ($cache->isCached()) { return $cache->fetchText(); } else { return ''; } }
private function main() { global $wgUseFileCache, $wgTitle, $wgUseAjax; wfProfileIn(__METHOD__); $request = $this->context->getRequest(); // Send Ajax requests to the Ajax dispatcher. if ($wgUseAjax && $request->getVal('action', 'view') == 'ajax') { // Set a dummy title, because $wgTitle == null might break things // Wikia change - start // @author macbre, wladek $title = Wikia::createTitleFromRequest($request); // Wikia change - end $this->context->setTitle($title); $wgTitle = $title; $dispatcher = new AjaxDispatcher(); $dispatcher->performAction(); wfProfileOut(__METHOD__); return; } // Get title from request parameters, // is set on the fly by parseTitle the first time. $title = $this->getTitle(); $action = $this->getAction(); $wgTitle = $title; if ($wgUseFileCache && $title->getNamespace() >= 0) { wfProfileIn('main-try-filecache'); if (HTMLFileCache::useFileCache($this->context)) { // Try low-level file cache hit $cache = HTMLFileCache::newFromTitle($title, $action); if ($cache->isCacheGood()) { // Check incoming headers to see if client has this cached $timestamp = $cache->cacheTimestamp(); if (!$this->context->getOutput()->checkLastModified($timestamp)) { $cache->loadFromFileCache($this->context); } // Do any stats increment/watchlist stuff $this->context->getWikiPage()->doViewUpdates($this->context->getUser()); // Tell OutputPage that output is taken care of $this->context->getOutput()->disable(); wfProfileOut('main-try-filecache'); wfProfileOut(__METHOD__); return; } } wfProfileOut('main-try-filecache'); } $this->performRequest(); $this->finalCleanup(); wfProfileOut(__METHOD__); }