PageRenderTime 57ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/package/app/app/symfony/view/sfViewCacheManager.class.php

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