PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/www/libs/Zend/Cache/Pattern/CallbackCache.php

https://bitbucket.org/Ppito/kawaiviewmodel2
PHP | 208 lines | 128 code | 19 blank | 61 comment | 14 complexity | 96edc20dca9e879be46561717efb6355 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Cache
  9. */
  10. namespace Zend\Cache\Pattern;
  11. use Zend\Cache\Exception;
  12. use Zend\Stdlib\ErrorHandler;
  13. /**
  14. * @category Zend
  15. * @package Zend_Cache
  16. * @subpackage Pattern
  17. */
  18. class CallbackCache extends AbstractPattern
  19. {
  20. /**
  21. * Set options
  22. *
  23. * @param PatternOptions $options
  24. * @return CallbackCache
  25. * @throws Exception\InvalidArgumentException if missing storage option
  26. */
  27. public function setOptions(PatternOptions $options)
  28. {
  29. parent::setOptions($options);
  30. if (!$options->getStorage()) {
  31. throw new Exception\InvalidArgumentException("Missing option 'storage'");
  32. }
  33. return $this;
  34. }
  35. /**
  36. * Call the specified callback or get the result from cache
  37. *
  38. * @param callable $callback A valid callback
  39. * @param array $args Callback arguments
  40. * @return mixed Result
  41. * @throws Exception\RuntimeException if invalid cached data
  42. * @throws \Exception
  43. */
  44. public function call($callback, array $args = array())
  45. {
  46. $options = $this->getOptions();
  47. $storage = $options->getStorage();
  48. $success = null;
  49. $key = $this->generateCallbackKey($callback, $args);
  50. $result = $storage->getItem($key, $success);
  51. if ($success) {
  52. if (!isset($result[0])) {
  53. throw new Exception\RuntimeException("Invalid cached data for key '{$key}'");
  54. }
  55. echo isset($result[1]) ? $result[1] : '';
  56. return $result[0];
  57. }
  58. $cacheOutput = $options->getCacheOutput();
  59. if ($cacheOutput) {
  60. ob_start();
  61. ob_implicit_flush(false);
  62. }
  63. // TODO: do not cache on errors using [set|restore]_error_handler
  64. try {
  65. if ($args) {
  66. $ret = call_user_func_array($callback, $args);
  67. } else {
  68. $ret = call_user_func($callback);
  69. }
  70. } catch (\Exception $e) {
  71. if ($cacheOutput) {
  72. ob_end_flush();
  73. }
  74. throw $e;
  75. }
  76. if ($cacheOutput) {
  77. $data = array($ret, ob_get_flush());
  78. } else {
  79. $data = array($ret);
  80. }
  81. $storage->setItem($key, $data);
  82. return $ret;
  83. }
  84. /**
  85. * function call handler
  86. *
  87. * @param string $function Function name to call
  88. * @param array $args Function arguments
  89. * @return mixed
  90. * @throws Exception\RuntimeException
  91. * @throws \Exception
  92. */
  93. public function __call($function, array $args)
  94. {
  95. return $this->call($function, $args);
  96. }
  97. /**
  98. * Generate a unique key in base of a key representing the callback part
  99. * and a key representing the arguments part.
  100. *
  101. * @param callable $callback A valid callback
  102. * @param array $args Callback arguments
  103. * @return string
  104. * @throws Exception\RuntimeException
  105. * @throws Exception\InvalidArgumentException
  106. */
  107. public function generateKey($callback, array $args = array())
  108. {
  109. return $this->generateCallbackKey($callback, $args);
  110. }
  111. /**
  112. * Generate a unique key in base of a key representing the callback part
  113. * and a key representing the arguments part.
  114. *
  115. * @param callable $callback A valid callback
  116. * @param array $args Callback arguments
  117. * @throws Exception\RuntimeException if callback not serializable
  118. * @throws Exception\InvalidArgumentException if invalid callback
  119. * @return string
  120. */
  121. protected function generateCallbackKey($callback, array $args)
  122. {
  123. if (!is_callable($callback, false, $callbackKey)) {
  124. throw new Exception\InvalidArgumentException('Invalid callback');
  125. }
  126. // functions, methods and classnames are case-insensitive
  127. $callbackKey = strtolower($callbackKey);
  128. // generate a unique key of object callbacks
  129. if (is_object($callback)) { // Closures & __invoke
  130. $object = $callback;
  131. } elseif (isset($callback[0])) { // array($object, 'method')
  132. $object = $callback[0];
  133. }
  134. if (isset($object)) {
  135. ErrorHandler::start();
  136. try {
  137. $serializedObject = serialize($object);
  138. } catch (\Exception $e) {
  139. ErrorHandler::stop();
  140. throw new Exception\RuntimeException(
  141. "Can't serialize callback: see previous exception", 0, $e
  142. );
  143. }
  144. $error = ErrorHandler::stop();
  145. if (!$serializedObject) {
  146. throw new Exception\RuntimeException(sprintf(
  147. 'Cannot serialize callback%s',
  148. ($error ? ': ' . $error->getMessage() : '')
  149. ), 0, $error);
  150. }
  151. $callbackKey.= $serializedObject;
  152. }
  153. return md5($callbackKey) . $this->generateArgumentsKey($args);
  154. }
  155. /**
  156. * Generate a unique key of the argument part.
  157. *
  158. * @param array $args
  159. * @throws Exception\RuntimeException
  160. * @return string
  161. */
  162. protected function generateArgumentsKey(array $args)
  163. {
  164. if (!$args) {
  165. return '';
  166. }
  167. ErrorHandler::start();
  168. try {
  169. $serializedArgs = serialize(array_values($args));
  170. } catch (\Exception $e) {
  171. ErrorHandler::stop();
  172. throw new Exception\RuntimeException(
  173. "Can't serialize arguments: see previous exception"
  174. , 0, $e);
  175. }
  176. $error = ErrorHandler::stop();
  177. if (!$serializedArgs) {
  178. throw new Exception\RuntimeException(sprintf(
  179. 'Cannot serialize arguments%s',
  180. ($error ? ': ' . $error->getMessage() : '')
  181. ), 0, $error);
  182. }
  183. return md5($serializedArgs);
  184. }
  185. }