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 ********************************************************************************/
39 * Abstract cache class
42 abstract class SugarCacheAbstract
45 * @var set to false if you don't want to use the local store, true by default.
47 public $useLocalStore = true;
50 * @var timeout in seconds used for cache item expiration
52 protected $_expireTimeout = 300;
55 * @var prefix to use for all cache key entries
57 protected $_keyPrefix = 'sugarcrm_';
60 * @var stores locally any cached items so we don't have to hit the external cache as much
62 protected $_localStore = array();
65 * @var records the number of get requests made against the cache
67 protected $_cacheRequests = 0;
70 * @var records the number of hits made against the cache that have been resolved without hitting the
73 protected $_cacheLocalHits = 0;
76 * @var records the number of hits made against the cache that are resolved using the external cache
78 protected $_cacheExternalHits = 0;
81 * @var records the number of get requests that aren't in the cache
83 protected $_cacheMisses = 0;
86 * @var indicates the priority level for using this cache; the lower number indicates the highest
87 * priority ( 1 would be the highest priority, but we should never ship a backend with this number
88 * so we don't bump out custom backends. ) Shipping backends use priorities in the range of 900-999.
90 protected $_priority = 899;
95 public function __construct()
97 if ( isset($GLOBALS['sugar_config']['cache_expire_timeout']) )
98 $this->_expireTimeout = $GLOBALS['sugar_config']['cache_expire_timeout'];
99 if ( isset($GLOBALS['sugar_config']['unique_key']) )
100 $this->_keyPrefix = $GLOBALS['sugar_config']['unique_key'];
106 public function __destruct()
111 * PHP's magic __get() method, used here for getting the current value from the cache.
116 public function __get(
120 if ( SugarCache::$isCacheReset )
123 $this->_cacheRequests++;
124 if ( !$this->useLocalStore || !isset($this->_localStore[$key]) ) {
125 $this->_localStore[$key] = $this->_getExternal($this->_keyPrefix.$key);
126 if ( isset($this->_localStore[$key]) ) {
127 $this->_cacheExternalHits++;
130 $this->_cacheMisses++;
133 elseif ( isset($this->_localStore[$key]) ) {
134 $this->_cacheLocalHits++;
137 if ( isset($this->_localStore[$key]) ) {
138 return $this->_localStore[$key];
145 * PHP's magic __set() method, used here for setting a value for a key in the cache.
150 public function __set(
155 if ( is_null($value) ) {
156 $value = SugarCache::EXTERNAL_CACHE_NULL_VALUE;
159 if ( $this->useLocalStore ) {
160 $this->_localStore[$key] = $value;
162 $this->_setExternal($this->_keyPrefix.$key,$value);
166 * PHP's magic __isset() method, used here for checking for a key in the cache.
171 public function __isset(
175 return !is_null($this->__get($key));
179 * PHP's magic __unset() method, used here for clearing a key in the cache.
184 public function __unset(
188 unset($this->_localStore[$key]);
189 $this->_clearExternal($this->_keyPrefix.$key);
193 * Reset the cache for this request
195 public function reset()
197 $this->_localStore = array();
198 SugarCache::$isCacheReset = true;
202 * Reset the cache fully
204 public function resetFull()
207 $this->_resetExternal();
211 * Flush the contents of the cache
213 public function flush()
215 $this->_localStore = array();
216 $this->_resetExternal();
220 * Returns the number of cache hits made
222 * @return array assocative array with each key have the value
224 public function getCacheStats()
227 'requests' => $this->_cacheRequests,
228 'externalHits' => $this->_cacheExternalHits,
229 'localHits' => $this->_cacheLocalHits,
230 'misses' => $this->_cacheMisses,
235 * Returns what backend is used for caching, uses normalized class name for lookup
239 public function __toString()
241 return strtolower(str_replace('SugarCache','',get_class($this)));
245 * Hook for the child implementations of the individual backends to provide thier own logic for
246 * setting a value from cache
249 * @param mixed $value
251 abstract protected function _setExternal(
257 * Hook for the child implementations of the individual backends to provide thier own logic for
258 * getting a value from cache
261 * @return mixed $value, returns null if the key is not in the cache
263 abstract protected function _getExternal(
268 * Hook for the child implementations of the individual backends to provide thier own logic for
269 * clearing a value out of thier cache
273 abstract protected function _clearExternal(
278 * Hook for the child implementations of the individual backends to provide thier own logic for
279 * clearing thier cache out fully
281 abstract protected function _resetExternal();
284 * Hook for testing if the backend should be used or not. Typically we'll extend this for backend specific
287 * @return boolean true if we can use the backend, false if not
289 public function useBackend()
291 if ( !empty($GLOBALS['sugar_config']['external_cache_disabled'])
292 && $GLOBALS['sugar_config']['external_cache_disabled'] == true ) {
296 if (defined('SUGARCRM_IS_INSTALLING')) {
300 if ( isset($GLOBALS['sugar_config']['external_cache_force_backend'])
301 && ( $GLOBALS['sugar_config']['external_cache_force_backend'] != (string) $this ) ) {
309 * Returns the priority level for this backend
311 * @see self::$_priority
315 public function getPriority()
317 return $this->_priority;