$parserCache = ParserCache::singleton();
$wgOut->setETag( $parserCache->getETag($this,$wgUser) );
}
- if( $wgOut->checkLastModified( $this->getTouched() ) ){
+ if( $wgOut->checkLastModified( $this->getTouched() ) ) {
wfProfileOut( __METHOD__ );
return;
} else if( $this->tryFileCache() ) {
/**
* Do standard deferred updates after page view
*/
- protected function viewUpdates() {
- global $wgDeferredUpdateList, $wgUser;
- if( 0 != $this->getID() ) {
- # Don't update page view counters on views from bot users (bug 14044)
- global $wgDisableCounters;
- if( !$wgDisableCounters && !$wgUser->isAllowed( 'bot' ) ) {
- Article::incViewCount( $this->getID() );
- $u = new SiteStatsUpdate( 1, 0, 0 );
- array_push( $wgDeferredUpdateList, $u );
- }
+ public function viewUpdates() {
+ global $wgDeferredUpdateList, $wgDisableCounters, $wgUser;
+ # Don't update page view counters on views from bot users (bug 14044)
+ if( !$wgDisableCounters && !$wgUser->isAllowed('bot') && $this->getID() ) {
+ Article::incViewCount( $this->getID() );
+ $u = new SiteStatsUpdate( 1, 0, 0 );
+ array_push( $wgDeferredUpdateList, $u );
}
# Update newtalk / watchlist notification status
$wgUser->clearNotification( $this->mTitle );
* @return bool
*/
public function isFileCacheable() {
- global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest, $wgLang, $wgContLang;
- // Get all query values
- $queryVals = $wgRequest->getValues();
- foreach( $queryVals as $query => $val ) {
- // Normal page view in query form can have action=view
- if( $query !== 'title' && $query !== 'curid' && !($query == 'action' && $val == 'view') ) {
- return false;
+ $cacheable = false;
+ if( HTMLFileCache::useFileCache() ) {
+ $cacheable = $this->getID() && !$this->mRedirectedFrom;
+ // Extension may have reason to disable file caching on some pages.
+ if( $cacheable ) {
+ $cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) );
}
}
- // Check for non-standard user language; this covers uselang,
- // and extensions for auto-detecting user language.
- $ulang = $wgLang->getCode();
- $clang = $wgContLang->getCode();
-
- $cacheable = $wgUseFileCache
- && !$wgShowIPinHeader
- && $this->getID() > 0
- && $wgUser->isAnon()
- && !$wgUser->getNewtalk()
- && !$this->mRedirectedFrom
- && $ulang === $clang;
- // Extension may have reason to disable file caching on some pages.
- if( $cacheable ) {
- $cacheable = wfRunHooks( 'IsFileCacheable', array( &$this ) );
- }
return $cacheable;
}
class HTMLFileCache {
var $mTitle, $mFileCache;
- function HTMLFileCache( &$title ) {
+ public function __construct( &$title ) {
$this->mTitle = $title;
$this->mFileCache = $this->fileCacheName();
}
- function fileCacheName() {
+ public function fileCacheName() {
global $wgFileCacheDirectory;
if( !$this->mFileCache ) {
$key = $this->mTitle->getPrefixedDbkey();
return $this->mFileCache;
}
- function isFileCached() {
+ public function isFileCached() {
return file_exists( $this->fileCacheName() );
}
- function fileCacheTime() {
+ public function fileCacheTime() {
return wfTimestamp( TS_MW, filemtime( $this->fileCacheName() ) );
}
+
+ /**
+ * Check if pages can be cached for this request/user
+ * @return bool
+ */
+ public static function useFileCache() {
+ global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest, $wgLang, $wgContLang;
+ if( !$wgUseFileCache )
+ return false;
+ // Get all query values
+ $queryVals = $wgRequest->getValues();
+ foreach( $queryVals as $query => $val ) {
+ // Normal page view in query form can have action=view
+ if( $query !== 'title' && $query !== 'curid' && !($query == 'action' && $val == 'view') ) {
+ return false;
+ }
+ }
+ // Check for non-standard user language; this covers uselang,
+ // and extensions for auto-detecting user language.
+ $ulang = $wgLang->getCode();
+ $clang = $wgContLang->getCode();
+
+ return !$wgShowIPinHeader && !$wgUser->getId() && !$wgUser->getNewtalk() && $ulang == $clang;
+ }
- function isFileCacheGood( $timestamp ) {
+ /*
+ * Check if up to date cache file exists
+ * @param $timestamp string
+ */
+ public function isFileCacheGood( $timestamp = '' ) {
global $wgCacheEpoch;
if( !$this->isFileCached() ) return false;
+ if( !$timestamp ) return true; // should be invalidated on change
$cachetime = $this->fileCacheTime();
$good = $timestamp <= $cachetime && $wgCacheEpoch <= $cachetime;
- wfDebug(" isFileCacheGood() - cachetime $cachetime, touched {$timestamp} epoch {$wgCacheEpoch}, good $good\n");
+ wfDebug(" isFileCacheGood() - cachetime $cachetime, touched '{$timestamp}' epoch {$wgCacheEpoch}, good $good\n");
return $good;
}
- function useGzip() {
+ public function useGzip() {
global $wgUseGzip;
return $wgUseGzip;
}
/* In handy string packages */
- function fetchRawText() {
+ public function fetchRawText() {
return file_get_contents( $this->fileCacheName() );
}
- function fetchPageText() {
+ public function fetchPageText() {
if( $this->useGzip() ) {
/* Why is there no gzfile_get_contents() or gzdecode()? */
return implode( '', gzfile( $this->fileCacheName() ) );
}
/* Working directory to/from output */
- function loadFromFileCache() {
+ public function loadFromFileCache() {
global $wgOut, $wgMimeType, $wgOutputEncoding, $wgContLanguageCode;
wfDebug(" loadFromFileCache()\n");
readfile( $filename );
}
- function checkCacheDirs() {
+ protected function checkCacheDirs() {
$filename = $this->fileCacheName();
$mydir2 = substr($filename,0,strrpos($filename,'/')); # subdirectory level 2
$mydir1 = substr($mydir2,0,strrpos($mydir2,'/')); # subdirectory level 1
wfMkdirParents( $mydir2 );
}
- function saveToFileCache( $origtext ) {
+ public function saveToFileCache( $origtext ) {
global $wgUseFileCache;
if( !$wgUseFileCache ) {
return $origtext; // return to output
/* actions that need to be made when we have a special pages */
SpecialPage::executePath( $title );
} else {
+ /* Try low-level file cache hit */
+ if( $title->getNamespace() != NS_MEDIAWIKI && HTMLFileCache::useFileCache() ) {
+ $cache = new HTMLFileCache( $title );
+ if( $cache->isFileCacheGood( /* Assume up to date */ ) ) {
+ global $wgOut;
+ /* Check incoming headers to see if client has this cached */
+ if( !$wgOut->checkLastModified( $cache->fileCacheTime() ) ) {
+ wfDebug( "MediaWiki::initializeSpecialCases(): about to load file cache\n" );
+ $cache->loadFromFileCache();
+ # Tell $wgOut that output is taken care of
+ $wgOut->disable();
+ # Do any stats increment/watchlist stuff
+ $article = self::articleFromTitle( $title );
+ $article->viewUpdates();
+ }
+ wfProfileOut( __METHOD__ );
+ return true;
+ }
+ }
/* No match to special cases */
wfProfileOut( __METHOD__ );
return false;
* @param $deferredUpdates array of updates to do
* @param $output OutputPage
*/
- function finalCleanup ( &$deferredUpdates, &$output ) {
+ function finalCleanup( &$deferredUpdates, &$output ) {
wfProfileIn( __METHOD__ );
# Now commit any transactions, so that unreported errors after output() don't roll back the whole thing
$factory = wfGetLBFactory();