[ Index ] |
|
Code source de Symfony 1.0.0 |
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 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Fri Mar 16 22:42:14 2007 | par Balluche grâce à PHPXref 0.7 |