Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
70.21% covered (warning)
70.21%
33 / 47
30.00% covered (danger)
30.00%
3 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
ObjectCache
70.21% covered (warning)
70.21%
33 / 47
30.00% covered (danger)
30.00%
3 / 10
41.52
0.00% covered (danger)
0.00%
0 / 1
 getInstance
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 newFromParams
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 newAnything
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getAnythingId
93.33% covered (success)
93.33%
14 / 15
0.00% covered (danger)
0.00%
0 / 1
8.02
 getLocalServerInstance
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getLocalClusterInstance
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isDatabaseId
88.89% covered (warning)
88.89%
8 / 9
0.00% covered (danger)
0.00%
0 / 1
4.02
 clear
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 makeLocalServerCache
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
 getLocalServerCacheClass
25.00% covered (danger)
25.00%
2 / 8
0.00% covered (danger)
0.00%
0 / 1
21.19
1<?php
2/**
3 * Functions to get cache objects.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup Cache
22 */
23
24use MediaWiki\MediaWikiServices;
25
26/**
27 * @see ObjectCacheFactory
28 * @ingroup Cache
29 */
30class ObjectCache {
31    /**
32     * @deprecated Use ObjectCacheFactory instead.
33     * @var BagOStuff[] Map of (id => BagOStuff)
34     */
35    public static $instances = [];
36
37    /**
38     * @internal for ObjectCacheTest
39     * @var string
40     */
41    public static $localServerCacheClass;
42
43    /**
44     * Get a cached instance of the specified type of cache object.
45     *
46     * @deprecated Use ObjectCacheFactory::getInstance instead.
47     *
48     * @param string|int $id A key in $wgObjectCaches.
49     * @return BagOStuff
50     */
51    public static function getInstance( $id ) {
52        return MediaWikiServices::getInstance()->getObjectCacheFactory()->getInstance( $id );
53    }
54
55    /**
56     * @see ObjectCacheFactory::newFromParams()
57     *
58     * @deprecated since 1.42, Use ObjectCacheFactory::newFromParams instead.
59     * @param array $params
60     *
61     * @return BagOStuff
62     */
63    public static function newFromParams( array $params ) {
64        return MediaWikiServices::getInstance()->getObjectCacheFactory()
65            ->newFromParams( $params );
66    }
67
68    /**
69     * Factory function for CACHE_ANYTHING (referenced by configuration)
70     *
71     * CACHE_ANYTHING means that stuff has to be cached, not caching is not an option.
72     * If a caching method is configured for any of the main caches ($wgMainCacheType,
73     * $wgMessageCacheType, $wgParserCacheType), then CACHE_ANYTHING will effectively
74     * be an alias to the configured cache choice for that.
75     * If no cache choice is configured (by default $wgMainCacheType is CACHE_NONE),
76     * then CACHE_ANYTHING will forward to CACHE_DB.
77     *
78     * @deprecated since 1.42,
79     *     Use ObjectCacheFactory::newInstance( ObjectCache::getAnythingId() );
80     *
81     * @return BagOStuff
82     */
83    public static function newAnything() {
84        return MediaWikiServices::getInstance()->getObjectCacheFactory()
85            ->getInstance( self::getAnythingId() );
86    }
87
88    /**
89     * @internal Used by ObjectCacheFactory and ObjectCache.
90     *
91     * Get the ID that will be used for CACHE_ANYTHING
92     * @return string|int
93     */
94    public static function getAnythingId() {
95        global $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType;
96        $candidates = [ $wgMainCacheType, $wgMessageCacheType, $wgParserCacheType ];
97        foreach ( $candidates as $candidate ) {
98            if ( $candidate === CACHE_ACCEL ) {
99                // CACHE_ACCEL might default to nothing if no APCu
100                // See includes/ServiceWiring.php
101                $class = self::getLocalServerCacheClass();
102                if ( $class !== EmptyBagOStuff::class ) {
103                    return $candidate;
104                }
105            } elseif ( $candidate !== CACHE_NONE && $candidate !== CACHE_ANYTHING ) {
106                return $candidate;
107            }
108        }
109
110        $services = MediaWikiServices::getInstance();
111
112        if ( $services->isServiceDisabled( 'DBLoadBalancer' ) ) {
113            // The DBLoadBalancer service is disabled, so we can't use the database!
114            $candidate = CACHE_NONE;
115        } elseif ( $services->isStorageDisabled() ) {
116            // Storage services are disabled because MediaWikiServices::disableStorage()
117            // was called. This is typically the case during installation.
118            $candidate = CACHE_NONE;
119        } else {
120            $candidate = CACHE_DB;
121        }
122        return $candidate;
123    }
124
125    /**
126     * @deprecated since 1.42, Use ObjectCacheFactory::getLocalServerInstance()
127     * @param int|string|array $fallback Fallback cache or parameter map with 'fallback'
128     * @return BagOStuff
129     * @throws InvalidArgumentException
130     * @since 1.27
131     */
132    public static function getLocalServerInstance( $fallback = CACHE_NONE ) {
133        return MediaWikiServices::getInstance()->getObjectCacheFactory()
134            ->getLocalServerInstance( $fallback );
135    }
136
137    /**
138     * Get the main cluster-local cache object.
139     *
140     * @since 1.27
141     * @return BagOStuff
142     */
143    public static function getLocalClusterInstance() {
144        return MediaWikiServices::getInstance()->get( '_LocalClusterCache' );
145    }
146
147    /**
148     * Determine whether a config ID would access the database
149     *
150     * @param string|int $id A key in $wgObjectCaches
151     * @return bool
152     */
153    public static function isDatabaseId( $id ) {
154        global $wgObjectCaches;
155
156        // NOTE: Sanity check if $id is set to CACHE_ANYTHING and
157        // everything is going through service wiring. CACHE_ANYTHING
158        // would default to CACHE_DB, let's handle that early for cases
159        // where all cache configs are set to CACHE_ANYTHING (T362686).
160        if ( $id === CACHE_ANYTHING ) {
161            $id = self::getAnythingId();
162            return self::isDatabaseId( $id );
163        }
164
165        if ( !isset( $wgObjectCaches[$id] ) ) {
166            return false;
167        }
168        $cache = $wgObjectCaches[$id];
169        if ( ( $cache['class'] ?? '' ) === SqlBagOStuff::class ) {
170            return true;
171        }
172
173        return false;
174    }
175
176    /**
177     * @deprecated since 1.42, Use ObjectCacheFactory::clear() instead.
178     *
179     * Clear all the cached instances.
180     */
181    public static function clear() {
182        MediaWikiServices::getInstance()->getObjectCacheFactory()->clear();
183    }
184
185    /**
186     * Create a new BagOStuff instance for local-server caching.
187     *
188     * Only use this if you explicitly require the creation of
189     * a fresh instance. Whenever possible, use or inject the object
190     * from MediaWikiServices::getLocalServerObjectCache() instead.
191     *
192     * NOTE: This method is called very early via Setup.php by ExtensionRegistry,
193     * and thus must remain fairly standalone so as to not cause initialization
194     * of the MediaWikiServices singleton.
195     *
196     * @internal For use by ServiceWiring and ExtensionRegistry. There are use
197     *   cases whereby we want to build up local server cache without service
198     *   wiring available.
199     * @since 1.35
200     * @param string $keyspace
201     * @return BagOStuff
202     */
203    public static function makeLocalServerCache( $keyspace ): BagOStuff {
204        $params = [
205            'reportDupes' => false,
206            // Even simple caches must use a keyspace (T247562)
207            'keyspace' => $keyspace,
208        ];
209        $class = self::getLocalServerCacheClass();
210        return new $class( $params );
211    }
212
213    /**
214     * Get the class which will be used for the local server cache
215     * @return string
216     */
217    private static function getLocalServerCacheClass() {
218        if ( self::$localServerCacheClass !== null ) {
219            return self::$localServerCacheClass;
220        }
221        if ( function_exists( 'apcu_fetch' ) ) {
222            // Make sure the APCu methods actually store anything
223            if ( PHP_SAPI !== 'cli' || ini_get( 'apc.enable_cli' ) ) {
224                return APCUBagOStuff::class;
225
226            }
227        } elseif ( function_exists( 'wincache_ucache_get' ) ) {
228            return WinCacheBagOStuff::class;
229        }
230
231        return EmptyBagOStuff::class;
232    }
233}