SugarCache   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 104
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 6.67%
Metric Value
dl 0
loc 104
ccs 3
cts 45
cp 0.0667
rs 10
wmc 28
lcom 1
cbo 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 1 1
C _init() 0 28 12
A instance() 0 7 2
D cleanOpcodes() 0 28 10
A cleanFile() 0 8 3
1
<?php
2
/*********************************************************************************
3
 * SugarCRM Community Edition is a customer relationship management program developed by
4
 * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc.
5
6
 * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd.
7
 * Copyright (C) 2011 - 2014 Salesagility Ltd.
8
 *
9
 * This program is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU Affero General Public License version 3 as published by the
11
 * Free Software Foundation with the addition of the following permission added
12
 * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
13
 * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
14
 * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
15
 *
16
 * This program is distributed in the hope that it will be useful, but WITHOUT
17
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
 * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
19
 * details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License along with
22
 * this program; if not, see http://www.gnu.org/licenses or write to the Free
23
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24
 * 02110-1301 USA.
25
 *
26
 * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
27
 * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected].
28
 *
29
 * The interactive user interfaces in modified source and object code versions
30
 * of this program must display Appropriate Legal Notices, as required under
31
 * Section 5 of the GNU Affero General Public License version 3.
32
 *
33
 * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
34
 * these Appropriate Legal Notices must retain the display of the "Powered by
35
 * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not
36
 * reasonably feasible for  technical reasons, the Appropriate Legal Notices must
37
 * display the words  "Powered by SugarCRM" and "Supercharged by SuiteCRM".
38
 ********************************************************************************/
39
40
41
/**
42
 * Sugar Cache manager
43
 * @api
44
 */
45
class SugarCache
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
46
{
47
    const EXTERNAL_CACHE_NULL_VALUE = "SUGAR_CACHE_NULL_ZZ";
48
49
    protected static $_cacheInstance;
50
51
    /**
52
     * @var true if the cache has been reset during this request, so we no longer return values from
53
     *      cache until the next reset
54
     */
55
    public static $isCacheReset = false;
56
57
    private function __construct() {}
58
59
    /**
60
     * initializes the cache in question
61
     */
62
    protected static function _init()
63
    {
64
        $lastPriority = 1000;
65
        $locations = array('include/SugarCache','custom/include/SugarCache');
66
 	    foreach ( $locations as $location ) {
67
            if (sugar_is_dir($location) && $dir = opendir($location)) {
68
                while (($file = readdir($dir)) !== false) {
69
                    if ($file == ".."
70
                            || $file == "."
71
                            || !is_file("$location/$file")
72
                            )
73
                        continue;
74
                    require_once("$location/$file");
75
                    $cacheClass = basename($file, ".php");
76
                    if ( class_exists($cacheClass) && is_subclass_of($cacheClass,'SugarCacheAbstract') ) {
77
                        $GLOBALS['log']->debug("Found cache backend $cacheClass");
78
                        $cacheInstance = new $cacheClass();
79
                        if ( $cacheInstance->useBackend()
80
                                && $cacheInstance->getPriority() < $lastPriority ) {
81
                            $GLOBALS['log']->debug("Using cache backend $cacheClass, since ".$cacheInstance->getPriority()." is less than ".$lastPriority);
82
                            self::$_cacheInstance = $cacheInstance;
83
                            $lastPriority = $cacheInstance->getPriority();
84
                        }
85
                    }
86
                }
87
            }
88
        }
89
    }
90
91
    /**
92
     * Returns the instance of the SugarCacheAbstract object, cooresponding to the external
93
     * cache being used.
94
     */
95 900
    public static function instance()
96
    {
97 900
        if ( !is_subclass_of(self::$_cacheInstance,'SugarCacheAbstract') )
98
            self::_init();
99
100 900
        return self::$_cacheInstance;
101
    }
102
103
    /**
104
     * Try to reset any opcode caches we know about
105
     *
106
     * @todo make it so developers can extend this somehow
107
     */
108
    public static function cleanOpcodes()
109
    {
110
        // APC
111
        if ( function_exists('apc_clear_cache') && ini_get('apc.stat') == 0 ) {
112
            apc_clear_cache();
113
        }
114
        // Wincache
115
        if ( function_exists('wincache_refresh_if_changed') ) {
116
            wincache_refresh_if_changed();
117
        }
118
        // Zend
119
        if ( function_exists('accelerator_reset') ) {
120
            accelerator_reset();
121
        }
122
        // eAccelerator
123
        if ( function_exists('eaccelerator_clear') ) {
124
            eaccelerator_clear();
125
        }
126
        // XCache
127
        if ( function_exists('xcache_clear_cache') && !ini_get('xcache.admin.enable_auth') ) {
128
            $max = xcache_count(XC_TYPE_PHP);
129
            for ($i = 0; $i < $max; $i++) {
130
                if (!xcache_clear_cache(XC_TYPE_PHP, $i)) {
131
                    break;
132
                }
133
            }
134
        }
135
    }
136
137
    /**
138
     * Try to reset file from caches
139
     */
140
    public static function cleanFile( $file )
141
    {
142
        // APC
143
        if ( function_exists('apc_delete_file') && ini_get('apc.stat') == 0 )
144
        {
145
            apc_delete_file( $file );
146
        }
147
    }
148
}
149
150
/**
151
 * Procedural API for external cache
152
 */
153
154
/**
155
 * Retrieve a key from cache.  For the Zend Platform, a maximum age of 5 minutes is assumed.
156
 *
157
 * @param String $key -- The item to retrieve.
158
 * @return The item unserialized
159
 */
160
function sugar_cache_retrieve($key)
161
{
162 308
    return SugarCache::instance()->$key;
163
}
164
165
/**
166
 * Put a value in the cache under a key
167
 *
168
 * @param String $key -- Global namespace cache.  Key for the data.
169
 * @param Serializable $value -- The value to store in the cache.
170
 */
171
function sugar_cache_put($key, $value, $ttl = null)
172
{
173 878
    SugarCache::instance()->set($key,$value, $ttl);
174 878
}
175
176
/**
177
 * Clear a key from the cache.  This is used to invalidate a single key.
178
 *
179
 * @param String $key -- Key from global namespace
180
 */
181
function sugar_cache_clear($key)
182
{
183 6
    unset(SugarCache::instance()->$key);
184 6
}
185
186
/**
187
 * Turn off external caching for the rest of this round trip and for all round
188
 * trips for the next cache timeout.  This function should be called when global arrays
189
 * are affected (studio, module loader, upgrade wizard, ... ) and it is not ok to
190
 * wait for the cache to expire in order to see the change.
191
 */
192
function sugar_cache_reset()
193
{
194
    SugarCache::instance()->reset();
195
    SugarCache::cleanOpcodes();
196
}
197
198
/**
199
 * Flush the cache in its entirety including the local and external store along with the opcodes.
200
 */
201
function sugar_cache_reset_full()
202
{
203
    SugarCache::instance()->resetFull();
204
    SugarCache::cleanOpcodes();
205
}
206
207
/**
208
 * Clean out whatever opcode cache we may have out there.
209
 */
210
function sugar_clean_opcodes()
211
{
212
    SugarCache::cleanOpcodes();
213
}
214
215
/**
216
 * Internal -- Determine if there is an external cache available for use.
217
 *
218
 * @deprecated
219
 */
220
function check_cache()
221
{
222
    SugarCache::instance();
223
}
224
225
/**
226
 * This function is called once an external cache has been identified to ensure that it is correctly
227
 * working.
228
 *
229
 * @deprecated
230
 *
231
 * @return true for success, false for failure.
232
 */
233
function sugar_cache_validate()
234
{
235
    $instance = SugarCache::instance();
236
237
    return is_object($instance);
238
}
239
240
/**
241
 * Internal -- This function actually retrieves information from the caches.
242
 * It is a helper function that provides that actual cache API abstraction.
243
 *
244
 * @param unknown_type $key
245
 * @return unknown
246
 * @deprecated
247
 * @see sugar_cache_retrieve
248
 */
249
function external_cache_retrieve_helper($key)
250
{
251
    return SugarCache::instance()->$key;
252
}
253