[ Index ]
 

Code source de DokuWiki 2006-11-06

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/inc/ -> cache.php (source)

   1  <?php
   2  /**
   3   * Generic class to handle caching
   4   *
   5   * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
   6   * @author     Chris Smith <chris@jalakai.co.uk>
   7   */
   8  
   9  if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/');
  10  
  11  require_once (DOKU_INC.'inc/io.php');
  12  require_once (DOKU_INC.'inc/pageutils.php');
  13  require_once (DOKU_INC.'inc/parserutils.php');
  14  
  15  class cache {
  16    var $key = '';          // primary identifier for this item
  17    var $ext = '';          // file ext for cache data, secondary identifier for this item
  18    var $cache = '';        // cache file name
  19    var $depends = array(); // array containing cache dependency information,
  20                            //   used by _useCache to determine cache validity
  21  
  22    var $_event = '';       // event to be triggered during useCache
  23  
  24    function cache($key,$ext) {
  25      $this->key = $key;
  26      $this->ext = $ext;
  27      $this->cache = getCacheName($key,$ext);
  28    }
  29  
  30    /**
  31     * public method to determine whether the cache can be used
  32     *
  33     * to assist in cetralisation of event triggering and calculation of cache statistics, 
  34     * don't override this function override _useCache()
  35     *
  36     * @param  array   $depends   array of cache dependencies, support dependecies:
  37     *                            'age'   => max age of the cache in seconds
  38     *                            'files' => cache must be younger than mtime of each file
  39     *                                       (nb. dependency passes if file doesn't exist)
  40     *
  41     * @return bool    true if cache can be used, false otherwise
  42     */
  43    function useCache($depends=array()) {
  44      $this->depends = $depends;
  45      $this->_addDependencies();
  46  
  47      if ($this->_event) {
  48        return $this->_stats(trigger_event($this->_event,$this,array($this,'_useCache')));
  49      } else {
  50        return $this->_stats($this->_useCache());
  51      }
  52    }
  53  
  54    /**
  55     * private method containing cache use decision logic
  56     *
  57     * this function processes the following keys in the depends array
  58     *   purge - force a purge on any non empty value
  59     *   age   - expire cache if older than age (seconds)
  60     *   files - expire cache if any file in this array was updated more recently than the cache
  61     *
  62     * can be overridden
  63     *
  64     * @return bool               see useCache()
  65     */
  66    function _useCache() {
  67  
  68      if (!empty($this->depends['purge'])) return false;              // purge requested?
  69      if (!($this->_time = @filemtime($this->cache))) return false;   // cache exists?
  70  
  71      // cache too old?
  72      if (!empty($this->depends['age']) && ((time() - $this->_time) > $this->depends['age'])) return false;
  73  
  74      if (!empty($this->depends['files'])) {
  75        foreach ($this->depends['files'] as $file) {
  76          if ($this->_time < @filemtime($file)) return false;         // cache older than files it depends on?
  77        }
  78      }
  79  
  80      return true;
  81    }
  82  
  83    /**
  84     * add dependencies to the depends array
  85     *
  86     * this method should only add dependencies,
  87     * it should not remove any existing dependencies and
  88     * it should only overwrite a dependency when the new value is more stringent than the old
  89     */
  90    function _addDependencies() {
  91      if (isset($_REQUEST['purge'])) $this->depends['purge'] = true;   // purge requested
  92    }
  93  
  94    /**
  95     * retrieve the cached data
  96     *
  97     * @param   bool   $clean   true to clean line endings, false to leave line endings alone
  98     * @return  string          cache contents
  99     */
 100    function retrieveCache($clean=true) {
 101      return io_readFile($this->cache, $clean);
 102    }
 103  
 104    /**
 105     * cache $data
 106     *
 107     * @param   string $data   the data to be cached
 108     * @return  none
 109     */
 110    function storeCache($data) {
 111      io_savefile($this->cache, $data);
 112    }
 113  
 114    /**
 115     * remove any cached data associated with this cache instance
 116     */
 117    function removeCache() {
 118      @unlink($this->cache);
 119    }
 120  
 121    /**
 122     * Record cache hits statistics.
 123     * (Only when debugging allowed, to reduce overhead.)
 124     *
 125     * @param    bool   $success   result of this cache use attempt
 126     * @return   bool              pass-thru $success value
 127     */
 128    function _stats($success) {
 129      global $conf;
 130      static $stats = NULL;
 131      static $file;
 132  
 133      if (!$conf['allowdebug']) { return $success; }
 134  
 135      if (is_null($stats)) {
 136        $file = $conf['cachedir'].'/cache_stats.txt';
 137        $lines = explode("\n",io_readFile($file));
 138  
 139        foreach ($lines as $line) {
 140          $i = strpos($line,',');
 141          $stats[substr($line,0,$i)] = $line;
 142        }
 143      }
 144  
 145      if (isset($stats[$this->ext])) {
 146        list($ext,$count,$hits) = explode(',',$stats[$this->ext]);
 147      } else {
 148        $ext = $this->ext;
 149        $count = 0;
 150        $hits = 0;
 151      }
 152  
 153      $count++;
 154      if ($success) $hits++;
 155      $stats[$this->ext] = "$ext,$count,$hits";
 156  
 157      io_saveFile($file,join("\n",$stats));
 158  
 159      return $success;
 160    }
 161  }
 162  
 163  class cache_parser extends cache {
 164  
 165    var $file = '';       // source file for cache
 166    var $mode = '';       // input mode (represents the processing the input file will undergo)
 167  
 168    var $_event = 'PARSER_CACHE_USE';
 169  
 170    function cache_parser($id, $file, $mode) {
 171      if ($id) $this->page = $id;
 172      $this->file = $file;
 173      $this->mode = $mode;
 174  
 175      parent::cache($file.$_SERVER['HTTP_HOST'].$_SERVER['SERVER_PORT'],'.'.$mode);
 176    }
 177  
 178    function _useCache() {
 179  
 180      if (!@file_exists($this->file)) return false;                   // source exists?
 181      return parent::_useCache();
 182    }
 183  
 184    function _addDependencies() {
 185      global $conf;
 186  
 187      $this->depends['age'] = isset($this->depends['age']) ? 
 188                     min($this->depends['age'],$conf['cachetime']) : $conf['cachetime'];
 189  
 190      // parser cache file dependencies ...
 191      $files = array($this->file,                                     // ... source
 192                     DOKU_CONF.'dokuwiki.php',                        // ... config
 193                     DOKU_CONF.'local.php',                           // ... local config
 194                     DOKU_INC.'inc/parser/parser.php',                // ... parser
 195                     DOKU_INC.'inc/parser/handler.php',               // ... handler
 196               );
 197  
 198      $this->depends['files'] = !empty($this->depends['files']) ? array_merge($files, $this->depends['files']) : $files;
 199      parent::_addDependencies();
 200    }
 201  
 202  }
 203  
 204  class cache_renderer extends cache_parser {
 205  
 206    function useCache($depends=array()) {
 207      $use = parent::useCache($depends);
 208  
 209      // meta data needs to be kept in step with the cache
 210      if (!$use && isset($this->page)) {
 211        p_set_metadata($this->page,array(),true);
 212      }
 213  
 214      return $use;
 215    }
 216  
 217    function _useCache() {
 218      global $conf;
 219  
 220      if (!parent::_useCache()) return false;
 221  
 222      // for wiki pages, check metadata dependencies
 223      if (isset($this->page)) {
 224        $metadata = p_get_metadata($this->page);
 225  
 226        // check currnent link existence is consistent with cache version
 227        // first check the purgefile
 228        // - if the cache is more recent that the purgefile we know no links can have been updated
 229        if ($this->_time < @filemtime($conf['cachedir'].'/purgefile')) {
 230  
 231  #       $links = p_get_metadata($this->page,"relation references");
 232          $links = $metadata['relation']['references'];
 233  
 234          if (!empty($links)) {
 235            foreach ($links as $id => $exists) {
 236              if ($exists != @file_exists(wikiFN($id,'',false))) return false;
 237            }
 238          }
 239        }
 240      }
 241  
 242      return true;
 243    }
 244  
 245    function _addDependencies() {
 246  
 247      // renderer cache file dependencies ...
 248      $files = array(
 249                     DOKU_INC.'inc/parser/'.$this->mode.'.php',       // ... the renderer
 250               );
 251  
 252      // page implies metadata and possibly some other dependencies
 253      if (isset($this->page)) {
 254  
 255        $metafile = metaFN($this->page,'.meta');
 256        if (@file_exists($metafile)) {
 257          $files[] = $metafile;                                       // ... the page's own metadata
 258          $files[] = DOKU_INC.'inc/parser/metadata.php';              // ... the metadata renderer
 259  
 260          $valid = p_get_metadata($this->page, 'date valid');
 261          if (!empty($valid['age'])) {
 262            $this->depends['age'] = isset($this->depends['age']) ?
 263                     min($this->depends['age'],$valid['age']) : $valid['age'];
 264          }
 265  
 266        } else {
 267          $this->depends['purge'] = true;                             // ... purging cache will generate metadata
 268          return;
 269        }
 270      }
 271  
 272      $this->depends['files'] = !empty($this->depends['files']) ? array_merge($files, $this->depends['files']) : $files;
 273      parent::_addDependencies();
 274    }
 275  }
 276  
 277  class cache_instructions extends cache_parser {
 278  
 279    function cache_instructions($id, $file) {
 280      parent::cache_parser($id, $file, 'i');
 281    }
 282  
 283    function retrieveCache() {
 284      $contents = io_readFile($this->cache, false);
 285      return !empty($contents) ? unserialize($contents) : array();
 286    }
 287  
 288    function storeCache($instructions) {
 289      io_savefile($this->cache,serialize($instructions));
 290    }
 291  }


Généré le : Tue Apr 3 20:47:31 2007 par Balluche grâce à PHPXref 0.7