2 /*********************************************************************************
3 * SugarCRM Community Edition is a customer relationship management program developed by
4 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
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.
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
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
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.
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.
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 ********************************************************************************/
38 abstract class SugarCacheAbstract
41 * @var set to false if you don't want to use the local store, true by default.
43 public $useLocalStore = true;
46 * @var timeout in seconds used for cache item expiration
48 protected $_expireTimeout = 300;
51 * @var prefix to use for all cache key entries
53 protected $_keyPrefix = 'sugarcrm_';
56 * @var stores locally any cached items so we don't have to hit the external cache as much
58 protected $_localStore = array();
61 * @var records the number of get requests made against the cache
63 protected $_cacheRequests = 0;
66 * @var records the number of hits made against the cache that have been resolved without hitting the
69 protected $_cacheLocalHits = 0;
72 * @var records the number of hits made against the cache that are resolved using the external cache
74 protected $_cacheExternalHits = 0;
77 * @var records the number of get requests that aren't in the cache
79 protected $_cacheMisses = 0;
82 * @var indicates the priority level for using this cache; the lower number indicates the highest
83 * priority ( 1 would be the highest priority, but we should never ship a backend with this number
84 * so we don't bump out custom backends. ) Shipping backends use priorities in the range of 900-999.
86 protected $_priority = 899;
91 public function __construct()
93 if ( isset($GLOBALS['sugar_config']['cache_expire_timeout']) )
94 $this->_expireTimeout = $GLOBALS['sugar_config']['cache_expire_timeout'];
95 if ( isset($GLOBALS['sugar_config']['unique_key']) )
96 $this->_keyPrefix = $GLOBALS['sugar_config']['unique_key'];
102 public function __destruct()
107 * PHP's magic __get() method, used here for getting the current value from the cache.
112 public function __get(
116 if ( SugarCache::$isCacheReset )
119 $this->_cacheRequests++;
120 if ( !$this->useLocalStore || !isset($this->_localStore[$key]) ) {
121 $this->_localStore[$key] = $this->_getExternal($this->_keyPrefix.$key);
122 if ( isset($this->_localStore[$key]) ) {
123 $this->_cacheExternalHits++;
126 $this->_cacheMisses++;
129 elseif ( isset($this->_localStore[$key]) ) {
130 $this->_cacheLocalHits++;
133 if ( isset($this->_localStore[$key]) ) {
134 return $this->_localStore[$key];
141 * PHP's magic __set() method, used here for setting a value for a key in the cache.
146 public function __set(
151 if ( is_null($value) ) {
152 $value = SugarCache::EXTERNAL_CACHE_NULL_VALUE;
155 if ( $this->useLocalStore ) {
156 $this->_localStore[$key] = $value;
158 $this->_setExternal($this->_keyPrefix.$key,$value);
162 * PHP's magic __isset() method, used here for checking for a key in the cache.
167 public function __isset(
171 return !is_null($this->__get($key));
175 * PHP's magic __unset() method, used here for clearing a key in the cache.
180 public function __unset(
184 unset($this->_localStore[$key]);
185 $this->_clearExternal($this->_keyPrefix.$key);
189 * Reset the cache for this request
191 public function reset()
193 $this->_localStore = array();
194 SugarCache::$isCacheReset = true;
198 * Reset the cache fully
200 public function resetFull()
203 $this->_resetExternal();
207 * Flush the contents of the cache
209 public function flush()
211 $this->_localStore = array();
212 $this->_resetExternal();
216 * Returns the number of cache hits made
218 * @return array assocative array with each key have the value
220 public function getCacheStats()
223 'requests' => $this->_cacheRequests,
224 'externalHits' => $this->_cacheExternalHits,
225 'localHits' => $this->_cacheLocalHits,
226 'misses' => $this->_cacheMisses,
231 * Returns what backend is used for caching, uses normalized class name for lookup
235 public function __toString()
237 return strtolower(str_replace('SugarCache','',get_class($this)));
241 * Hook for the child implementations of the individual backends to provide thier own logic for
242 * setting a value from cache
245 * @param mixed $value
247 abstract protected function _setExternal(
253 * Hook for the child implementations of the individual backends to provide thier own logic for
254 * getting a value from cache
257 * @return mixed $value, returns null if the key is not in the cache
259 abstract protected function _getExternal(
264 * Hook for the child implementations of the individual backends to provide thier own logic for
265 * clearing a value out of thier cache
269 abstract protected function _clearExternal(
274 * Hook for the child implementations of the individual backends to provide thier own logic for
275 * clearing thier cache out fully
277 abstract protected function _resetExternal();
280 * Hook for testing if the backend should be used or not. Typically we'll extend this for backend specific
283 * @return boolean true if we can use the backend, false if not
285 public function useBackend()
287 if ( !empty($GLOBALS['sugar_config']['external_cache_disabled'])
288 && $GLOBALS['sugar_config']['external_cache_disabled'] == true ) {
292 if (defined('SUGARCRM_IS_INSTALLING')) {
296 if ( isset($GLOBALS['sugar_config']['external_cache_force_backend'])
297 && ( $GLOBALS['sugar_config']['external_cache_force_backend'] != (string) $this ) ) {
305 * Returns the priority level for this backend
307 * @see self::$_priority
311 public function getPriority()
313 return $this->_priority;