Development

/branches/1.2/lib/view/sfViewCacheManager.class.php

You must first sign up to be able to contribute.

root/branches/1.2/lib/view/sfViewCacheManager.class.php

Revision 11195, 25.7 kB (checked in by fabien, 5 years ago)

[1.1, 1.2] fixed a notice in sfViewCacheManager

  • Property svn:mime-type set to text/x-php
  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Rev Date
Line 
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 a sfCache instance implementation to store cache.
15  *
16  * To disable all caching, you can set the [sf_cache] constant to false.
17  *
18  * @package    symfony
19  * @subpackage view
20  * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
21  * @version    SVN: $Id$
22  */
23 class sfViewCacheManager
24 {
25   protected
26     $cache       = null,
27     $cacheConfig = array(),
28     $context     = null,
29     $dispatcher  = null,
30     $controller  = null,
31     $routing     = null,
32     $loaded      = array();
33
34   /**
35    * Class constructor.
36    *
37    * @see initialize()
38    */
39   public function __construct($context, sfCache $cache)
40   {
41     $this->initialize($context, $cache);
42   }
43
44   /**
45    * Initializes the cache manager.
46    *
47    * @param sfContext $context  Current application context
48    * @param sfCache   $cache    An sfCache instance
49    */
50   public function initialize($context, sfCache $cache)
51   {
52     $this->context    = $context;
53     $this->dispatcher = $context->getEventDispatcher();
54     $this->controller = $context->getController();
55
56     if (sfConfig::get('sf_web_debug'))
57     {
58       $this->dispatcher->connect('view.cache.filter_content', array($this, 'decorateContentWithDebug'));
59     }
60
61     // empty configuration
62     $this->cacheConfig = array();
63
64     // cache instance
65     $this->cache = $cache;
66
67     // routing instance
68     $this->routing = $context->getRouting();
69   }
70
71   /**
72    * Retrieves the current cache context.
73    *
74    * @return sfContext The sfContext instance
75    */
76   public function getContext()
77   {
78     return $this->context;
79   }
80
81   /**
82    * Retrieves the current cache object.
83    *
84    * @return sfCache The current cache object
85    */
86   public function getCache()
87   {
88     return $this->cache;
89   }
90
91   /**
92    * Generates a unique cache key for an internal URI.
93    * This cache key can be used by any of the cache engines as a unique identifier to a cached resource
94    *
95    * Basically, the cache key generated for the following internal URI:
96    *   module/action?key1=value1&key2=value2
97    * Looks like:
98    *   /localhost/all/module/action/key1/value1/key2/value2
99    *
100    * @param  string $internalUri       The internal unified resource identifier
101    *                                   Accepts rules formatted like 'module/action?key1=value1&key2=value2'
102    *                                   Does not accept rules starting with a route name, except for '@sf_cache_partial'
103    * @param  string $hostName          The host name
104    *                                   Optional - defaults to the current host name bu default
105    * @param  string $vary              The vary headers, separated by |, or "all" for all vary headers
106    *                                   Defaults to 'all'
107    * @param  string $contextualPrefix  The contextual prefix for contextual partials.
108    *                                   Defaults to 'currentModule/currentAction/currentPAram1/currentvalue1'
109    *                                   Used only by the sfViewCacheManager::remove() method
110    *
111    * @return string The cache key
112    *                If some of the parameters contained wildcards (* or **), the generated key will also have wildcards
113    */
114   public function generateCacheKey($internalUri, $hostName = '', $vary = '', $contextualPrefix = '')
115   {
116     if ($callable = sfConfig::get('sf_cache_namespace_callable'))
117     {
118       if (!is_callable($callable))
119       {
120         throw new sfException(sprintf('"%s" cannot be called as a function.', var_export($callable, true)));
121       }
122
123       return call_user_func($callable, $internalUri, $hostName, $vary, $contextualPrefix);
124     }
125
126     if (strpos($internalUri, '@') === 0 && strpos($internalUri, '@sf_cache_partial') === false)
127     {
128       throw new sfException('A cache key cannot be generated for an internal URI using the @rule syntax');
129     }
130
131     $cacheKey = '';
132
133     if ($this->isContextual($internalUri))
134     {
135       // Contextual partial
136       if (!$contextualPrefix)
137       {
138         list($route_name, $params) = $this->controller->convertUrlStringToParameters($this->routing->getCurrentInternalUri());
139         $cacheKey = $this->convertParametersToKey($params);
140       }
141       else
142       {
143         $cacheKey = $contextualPrefix;
144       }
145       list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
146       $cacheKey .= sprintf('/%s/%s/%s', $params['module'], $params['action'], isset($params['sf_cache_key']) ? $params['sf_cache_key'] : '');
147     }
148     else
149     {
150       // Regular action or non-contextual partial
151       list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
152       if ($route_name == 'sf_cache_partial')
153       {
154         $cacheKey = 'sf_cache_partial/';
155       }
156
157       $cacheKey .= $this->convertParametersToKey($params);
158     }
159
160     // prefix with vary headers
161     if (!$vary)
162     {
163       $varyHeaders = $this->getVary($internalUri);
164       if ($varyHeaders)
165       {
166         sort($varyHeaders);
167         $request = $this->context->getRequest();
168         $vary = '';
169
170         foreach ($varyHeaders as $header)
171         {
172           $vary .= $request->getHttpHeader($header).'|';
173         }
174
175         $vary = $vary;
176       }
177       else
178       {
179         $vary = 'all';
180       }
181     }
182
183     // prefix with hostname
184     if (!$hostName)
185     {
186       $request = $this->context->getRequest();
187       $hostName = $request->getHost();
188       $hostName = preg_replace('/[^a-z0-9]/i', '_', $hostName);
189       $hostName = strtolower(preg_replace('/_+/', '_', $hostName));
190     }
191
192     $cacheKey = sprintf('/%s/%s/%s', $hostName, $vary, $cacheKey);
193
194     // replace multiple /
195     $cacheKey = preg_replace('#/+#', '/', $cacheKey);
196
197     return $cacheKey;
198   }
199
200   /**
201    * Transforms an associative array of parameters from an URI into a unique key
202    *
203    * @param  array $params  Associative array of parameters from the URI (including, at least, module and action)
204    *
205    * @return string Unique key
206    */
207   protected function convertParametersToKey($params)
208   {
209     if(!isset($params['module']) || !isset($params['action']))
210     {
211       throw new sfException('A cache key must contain both a module and an action parameter');
212     }
213     $module = $params['module'];
214     unset($params['module']);
215     $action = $params['action'];
216     unset($params['action']);
217     ksort($params);
218     $cacheKey = sprintf('%s/%s', $module, $action);
219     foreach ($params as $key => $value)
220     {
221       $cacheKey .= sprintf('/%s/%s', $key, $value);
222     }
223
224     return $cacheKey;
225   }
226
227   /**
228    * Adds a cache to the manager.
229    *
230    * @param string $moduleName  Module name
231    * @param string $actionName  Action name
232    * @param array  $options     Options for the cache
233    */
234   public function addCache($moduleName, $actionName, $options = array())
235   {
236     // normalize vary headers
237     if (isset($options['vary']))
238     {
239       foreach ($options['vary'] as $key => $name)
240       {
241         $options['vary'][$key] = strtr(strtolower($name), '_', '-');
242       }
243     }
244
245     $options['lifeTime'] = isset($options['lifeTime']) ? $options['lifeTime'] : 0;
246     if (!isset($this->cacheConfig[$moduleName]))
247     {
248       $this->cacheConfig[$moduleName] = array();
249     }
250     $this->cacheConfig[$moduleName][$actionName] = array(
251       'withLayout'     => isset($options['withLayout']) ? $options['withLayout'] : false,
252       'lifeTime'       => $options['lifeTime'],
253       'clientLifeTime' => isset($options['clientLifeTime']) ? $options['clientLifeTime'] : $options['lifeTime'],
254       'contextual'     => isset($options['contextual']) ? $options['contextual'] : false,
255       'vary'           => isset($options['vary']) ? $options['vary'] : array(),
256     );
257   }
258
259   /**
260    * Registers configuration options for the cache.
261    *
262    * @param string $moduleName  Module name
263    */
264   public function registerConfiguration($moduleName)
265   {
266     if (!isset($this->loaded[$moduleName]))
267     {
268       require($this->context->getConfigCache()->checkConfig('modules/'.$moduleName.'/config/cache.yml'));
269       $this->loaded[$moduleName] = true;
270     }
271   }
272
273   /**
274    * Retrieves the layout from the cache option list.
275    *
276    * @param  string $internalUri  Internal uniform resource identifier
277    *
278    * @return bool true, if have layout otherwise false
279    */
280   public function withLayout($internalUri)
281   {
282     return $this->getCacheConfig($internalUri, 'withLayout', false);
283   }
284
285   /**
286    * Retrieves lifetime from the cache option list.
287    *
288    * @param  string $internalUri  Internal uniform resource identifier
289    *
290    * @return int LifeTime
291    */
292   public function getLifeTime($internalUri)
293   {
294     return $this->getCacheConfig($internalUri, 'lifeTime', 0);
295   }
296
297   /**
298    * Retrieves client lifetime from the cache option list
299    *
300    * @param  string $internalUri  Internal uniform resource identifier
301    *
302    * @return int Client lifetime
303    */
304   public function getClientLifeTime($internalUri)
305   {
306     return $this->getCacheConfig($internalUri, 'clientLifeTime', 0);
307   }
308
309   /**
310    * Retrieves contextual option from the cache option list.
311    *
312    * @param  string $internalUri  Internal uniform resource identifier
313    *
314    * @return boolean true, if is contextual otherwise false
315    */
316   public function isContextual($internalUri)
317   {
318     return $this->getCacheConfig($internalUri, 'contextual', false);
319   }
320
321   /**
322    * Retrieves vary option from the cache option list.
323    *
324    * @param  string $internalUri  Internal uniform resource identifier
325    *
326    * @return array Vary options for the cache
327    */
328   public function getVary($internalUri)
329   {
330     return $this->getCacheConfig($internalUri, 'vary', array());
331   }
332
333   /**
334    * Gets a config option from the cache.
335    *
336    * @param string $internalUri   Internal uniform resource identifier
337    * @param string $key           Option name
338    * @param string $defaultValue  Default value of the option
339    *
340    * @return mixed Value of the option
341    */
342   protected function getCacheConfig($internalUri, $key, $defaultValue = null)
343   {
344     list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
345
346     $value = $defaultValue;
347     if (isset($this->cacheConfig[$params['module']][$params['action']][$key]))
348     {
349       $value = $this->cacheConfig[$params['module']][$params['action']][$key];
350     }
351     else if (isset($this->cacheConfig[$params['module']]['DEFAULT'][$key]))
352     {
353       $value = $this->cacheConfig[$params['module']]['DEFAULT'][$key];
354     }
355
356     return $value;
357   }
358
359   /**
360    * Returns true if the current content is cacheable.
361    *
362    * @param  string $internalUri  Internal uniform resource identifier
363    *
364    * @return bool true, if the content is cacheable otherwise false
365    */
366   public function isCacheable($internalUri)
367   {
368     if (count($_GET) || count($_POST))
369     {
370       return false;
371     }
372
373     list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
374
375     if (isset($this->cacheConfig[$params['module']][$params['action']]))
376     {
377       return ($this->cacheConfig[$params['module']][$params['action']]['lifeTime'] > 0);
378     }
379     else if (isset($this->cacheConfig[$params['module']]['DEFAULT']))
380     {
381       return ($this->cacheConfig[$params['module']]['DEFAULT']['lifeTime'] > 0);
382     }
383
384     return false;
385   }
386
387   /**
388    * Retrieves content in the cache.
389    *
390    * @param  string $internalUri  Internal uniform resource identifier
391    *
392    * @return string The content in the cache
393    */
394   public function get($internalUri)
395   {
396     // no cache or no cache set for this action
397     if (!$this->isCacheable($internalUri) || $this->ignore())
398     {
399       return null;
400     }
401
402     $retval = $this->cache->get($this->generateCacheKey($internalUri));
403
404     if (sfConfig::get('sf_logging_enabled'))
405     {
406       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Cache for "%s" %s', $internalUri, $retval !== null ? 'exists' : 'does not exist'))));
407     }
408
409     return $retval;
410   }
411
412   /**
413    * Returns true if there is a cache.
414    *
415    * @param  string $internalUri  Internal uniform resource identifier
416    *
417    * @return bool true, if there is a cache otherwise false
418    */
419   public function has($internalUri)
420   {
421     if (!$this->isCacheable($internalUri) || $this->ignore())
422     {
423       return null;
424     }
425
426     return $this->cache->has($this->generateCacheKey($internalUri));
427   }
428
429   /**
430    * Ignores the cache functionality.
431    *
432    * @return bool true, if the cache is ignore otherwise false
433    */
434   protected function ignore()
435   {
436     // ignore cache parameter? (only available in debug mode)
437     if (sfConfig::get('sf_debug') && $this->context->getRequest()->getAttribute('_sf_ignore_cache'))
438     {
439       if (sfConfig::get('sf_logging_enabled'))
440       {
441         $this->dispatcher->notify(new sfEvent($this, 'application.log', array('Discard cache')));
442       }
443
444       return true;
445     }
446
447     return false;
448   }
449
450   /**
451    * Sets the cache content.
452    *
453    * @param  string $data         Data to put in the cache
454    * @param  string $internalUri  Internal uniform resource identifier
455    *
456    * @return boolean true, if the data get set successfully otherwise false
457    */
458   public function set($data, $internalUri)
459   {
460     if (!$this->isCacheable($internalUri))
461     {
462       return false;
463     }
464
465     try
466     {
467       $ret = $this->cache->set($this->generateCacheKey($internalUri), $data, $this->getLifeTime($internalUri));
468     }
469     catch (Exception $e)
470     {
471       return false;
472     }
473
474     if (sfConfig::get('sf_logging_enabled'))
475     {
476       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Save cache for "%s"', $internalUri))));
477     }
478
479     return true;
480   }
481
482   /**
483    * Removes the content in the cache.
484    *
485    * @param  string $internalUri       Internal uniform resource identifier
486    * @param  string $hostName          The host name
487    * @param  string $vary              The vary headers, separated by |, or "all" for all vary headers
488    * @param  string $contextualPrefix  The removal prefix for contextual partials. Deauls to '**' (all actions, all params)
489    *
490    * @return bool true, if the remove happened, false otherwise
491    */
492   public function remove($internalUri, $hostName = '', $vary = '', $contextualPrefix = '**')
493   {
494     if (sfConfig::get('sf_logging_enabled'))
495     {
496       $this->dispatcher->notify(new sfEvent($this, 'application.log', array(sprintf('Remove cache for "%s"', $internalUri))));
497     }
498
499     $cacheKey = $this->generateCacheKey($internalUri, $hostName, $vary, $contextualPrefix);
500
501     if(strpos($cacheKey, '*'))
502     {
503       return $this->cache->removePattern($cacheKey);
504     }
505     elseif ($this->cache->has($cacheKey))
506     {
507       return $this->cache->remove($cacheKey);
508     }
509   }
510
511   /**
512    * Retrieves the last modified time.
513    *
514    * @param  string $internalUri  Internal uniform resource identifier
515    *
516    * @return int    The last modified datetime
517    */
518   public function getLastModified($internalUri)
519   {
520     if (!$this->isCacheable($internalUri))
521     {
522       return 0;
523     }
524
525     return $this->cache->getLastModified($this->generateCacheKey($internalUri));
526   }
527
528   /**
529    * Retrieves the timeout.
530    *
531    * @param  string $internalUri  Internal uniform resource identifier
532    *
533    * @return int    The timeout datetime
534    */
535   public function getTimeout($internalUri)
536   {
537     if (!$this->isCacheable($internalUri))
538     {
539       return 0;
540     }
541
542     return $this->cache->getTimeout($this->generateCacheKey($internalUri));
543   }
544
545   /**
546    * Starts the fragment cache.
547    *
548    * @param  string $name            Unique fragment name
549    * @param  string $lifeTime        Life time for the cache
550    * @param  string $clientLifeTime  Client life time for the cache
551    * @param  array  $vary            Vary options for the cache
552    *
553    * @return bool true, if success otherwise false
554    */
555   public function start($name, $lifeTime, $clientLifeTime = null, $vary = array())
556   {
557     $internalUri = $this->routing->getCurrentInternalUri();
558
559     if (!$clientLifeTime)
560     {
561       $clientLifeTime = $lifeTime;
562     }
563
564     // add cache config to cache manager
565     list($route_name, $params) = $this->controller->convertUrlStringToParameters($internalUri);
566     $this->addCache($params['module'], $params['action'], array('withLayout' => false, 'lifeTime' => $lifeTime, 'clientLifeTime' => $clientLifeTime, 'vary' => $vary));
567
568     // get data from cache if available
569     $data = $this->get($internalUri.(strpos($internalUri, '?') ? '&' : '?').'_sf_cache_key='.$name);
570     if ($data !== null)
571     {
572       return $data;
573     }
574     else
575     {
576       ob_start();
577       ob_implicit_flush(0);
578
579       return null;
580     }
581   }
582
583   /**
584    * Stops the fragment cache.
585    *
586    * @param  string $name Unique fragment name
587    *
588    * @return bool true, if success otherwise false
589    */
590   public function stop($name)
591   {
592     $data = ob_get_clean();
593
594     // save content to cache
595     $internalUri = $this->routing->getCurrentInternalUri();
596     try
597     {
598       $this->set($data, $internalUri.(strpos($internalUri, '?') ? '&' : '?').'_sf_cache_key='.$name);
599     }
600     catch (Exception $e)
601     {
602     }
603
604     return $data;
605   }
606
607   /**
608    * Computes the cache key based on the passed parameters.
609    *
610    * @param array $parameters  An array of parameters
611    */
612   public function computeCacheKey(array $parameters)
613   {
614     return isset($parameters['sf_cache_key']) ? $parameters['sf_cache_key'] : md5(serialize($parameters));
615   }
616
617   /**
618    * Computes a partial internal URI.
619    *
620    * @param  string $module    The module name
621    * @param  string $action    The action name
622    * @param  string $cacheKey  The cache key
623    *
624    * @return string The internal URI
625    */
626   public function getPartialUri($module, $action, $cacheKey)
627   {
628     return sprintf('@sf_cache_partial?module=%s&action=%s&sf_cache_key=%s', $module, $action, $cacheKey);
629   }
630
631   /**
632    * Returns whether a partial template is in the cache.
633    *
634    * @param  string $module    The module name
635    * @param  string $action    The action name
636    * @param  string $cacheKey  The cache key
637    *
638    * @return bool true if a partial is in the cache, false otherwise
639    */
640   public function hasPartialCache($module, $action, $cacheKey)
641   {
642     return $this->has($this->getPartialUri($module, $action, $cacheKey));
643   }
644
645   /**
646    * Gets a partial template from the cache.
647    *
648    * @param  string $module    The module name
649    * @param  string $action    The action name
650    * @param  string $cacheKey  The cache key
651    *
652    * @return string The cache content
653    */
654   public function getPartialCache($module, $action, $cacheKey)
655   {
656     $uri = $this->getPartialUri($module, $action, $cacheKey);
657
658     if (!$this->isCacheable($uri))
659     {
660       return null;
661     }
662
663     // retrieve content from cache
664     $cache = $this->get($uri);
665
666     if (is_null($cache))
667     {
668       return null;
669     }
670
671     $cache = unserialize($cache);
672     $content = $cache['content'];
673     $this->context->getResponse()->merge($cache['response']);
674
675     if (sfConfig::get('sf_web_debug'))
676     {
677       $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => false)), $content)->getReturnValue();
678     }
679
680     return $content;
681   }
682
683   /**
684    * Sets an action template in the cache.
685    *
686    * @param  string $module    The module name
687    * @param  string $action    The action name
688    * @param  string $cacheKey  The cache key
689    * @param  string $content   The content to cache
690    *
691    * @return string The cached content
692    */
693   public function setPartialCache($module, $action, $cacheKey, $content)
694   {
695     $uri = $this->getPartialUri($module, $action, $cacheKey);
696     if (!$this->isCacheable($uri))
697     {
698       return $content;
699     }
700
701     $saved = $this->set(serialize(array('content' => $content, 'response' => $this->context->getResponse())), $uri);
702
703     if ($saved && sfConfig::get('sf_web_debug'))
704     {
705       $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => true)), $content)->getReturnValue();
706     }
707
708     return $content;
709   }
710
711   /**
712    * Returns whether an action template is in the cache.
713    *
714    * @param  string  $uri  The internal URI
715    *
716    * @return bool true if an action is in the cache, false otherwise
717    */
718   public function hasActionCache($uri)
719   {
720     return $this->has($uri) && !$this->withLayout($uri);
721   }
722
723   /**
724    * Gets an action template from the cache.
725    *
726    * @param  string $uri  The internal URI
727    *
728    * @return array  An array composed of the cached content and the view attribute holder
729    */
730   public function getActionCache($uri)
731   {
732     if (!$this->isCacheable($uri) || $this->withLayout($uri))
733     {
734       return null;
735     }
736
737     // retrieve content from cache
738     $cache = $this->get($uri);
739
740     if (is_null($cache))
741     {
742       return null;
743     }
744
745     $cache = unserialize($cache);
746     $content = $cache['content'];
747     $cache['response']->setEventDispatcher($this->dispatcher);
748     $this->context->getResponse()->copyProperties($cache['response']);
749
750     if (sfConfig::get('sf_web_debug'))
751     {
752       $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => false)), $content)->getReturnValue();
753     }
754
755     return array($content, $cache['decoratorTemplate']);
756   }
757
758   /**
759    * Sets an action template in the cache.
760    *
761    * @param  string $uri                The internal URI
762    * @param  string $content            The content to cache
763    * @param  string $decoratorTemplate  The view attribute holder to cache
764    *
765    * @return string The cached content
766    */
767   public function setActionCache($uri, $content, $decoratorTemplate)
768   {
769     if (!$this->isCacheable($uri) || $this->withLayout($uri))
770     {
771       return $content;
772     }
773
774     $saved = $this->set(serialize(array('content' => $content, 'decoratorTemplate' => $decoratorTemplate, 'response' => $this->context->getResponse())), $uri);
775
776     if ($saved && sfConfig::get('sf_web_debug'))
777     {
778       $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => true)), $content)->getReturnValue();
779     }
780
781     return $content;
782   }
783
784   /**
785    * Sets a page in the cache.
786    *
787    * @param string $uri  The internal URI
788    */
789   public function setPageCache($uri)
790   {
791     if (sfView::RENDER_CLIENT != $this->controller->getRenderMode())
792     {
793       return;
794     }
795
796     // save content in cache
797     $saved = $this->set(serialize($this->context->getResponse()), $uri);
798
799     if ($saved && sfConfig::get('sf_web_debug'))
800     {
801       $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => true)), $this->context->getResponse()->getContent())->getReturnValue();
802
803       $this->context->getResponse()->setContent($content);
804     }
805   }
806
807   /**
808    * Gets a page from the cache.
809    *
810    * @param  string $uri  The internal URI
811    *
812    * @return string The cached page
813    */
814   public function getPageCache($uri)
815   {
816     $retval = $this->get($uri);
817
818     if (is_null($retval))
819     {
820       return false;
821     }
822
823     $cachedResponse = unserialize($retval);
824     $cachedResponse->setEventDispatcher($this->dispatcher);
825
826     if (sfView::RENDER_VAR == $this->controller->getRenderMode())
827     {
828       $this->controller->getActionStack()->getLastEntry()->setPresentation($cachedResponse->getContent());
829       $this->response->setContent('');
830     }
831     else
832     {
833       $this->context->setResponse($cachedResponse);
834
835       if (sfConfig::get('sf_web_debug'))
836       {
837         $content = $this->dispatcher->filter(new sfEvent($this, 'view.cache.filter_content', array('response' => $this->context->getResponse(), 'uri' => $uri, 'new' => false)), $this->context->getResponse()->getContent())->getReturnValue();
838
839         $this->context->getResponse()->setContent($content);
840       }
841     }
842
843     return true;
844   }
845
846   /**
847    * Listens to the 'view.cache.filter_content' event to decorate a chunk of HTML with cache information.
848    *
849    * @param sfEvent $event   A sfEvent instance
850    * @param string  $content The HTML content
851    *
852    * @return string The decorated HTML string
853    */
854   public function decorateContentWithDebug(sfEvent $event, $content)
855   {
856     // don't decorate if not html or if content is null
857     if (!$content || false === strpos($event['response']->getContentType(), 'html'))
858     {
859       return $content;
860     }
861
862     sfLoader::loadHelpers(array('Helper', 'Url', 'Asset', 'Tag'));
863
864     $bgColor      = $event['new'] ? '#9ff' : '#ff9';
865     $lastModified = $this->getLastModified($event['uri']);
866     $id           = md5($event['uri']);
867
868     return '
869       <div id="main_'.$id.'" class="sfWebDebugActionCache" style="border: 1px solid #f00">
870       <div id="sub_main_'.$id.'" class="sfWebDebugCache" style="background-color: '.$bgColor.'; border-right: 1px solid #f00; border-bottom: 1px solid #f00;">
871       <div style="height: 16px; padding: 2px"><a href="#" onclick="sfWebDebugToggle(\'sub_main_info_'.$id.'\'); return false;"><strong>cache information</strong></a>&nbsp;<a href="#" onclick="sfWebDebugToggle(\'sub_main_'.$id.'\'); document.getElementById(\'main_'.$id.'\').style.border = \'none\'; return false;">'.image_tag(sfConfig::get('sf_web_debug_web_dir').'/images/close.png').'</a>&nbsp;</div>
872         <div style="padding: 2px; display: none" id="sub_main_info_'.$id.'">
873         [uri]&nbsp;'.htmlspecialchars($event['uri'], ENT_QUOTES, sfConfig::get('sf_charset')).'<br />
874         [life&nbsp;time]&nbsp;'.$this->getLifeTime($event['uri']).'&nbsp;seconds<br />
875         [last&nbsp;modified]&nbsp;'.(time() - $lastModified).'&nbsp;seconds<br />
876         &nbsp;<br />&nbsp;
877         </div>
878       </div><div>
879       '.$content.'
880       </div></div>
881     ';
882   }
883 }
884
Note: See TracBrowser for help on using the browser.