PageRenderTime 35ms CodeModel.GetById 7ms RepoModel.GetById 0ms app.codeStats 0ms

/include/SugarCache/SugarCacheAbstract.php

https://github.com/jacknicole/sugarcrm_dev
PHP | 315 lines | 131 code | 34 blank | 150 comment | 17 complexity | 17c685bba109994950cdc66be58c4460 MD5 | raw file
  1. <?php
  2. /*********************************************************************************
  3. * SugarCRM Community Edition is a customer relationship management program developed by
  4. * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
  5. *
  6. * This program is free software; you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License version 3 as published by the
  8. * Free Software Foundation with the addition of the following permission added
  9. * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
  10. * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
  11. * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
  12. *
  13. * This program is distributed in the hope that it will be useful, but WITHOUT
  14. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  15. * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Affero General Public License along with
  19. * this program; if not, see http://www.gnu.org/licenses or write to the Free
  20. * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  21. * 02110-1301 USA.
  22. *
  23. * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
  24. * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
  25. *
  26. * The interactive user interfaces in modified source and object code versions
  27. * of this program must display Appropriate Legal Notices, as required under
  28. * Section 5 of the GNU Affero General Public License version 3.
  29. *
  30. * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
  31. * these Appropriate Legal Notices must retain the display of the "Powered by
  32. * SugarCRM" logo. If the display of the logo is not reasonably feasible for
  33. * technical reasons, the Appropriate Legal Notices must display the words
  34. * "Powered by SugarCRM".
  35. ********************************************************************************/
  36. abstract class SugarCacheAbstract
  37. {
  38. /**
  39. * @var set to false if you don't want to use the local store, true by default.
  40. */
  41. public $useLocalStore = true;
  42. /**
  43. * @var timeout in seconds used for cache item expiration
  44. */
  45. protected $_expireTimeout = 300;
  46. /**
  47. * @var prefix to use for all cache key entries
  48. */
  49. protected $_keyPrefix = 'sugarcrm_';
  50. /**
  51. * @var stores locally any cached items so we don't have to hit the external cache as much
  52. */
  53. protected $_localStore = array();
  54. /**
  55. * @var records the number of get requests made against the cache
  56. */
  57. protected $_cacheRequests = 0;
  58. /**
  59. * @var records the number of hits made against the cache that have been resolved without hitting the
  60. * external cache
  61. */
  62. protected $_cacheLocalHits = 0;
  63. /**
  64. * @var records the number of hits made against the cache that are resolved using the external cache
  65. */
  66. protected $_cacheExternalHits = 0;
  67. /**
  68. * @var records the number of get requests that aren't in the cache
  69. */
  70. protected $_cacheMisses = 0;
  71. /**
  72. * @var indicates the priority level for using this cache; the lower number indicates the highest
  73. * priority ( 1 would be the highest priority, but we should never ship a backend with this number
  74. * so we don't bump out custom backends. ) Shipping backends use priorities in the range of 900-999.
  75. */
  76. protected $_priority = 899;
  77. /**
  78. * Constructor
  79. */
  80. public function __construct()
  81. {
  82. if ( isset($GLOBALS['sugar_config']['cache_expire_timeout']) )
  83. $this->_expireTimeout = $GLOBALS['sugar_config']['cache_expire_timeout'];
  84. if ( isset($GLOBALS['sugar_config']['unique_key']) )
  85. $this->_keyPrefix = $GLOBALS['sugar_config']['unique_key'];
  86. }
  87. /**
  88. * Destructor
  89. */
  90. public function __destruct()
  91. {
  92. }
  93. /**
  94. * PHP's magic __get() method, used here for getting the current value from the cache.
  95. *
  96. * @param string $key
  97. * @return mixed
  98. */
  99. public function __get(
  100. $key
  101. )
  102. {
  103. if ( SugarCache::$isCacheReset )
  104. return;
  105. $this->_cacheRequests++;
  106. if ( !$this->useLocalStore || !isset($this->_localStore[$key]) ) {
  107. $this->_localStore[$key] = $this->_getExternal($this->_keyPrefix.$key);
  108. if ( isset($this->_localStore[$key]) ) {
  109. $this->_cacheExternalHits++;
  110. }
  111. else {
  112. $this->_cacheMisses++;
  113. }
  114. }
  115. elseif ( isset($this->_localStore[$key]) ) {
  116. $this->_cacheLocalHits++;
  117. }
  118. if ( isset($this->_localStore[$key]) ) {
  119. return $this->_localStore[$key];
  120. }
  121. return null;
  122. }
  123. /**
  124. * PHP's magic __set() method, used here for setting a value for a key in the cache.
  125. *
  126. * @param string $key
  127. * @return mixed
  128. */
  129. public function __set(
  130. $key,
  131. $value
  132. )
  133. {
  134. if ( is_null($value) ) {
  135. $value = SugarCache::EXTERNAL_CACHE_NULL_VALUE;
  136. }
  137. if ( $this->useLocalStore ) {
  138. $this->_localStore[$key] = $value;
  139. }
  140. $this->_setExternal($this->_keyPrefix.$key,$value);
  141. }
  142. /**
  143. * PHP's magic __isset() method, used here for checking for a key in the cache.
  144. *
  145. * @param string $key
  146. * @return mixed
  147. */
  148. public function __isset(
  149. $key
  150. )
  151. {
  152. return !is_null($this->__get($key));
  153. }
  154. /**
  155. * PHP's magic __unset() method, used here for clearing a key in the cache.
  156. *
  157. * @param string $key
  158. * @return mixed
  159. */
  160. public function __unset(
  161. $key
  162. )
  163. {
  164. unset($this->_localStore[$key]);
  165. $this->_clearExternal($this->_keyPrefix.$key);
  166. }
  167. /**
  168. * Reset the cache for this request
  169. */
  170. public function reset()
  171. {
  172. $this->_localStore = array();
  173. SugarCache::$isCacheReset = true;
  174. }
  175. /**
  176. * Reset the cache fully
  177. */
  178. public function resetFull()
  179. {
  180. $this->reset();
  181. $this->_resetExternal();
  182. }
  183. /**
  184. * Flush the contents of the cache
  185. */
  186. public function flush()
  187. {
  188. $this->_localStore = array();
  189. $this->_resetExternal();
  190. }
  191. /**
  192. * Returns the number of cache hits made
  193. *
  194. * @return array assocative array with each key have the value
  195. */
  196. public function getCacheStats()
  197. {
  198. return array(
  199. 'requests' => $this->_cacheRequests,
  200. 'externalHits' => $this->_cacheExternalHits,
  201. 'localHits' => $this->_cacheLocalHits,
  202. 'misses' => $this->_cacheMisses,
  203. );
  204. }
  205. /**
  206. * Returns what backend is used for caching, uses normalized class name for lookup
  207. *
  208. * @return string
  209. */
  210. public function __toString()
  211. {
  212. return strtolower(str_replace('SugarCache','',get_class($this)));
  213. }
  214. /**
  215. * Hook for the child implementations of the individual backends to provide thier own logic for
  216. * setting a value from cache
  217. *
  218. * @param string $key
  219. * @param mixed $value
  220. */
  221. abstract protected function _setExternal(
  222. $key,
  223. $value
  224. );
  225. /**
  226. * Hook for the child implementations of the individual backends to provide thier own logic for
  227. * getting a value from cache
  228. *
  229. * @param string $key
  230. * @return mixed $value, returns null if the key is not in the cache
  231. */
  232. abstract protected function _getExternal(
  233. $key
  234. );
  235. /**
  236. * Hook for the child implementations of the individual backends to provide thier own logic for
  237. * clearing a value out of thier cache
  238. *
  239. * @param string $key
  240. */
  241. abstract protected function _clearExternal(
  242. $key
  243. );
  244. /**
  245. * Hook for the child implementations of the individual backends to provide thier own logic for
  246. * clearing thier cache out fully
  247. */
  248. abstract protected function _resetExternal();
  249. /**
  250. * Hook for testing if the backend should be used or not. Typically we'll extend this for backend specific
  251. * checks as well.
  252. *
  253. * @return boolean true if we can use the backend, false if not
  254. */
  255. public function useBackend()
  256. {
  257. if ( !empty($GLOBALS['sugar_config']['external_cache_disabled'])
  258. && $GLOBALS['sugar_config']['external_cache_disabled'] == true ) {
  259. return false;
  260. }
  261. if (defined('SUGARCRM_IS_INSTALLING')) {
  262. return false;
  263. }
  264. if ( isset($GLOBALS['sugar_config']['external_cache_force_backend'])
  265. && ( $GLOBALS['sugar_config']['external_cache_force_backend'] != (string) $this ) ) {
  266. return false;
  267. }
  268. return true;
  269. }
  270. /**
  271. * Returns the priority level for this backend
  272. *
  273. * @see self::$_priority
  274. *
  275. * @return int
  276. */
  277. public function getPriority()
  278. {
  279. return $this->_priority;
  280. }
  281. }