cache.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: cache.php 8193 2009-06-10 17:11:17Z gwoo $ */
00003 /**
00004  * Short description for file.
00005  *
00006  * Long description for file
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs.view.helpers
00021  * @since         CakePHP(tm) v 1.0.0.2277
00022  * @version       $Revision: 8193 $
00023  * @modifiedby    $LastChangedBy: gwoo $
00024  * @lastmodified  $Date: 2009-06-10 13:11:17 -0400 (Wed, 10 Jun 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Short description for file.
00029  *
00030  * Long description for file
00031  *
00032  * @package       cake
00033  * @subpackage    cake.cake.libs.view.helpers
00034  */
00035 class CacheHelper extends AppHelper {
00036 /**
00037  * Array of strings replaced in cached views.
00038  * The strings are found between <cake:nocache><cake:nocache> in views
00039  *
00040  * @var array
00041  * @access private
00042  */
00043     var $__replace = array();
00044 /**
00045  * Array of string that are replace with there var replace above.
00046  * The strings are any content inside <cake:nocache><cake:nocache> and includes the tags in views
00047  *
00048  * @var array
00049  * @access private
00050  */
00051     var $__match = array();
00052 /**
00053  * holds the View object passed in final call to CacheHelper::cache()
00054  *
00055  * @var View
00056  * @access public
00057  */
00058     var $view;
00059 /**
00060  * cache action time
00061  *
00062  * @var object
00063  * @access public
00064  */
00065     var $cacheAction;
00066 /**
00067  * Main method used to cache a view
00068  *
00069  * @param string $file File to cache
00070  * @param string $out output to cache
00071  * @param boolean $cache
00072  * @return view ouput
00073  */
00074     function cache($file, $out, $cache = false) {
00075         $cacheTime = 0;
00076         $useCallbacks = false;
00077         if (is_array($this->cacheAction)) {
00078             $contoller = Inflector::underscore($this->controllerName);
00079             $check = str_replace('/', '_', $this->here);
00080             $replace = str_replace('/', '_', $this->base);
00081             $match = str_replace($this->base, '', $this->here);
00082             $match = str_replace('//', '/', $match);
00083             $match = str_replace('/' . $contoller . '/', '', $match);
00084             $match = str_replace('/' . $this->controllerName . '/', '', $match);
00085             $check = str_replace($replace, '', $check);
00086             $check = str_replace('_' . $contoller . '_', '', $check);
00087             $check = str_replace('_' . $this->controllerName . '_', '', $check);
00088             $check = Inflector::slug($check);
00089             $check = preg_replace('/^_+/', '', $check);
00090             $keys = str_replace('/', '_', array_keys($this->cacheAction));
00091             $found = array_keys($this->cacheAction);
00092             $index = null;
00093             $count = 0;
00094 
00095             foreach ($keys as $key => $value) {
00096                 if (strpos($check, $value) === 0) {
00097                     $index = $found[$count];
00098                     break;
00099                 }
00100                 $count++;
00101             }
00102 
00103             if (isset($index)) {
00104                 $pos1 = strrpos($match, '/');
00105                 $char = strlen($match) - 1;
00106 
00107                 if ($pos1 == $char) {
00108                     $match = substr($match, 0, $char);
00109                 }
00110 
00111                 $key = $match;
00112             } elseif ($this->action == 'index') {
00113                 $index = 'index';
00114             }
00115 
00116             $options = $this->cacheAction;
00117             if (isset($this->cacheAction[$index])) {
00118                 if (is_array($this->cacheAction[$index])) {
00119                     $options = array_merge(array('duration'=> 0, 'callbacks' => false), $this->cacheAction[$index]);
00120                 } else {
00121                     $cacheTime = $this->cacheAction[$index];
00122                 }
00123             }
00124 
00125             if (array_key_exists('duration', $options)) {
00126                 $cacheTime = $options['duration'];
00127             }
00128             if (array_key_exists('callbacks', $options)) {
00129                 $useCallbacks = $options['callbacks'];
00130             }
00131 
00132         } else {
00133             $cacheTime = $this->cacheAction;
00134         }
00135 
00136         if ($cacheTime != '' && $cacheTime > 0) {
00137             $this->__parseFile($file, $out);
00138             if ($cache === true) {
00139                 $cached = $this->__parseOutput($out);
00140                 $this->__writeFile($cached, $cacheTime, $useCallbacks);
00141             }
00142             return $out;
00143         } else {
00144             return $out;
00145         }
00146     }
00147 /**
00148  * Parse file searching for no cache tags
00149  *
00150  * @param string $file
00151  * @param boolean $cache
00152  * @access private
00153  */
00154     function __parseFile($file, $cache) {
00155         if (is_file($file)) {
00156             $file = file_get_contents($file);
00157         } elseif ($file = fileExistsInPath($file)) {
00158             $file = file_get_contents($file);
00159         }
00160 
00161         preg_match_all('/(<cake:nocache>(?<=<cake:nocache>)[\\s\\S]*?(?=<\/cake:nocache>)<\/cake:nocache>)/i', $cache, $oresult, PREG_PATTERN_ORDER);
00162         preg_match_all('/(?<=<cake:nocache>)([\\s\\S]*?)(?=<\/cake:nocache>)/i', $file, $result, PREG_PATTERN_ORDER);
00163 
00164         if (!empty($this->__replace)) {
00165             foreach ($oresult['0'] as $k => $element) {
00166                 $index = array_search($element, $this->__match);
00167                 if ($index !== false) {
00168                     array_splice($oresult[0], $k, 1);
00169                 }
00170             }
00171         }
00172 
00173         if (!empty($result['0'])) {
00174             $count = 0;
00175             foreach ($result['0'] as $block) {
00176                 if (isset($oresult['0'][$count])) {
00177                     $this->__replace[] = $block;
00178                     $this->__match[] = $oresult['0'][$count];
00179                 }
00180                 $count++;
00181             }
00182         }
00183     }
00184 /**
00185  * Parse the output and replace cache tags
00186  *
00187  * @param sting $cache
00188  * @return string with all replacements made to <cake:nocache><cake:nocache>
00189  * @access private
00190  */
00191     function __parseOutput($cache) {
00192         $count = 0;
00193         if (!empty($this->__match)) {
00194 
00195             foreach ($this->__match as $found) {
00196                 $original = $cache;
00197                 $length = strlen($found);
00198                 $position = 0;
00199 
00200                     for ($i = 1; $i <= 1; $i++) {
00201                         $position = strpos($cache, $found, $position);
00202 
00203                         if ($position !== false) {
00204                             $cache = substr($original, 0, $position);
00205                             $cache .= $this->__replace[$count];
00206                             $cache .= substr($original, $position + $length);
00207                         } else {
00208                             break;
00209                         }
00210                     }
00211                     $count++;
00212             }
00213             return $cache;
00214         }
00215         return $cache;
00216     }
00217 /**
00218  * Write a cached version of the file
00219  *
00220  * @param string $file
00221  * @param sting $timestamp
00222  * @return cached view
00223  * @access private
00224  */
00225     function __writeFile($content, $timestamp, $useCallbacks = false) {
00226         $now = time();
00227 
00228         if (is_numeric($timestamp)) {
00229             $cacheTime = $now + $timestamp;
00230         } else {
00231             $cacheTime = strtotime($timestamp, $now);
00232         }
00233         $path = $this->here;
00234         if ($this->here == '/') {
00235             $path = 'home';
00236         }
00237         $cache = strtolower(Inflector::slug($path));
00238 
00239         if (empty($cache)) {
00240             return;
00241         }
00242         $cache = $cache . '.php';
00243         $file = '<!--cachetime:' . $cacheTime . '--><?php';
00244 
00245         if (empty($this->plugin)) {
00246             $file .= '
00247             App::import(\'Controller\', \'' . $this->controllerName. '\');
00248             ';
00249         } else {
00250             $file .= '
00251             App::import(\'Controller\', \'' . $this->plugin . '.' . $this->controllerName. '\');
00252             ';
00253         }
00254 
00255         $file .= '$controller =& new ' . $this->controllerName . 'Controller();
00256                 $controller->plugin = $this->plugin = \''.$this->plugin.'\';
00257                 $controller->helpers = $this->helpers = unserialize(\'' . serialize($this->helpers) . '\');
00258                 $controller->base = $this->base = \'' . $this->base . '\';
00259                 $controller->layout = $this->layout = \'' . $this->layout. '\';
00260                 $controller->webroot = $this->webroot = \'' . $this->webroot . '\';
00261                 $controller->here = $this->here = \'' . $this->here . '\';
00262                 $controller->namedArgs  = $this->namedArgs  = \'' . $this->namedArgs . '\';
00263                 $controller->argSeparator = $this->argSeparator = \'' . $this->argSeparator . '\';
00264                 $controller->params = $this->params = unserialize(stripslashes(\'' . addslashes(serialize($this->params)) . '\'));
00265                 $controller->action = $this->action = unserialize(\'' . serialize($this->action) . '\');
00266                 $controller->data = $this->data = unserialize(stripslashes(\'' . addslashes(serialize($this->data)) . '\'));
00267                 $controller->themeWeb = $this->themeWeb = \'' . $this->themeWeb . '\';
00268                 Router::setRequestInfo(array($this->params, array(\'base\' => $this->base, \'webroot\' => $this->webroot)));';
00269 
00270         if ($useCallbacks == true) {
00271             $file .= '
00272                 $controller->constructClasses();
00273                 $controller->Component->initialize($controller);
00274                 $controller->beforeFilter();
00275                 $controller->Component->startup($controller);';
00276         }
00277 
00278         $file .= '
00279                 $loadedHelpers = array();
00280                 $loadedHelpers = $this->_loadHelpers($loadedHelpers, $this->helpers);
00281                 foreach (array_keys($loadedHelpers) as $helper) {
00282                     $camelBackedHelper = Inflector::variable($helper);
00283                     ${$camelBackedHelper} =& $loadedHelpers[$helper];
00284                     $this->loaded[$camelBackedHelper] =& ${$camelBackedHelper};
00285                 }
00286         ?>';
00287         $content = preg_replace("/(<\\?xml)/", "<?php echo '$1';?>",$content);
00288         $file .= $content;
00289         return cache('views' . DS . $cache, $file, $timestamp);
00290     }
00291 }
00292 
00293 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7