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