MediaWiki  REL1_22
CacheHelper.php
Go to the documentation of this file.
00001 <?php
00030 interface ICacheHelper {
00031 
00038     function setCacheEnabled( $cacheEnabled );
00039 
00049     function startCache( $cacheExpiry = null, $cacheEnabled = null );
00050 
00065     function getCachedValue( $computeFunction, $args = array(), $key = null );
00066 
00073     function saveCache();
00074 
00083     function setExpiry( $cacheExpiry );
00084 
00085 }
00086 
00105 class CacheHelper implements ICacheHelper {
00106 
00113     protected $cacheExpiry = 3600;
00114 
00123     protected $cachedChunks;
00124 
00132     protected $hasCached = null;
00133 
00140     protected $cacheEnabled = true;
00141 
00148     protected $onInitHandler = false;
00149 
00156     protected $cacheKey = array();
00157 
00164     public function setCacheEnabled( $cacheEnabled ) {
00165         $this->cacheEnabled = $cacheEnabled;
00166     }
00167 
00177     public function startCache( $cacheExpiry = null, $cacheEnabled = null ) {
00178         if ( is_null( $this->hasCached ) ) {
00179             if ( !is_null( $cacheExpiry ) ) {
00180                 $this->cacheExpiry = $cacheExpiry;
00181             }
00182 
00183             if ( !is_null( $cacheEnabled ) ) {
00184                 $this->setCacheEnabled( $cacheEnabled );
00185             }
00186 
00187             $this->initCaching();
00188         }
00189     }
00190 
00202     public function getCachedNotice( IContextSource $context, $includePurgeLink = true ) {
00203         if ( $this->cacheExpiry < 86400 * 3650 ) {
00204             $message = $context->msg(
00205                 'cachedspecial-viewing-cached-ttl',
00206                 $context->getLanguage()->formatDuration( $this->cacheExpiry )
00207             )->escaped();
00208         }
00209         else {
00210             $message = $context->msg(
00211                 'cachedspecial-viewing-cached-ts'
00212             )->escaped();
00213         }
00214 
00215         if ( $includePurgeLink ) {
00216             $refreshArgs = $context->getRequest()->getQueryValues();
00217             unset( $refreshArgs['title'] );
00218             $refreshArgs['action'] = 'purge';
00219 
00220             $subPage = $context->getTitle()->getFullText();
00221             $subPage = explode( '/', $subPage, 2 );
00222             $subPage = count( $subPage ) > 1 ? $subPage[1] : false;
00223 
00224             $message .= ' ' . Linker::link(
00225                 $context->getTitle( $subPage ),
00226                 $context->msg( 'cachedspecial-refresh-now' )->escaped(),
00227                 array(),
00228                 $refreshArgs
00229             );
00230         }
00231 
00232         return $message;
00233     }
00234 
00241     protected function initCaching() {
00242         if ( $this->cacheEnabled && is_null( $this->hasCached ) ) {
00243             $cachedChunks = wfGetCache( CACHE_ANYTHING )->get( $this->getCacheKeyString() );
00244 
00245             $this->hasCached = is_array( $cachedChunks );
00246             $this->cachedChunks = $this->hasCached ? $cachedChunks : array();
00247 
00248             if ( $this->onInitHandler !== false ) {
00249                 call_user_func( $this->onInitHandler, $this->hasCached );
00250             }
00251         }
00252     }
00253 
00268     public function getCachedValue( $computeFunction, $args = array(), $key = null ) {
00269         $this->initCaching();
00270 
00271         if ( $this->cacheEnabled && $this->hasCached ) {
00272             $value = null;
00273 
00274             if ( is_null( $key ) ) {
00275                 $itemKey = array_keys( array_slice( $this->cachedChunks, 0, 1 ) );
00276                 $itemKey = array_shift( $itemKey );
00277 
00278                 if ( !is_integer( $itemKey ) ) {
00279                     wfWarn( "Attempted to get item with non-numeric key while the next item in the queue has a key ($itemKey) in " . __METHOD__ );
00280                 }
00281                 elseif ( is_null( $itemKey ) ) {
00282                     wfWarn( "Attempted to get an item while the queue is empty in " . __METHOD__ );
00283                 }
00284                 else {
00285                     $value = array_shift( $this->cachedChunks );
00286                 }
00287             }
00288             else {
00289                 if ( array_key_exists( $key, $this->cachedChunks ) ) {
00290                     $value = $this->cachedChunks[$key];
00291                     unset( $this->cachedChunks[$key] );
00292                 }
00293                 else {
00294                     wfWarn( "There is no item with key '$key' in this->cachedChunks in " . __METHOD__ );
00295                 }
00296             }
00297         }
00298         else {
00299             if ( !is_array( $args ) ) {
00300                 $args = array( $args );
00301             }
00302 
00303             $value = call_user_func_array( $computeFunction, $args );
00304 
00305             if ( $this->cacheEnabled ) {
00306                 if ( is_null( $key ) ) {
00307                     $this->cachedChunks[] = $value;
00308                 }
00309                 else {
00310                     $this->cachedChunks[$key] = $value;
00311                 }
00312             }
00313         }
00314 
00315         return $value;
00316     }
00317 
00324     public function saveCache() {
00325         if ( $this->cacheEnabled && $this->hasCached === false && !empty( $this->cachedChunks ) ) {
00326             wfGetCache( CACHE_ANYTHING )->set( $this->getCacheKeyString(), $this->cachedChunks, $this->cacheExpiry );
00327         }
00328     }
00329 
00338     public function setExpiry( $cacheExpiry ) {
00339         $this->cacheExpiry = $cacheExpiry;
00340     }
00341 
00351     protected function getCacheKeyString() {
00352         if ( $this->cacheKey === array() ) {
00353             throw new MWException( 'No cache key set, so cannot obtain or save the CacheHelper values.' );
00354         }
00355 
00356         return call_user_func_array( 'wfMemcKey', $this->cacheKey );
00357     }
00358 
00366     public function setCacheKey( array $cacheKey ) {
00367         $this->cacheKey = $cacheKey;
00368     }
00369 
00377     public function rebuildOnDemand() {
00378         $this->hasCached = false;
00379     }
00380 
00388     public function setOnInitializedHandler( $handlerFunction ) {
00389         $this->onInitHandler = $handlerFunction;
00390     }
00391 
00392 }