PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Zend/Cache/Pattern/ObjectCache.php

http://github.com/zendframework/zf2
PHP | 284 lines | 133 code | 31 blank | 120 comment | 20 complexity | 60a25632e1ff476532545af53b3c6bb8 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-2015 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. */
  9. namespace Zend\Cache\Pattern;
  10. use Zend\Cache\Exception;
  11. class ObjectCache extends CallbackCache
  12. {
  13. /**
  14. * Set options
  15. *
  16. * @param PatternOptions $options
  17. * @return void
  18. * @throws Exception\InvalidArgumentException
  19. */
  20. public function setOptions(PatternOptions $options)
  21. {
  22. parent::setOptions($options);
  23. if (!$options->getObject()) {
  24. throw new Exception\InvalidArgumentException("Missing option 'object'");
  25. } elseif (!$options->getStorage()) {
  26. throw new Exception\InvalidArgumentException("Missing option 'storage'");
  27. }
  28. }
  29. /**
  30. * Call and cache a class method
  31. *
  32. * @param string $method Method name to call
  33. * @param array $args Method arguments
  34. * @return mixed
  35. * @throws Exception\RuntimeException
  36. * @throws \Exception
  37. */
  38. public function call($method, array $args = array())
  39. {
  40. $options = $this->getOptions();
  41. $object = $options->getObject();
  42. $method = strtolower($method);
  43. // handle magic methods
  44. switch ($method) {
  45. case '__set':
  46. $property = array_shift($args);
  47. $value = array_shift($args);
  48. $object->{$property} = $value;
  49. if (!$options->getObjectCacheMagicProperties()
  50. || property_exists($object, $property)
  51. ) {
  52. // no caching if property isn't magic
  53. // or caching magic properties is disabled
  54. return;
  55. }
  56. // remove cached __get and __isset
  57. $removeKeys = null;
  58. if (method_exists($object, '__get')) {
  59. $removeKeys[] = $this->generateKey('__get', array($property));
  60. }
  61. if (method_exists($object, '__isset')) {
  62. $removeKeys[] = $this->generateKey('__isset', array($property));
  63. }
  64. if ($removeKeys) {
  65. $options->getStorage()->removeItems($removeKeys);
  66. }
  67. return;
  68. case '__get':
  69. $property = array_shift($args);
  70. if (!$options->getObjectCacheMagicProperties()
  71. || property_exists($object, $property)
  72. ) {
  73. // no caching if property isn't magic
  74. // or caching magic properties is disabled
  75. return $object->{$property};
  76. }
  77. array_unshift($args, $property);
  78. return parent::call(array($object, '__get'), $args);
  79. case '__isset':
  80. $property = array_shift($args);
  81. if (!$options->getObjectCacheMagicProperties()
  82. || property_exists($object, $property)
  83. ) {
  84. // no caching if property isn't magic
  85. // or caching magic properties is disabled
  86. return isset($object->{$property});
  87. }
  88. return parent::call(array($object, '__isset'), array($property));
  89. case '__unset':
  90. $property = array_shift($args);
  91. unset($object->{$property});
  92. if (!$options->getObjectCacheMagicProperties()
  93. || property_exists($object, $property)
  94. ) {
  95. // no caching if property isn't magic
  96. // or caching magic properties is disabled
  97. return;
  98. }
  99. // remove previous cached __get and __isset calls
  100. $removeKeys = null;
  101. if (method_exists($object, '__get')) {
  102. $removeKeys[] = $this->generateKey('__get', array($property));
  103. }
  104. if (method_exists($object, '__isset')) {
  105. $removeKeys[] = $this->generateKey('__isset', array($property));
  106. }
  107. if ($removeKeys) {
  108. $options->getStorage()->removeItems($removeKeys);
  109. }
  110. return;
  111. }
  112. $cache = $options->getCacheByDefault();
  113. if ($cache) {
  114. $cache = !in_array($method, $options->getObjectNonCacheMethods());
  115. } else {
  116. $cache = in_array($method, $options->getObjectCacheMethods());
  117. }
  118. if (!$cache) {
  119. if ($args) {
  120. return call_user_func_array(array($object, $method), $args);
  121. }
  122. return $object->{$method}();
  123. }
  124. return parent::call(array($object, $method), $args);
  125. }
  126. /**
  127. * Generate a unique key in base of a key representing the callback part
  128. * and a key representing the arguments part.
  129. *
  130. * @param string $method The method
  131. * @param array $args Callback arguments
  132. * @return string
  133. * @throws Exception\RuntimeException
  134. */
  135. public function generateKey($method, array $args = array())
  136. {
  137. return $this->generateCallbackKey(
  138. array($this->getOptions()->getObject(), $method),
  139. $args
  140. );
  141. }
  142. /**
  143. * Generate a unique key in base of a key representing the callback part
  144. * and a key representing the arguments part.
  145. *
  146. * @param callable $callback A valid callback
  147. * @param array $args Callback arguments
  148. * @return string
  149. * @throws Exception\RuntimeException
  150. */
  151. protected function generateCallbackKey($callback, array $args = array())
  152. {
  153. $callbackKey = md5($this->getOptions()->getObjectKey() . '::' . strtolower($callback[1]));
  154. $argumentKey = $this->generateArgumentsKey($args);
  155. return $callbackKey . $argumentKey;
  156. }
  157. /**
  158. * Class method call handler
  159. *
  160. * @param string $method Method name to call
  161. * @param array $args Method arguments
  162. * @return mixed
  163. * @throws Exception\RuntimeException
  164. * @throws \Exception
  165. */
  166. public function __call($method, array $args)
  167. {
  168. return $this->call($method, $args);
  169. }
  170. /**
  171. * Writing data to properties.
  172. *
  173. * NOTE:
  174. * Magic properties will be cached too if the option cacheMagicProperties
  175. * is enabled and the property doesn't exist in real. If so it calls __set
  176. * and removes cached data of previous __get and __isset calls.
  177. *
  178. * @param string $name
  179. * @param mixed $value
  180. * @return void
  181. * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members
  182. */
  183. public function __set($name, $value)
  184. {
  185. return $this->call('__set', array($name, $value));
  186. }
  187. /**
  188. * Reading data from properties.
  189. *
  190. * NOTE:
  191. * Magic properties will be cached too if the option cacheMagicProperties
  192. * is enabled and the property doesn't exist in real. If so it calls __get.
  193. *
  194. * @param string $name
  195. * @return mixed
  196. * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members
  197. */
  198. public function __get($name)
  199. {
  200. return $this->call('__get', array($name));
  201. }
  202. /**
  203. * Checking existing properties.
  204. *
  205. * NOTE:
  206. * Magic properties will be cached too if the option cacheMagicProperties
  207. * is enabled and the property doesn't exist in real. If so it calls __get.
  208. *
  209. * @param string $name
  210. * @return bool
  211. * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members
  212. */
  213. public function __isset($name)
  214. {
  215. return $this->call('__isset', array($name));
  216. }
  217. /**
  218. * Unseting a property.
  219. *
  220. * NOTE:
  221. * Magic properties will be cached too if the option cacheMagicProperties
  222. * is enabled and the property doesn't exist in real. If so it removes
  223. * previous cached __isset and __get calls.
  224. *
  225. * @param string $name
  226. * @return void
  227. * @see http://php.net/manual/language.oop5.overloading.php#language.oop5.overloading.members
  228. */
  229. public function __unset($name)
  230. {
  231. return $this->call('__unset', array($name));
  232. }
  233. /**
  234. * Handle casting to string
  235. *
  236. * @return string
  237. * @see http://php.net/manual/language.oop5.magic.php#language.oop5.magic.tostring
  238. */
  239. public function __toString()
  240. {
  241. return $this->call('__toString');
  242. }
  243. /**
  244. * Handle invoke calls
  245. *
  246. * @return mixed
  247. * @see http://php.net/manual/language.oop5.magic.php#language.oop5.magic.invoke
  248. */
  249. public function __invoke()
  250. {
  251. return $this->call('__invoke', func_get_args());
  252. }
  253. }