[ Index ]
 

Code source de Plume CMS 1.2.2

Accédez au Source d'autres logiciels libres

Classes | Fonctions | Variables | Constantes | Tables

title

Body

[fermer]

/manager/inc/ -> class.cache.php (source)

   1  <?php
   2  /* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
   3  /*
   4  # ***** BEGIN LICENSE BLOCK *****
   5  # This file is part of Plume CMS, a website management application.
   6  # Copyright (C) 2001-2005 Loic d'Anterroches and contributors.
   7  #
   8  # Plume CMS is free software; you can redistribute it and/or modify
   9  # it under the terms of the GNU General Public License as published by
  10  # the Free Software Foundation; either version 2 of the License, or
  11  # (at your option) any later version.
  12  #
  13  # Copyright (C) 2003 KDO / VWT (The Virtual Web Team)
  14  #
  15  # Plume CMS is distributed in the hope that it will be useful,
  16  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  # GNU General Public License for more details.
  19  #
  20  # You should have received a copy of the GNU General Public License
  21  # along with this program; if not, write to the Free Software
  22  # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  23  #
  24  # ***** END LICENSE BLOCK ***** */
  25  
  26  /**
  27   * Cache: Gestion de cache pages dynamiques
  28   *
  29   * Utilise l'output buffering: fonctions type ob_xxx de PHP
  30   * Sample usage-1:
  31   *   $cc = new Cache('cacheFileName', 300);
  32   *   if($cc->processPage()) {
  33   *      .... // Ce que vous voulez cacher
  34   *      $cc->endCache();
  35   *   }
  36   * Sample usage-2:
  37   *   $cc = new Cache('basfilename');
  38   *   if($cc->processSegment(200)) {
  39   *      .... // Ce que vous voulez cacher
  40   *      $cc->endCache();
  41   *   }
  42   *   .... // Suite non cachée
  43   *   if($cc->processSegment(600)) {
  44   *      .... // Autre partie à cacher
  45   *      $cc->endCache();
  46   *   }
  47   *
  48   */
  49  class Cache 
  50  {
  51      var $data; /**< Data to cache. */
  52      var $cacheDir = '/tmp/'; /**< Cache folder. */
  53      var $file; /**< Cache file. */
  54      var $Fname; /**< Cache file name. */
  55      var $FnameOrig; /**< Original cache file name, use for segmented cache. */
  56      var $segmentId = 1; /**< Segment id, used to generate the cache file. */
  57      var $refreshTime; /**< Cache validity timestamp. */
  58      var $needUpdate = 0; /**< Need to update the cache. */
  59      var $isActive = false; /**< Are we in a processcache/processsegment loop */
  60      var $isSegment = false; /**< In a segment or not. */
  61      var $timeout; /**< Validity of a cache in seconds. */
  62      var $headers = array(); /**< Extra headers to send. */
  63      var $debug = false; /**< Debug mode (no caching). */
  64  
  65      /**
  66       * Init the cache
  67       *
  68       * @param string Cache file name
  69       * @param int Timeout in minutes (180)
  70       */
  71      function Cache($fname, $timeout=180) 
  72      {
  73          $fname = md5($fname);
  74          $this->Fname = $fname;
  75          $this->FnameOrig = $fname;
  76          $this->file = $this->cacheDir.$fname;
  77          $this->setTimeout($timeout);
  78      }
  79  
  80      /**
  81       * Set the cache directory.
  82       *
  83       * @param string Full path to cache directory with trailing slash
  84       */
  85      function setCacheDirectory($dir) 
  86      {
  87          $this->cacheDir = $dir;
  88          $this->file = $dir.$this->Fname;
  89      }
  90  
  91      /**
  92       * Set the timeout.
  93       *
  94       * @param int Timeout in minutes (180)
  95       */
  96      function setTimeout($timeout=180)
  97      {
  98          $this->refreshTime = time() - ($timeout * 60);
  99          $this->timeout = $timeout * 60;
 100      }
 101  
 102      /**
 103       * Set extra header to send.
 104       *
 105       * @param string Extra header.
 106       */
 107      function setHeader($header) {
 108          if (0 != strlen($header)) {
 109              $this->headers[] = $header;
 110          }
 111      }
 112      
 113      /**
 114       * Send the extra headers.
 115       */
 116      function sendHeaders() 
 117      {
 118          foreach ($this->headers as $header) {
 119              header($header);
 120          }
 121      }
 122  
 123      /**
 124       * Process the cache
 125       *
 126       * @param int Timeout in minutes (false) if false use the one at construct
 127       * @return boolean false if cache content is valid
 128       */
 129      function processPage($timeout=false) 
 130      {
 131          if ($timeout !== false) {
 132              $this->setTimeout($timeout);
 133          }
 134          if(!$this->isActive ) {
 135              $this->isActive = true;
 136              ob_start();
 137              ob_implicit_flush(0);
 138              if (!$this->debug 
 139                  && file_exists($this->file) 
 140                  && (@filemtime(config::getMassUpdateFile())-10 < @filemtime($this->file))
 141                  && (@filemtime($this->file) > $this->refreshTime)
 142                  ) {
 143                  if (!$this->isSegment) {
 144                      if (isset($_SERVER["HTTP_IF_MODIFIED_SINCE"])) {
 145                          $gmtime = gmdate('D, d M Y H:i:s', filemtime($this->file)).' GMT';
 146                          $usertime = substr($_SERVER["HTTP_IF_MODIFIED_SINCE"], 0, strpos($_SERVER["HTTP_IF_MODIFIED_SINCE"], 'GMT') + 3);
 147                          if ($usertime == $gmtime) {
 148                              header("HTTP/1.1 304 Not Modified");
 149                              ob_end_flush();
 150                              exit;
 151                          }
 152                      }
 153                  }
 154                  $this->read();
 155                  if (empty($gmtime)) 
 156                      $gmtime = gmdate('D, d M Y H:i:s', 
 157                                       filemtime($this->file)).' GMT';
 158                  if (!$this->isSegment) 
 159                      header("Last-Modified: ".$gmtime);
 160                  echo $this->data;
 161                  ob_end_flush();
 162                  $this->isActive = false;
 163                  return false;
 164  
 165              } else {
 166                  if (!$this->isSegment) {
 167                      header('Cache-Control:  no-cache');
 168                      header('Pragma:  no-cache');
 169                      $time = gmdate('D, d M Y H:i:s', 123456).' GMT';
 170                      header("Last-Modified: ".$time);
 171                  }
 172                  $this->needUpdate = 1;
 173                  return true;
 174              }
 175          }
 176      }
 177  
 178      /**
 179       * Réalise le cache pour un segment donné
 180       *
 181       * @since  2002-02-21
 182       * @return boolean false si le contenu  du cache est valide
 183       * @access public
 184       */
 185      function processSegment($timeout=180) 
 186      {
 187          if (!$this->isActive) {
 188              $this->isSegment = true;
 189              $this->Fname = $this->FnameOrig.'%%'.$this->segmentId;
 190              $this->segmentId += 1;
 191              $this->file = $this->cacheDir.$this->Fname;
 192              return $this->processPage($timeout);
 193          }
 194          return true;
 195      }
 196  
 197      /**
 198       * End of cache block.
 199       */
 200      function endCache() 
 201      {
 202          $this->isActive = false;
 203          if ($this->needUpdate) {
 204              $this->data = ob_get_contents();
 205              $this->write();
 206              if (!$this->isSegment) {
 207                  clearstatcache();
 208                  $FT = @filemtime($this->file);
 209                  $gnow = gmdate('D, d M Y H:i:s', $FT+$this->timeout).' GMT';
 210                  if ($this->timeout != -1)
 211                      header('Expires: '.$gnow);
 212                  $gnow = gmdate('D, d M Y H:i:s', $FT).' GMT';
 213                  header('Last-Modified: '.$gnow);
 214              }
 215              ob_end_flush();
 216              $this->isSegment = false;
 217          }
 218      }
 219  
 220      /**
 221       * Ecrit les données dans le fichier de cache
 222       *
 223       * @return true si l'on a pu ecrire dans le fichier, false sinon
 224       * @access private
 225       */
 226      function write() 
 227      {
 228          // mode "a" pour ne pas tronquer avant d'avoir le lock
 229          $fp = @fopen($this->file, 'a'); 
 230          if ($fp) {
 231              // lock exclusif pour l'écriture
 232              flock($fp, LOCK_EX); 
 233              // maintenant qu'on a le seul pointeur on tronque
 234              ftruncate($fp,0); 
 235              // on se replace, comme si on avait ouvert en +w 
 236              rewind($fp); 
 237              fwrite($fp, $this->data, strlen($this->data));
 238              // lock relaché, on peut acceder en lecture 
 239              flock($fp, LOCK_UN);  
 240              fclose($fp);
 241              @chmod($this->file, 0666);
 242              return true;
 243          }
 244          return false;
 245      }
 246  
 247      /**
 248       * Lit les données dans le cache
 249       *
 250       * @return boolean - true si l'on a pu lire le cache, false sinon
 251       * @access private
 252       */
 253      function read() 
 254      {
 255          $fp = @fopen($this->file, 'r');
 256          if ($fp) {
 257              flock($fp, LOCK_SH);
 258              $this->data = '';
 259              while ($tmp=fread($fp, 4096)) {
 260                  $this->data .= $tmp;
 261              }
 262              // un ralachement du lock, même si normalement ca marche sans 
 263              flock($fp, LOCK_UN);
 264              fclose($fp);
 265              return true;
 266          }
 267          return false;
 268      }
 269  }
 270  ?>


Généré le : Mon Nov 26 11:57:01 2007 par Balluche grâce à PHPXref 0.7
  Clicky Web Analytics