composer package updates
[openemr.git] / vendor / zendframework / zend-cache / src / Pattern / CallbackCache.php
blob47fad1c13be76c4643967f382ded8b55c0123725
1 <?php
2 /**
3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
8 */
10 namespace Zend\Cache\Pattern;
12 use Zend\Cache\Exception;
13 use Zend\Stdlib\ErrorHandler;
15 class CallbackCache extends AbstractPattern
17 /**
18 * Set options
20 * @param PatternOptions $options
21 * @return CallbackCache Provides a fluent interface
22 * @throws Exception\InvalidArgumentException if missing storage option
24 public function setOptions(PatternOptions $options)
26 parent::setOptions($options);
28 if (! $options->getStorage()) {
29 throw new Exception\InvalidArgumentException("Missing option 'storage'");
31 return $this;
34 /**
35 * Call the specified callback or get the result from cache
37 * @param callable $callback A valid callback
38 * @param array $args Callback arguments
39 * @return mixed Result
40 * @throws Exception\RuntimeException if invalid cached data
41 * @throws \Exception
43 public function call($callback, array $args = [])
45 $options = $this->getOptions();
46 $storage = $options->getStorage();
47 $success = null;
48 $key = $this->generateCallbackKey($callback, $args);
49 $result = $storage->getItem($key, $success);
50 if ($success) {
51 if (! array_key_exists(0, $result)) {
52 throw new Exception\RuntimeException("Invalid cached data for key '{$key}'");
55 echo isset($result[1]) ? $result[1] : '';
56 return $result[0];
59 $cacheOutput = $options->getCacheOutput();
60 if ($cacheOutput) {
61 ob_start();
62 ob_implicit_flush(0);
65 // TODO: do not cache on errors using [set|restore]_error_handler
67 try {
68 if ($args) {
69 $ret = call_user_func_array($callback, $args);
70 } else {
71 $ret = call_user_func($callback);
73 } catch (\Exception $e) {
74 if ($cacheOutput) {
75 ob_end_flush();
77 throw $e;
80 if ($cacheOutput) {
81 $data = [$ret, ob_get_flush()];
82 } else {
83 $data = [$ret];
86 $storage->setItem($key, $data);
88 return $ret;
91 /**
92 * function call handler
94 * @param string $function Function name to call
95 * @param array $args Function arguments
96 * @return mixed
97 * @throws Exception\RuntimeException
98 * @throws \Exception
100 public function __call($function, array $args)
102 return $this->call($function, $args);
106 * Generate a unique key in base of a key representing the callback part
107 * and a key representing the arguments part.
109 * @param callable $callback A valid callback
110 * @param array $args Callback arguments
111 * @return string
112 * @throws Exception\RuntimeException
113 * @throws Exception\InvalidArgumentException
115 public function generateKey($callback, array $args = [])
117 return $this->generateCallbackKey($callback, $args);
121 * Generate a unique key in base of a key representing the callback part
122 * and a key representing the arguments part.
124 * @param callable $callback A valid callback
125 * @param array $args Callback arguments
126 * @throws Exception\RuntimeException if callback not serializable
127 * @throws Exception\InvalidArgumentException if invalid callback
128 * @return string
130 protected function generateCallbackKey($callback, array $args)
132 if (! is_callable($callback, false, $callbackKey)) {
133 throw new Exception\InvalidArgumentException('Invalid callback');
136 // functions, methods and classnames are case-insensitive
137 $callbackKey = strtolower($callbackKey);
139 // generate a unique key of object callbacks
140 if (is_object($callback)) {
141 // Closures & __invoke
142 $object = $callback;
143 } elseif (isset($callback[0])) {
144 // array($object, 'method')
145 $object = $callback[0];
147 if (isset($object)) {
148 ErrorHandler::start();
149 try {
150 $serializedObject = serialize($object);
151 } catch (\Exception $e) {
152 ErrorHandler::stop();
153 throw new Exception\RuntimeException("Can't serialize callback: see previous exception", 0, $e);
155 $error = ErrorHandler::stop();
157 if (! $serializedObject) {
158 throw new Exception\RuntimeException(
159 sprintf('Cannot serialize callback%s', ($error ? ': ' . $error->getMessage() : '')),
161 $error
164 $callbackKey .= $serializedObject;
167 return md5($callbackKey) . $this->generateArgumentsKey($args);
171 * Generate a unique key of the argument part.
173 * @param array $args
174 * @throws Exception\RuntimeException
175 * @return string
177 protected function generateArgumentsKey(array $args)
179 if (! $args) {
180 return '';
183 ErrorHandler::start();
184 try {
185 $serializedArgs = serialize(array_values($args));
186 } catch (\Exception $e) {
187 ErrorHandler::stop();
188 throw new Exception\RuntimeException("Can't serialize arguments: see previous exception", 0, $e);
190 $error = ErrorHandler::stop();
192 if (! $serializedArgs) {
193 throw new Exception\RuntimeException(
194 sprintf('Cannot serialize arguments%s', ($error ? ': ' . $error->getMessage() : '')),
196 $error
200 return md5($serializedArgs);