2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4 * SugarCRM is a customer relationship management program developed by
5 * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
7 * This program is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU Affero General Public License version 3 as published by the
9 * Free Software Foundation with the addition of the following permission added
10 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
19 * You should have received a copy of the GNU Affero General Public License along with
20 * this program; if not, see http://www.gnu.org/licenses or write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25 * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
27 * The interactive user interfaces in modified source and object code versions
28 * of this program must display Appropriate Legal Notices, as required under
29 * Section 5 of the GNU Affero General Public License version 3.
31 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32 * these Appropriate Legal Notices must retain the display of the "Powered by
33 * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34 * technical reasons, the Appropriate Legal Notices must display the words
35 * "Powered by SugarCRM".
36 ********************************************************************************/
42 * Discover and return available cache adapter of false if nothing is available
44 * @return SugarCache_Abstract|false
48 // If the cache is manually disabled, turn it off.
49 if(!empty($GLOBALS['sugar_config']['external_cache_disabled']) && true == $GLOBALS['sugar_config']['external_cache_disabled'])
51 if (EXTERNAL_CACHE_DEBUG) {
52 SugarCache::log("SugarCache::discover() -- caching explicitly disabled", 'fail');
54 $GLOBALS['external_cache_enabled'] = false;
55 return SugarCache::factory('Base');
58 // check for Zend caching
59 if(function_exists("output_cache_get") && empty($GLOBALS['sugar_config']['external_cache_disabled_zend']))
61 $GLOBALS['external_cache_enabled'] = true;
62 $GLOBALS['external_cache_type'] = "zend";
63 $cache = SugarCache::factory('Zend');
64 if (EXTERNAL_CACHE_DEBUG) {
65 SugarCache::log('Found Zend - attempting to use', 'pass');
68 elseif (function_exists("zend_shm_cache_store") && empty($GLOBALS['sugar_config']['external_cache_disabled_zendserver'])) {
69 $GLOBALS['external_cache_enabled'] = true;
70 $GLOBALS['external_cache_type'] = 'zendserver';
71 $cache = SugarCache::factory('ZendServer');
72 if (EXTERNAL_CACHE_DEBUG) {
73 SugarCache::log('Found Zend Server - attempting to use', 'pass');
76 elseif (extension_loaded('memcache') && empty($GLOBALS['sugar_config']['external_cache_disabled_memcache'])) {
77 $GLOBALS['external_cache_enabled'] = true;
78 $GLOBALS['external_cache_type'] = 'memcache';
79 $cache = SugarCache::factory('Memcache');
80 if (EXTERNAL_CACHE_DEBUG) {
81 SugarCache::log('Found memcache - attempting to use', 'pass');
84 elseif(function_exists("apc_store") && empty($GLOBALS['sugar_config']['external_cache_disabled_apc']))
86 $GLOBALS['external_cache_enabled'] = true;
87 $GLOBALS['external_cache_type'] = "apc";
88 $cache = SugarCache::factory('APC');
89 if (EXTERNAL_CACHE_DEBUG) {
90 SugarCache::log('Found APC - attempting to use', 'pass');
93 elseif(function_exists("wincache_ucache_set") && empty($GLOBALS['sugar_config']['external_cache_disabled_wincache']))
95 $GLOBALS['external_cache_enabled'] = true;
96 $GLOBALS['external_cache_type'] = "wincache";
97 $cache = SugarCache::factory('Wincache');
98 if (EXTERNAL_CACHE_DEBUG) {
99 SugarCache::log('Found Wincache - attempting to use', 'pass');
102 elseif(function_exists("zget") && empty($GLOBALS['sugar_config']['external_cache_disabled_smash']))
104 $GLOBALS['external_cache_enabled'] = true;
105 $GLOBALS['external_cache_type'] = "smash";
106 $cache = SugarCache::factory('sMash');
107 if (EXTERNAL_CACHE_DEBUG) {
108 SugarCache::log('Found sMash - attempting to use', 'pass');
112 // @todo file cache as fallback
115 // no cache available....return
116 $GLOBALS['external_cache_enabled'] = true;
117 $GLOBALS['external_cache_type'] = 'base-in-memory';
118 $cache = SugarCache::factory('Base');
119 if (EXTERNAL_CACHE_DEBUG) {
120 SugarCache::log('Found no caching solution - using base');
125 if(!$cache->initialized)
127 // Validation failed. Turn off the external cache and return SugarCache_Base
128 $GLOBALS['external_cache_enabled'] = false;
129 if(EXTERNAL_CACHE_DEBUG) {
130 SugarCache::log("external cache validation check failed...tried cache {$GLOBALS['external_cache_type']}", 'fail');
131 SugarCache::log('returning Base');
133 return SugarCache::factory('Base');
136 // If the cache is being reset, turn it off for this round trip
138 if(isset($GLOBALS['sugar_config']) && isset($GLOBALS['sugar_config']['unique_key']))
140 $value = $cache->get($GLOBALS['sugar_config']['unique_key'].'EXTERNAL_CACHE_RESET');
144 // We are in a cache reset, do not use the cache.
145 $GLOBALS['external_cache_enabled'] = false;
149 // Add one to the external cache hits. This will keep the end user statistics simple.
150 // All real checks suceeding will result in 100%. Otherwise people will be looking for
151 // the one check that did not pass.
152 $GLOBALS['external_cache_request_external_hits']++;
157 function factory($type)
159 $class = 'SugarCache_' . $type;
160 $cache = new $class();
166 * Performs basic logging for messages generated by the external caching mechanism
168 * Currently this only outputs directly to the screen as it's only used internally.
170 * There are five supported $type values:
171 * neutral :: just a log message with information value
172 * pass :: a pass that attention should be brought to
173 * lightpass :: a pass without much consequence
174 * fail :: a fail that attention should be brought to
175 * lightfail :: a failure without much consequence, or one that might succeed later in
176 * the execution chain
178 * @param string $msg Message to output. Note it will be filtered through htmlspecialchars()
179 * @param string $type Type of message to output
181 function log($msg, $type = 'neutral') {
182 static $messages = array();
183 static $valid_types = array(
191 if (!isset($valid_types[$type])) {
192 SugarCache::log("Invalid type provided: {$type}", 'fail');
195 $session_id = session_id();
196 if (empty($session_id)) {
197 // add to stack of messages to output after the session starts so we don't kill the headers
199 'message' => htmlspecialchars($msg),
203 if ($messages !== false) {
204 // output base styles on first round trip - this doesn't worry that its
205 // not in the proper place as its for debugging purposes only.
206 echo "<style type='text/css'>"
207 . "hr +span { padding:3px 5px; display:block; } "
208 . "hr +.pass { background-color:green; color: white; } "
209 . "hr +.lightpass { background-color: #CFC; color:black; }"
210 . "hr +.fail { background-color:red; color:white; } "
211 . "hr +.lightfail { background-color:#F99; color: black; }"
212 . "hr +.neutral { background-color:#FFFFE0; color:black; } "
215 if ($messages !== false && count($messages) > 0) {
216 // clear stack of messages;
217 echo '<hr />Messages logged prior to session starting...<hr />', "\n";
218 foreach ($messages as $id => $old_msg) {
219 echo "<hr /><span class='{$old_msg['type']}'>{$id} -- {$old_msg['message']}</span><hr />\n";
221 echo "<hr />End of messages prior to session starting...<hr />\n";
224 $msg = htmlspecialchars($msg);
225 echo "<hr /><span class='{$type}'>{$msg}</span><hr />\n";