• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

system/classes/filecache.php

00001 <?php
00007 namespace Habari;
00008 
00014 class FileCache extends Cache
00015 {
00016   protected $cache_location;
00017   protected $enabled = false;
00018   protected $cache_files = array();
00019   protected $cache_data = array();
00020   protected $index_file;
00021 
00027   public function __construct()
00028   {
00029     if ( !defined( 'FILE_CACHE_LOCATION' ) ) {
00030       define( 'FILE_CACHE_LOCATION', HABARI_PATH . '/user/cache/' );
00031     }
00032     $this->cache_location = FILE_CACHE_LOCATION;
00033     $this->index_file = $this->cache_location . md5( 'index' . Options::get( 'private-GUID' ) ) . '.data';
00034     $this->enabled = is_writeable( $this->cache_location );
00035     if ( $this->enabled ) {
00036       if ( file_exists( $this->index_file ) ) {
00037         $this->cache_files = unserialize( file_get_contents( $this->index_file ) );
00038       }
00039     }
00040     else {
00041       Session::error( _t( "The cache directory '%s' is not writable - the cache is disabled. The user, or group, which your web server is running as, needs to have read, write, and execute permissions on this directory.", array( $this->cache_location ) ), 'filecache' );
00042       EventLog::log( _t( "The cache directory '%s' is not writable - the cache is disabled.", array( $this->cache_location ) ), 'notice', 'cache', 'habari' );
00043     }
00044   }
00045 
00052   protected function _has( $name, $group )
00053   {
00054     if ( !$this->enabled ) {
00055       return false;
00056     }
00057     $hash = $this->get_name_hash( $name );
00058     $ghash = $this->get_group_hash( $group );
00059 
00060     return isset( $this->cache_files[$ghash][$hash] )
00061       && ( $this->cache_files[$ghash][$hash]['keep'] || $this->cache_files[$ghash][$hash]['expires'] > time() )
00062       && file_exists( $this->cache_files[$ghash][$hash]['file'] );
00063   }
00064 
00071   protected function _has_group( $group )
00072   {
00073     if ( !$this->enabled ) {
00074       return false;
00075     }
00076     $ghash = $this->get_group_hash( $group );
00077 
00078     $valid = true;
00079     $now = time();
00080     foreach ( $this->cache_files[$ghash] as $hash => $record ) {
00081       if ( ! file_exists( $record['file'] ) || $record['expires'] <= $now ) {
00082         $valid = false;
00083         break;
00084       }
00085     }
00086 
00087     return ( isset( $this->cache_files[$ghash] ) && count( $this->cache_files[$ghash] ) > 1 ) && $valid;
00088   }
00089 
00096   protected function _get_group( $group )
00097   {
00098     if ( !$this->enabled ) {
00099       return null;
00100     }
00101     $ghash = $this->get_group_hash( $group );
00102 
00103     if ( !isset( $this->cache_data[$group] ) ) {
00104       $this->cache_data[$group] = array();
00105       if ( isset( $this->cache_files[$ghash] ) ) {
00106         foreach ( $this->cache_files[$ghash] as $hash => $record ) {
00107           $this->cache_data[$group][$record['name']] = unserialize(
00108             file_get_contents( $record['file'] )
00109           );
00110         }
00111       }
00112     }
00113     return $this->cache_data[$group];
00114   }
00115 
00122   protected function _get( $name, $group )
00123   {
00124     if ( !$this->enabled ) {
00125       return null;
00126     }
00127     $hash = $this->get_name_hash( $name );
00128     $ghash = $this->get_group_hash( $group );
00129 
00130     if ( !isset( $this->cache_data[$group][$name] ) ) {
00131       $this->cache_data[$group][$name] = null;
00132       if ( isset( $this->cache_files[$ghash][$hash] ) && ($this->cache_files[$ghash][$hash]['keep'] || $this->cache_files[$ghash][$hash]['expires'] > time()) && file_exists( $this->cache_files[$ghash][$hash]['file'] ) ) {
00133         $this->cache_data[$group][$name] = unserialize( file_get_contents( $this->cache_files[$ghash][$hash]['file'] ) );
00134       }
00135     }
00136     return $this->cache_data[$group][$name];
00137   }
00138 
00139   protected function _set( $name, $value, $expiry, $group, $keep )
00140   {
00141     if ( !$this->enabled ) {
00142       return null;
00143     }
00144 
00145     Plugins::act( 'cache_set_before', $name, $group, $value, $expiry );
00146 
00147     $hash = $this->get_name_hash( $name );
00148     $ghash = $this->get_group_hash( $group );
00149 
00150     if ( !isset( $this->cache_data[$group] ) ) {
00151       // prime our cache so the local version is up-to-date and complete
00152       $this->_get_group( $group );
00153     }
00154     $this->cache_data[$group][$name] = $value;
00155 
00156     file_put_contents( $this->cache_location . $ghash . $hash, serialize( $value ) );
00157     $this->cache_files[$ghash][$hash] = array( 'file' => $this->cache_location . $ghash . $hash, 'expires' => time() + $expiry, 'name' => $name, 'keep' => $keep );
00158     $this->clear_expired();
00159     file_put_contents( $this->index_file, serialize( $this->cache_files ) );
00160 
00161     Plugins::act( 'cache_set_after', $name, $group, $value, $expiry );
00162 
00163     return true;
00164   }
00165 
00173   protected function _expire( $name, $group, $match_mode = 'strict' )
00174   {
00175     if ( !$this->enabled ) {
00176       return null;
00177     }
00178     
00179     // prime the variable cache.
00180     // dirty, dirty hack. we should *never* load all the data in, especially when we only care about the expirey
00181     // alas, this crappy code requires it
00182     $this->_get_group($group);
00183     
00184     $keys = array();
00185     switch ( strtolower( $match_mode ) ) {
00186       case 'glob':
00187         if ( array_key_exists( $group, $this->cache_data ) ) {
00188           $keys = preg_grep( Utils::glob_to_regex( $name ), array_keys( $this->cache_data[$group] ) );
00189         }
00190         break;
00191       case 'regex':
00192         if ( array_key_exists( $group, $this->cache_data ) ) {
00193           $keys = preg_grep( $name, array_keys( $this->cache_data[$group] ) );
00194         }
00195         break;
00196       case 'strict':
00197       default:
00198         $keys = array( $name );
00199         break;
00200     }
00201 
00202     $ghash = $this->get_group_hash( $group );
00203     foreach ( $keys as $key ) {
00204       Plugins::act( 'cache_expire_before', $name, $group );
00205 
00206       $hash = $this->get_name_hash( $key );
00207 
00208       if ( isset( $this->cache_files[$ghash][$hash] ) && file_exists( $this->cache_files[$ghash][$hash]['file'] ) ) {
00209         unlink( $this->cache_files[$ghash][$hash]['file'] );
00210         unset( $this->cache_files[$ghash][$hash] );
00211         unset( $this->cache_data[$group][$name] );
00212       }
00213 
00214       Plugins::act( 'cache_expire_after', $name, $group );
00215     }
00216 
00217     $this->clear_expired();
00218     file_put_contents( $this->index_file, serialize( $this->cache_files ) );
00219   }
00220 
00221 
00229   protected function _expired( $name, $group )
00230   {
00231     if ( !$this->enabled ) {
00232       return null;
00233     }
00234     $hash = $this->get_name_hash( $name );
00235     $ghash = $this->get_group_hash( $group );
00236 
00237     // Do not check cached data, since we can return (and cache in this object) data if the cache is set to 'keep'
00238     if ( isset( $this->cache_files[$ghash][$hash] ) && $this->cache_files[$ghash][$hash]['expires'] > time() && file_exists( $this->cache_files[$ghash][$hash]['file'] ) ) {
00239       return false;
00240     }
00241     else {
00242       return true;
00243     }
00244   }
00245 
00252   protected function _extend( $name, $expiry, $group )
00253   {
00254     if ( !$this->enabled ) {
00255       return null;
00256     }
00257 
00258     Plugins::act( 'cache_extend_before', $name, $group, $expiry );
00259 
00260     $hash = $this->get_name_hash( $name );
00261     $ghash = $this->get_group_hash( $group );
00262 
00263     if ( isset( $this->cache_files[$ghash][$hash] ) ) {
00264       $this->cache_files[$ghash][$hash]['expires'] = time() + $expiry;
00265       $this->clear_expired();
00266       file_put_contents( $this->index_file, serialize( $this->cache_files ) );
00267     }
00268 
00269     Plugins::act( 'cache_extend_after', $name, $group, $expiry );
00270   }
00271 
00275   protected function _purge()
00276   {
00277     Plugins::act( 'cache_purge_before' );
00278 
00279     $glob = Utils::glob( FILE_CACHE_LOCATION . '*.data' );
00280     foreach ( $glob as $file ) {
00281       unlink( $file );
00282     }
00283     $glob = Utils::glob( FILE_CACHE_LOCATION . '*.cache' );
00284     foreach ( $glob as $file ) {
00285       unlink( $file );
00286     }
00287 
00288     Plugins::act( 'cache_purge_after' );
00289   }
00290 
00296   private function get_name_hash( $name )
00297   {
00298     return md5( $name . Options::get( 'private-GUID' ) ) . '.cache';
00299   }
00300 
00306   private function get_group_hash( $group )
00307   {
00308     return md5( $group . Options::get( 'private-GUID' ) ) . '.';
00309   }
00310 
00314   private function record_fresh( $record )
00315   {
00316     if ( $record['expires'] > time() || $record['keep'] ) {
00317       return true;
00318     }
00319     elseif ( file_exists( $record['file'] ) ) {
00320       unlink( $record['file'] );
00321     }
00322     return false;
00323   }
00324 
00328   private function clear_expired()
00329   {
00330     foreach ( $this->cache_files as $ghash => $records ) {
00331       $this->cache_files[$ghash] = array_filter( $records, array( $this, 'record_fresh' ) );
00332     }
00333   }
00334 
00335 }
00336 
00337 ?>

Generated on Sun Aug 4 2013 12:51:43 for Habari by  doxygen 1.7.1