]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/SugarCache/SugarCache.php
Release 6.4.0
[Github/sugarcrm.git] / include / SugarCache / SugarCache.php
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
37
38 /**
39  * Sugar Cache manager
40  * @api
41  */
42 class SugarCache
43 {
44     const EXTERNAL_CACHE_NULL_VALUE = "SUGAR_CACHE_NULL_ZZ";
45
46     protected static $_cacheInstance;
47
48     /**
49      * @var true if the cache has been reset during this request, so we no longer return values from
50      *      cache until the next reset
51      */
52     public static $isCacheReset = false;
53
54     private function __construct() {}
55
56     /**
57      * initializes the cache in question
58      */
59     protected static function _init()
60     {
61         $lastPriority = 1000;
62         $locations = array('include/SugarCache','custom/include/SugarCache');
63             foreach ( $locations as $location ) {
64             if (sugar_is_dir($location) && $dir = opendir($location)) {
65                 while (($file = readdir($dir)) !== false) {
66                     if ($file == ".."
67                             || $file == "."
68                             || !is_file("$location/$file")
69                             )
70                         continue;
71                     require_once("$location/$file");
72                     $cacheClass = basename($file, ".php");
73                     if ( class_exists($cacheClass) && is_subclass_of($cacheClass,'SugarCacheAbstract') ) {
74                         $GLOBALS['log']->debug("Found cache backend $cacheClass");
75                         $cacheInstance = new $cacheClass();
76                         if ( $cacheInstance->useBackend()
77                                 && $cacheInstance->getPriority() < $lastPriority ) {
78                             $GLOBALS['log']->debug("Using cache backend $cacheClass, since ".$cacheInstance->getPriority()." is less than ".$lastPriority);
79                             self::$_cacheInstance = $cacheInstance;
80                             $lastPriority = $cacheInstance->getPriority();
81                         }
82                     }
83                 }
84             }
85         }
86     }
87
88     /**
89      * Returns the instance of the SugarCacheAbstract object, cooresponding to the external
90      * cache being used.
91      */
92     public static function instance()
93     {
94         if ( !is_subclass_of(self::$_cacheInstance,'SugarCacheAbstract') )
95             self::_init();
96
97         return self::$_cacheInstance;
98     }
99
100     /**
101      * Try to reset any opcode caches we know about
102      *
103      * @todo make it so developers can extend this somehow
104      */
105     public static function cleanOpcodes()
106     {
107         // APC
108         if ( function_exists('apc_clear_cache') && ini_get('apc.stat') == 0 ) {
109             apc_clear_cache();
110         }
111         // Wincache
112         if ( function_exists('wincache_refresh_if_changed') ) {
113             wincache_refresh_if_changed();
114         }
115         // Zend
116         if ( function_exists('accelerator_reset') ) {
117             accelerator_reset();
118         }
119         // eAccelerator
120         if ( function_exists('eaccelerator_clear') ) {
121             eaccelerator_clear();
122         }
123         // XCache
124         if ( function_exists('xcache_clear_cache') && !ini_get('xcache.admin.enable_auth') ) {
125             $max = xcache_count(XC_TYPE_PHP);
126             for ($i = 0; $i < $max; $i++) {
127                 if (!xcache_clear_cache(XC_TYPE_PHP, $i)) {
128                     break;
129                 }
130             }
131         }
132     }
133 }
134
135 /**
136  * Procedural API for external cache
137  */
138
139 /**
140  * Retrieve a key from cache.  For the Zend Platform, a maximum age of 5 minutes is assumed.
141  *
142  * @param String $key -- The item to retrieve.
143  * @return The item unserialized
144  */
145 function sugar_cache_retrieve($key)
146 {
147     return SugarCache::instance()->$key;
148 }
149
150 /**
151  * Put a value in the cache under a key
152  *
153  * @param String $key -- Global namespace cache.  Key for the data.
154  * @param Serializable $value -- The value to store in the cache.
155  */
156 function sugar_cache_put($key, $value)
157 {
158     SugarCache::instance()->$key = $value;
159 }
160
161 /**
162  * Clear a key from the cache.  This is used to invalidate a single key.
163  *
164  * @param String $key -- Key from global namespace
165  */
166 function sugar_cache_clear($key)
167 {
168     unset(SugarCache::instance()->$key);
169 }
170
171 /**
172  * Turn off external caching for the rest of this round trip and for all round
173  * trips for the next cache timeout.  This function should be called when global arrays
174  * are affected (studio, module loader, upgrade wizard, ... ) and it is not ok to
175  * wait for the cache to expire in order to see the change.
176  */
177 function sugar_cache_reset()
178 {
179     SugarCache::instance()->reset();
180     SugarCache::cleanOpcodes();
181 }
182
183 /**
184  * Flush the cache in its entirety including the local and external store along with the opcodes.
185  */
186 function sugar_cache_reset_full()
187 {
188     SugarCache::instance()->resetFull();
189     SugarCache::cleanOpcodes();
190 }
191
192 /**
193  * Clean out whatever opcode cache we may have out there.
194  */
195 function sugar_clean_opcodes()
196 {
197     SugarCache::cleanOpcodes();
198 }
199
200 /**
201  * Internal -- Determine if there is an external cache available for use.
202  *
203  * @deprecated
204  */
205 function check_cache()
206 {
207     SugarCache::instance();
208 }
209
210 /**
211  * This function is called once an external cache has been identified to ensure that it is correctly
212  * working.
213  *
214  * @deprecated
215  *
216  * @return true for success, false for failure.
217  */
218 function sugar_cache_validate()
219 {
220     $instance = SugarCache::instance();
221
222     return is_object($instance);
223 }
224
225 /**
226  * Internal -- This function actually retrieves information from the caches.
227  * It is a helper function that provides that actual cache API abstraction.
228  *
229  * @param unknown_type $key
230  * @return unknown
231  * @deprecated
232  * @see sugar_cache_retrieve
233  */
234 function external_cache_retrieve_helper($key)
235 {
236     return SugarCache::instance()->$key;
237 }