PageRenderTime 54ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Zend/Cache/Frontend/Page.php

https://bitbucket.org/baruffaldi/website-insaneminds
PHP | 330 lines | 201 code | 13 blank | 116 comment | 34 complexity | de0c015cdf1f37ac7c52f9373ecd3a7d MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Cache
  17. * @subpackage Zend_Cache_Frontend
  18. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. /**
  22. * @see Zend_Cache_Core
  23. */
  24. require_once 'Zend/Cache/Core.php';
  25. /**
  26. * @package Zend_Cache
  27. * @subpackage Zend_Cache_Frontend
  28. * @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
  29. * @license http://framework.zend.com/license/new-bsd New BSD License
  30. */
  31. class Zend_Cache_Frontend_Page extends Zend_Cache_Core
  32. {
  33. /**
  34. * This frontend specific options
  35. *
  36. * ====> (boolean) http_conditional :
  37. * - if true, http conditional mode is on
  38. * WARNING : http_conditional OPTION IS NOT IMPLEMENTED FOR THE MOMENT (TODO)
  39. *
  40. * ====> (boolean) debug_header :
  41. * - if true, a debug text is added before each cached pages
  42. *
  43. * ====> (boolean) content_type_memorization :
  44. * - if the Content-Type header is sent after the cache was started, the
  45. * corresponding value can be memorized and replayed when the cache is hit
  46. * (if false (default), the frontend doesn't take care of Content-Type header)
  47. *
  48. * ====> (array) default_options :
  49. * - an associative array of default options :
  50. * - (boolean) cache : cache is on by default if true
  51. * - (boolean) cacheWithXXXVariables (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') :
  52. * if true, cache is still on even if there are some variables in this superglobal array
  53. * if false, cache is off if there are some variables in this superglobal array
  54. * - (boolean) makeIdWithXXXVariables (XXXX = 'Get', 'Post', 'Session', 'Files' or 'Cookie') :
  55. * if true, we have to use the content of this superglobal array to make a cache id
  56. * if false, the cache id won't be dependent of the content of this superglobal array
  57. *
  58. * ====> (array) regexps :
  59. * - an associative array to set options only for some REQUEST_URI
  60. * - keys are (pcre) regexps
  61. * - values are associative array with specific options to set if the regexp matchs on $_SERVER['REQUEST_URI']
  62. * (see default_options for the list of available options)
  63. * - if several regexps match the $_SERVER['REQUEST_URI'], only the last one will be used
  64. *
  65. * @var array options
  66. */
  67. protected $_specificOptions = array(
  68. 'http_conditional' => false,
  69. 'debug_header' => false,
  70. 'content_type_memorization' => false,
  71. 'default_options' => array(
  72. 'cache_with_get_variables' => false,
  73. 'cache_with_post_variables' => false,
  74. 'cache_with_session_variables' => false,
  75. 'cache_with_files_variables' => false,
  76. 'cache_with_cookie_variables' => false,
  77. 'make_id_with_get_variables' => true,
  78. 'make_id_with_post_variables' => true,
  79. 'make_id_with_session_variables' => true,
  80. 'make_id_with_files_variables' => true,
  81. 'make_id_with_cookie_variables' => true,
  82. 'cache' => true
  83. ),
  84. 'regexps' => array()
  85. );
  86. /**
  87. * Internal array to store some options
  88. *
  89. * @var array associative array of options
  90. */
  91. protected $_activeOptions = array();
  92. /**
  93. * Constructor
  94. *
  95. * @param array $options Associative array of options
  96. * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested
  97. * @throws Zend_Cache_Exception
  98. * @return void
  99. */
  100. public function __construct($options = array())
  101. {
  102. while (list($name, $value) = each($options)) {
  103. $name = strtolower($name);
  104. switch ($name) {
  105. case 'regexps':
  106. $this->_setRegexps($value);
  107. break;
  108. case 'default_options':
  109. $this->_setDefaultOptions($value);
  110. break;
  111. default:
  112. $this->setOption($name, $value);
  113. }
  114. }
  115. if (isset($this->_specificOptions['http_conditional'])) {
  116. if ($this->_specificOptions['http_conditional']) {
  117. Zend_Cache::throwException('http_conditional is not implemented for the moment !');
  118. }
  119. }
  120. $this->setOption('automatic_serialization', true);
  121. }
  122. /**
  123. * Specific setter for the 'default_options' option (with some additional tests)
  124. *
  125. * @param array $options Associative array
  126. * @throws Zend_Cache_Exception
  127. * @return void
  128. */
  129. protected function _setDefaultOptions($options)
  130. {
  131. if (!is_array($options)) {
  132. Zend_Cache::throwException('default_options must be an array !');
  133. }
  134. foreach ($options as $key=>$value) {
  135. $key = strtolower($key);
  136. if (!isset($this->_specificOptions['default_options'][$key])) {
  137. Zend_Cache::throwException("unknown option [$key] !");
  138. } else {
  139. $this->_specificOptions['default_options'][$key] = $value;
  140. }
  141. }
  142. }
  143. /**
  144. * Specific setter for the 'regexps' option (with some additional tests)
  145. *
  146. * @param array $options Associative array
  147. * @throws Zend_Cache_Exception
  148. * @return void
  149. */
  150. protected function _setRegexps($regexps)
  151. {
  152. if (!is_array($regexps)) {
  153. Zend_Cache::throwException('regexps option must be an array !');
  154. }
  155. foreach ($regexps as $regexp=>$conf) {
  156. if (!is_array($conf)) {
  157. Zend_Cache::throwException('regexps option must be an array of arrays !');
  158. }
  159. $validKeys = array_keys($this->_specificOptions['default_options']);
  160. foreach ($conf as $key=>$value) {
  161. $key = strtolower($key);
  162. if (!in_array($key, $validKeys)) {
  163. Zend_Cache::throwException("unknown option [$key] !");
  164. }
  165. }
  166. }
  167. $this->setOption('regexps', $regexps);
  168. }
  169. /**
  170. * Start the cache
  171. *
  172. * @param string $id (optional) A cache id (if you set a value here, maybe you have to use Output frontend instead)
  173. * @param boolean $doNotDie For unit testing only !
  174. * @return boolean True if the cache is hit (false else)
  175. */
  176. public function start($id = false, $doNotDie = false)
  177. {
  178. $lastMatchingRegexp = null;
  179. foreach ($this->_specificOptions['regexps'] as $regexp => $conf) {
  180. if (preg_match("`$regexp`", $_SERVER['REQUEST_URI'])) {
  181. $lastMatchingRegexp = $regexp;
  182. }
  183. }
  184. $this->_activeOptions = $this->_specificOptions['default_options'];
  185. if (!is_null($lastMatchingRegexp)) {
  186. $conf = $this->_specificOptions['regexps'][$lastMatchingRegexp];
  187. foreach ($conf as $key=>$value) {
  188. $this->_activeOptions[$key] = $value;
  189. }
  190. }
  191. if (!($this->_activeOptions['cache'])) {
  192. return false;
  193. }
  194. if (!$id) {
  195. $id = $this->_makeId();
  196. if (!$id) {
  197. return false;
  198. }
  199. }
  200. $array = $this->load($id);
  201. if ($array !== false) {
  202. $data = $array['data'];
  203. $contentType = $array['contentType'];
  204. if ($this->_specificOptions['debug_header']) {
  205. echo 'DEBUG HEADER : This is a cached page !';
  206. }
  207. if ($this->_specificOptions['content_type_memorization']) {
  208. if (!is_null($contentType)) {
  209. if (!headers_sent()) {
  210. header("Content-Type: $contentType");
  211. }
  212. }
  213. }
  214. echo $data;
  215. if ($doNotDie) {
  216. return true;
  217. }
  218. die();
  219. }
  220. ob_start(array($this, '_flush'));
  221. ob_implicit_flush(false);
  222. return false;
  223. }
  224. /**
  225. * callback for output buffering
  226. * (shouldn't really be called manually)
  227. *
  228. * @param string $data Buffered output
  229. * @return string Data to send to browser
  230. */
  231. public function _flush($data)
  232. {
  233. $contentType = null;
  234. if ($this->_specificOptions['content_type_memorization']) {
  235. if (headers_sent()) {
  236. $headersList = headers_list();
  237. foreach ($headersList as $header) {
  238. $tmp = split(':', $header);
  239. if (strtolower(trim($tmp[0])) == 'content-type') {
  240. $contentType = trim($tmp[1]);
  241. }
  242. }
  243. }
  244. }
  245. $array = array(
  246. 'data' => $data,
  247. 'contentType' => $contentType
  248. );
  249. $this->save($array);
  250. return $data;
  251. }
  252. /**
  253. * Make an id depending on REQUEST_URI and superglobal arrays (depending on options)
  254. *
  255. * @return mixed|false a cache id (string), false if the cache should have not to be used
  256. */
  257. private function _makeId()
  258. {
  259. $tmp = $_SERVER['REQUEST_URI'];
  260. foreach (array('Get', 'Post', 'Session', 'Files', 'Cookie') as $arrayName) {
  261. $tmp2 = $this->_makePartialId($arrayName, $this->_activeOptions['cache_with_' . strtolower($arrayName) . '_variables'], $this->_activeOptions['make_id_with_' . strtolower($arrayName) . '_variables']);
  262. if ($tmp2===false) {
  263. return false;
  264. }
  265. $tmp = $tmp . $tmp2;
  266. }
  267. return md5($tmp);
  268. }
  269. /**
  270. * Make a partial id depending on options
  271. *
  272. * @param string $arrayName Superglobal array name
  273. * @param bool $bool1 If true, cache is still on even if there are some variables in the superglobal array
  274. * @param bool $bool2 If true, we have to use the content of the superglobal array to make a partial id
  275. * @return mixed|false Partial id (string) or false if the cache should have not to be used
  276. */
  277. private function _makePartialId($arrayName, $bool1, $bool2)
  278. {
  279. switch ($arrayName) {
  280. case 'Get':
  281. $var = $_GET;
  282. break;
  283. case 'Post':
  284. $var = $_POST;
  285. break;
  286. case 'Session':
  287. if (isset($_SESSION)) {
  288. $var = $_SESSION;
  289. } else {
  290. $var = null;
  291. }
  292. break;
  293. case 'Cookie':
  294. if (isset($_COOKIE)) {
  295. $var = $_COOKIE;
  296. } else {
  297. $var = null;
  298. }
  299. break;
  300. case 'Files':
  301. $var = $_FILES;
  302. break;
  303. default:
  304. return false;
  305. }
  306. if ($bool1) {
  307. if ($bool2) {
  308. return serialize($var);
  309. }
  310. return '';
  311. }
  312. if (count($var) > 0) {
  313. return false;
  314. }
  315. return '';
  316. }
  317. }