]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/SugarCache/SugarCache.php
Release 6.5.6
[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-2012 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      * Try to reset file from caches
136      */
137     public static function cleanFile( $file )
138     {
139         // APC
140         if ( function_exists('apc_delete_file') && ini_get('apc.stat') == 0 )
141         {
142             apc_delete_file( $file );
143         }
144     }
145 }
146
147 /**
148  * Procedural API for external cache
149  */
150
151 /**
152  * Retrieve a key from cache.  For the Zend Platform, a maximum age of 5 minutes is assumed.
153  *
154  * @param String $key -- The item to retrieve.
155  * @return The item unserialized
156  */
157 function sugar_cache_retrieve($key)
158 {
159     return SugarCache::instance()->$key;
160 }
161
162 /**
163  * Put a value in the cache under a key
164  *
165  * @param String $key -- Global namespace cache.  Key for the data.
166  * @param Serializable $value -- The value to store in the cache.
167  */
168 function sugar_cache_put($key, $value, $ttl = null)
169 {
170     SugarCache::instance()->set($key,$value, $ttl);
171 }
172
173 /**
174  * Clear a key from the cache.  This is used to invalidate a single key.
175  *
176  * @param String $key -- Key from global namespace
177  */
178 function sugar_cache_clear($key)
179 {
180     unset(SugarCache::instance()->$key);
181 }
182
183 /**
184  * Turn off external caching for the rest of this round trip and for all round
185  * trips for the next cache timeout.  This function should be called when global arrays
186  * are affected (studio, module loader, upgrade wizard, ... ) and it is not ok to
187  * wait for the cache to expire in order to see the change.
188  */
189 function sugar_cache_reset()
190 {
191     SugarCache::instance()->reset();
192     SugarCache::cleanOpcodes();
193 }
194
195 /**
196  * Flush the cache in its entirety including the local and external store along with the opcodes.
197  */
198 function sugar_cache_reset_full()
199 {
200     SugarCache::instance()->resetFull();
201     SugarCache::cleanOpcodes();
202 }
203
204 /**
205  * Clean out whatever opcode cache we may have out there.
206  */
207 function sugar_clean_opcodes()
208 {
209     SugarCache::cleanOpcodes();
210 }
211
212 /**
213  * Internal -- Determine if there is an external cache available for use.
214  *
215  * @deprecated
216  */
217 function check_cache()
218 {
219     SugarCache::instance();
220 }
221
222 /**
223  * This function is called once an external cache has been identified to ensure that it is correctly
224  * working.
225  *
226  * @deprecated
227  *
228  * @return true for success, false for failure.
229  */
230 function sugar_cache_validate()
231 {
232     $instance = SugarCache::instance();
233
234     return is_object($instance);
235 }
236
237 /**
238  * Internal -- This function actually retrieves information from the caches.
239  * It is a helper function that provides that actual cache API abstraction.
240  *
241  * @param unknown_type $key
242  * @return unknown
243  * @deprecated
244  * @see sugar_cache_retrieve
245  */
246 function external_cache_retrieve_helper($key)
247 {
248     return SugarCache::instance()->$key;
249 }