MediaWiki  REL1_21
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 }