MediaWiki  REL1_24
CacheHelper.php
Go to the documentation of this file.
00001 <?php
00030 interface ICacheHelper {
00037     function setCacheEnabled( $cacheEnabled );
00038 
00048     function startCache( $cacheExpiry = null, $cacheEnabled = null );
00049 
00064     function getCachedValue( $computeFunction, $args = array(), $key = null );
00065 
00072     function saveCache();
00073 
00082     function setExpiry( $cacheExpiry );
00083 }
00084 
00103 class CacheHelper implements ICacheHelper {
00110     protected $cacheExpiry = 3600;
00111 
00120     protected $cachedChunks;
00121 
00129     protected $hasCached = null;
00130 
00137     protected $cacheEnabled = true;
00138 
00145     protected $onInitHandler = false;
00146 
00153     protected $cacheKey = array();
00154 
00161     public function setCacheEnabled( $cacheEnabled ) {
00162         $this->cacheEnabled = $cacheEnabled;
00163     }
00164 
00174     public function startCache( $cacheExpiry = null, $cacheEnabled = null ) {
00175         if ( is_null( $this->hasCached ) ) {
00176             if ( !is_null( $cacheExpiry ) ) {
00177                 $this->cacheExpiry = $cacheExpiry;
00178             }
00179 
00180             if ( !is_null( $cacheEnabled ) ) {
00181                 $this->setCacheEnabled( $cacheEnabled );
00182             }
00183 
00184             $this->initCaching();
00185         }
00186     }
00187 
00199     public function getCachedNotice( IContextSource $context, $includePurgeLink = true ) {
00200         if ( $this->cacheExpiry < 86400 * 3650 ) {
00201             $message = $context->msg(
00202                 'cachedspecial-viewing-cached-ttl',
00203                 $context->getLanguage()->formatDuration( $this->cacheExpiry )
00204             )->escaped();
00205         } else {
00206             $message = $context->msg(
00207                 'cachedspecial-viewing-cached-ts'
00208             )->escaped();
00209         }
00210 
00211         if ( $includePurgeLink ) {
00212             $refreshArgs = $context->getRequest()->getQueryValues();
00213             unset( $refreshArgs['title'] );
00214             $refreshArgs['action'] = 'purge';
00215 
00216             $subPage = $context->getTitle()->getFullText();
00217             $subPage = explode( '/', $subPage, 2 );
00218             $subPage = count( $subPage ) > 1 ? $subPage[1] : false;
00219 
00220             $message .= ' ' . Linker::link(
00221                 $context->getTitle( $subPage ),
00222                 $context->msg( 'cachedspecial-refresh-now' )->escaped(),
00223                 array(),
00224                 $refreshArgs
00225             );
00226         }
00227 
00228         return $message;
00229     }
00230 
00237     protected function initCaching() {
00238         if ( $this->cacheEnabled && is_null( $this->hasCached ) ) {
00239             $cachedChunks = wfGetCache( CACHE_ANYTHING )->get( $this->getCacheKeyString() );
00240 
00241             $this->hasCached = is_array( $cachedChunks );
00242             $this->cachedChunks = $this->hasCached ? $cachedChunks : array();
00243 
00244             if ( $this->onInitHandler !== false ) {
00245                 call_user_func( $this->onInitHandler, $this->hasCached );
00246             }
00247         }
00248     }
00249 
00264     public function getCachedValue( $computeFunction, $args = array(), $key = null ) {
00265         $this->initCaching();
00266 
00267         if ( $this->cacheEnabled && $this->hasCached ) {
00268             $value = null;
00269 
00270             if ( is_null( $key ) ) {
00271                 $itemKey = array_keys( array_slice( $this->cachedChunks, 0, 1 ) );
00272                 $itemKey = array_shift( $itemKey );
00273 
00274                 if ( !is_integer( $itemKey ) ) {
00275                     wfWarn( "Attempted to get item with non-numeric key while " .
00276                         "the next item in the queue has a key ($itemKey) in " . __METHOD__ );
00277                 } elseif ( is_null( $itemKey ) ) {
00278                     wfWarn( "Attempted to get an item while the queue is empty in " . __METHOD__ );
00279                 } else {
00280                     $value = array_shift( $this->cachedChunks );
00281                 }
00282             } else {
00283                 if ( array_key_exists( $key, $this->cachedChunks ) ) {
00284                     $value = $this->cachedChunks[$key];
00285                     unset( $this->cachedChunks[$key] );
00286                 } else {
00287                     wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
00288                 }
00289             }
00290         } else {
00291             if ( !is_array( $args ) ) {
00292                 $args = array( $args );
00293             }
00294 
00295             $value = call_user_func_array( $computeFunction, $args );
00296 
00297             if ( $this->cacheEnabled ) {
00298                 if ( is_null( $key ) ) {
00299                     $this->cachedChunks[] = $value;
00300                 } else {
00301                     $this->cachedChunks[$key] = $value;
00302                 }
00303             }
00304         }
00305 
00306         return $value;
00307     }
00308 
00315     public function saveCache() {
00316         if ( $this->cacheEnabled && $this->hasCached === false && !empty( $this->cachedChunks ) ) {
00317             wfGetCache( CACHE_ANYTHING )->set(
00318                 $this->getCacheKeyString(),
00319                 $this->cachedChunks,
00320                 $this->cacheExpiry
00321             );
00322         }
00323     }
00324 
00333     public function setExpiry( $cacheExpiry ) {
00334         $this->cacheExpiry = $cacheExpiry;
00335     }
00336 
00346     protected function getCacheKeyString() {
00347         if ( $this->cacheKey === array() ) {
00348             throw new MWException( 'No cache key set, so cannot obtain or save the CacheHelper values.' );
00349         }
00350 
00351         return call_user_func_array( 'wfMemcKey', $this->cacheKey );
00352     }
00353 
00361     public function setCacheKey( array $cacheKey ) {
00362         $this->cacheKey = $cacheKey;
00363     }
00364 
00372     public function rebuildOnDemand() {
00373         $this->hasCached = false;
00374     }
00375 
00383     public function setOnInitializedHandler( $handlerFunction ) {
00384         $this->onInitHandler = $handlerFunction;
00385     }
00386 }