[ Index ]
 

Code source de Symfony 1.0.0

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

title

Body

[fermer]

/lib/view/ -> sfViewCacheManager.class.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the symfony package.
   5   * (c) 2004-2006 Fabien Potencier <fabien.potencier@symfony-project.com>
   6   *
   7   * For the full copyright and license information, please view the LICENSE
   8   * file that was distributed with this source code.
   9   */
  10  
  11  /**
  12   * Cache class to cache the HTML results for actions and templates.
  13   *
  14   * This class uses $cacheClass class to store cache.
  15   * All cache files are stored in files in the [sf_root_dir].'/cache/'.[sf_app].'/html' directory.
  16   * To disable all caching, you can set to false [sf_cache] constant.
  17   *
  18   * @package    symfony
  19   * @subpackage view
  20   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  21   * @version    SVN: $Id: sfViewCacheManager.class.php 3232 2007-01-11 20:51:54Z fabien $
  22   */
  23  class sfViewCacheManager
  24  {
  25    protected
  26      $cache              = null,
  27      $cacheConfig        = array(),
  28      $context            = null,
  29      $controller         = null,
  30      $loaded             = array();
  31  
  32    /**
  33     * Initializes the cache manager.
  34     *
  35     * @param sfContext Current application context
  36     * @param sfCache Type of the cache
  37     * @param array Cache parameters
  38     */
  39    public function initialize($context, $cacheClass, $cacheParameters = array())
  40    {
  41      $this->context    = $context;
  42      $this->controller = $context->getController();
  43  
  44      // empty configuration
  45      $this->cacheConfig = array();
  46  
  47      // create cache instance
  48      $this->cache = new $cacheClass();
  49      $this->cache->initialize($cacheParameters);
  50  
  51      // register a named route for our partial cache (at the end)
  52      $r = sfRouting::getInstance();
  53      if (!$r->hasRouteName('sf_cache_partial'))
  54      {
  55        $r->connect('sf_cache_partial', '/sf_cache_partial/:module/:action/:sf_cache_key.', array(), array());
  56      }
  57    }
  58  
  59    /**
  60     * Retrieves the current cache context.
  61     *
  62     * @return sfContext The sfContext instance
  63     */
  64    public function getContext()
  65    {
  66      return $this->context;
  67    }
  68  
  69    /**
  70     * Retrieves the current cache type.
  71     *
  72     * @return sfCache The current cache type
  73     */
  74    public function getCache()
  75    {
  76      return $this->cache;
  77    }
  78  
  79    /**
  80     * Generates namespaces for the cache manager
  81     *
  82     * @param string Internal unified resource identifier.
  83     *
  84     * @return array Path and filename for the current namespace
  85     *
  86     * @throws <b>sfException</b> if the generation fails
  87     */
  88    public function generateNamespace($internalUri)
  89    {
  90      if ($callable = sfConfig::get('sf_cache_namespace_callable'))
  91      {
  92        if (!is_callable($callable))
  93        {
  94          throw new sfException(sprintf('"%s" cannot be called as a function.', var_export($callable, true)));
  95        }
  96  
  97        return call_user_func($callable, $internalUri);
  98      }
  99  
 100      // generate uri
 101      // we want our URL with / only
 102      $oldUrlFormat = sfConfig::get('sf_url_format');
 103      sfConfig::set('sf_url_format', 'PATH');
 104      if ($this->isContextual($internalUri))
 105      {
 106        list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
 107        $uri = $this->controller->genUrl(sfRouting::getInstance()->getCurrentInternalUri()).sprintf('/%s/%s/%s', $params['module'], $params['action'], $params['sf_cache_key']);
 108      }
 109      else
 110      {
 111        $uri = $this->controller->genUrl($internalUri);
 112      }
 113      sfConfig::set('sf_url_format', $oldUrlFormat);
 114  
 115      // prefix with vary headers
 116      $varyHeaders = $this->getVary($internalUri);
 117      if ($varyHeaders)
 118      {
 119        sort($varyHeaders);
 120        $request = $this->getContext()->getRequest();
 121        $vary = '';
 122  
 123        foreach ($varyHeaders as $header)
 124        {
 125          $vary .= $request->getHttpHeader($header).'|';
 126        }
 127  
 128        $vary = $vary;
 129      }
 130      else
 131      {
 132        $vary = 'all';
 133      }
 134  
 135      // prefix with hostname
 136      $request = $this->context->getRequest();
 137      $hostName = $request->getHost();
 138      $hostName = preg_replace('/[^a-z0-9]/i', '_', $hostName);
 139      $hostName = strtolower(preg_replace('/_+/', '_', $hostName));
 140  
 141      $uri = '/'.$hostName.'/'.$vary.'/'.$uri;
 142  
 143      // replace multiple /
 144      $uri = preg_replace('#/+#', '/', $uri);
 145  
 146      return array(dirname($uri), basename($uri));
 147    }
 148  
 149    /**
 150     * Adds a cache to the manager.
 151     *
 152     * @param string Module name
 153     * @param string Action name
 154     * @param array Options for the cache
 155     */
 156    public function addCache($moduleName, $actionName, $options = array())
 157    {
 158      // normalize vary headers
 159      foreach ($options['vary'] as $key => $name)
 160      {
 161        $options['vary'][$key] = strtr(strtolower($name), '_', '-');
 162      }
 163  
 164      $options['lifeTime'] = isset($options['lifeTime']) ? $options['lifeTime'] : 0;
 165      if (!isset($this->cacheConfig[$moduleName]))
 166      {
 167        $this->cacheConfig[$moduleName] = array();
 168      }
 169      $this->cacheConfig[$moduleName][$actionName] = array(
 170        'withLayout'     => isset($options['withLayout']) ? $options['withLayout'] : false,
 171        'lifeTime'       => $options['lifeTime'],
 172        'clientLifeTime' => isset($options['clientLifeTime']) && $options['clientLifeTime'] ? $options['clientLifeTime'] : $options['lifeTime'],
 173        'contextual'     => isset($options['contextual']) ? $options['contextual'] : false,
 174        'vary'           => isset($options['vary']) ? $options['vary'] : array(),
 175      );
 176    }
 177  
 178    /**
 179     * Registers configuration options for the cache.
 180     *
 181     * @param string Module name
 182     */
 183    public function registerConfiguration($moduleName)
 184    {
 185      if (!isset($loaded[$moduleName]))
 186      {
 187        require(sfConfigCache::getInstance()->checkConfig(sfConfig::get('sf_app_module_dir_name').'/'.$moduleName.'/'.sfConfig::get('sf_app_module_config_dir_name').'/cache.yml'));
 188        $loaded[$moduleName] = true;
 189      }
 190    }
 191  
 192    /**
 193     * Retrieves the layout from the cache option list.
 194     *
 195     * @param string Internal uniform resource identifier
 196     *
 197     * @return boolean true, if have layout otherwise false
 198     */
 199    public function withLayout($internalUri)
 200    {
 201      return $this->getCacheConfig($internalUri, 'withLayout', false);
 202    }
 203  
 204    /**
 205     * Retrieves lifetime from the cache option list.
 206     *
 207     * @param string Internal uniform resource identifier
 208     *
 209     * @return int LifeTime
 210     */
 211    public function getLifeTime($internalUri)
 212    {
 213      return $this->getCacheConfig($internalUri, 'lifeTime', 0);
 214    }
 215  
 216    /**
 217     * Retrieves client lifetime from the cache option list
 218     *
 219     * @param string Internal uniform resource identifier
 220     *
 221     * @return int Client lifetime
 222     */
 223    public function getClientLifeTime($internalUri)
 224    {
 225      return $this->getCacheConfig($internalUri, 'clientLifeTime', 0);
 226    }
 227  
 228    /**
 229     * Retrieves contextual option from the cache option list.
 230     *
 231     * @param string Internal uniform resource identifier
 232     *
 233     * @return boolean true, if is contextual otherwise false
 234     */
 235    public function isContextual($internalUri)
 236    {
 237      return $this->getCacheConfig($internalUri, 'contextual', false);
 238    }
 239  
 240    /**
 241     * Retrieves vary option from the cache option list.
 242     *
 243     * @param string Internal uniform resource identifier
 244     *
 245     * @return array Vary options for the cache
 246     */
 247    public function getVary($internalUri)
 248    {
 249      return $this->getCacheConfig($internalUri, 'vary', array());
 250    }
 251  
 252    /**
 253     * Gets a config option from the cache.
 254     *
 255     * @param string Internal uniform resource identifier
 256     * @param string Option name
 257     * @param string Default value of the option
 258     *
 259     * @return mixed Value of the option
 260     */
 261    protected function getCacheConfig($internalUri, $key, $defaultValue = null)
 262    {
 263      list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
 264  
 265      $value = $defaultValue;
 266      if (isset($this->cacheConfig[$params['module']][$params['action']][$key]))
 267      {
 268        $value = $this->cacheConfig[$params['module']][$params['action']][$key];
 269      }
 270      else if (isset($this->cacheConfig[$params['module']]['DEFAULT'][$key]))
 271      {
 272        $value = $this->cacheConfig[$params['module']]['DEFAULT'][$key];
 273      }
 274  
 275      return $value;
 276    }
 277  
 278    /**
 279     * Returns true if the current content is cacheable.
 280     *
 281     * @param string Internal uniform resource identifier
 282     *
 283     * @return boolean true, if the content is cacheable otherwise false
 284     */
 285    public function isCacheable($internalUri)
 286    {
 287      list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
 288  
 289      if (isset($this->cacheConfig[$params['module']][$params['action']]))
 290      {
 291        return ($this->cacheConfig[$params['module']][$params['action']]['lifeTime'] > 0);
 292      }
 293      else if (isset($this->cacheConfig[$params['module']]['DEFAULT']))
 294      {
 295        return ($this->cacheConfig[$params['module']]['DEFAULT']['lifeTime'] > 0);
 296      }
 297  
 298      return false;
 299    }
 300  
 301    /**
 302     * Retrieves namespace for the current cache.
 303     *
 304     * @param string Internal uniform resource identifier
 305     *
 306     * @return string The data of the cache
 307     */
 308    public function get($internalUri)
 309    {
 310      // no cache or no cache set for this action
 311      if (!$this->isCacheable($internalUri) || $this->ignore())
 312      {
 313        return null;
 314      }
 315  
 316      list($namespace, $id) = $this->generateNamespace($internalUri);
 317  
 318      $this->cache->setLifeTime($this->getLifeTime($internalUri));
 319  
 320      $retval = $this->cache->get($id, $namespace);
 321  
 322      if (sfConfig::get('sf_logging_enabled'))
 323      {
 324        $this->getContext()->getLogger()->info(sprintf('{sfViewCacheManager} cache for "%s" %s', $internalUri, ($retval !== null ? 'exists' : 'does not exist')));
 325      }
 326  
 327      return $retval;
 328    }
 329  
 330    /**
 331     * Returns true if there is a cache.
 332     *
 333     * @param string Internal uniform resource identifier
 334     *
 335     * @return boolean true, if there is a cache otherwise false
 336     */
 337    public function has($internalUri)
 338    {
 339      if (!$this->isCacheable($internalUri) || $this->ignore())
 340      {
 341        return null;
 342      }
 343  
 344      list($namespace, $id) = $this->generateNamespace($internalUri);
 345  
 346      $this->cache->setLifeTime($this->getLifeTime($internalUri));
 347  
 348      return $this->cache->has($id, $namespace);
 349    }
 350  
 351    /**
 352     * Ignores the cache functionality.
 353     *
 354     * @return boolean true, if the cache is ignore otherwise false
 355     */
 356    protected function ignore()
 357    {
 358      // ignore cache parameter? (only available in debug mode)
 359      if (sfConfig::get('sf_debug') && $this->getContext()->getRequest()->getParameter('_sf_ignore_cache', false, 'symfony/request/sfWebRequest') == true)
 360      {
 361        if (sfConfig::get('sf_logging_enabled'))
 362        {
 363          $this->getContext()->getLogger()->info('{sfViewCacheManager} discard cache');
 364        }
 365  
 366        return true;
 367      }
 368  
 369      return false;
 370    }
 371  
 372    /**
 373     * Sets the cache content
 374     *
 375     * @param string Data to put in the cache
 376     * @param string Internal uniform resource identifier
 377     *
 378     * @return boolean true, if the data get set successfully otherwise false
 379     */
 380    public function set($data, $internalUri)
 381    {
 382      if (!$this->isCacheable($internalUri))
 383      {
 384        return false;
 385      }
 386  
 387      list($namespace, $id) = $this->generateNamespace($internalUri);
 388  
 389      try
 390      {
 391        $ret = $this->cache->set($id, $namespace, $data);
 392      }
 393      catch (Exception $e)
 394      {
 395        return false;
 396      }
 397  
 398      if (sfConfig::get('sf_logging_enabled'))
 399      {
 400        $this->context->getLogger()->info(sprintf('{sfViewCacheManager} save cache for "%s"', $internalUri));
 401      }
 402  
 403      return true;
 404    }
 405  
 406    /**
 407     * Removes the cache for the current namespace.
 408     *
 409     * @param string Internal uniform resource identifier
 410     *
 411     * @return boolean true, if the remove happend otherwise false
 412     */
 413    public function remove($internalUri)
 414    {
 415      list($namespace, $id) = $this->generateNamespace($internalUri);
 416  
 417      if (sfConfig::get('sf_logging_enabled'))
 418      {
 419        $this->context->getLogger()->info(sprintf('{sfViewCacheManager} remove cache for "%s"', $internalUri));
 420      }
 421  
 422      if ($this->cache->has($id, $namespace))
 423      {
 424        $this->cache->remove($id, $namespace);
 425      }
 426    }
 427  
 428    /**
 429     * Retrieves the last modified time.
 430     *
 431     * @param string Internal uniform resource identifier
 432     *
 433     * @return string Last modified datetime for the current namespace
 434     */
 435    public function lastModified($internalUri)
 436    {
 437      if (!$this->isCacheable($internalUri))
 438      {
 439        return null;
 440      }
 441  
 442      list($namespace, $id) = $this->generateNamespace($internalUri);
 443  
 444      return $this->cache->lastModified($id, $namespace);
 445    }
 446  
 447    /**
 448     * Starts the fragment cache.
 449     *
 450     * @param string Unique fragment name
 451     * @param string Life time for the cache
 452     * @param string Client life time for the cache
 453     * @param array Vary options for the cache
 454     *
 455     * @return boolean true, if success otherwise false
 456     */
 457    public function start($name, $lifeTime, $clientLifeTime = null, $vary = array())
 458    {
 459      $internalUri = sfRouting::getInstance()->getCurrentInternalUri();
 460  
 461      if (!$clientLifeTime)
 462      {
 463        $clientLifeTime = $lifeTime;
 464      }
 465  
 466      // add cache config to cache manager
 467      list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
 468      $this->addCache($params['module'], $params['action'], array('withLayout' => false, 'lifeTime' => $lifeTime, 'clientLifeTime' => $clientLifeTime, 'vary' => $vary));
 469  
 470      // get data from cache if available
 471      $data = $this->get($internalUri.(strpos($internalUri, '?') ? '&' : '?').'_sf_cache_key='.$name);
 472      if ($data !== null)
 473      {
 474        return $data;
 475      }
 476      else
 477      {
 478        ob_start();
 479        ob_implicit_flush(0);
 480  
 481        return null;
 482      }
 483    }
 484  
 485    /**
 486     * Stops the fragment cache.
 487     *
 488     * @param string Unique fragment name
 489     *
 490     * @return boolean true, if success otherwise false
 491     */
 492    public function stop($name)
 493    {
 494      $data = ob_get_clean();
 495  
 496      // save content to cache
 497      $internalUri = sfRouting::getInstance()->getCurrentInternalUri();
 498      try
 499      {
 500        $this->set($data, $internalUri.(strpos($internalUri, '?') ? '&' : '?').'_sf_cache_key='.$name);
 501      }
 502      catch (Exception $e)
 503      {
 504      }
 505  
 506      return $data;
 507    }
 508  
 509    /**
 510     * Executes the shutdown procedure.
 511     */
 512    public function shutdown()
 513    {
 514    }
 515  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7