[ Index ]
 

Code source de Symfony 1.0.0

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

title

Body

[fermer]

/lib/filter/ -> sfCacheFilter.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   * sfCacheFilter deals with page caching and action caching.
  13   *
  14   * @package    symfony
  15   * @subpackage filter
  16   * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
  17   * @version    SVN: $Id: sfCacheFilter.class.php 3502 2007-02-18 18:28:28Z fabien $
  18   */
  19  class sfCacheFilter extends sfFilter
  20  {
  21    protected
  22      $cacheManager = null,
  23      $request      = null,
  24      $response     = null,
  25      $cache        = array();
  26  
  27    /**
  28     * Initializes this Filter.
  29     *
  30     * @param sfContext The current application context
  31     * @param array   An associative array of initialization parameters
  32     *
  33     * @return bool true, if initialization completes successfully, otherwise false
  34     *
  35     * @throws <b>sfInitializationException</b> If an error occurs while initializing this Filter
  36     */
  37    public function initialize($context, $parameters = array())
  38    {
  39      parent::initialize($context, $parameters);
  40  
  41      $this->cacheManager = $context->getViewCacheManager();
  42      $this->request      = $context->getRequest();
  43      $this->response     = $context->getResponse();
  44    }
  45  
  46    /**
  47     * Executes this filter.
  48     *
  49     * @param sfFilterChain A sfFilterChain instance
  50     */
  51    public function execute($filterChain)
  52    {
  53      // execute this filter only once, if cache is set and no GET or POST parameters
  54      if (!sfConfig::get('sf_cache') || count($_GET) || count($_POST))
  55      {
  56        $filterChain->execute();
  57  
  58        return;
  59      }
  60  
  61      if ($this->executeBeforeExecution())
  62      {
  63        $filterChain->execute();
  64      }
  65  
  66      $this->executeBeforeRendering();
  67    }
  68  
  69    public function executeBeforeExecution()
  70    {
  71      // register our cache configuration
  72      $this->cacheManager->registerConfiguration($this->getContext()->getModuleName());
  73  
  74      $uri = sfRouting::getInstance()->getCurrentInternalUri();
  75  
  76      // page cache
  77      $this->cache[$uri] = array('page' => false, 'action' => false);
  78      $cacheable = $this->cacheManager->isCacheable($uri);
  79      if ($cacheable)
  80      {
  81        if ($this->cacheManager->withLayout($uri))
  82        {
  83          $inCache = $this->getPageCache($uri);
  84          $this->cache[$uri]['page'] = !$inCache;
  85  
  86          if ($inCache)
  87          {
  88            // page is in cache, so no need to run execution filter
  89            return false;
  90          }
  91        }
  92        else
  93        {
  94          $inCache = $this->getActionCache($uri);
  95          $this->cache[$uri]['action'] = !$inCache;
  96        }
  97      }
  98  
  99      return true;
 100    }
 101  
 102    /**
 103     * Executes this filter.
 104     *
 105     * @param sfFilterChain A sfFilterChain instance.
 106     */
 107    public function executeBeforeRendering()
 108    {
 109      // cache only 200 HTTP status
 110      if ($this->response->getStatusCode() == 200)
 111      {
 112        $uri = sfRouting::getInstance()->getCurrentInternalUri();
 113  
 114        // save page in cache
 115        if ($this->cache[$uri]['page'])
 116        {
 117          // set some headers that deals with cache
 118          $lifetime = $this->cacheManager->getClientLifeTime($uri, 'page');
 119          $this->response->setHttpHeader('Last-Modified', $this->response->getDate(time()), false);
 120          $this->response->setHttpHeader('Expires', $this->response->getDate(time() + $lifetime), false);
 121          $this->response->addCacheControlHttpHeader('max-age', $lifetime);
 122  
 123          // set Vary headers
 124          foreach ($this->cacheManager->getVary($uri, 'page') as $vary)
 125          {
 126            $this->response->addVaryHttpHeader($vary);
 127          }
 128  
 129          $this->setPageCache($uri);
 130        }
 131        else if ($this->cache[$uri]['action'])
 132        {
 133          // save action in cache
 134          $this->setActionCache($uri);
 135        }
 136      }
 137  
 138      // remove PHP automatic Cache-Control and Expires headers if not overwritten by application or cache
 139      if ($this->response->hasHttpHeader('Last-Modified') || sfConfig::get('sf_etag'))
 140      {
 141        // FIXME: these headers are set by PHP sessions (see session_cache_limiter())
 142        $this->response->setHttpHeader('Cache-Control', null, false);
 143        $this->response->setHttpHeader('Expires', null, false);
 144        $this->response->setHttpHeader('Pragma', null, false);
 145      }
 146  
 147      // Etag support
 148      if (sfConfig::get('sf_etag'))
 149      {
 150        $etag = md5($this->response->getContent());
 151        $this->response->setHttpHeader('ETag', $etag);
 152  
 153        if ($this->request->getHttpHeader('IF_NONE_MATCH') == $etag)
 154        {
 155          $this->response->setStatusCode(304);
 156          $this->response->setHeaderOnly(true);
 157  
 158          if (sfConfig::get('sf_logging_enabled'))
 159          {
 160            $this->getContext()->getLogger()->info('{sfFilter} ETag matches If-None-Match (send 304)');
 161          }
 162        }
 163      }
 164  
 165      // conditional GET support
 166      // never in debug mode
 167      if ($this->response->hasHttpHeader('Last-Modified') && !sfConfig::get('sf_debug'))
 168      {
 169        $last_modified = $this->response->getHttpHeader('Last-Modified');
 170        $last_modified = $last_modified[0];
 171        if ($this->request->getHttpHeader('IF_MODIFIED_SINCE') == $last_modified)
 172        {
 173          $this->response->setStatusCode(304);
 174          $this->response->setHeaderOnly(true);
 175  
 176          if (sfConfig::get('sf_logging_enabled'))
 177          {
 178            $this->getContext()->getLogger()->info('{sfFilter} Last-Modified matches If-Modified-Since (send 304)');
 179          }
 180        }
 181      }
 182    }
 183  
 184    /**
 185     * Sets a page template in the cache.
 186     *
 187     * @param string The internal URI
 188     */
 189    protected function setPageCache($uri)
 190    {
 191      if ($this->getContext()->getController()->getRenderMode() != sfView::RENDER_CLIENT)
 192      {
 193        return;
 194      }
 195  
 196      // save content in cache
 197      $this->cacheManager->set(serialize($this->response), $uri);
 198  
 199      if (sfConfig::get('sf_web_debug'))
 200      {
 201        $content = sfWebDebug::getInstance()->decorateContentWithDebug($uri, $this->response->getContent(), true);
 202        $this->response->setContent($content);
 203      }
 204    }
 205  
 206    /**
 207     * Gets a page template from the cache.
 208     *
 209     * @param string The internal URI
 210     */
 211    protected function getPageCache($uri)
 212    {
 213      $context = $this->getContext();
 214  
 215      // get the current action information
 216      $moduleName = $context->getModuleName();
 217      $actionName = $context->getActionName();
 218  
 219      $retval = $this->cacheManager->get($uri);
 220  
 221      if ($retval === null)
 222      {
 223        return false;
 224      }
 225  
 226      $cachedResponse = unserialize($retval);
 227      $cachedResponse->setContext($context);
 228  
 229      $controller = $context->getController();
 230      if ($controller->getRenderMode() == sfView::RENDER_VAR)
 231      {
 232        $controller->getActionStack()->getLastEntry()->setPresentation($cachedResponse->getContent());
 233        $this->response->setContent('');
 234      }
 235      else
 236      {
 237        $context->setResponse($cachedResponse);
 238        $this->response = $this->getContext()->getResponse();
 239  
 240        if (sfConfig::get('sf_web_debug'))
 241        {
 242          $content = sfWebDebug::getInstance()->decorateContentWithDebug($uri, $this->response->getContent(), false);
 243          $this->response->setContent($content);
 244        }
 245      }
 246  
 247      return true;
 248    }
 249  
 250    /**
 251     * Sets an action template in the cache.
 252     *
 253     * @param string The internal URI
 254     */
 255    protected function setActionCache($uri)
 256    {
 257      $content = $this->response->getParameter($uri.'_action', null, 'symfony/cache');
 258  
 259      if ($content !== null)
 260      {
 261        $this->cacheManager->set($content, $uri);
 262      }
 263    }
 264  
 265    /**
 266     * Gets an action template from the cache.
 267     *
 268     * @param string The internal URI
 269     */
 270    protected function getActionCache($uri)
 271    {
 272      // retrieve content from cache
 273      $retval = $this->cacheManager->get($uri);
 274  
 275      if ($retval && sfConfig::get('sf_web_debug'))
 276      {
 277        $cache = unserialize($retval);
 278        $this->response->mergeProperties($cache['response']);
 279        $cache['content'] = sfWebDebug::getInstance()->decorateContentWithDebug($uri, $cache['content'], false);
 280        $retval = serialize($cache);
 281      }
 282  
 283      $this->response->setParameter('current_key', $uri.'_action', 'symfony/cache/current');
 284      $this->response->setParameter($uri.'_action', $retval, 'symfony/cache');
 285  
 286      return $retval ? true : false;
 287    }
 288  }


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