protected $contLang;
/**
- * Singleton instance
- *
- * @var MessageCache $instance
+ * Track which languages have been loaded by load().
+ * @var array
*/
- private static $instance;
+ private $loadedLanguages = [];
/**
- * Get the signleton instance of this class
+ * Get the singleton instance of this class
*
+ * @deprecated in 1.34 inject an instance of this class instead of using global state
* @since 1.18
* @return MessageCache
*/
public static function singleton() {
- if ( self::$instance === null ) {
- global $wgUseDatabaseMessages, $wgMsgCacheExpiry, $wgUseLocalMessageCache;
- $services = MediaWikiServices::getInstance();
- self::$instance = new self(
- $services->getMainWANObjectCache(),
- wfGetMessageCacheStorage(),
- $wgUseLocalMessageCache
- ? $services->getLocalServerObjectCache()
- : new EmptyBagOStuff(),
- $wgUseDatabaseMessages,
- $wgMsgCacheExpiry,
- $services->getContentLanguage()
- );
- }
-
- return self::$instance;
- }
-
- /**
- * Destroy the singleton instance
- *
- * @since 1.18
- */
- public static function destroyInstance() {
- self::$instance = null;
+ return MediaWikiServices::getInstance()->getMessageCache();
}
/**
}
# Don't do double loading...
- if ( $this->cache->has( $code ) && $mode != self::FOR_UPDATE ) {
+ if ( isset( $this->loadedLanguages[$code] ) && $mode != self::FOR_UPDATE ) {
return true;
}
$this->overridable = array_flip( Language::getMessageKeysFor( $code ) );
- // T208897 array_flip can fail and return null
- if ( is_null( $this->overridable ) ) {
- LoggerFactory::getInstance( 'MessageCache' )->error(
- __METHOD__ . ': $this->overridable is null',
- [
- 'message_keys' => Language::getMessageKeysFor( $code ),
- 'code' => $code
- ]
- );
- }
-
# 8 lines of code just to say (once) that message cache is disabled
if ( $this->mDisable ) {
static $shownDisabled = false;
wfDebugLog( 'MessageCacheError', __METHOD__ . ": Failed to load $code\n" );
# This used to throw an exception, but that led to nasty side effects like
# the whole wiki being instantly down if the memcached server died
+ } else {
+ # All good, just record the success
+ $this->loadedLanguages[$code] = true;
}
if ( !$this->cache->has( $code ) ) { // sanity
__METHOD__ . "($code)-big"
);
foreach ( $res as $row ) {
- $name = $this->contLang->lcfirst( $row->page_title );
// Include entries/stubs for all keys in $mostused in adaptive mode
- if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
+ if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) {
$cache[$row->page_title] = '!TOO BIG';
}
// At least include revision ID so page changes are reflected in the hash
$revQuery['joins']
);
foreach ( $res as $row ) {
- $name = $this->contLang->lcfirst( $row->page_title );
// Include entries/stubs for all keys in $mostused in adaptive mode
- if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $name, $overridable ) ) {
+ if ( $wgAdaptiveMessageCache || $this->isMainCacheable( $row->page_title, $overridable ) ) {
try {
$rev = $revisionStore->newRevisionFromRow( $row );
$content = $rev->getContent( MediaWiki\Revision\SlotRecord::MAIN );
}
/**
- * @param string $name Message name with lowercase first letter
+ * @param string $name Message name (possibly with /code suffix)
* @param array $overridable Map of (key => unused) for software-defined messages
* @return bool
*/
private function isMainCacheable( $name, array $overridable ) {
+ // Convert first letter to lowercase, and strip /code suffix
+ $name = $this->contLang->lcfirst( $name );
+ $msg = preg_replace( '/\/[a-z0-9-]{2,}$/', '', $name );
// Include common conversion table pages. This also avoids problems with
// Installer::parse() bailing out due to disallowed DB queries (T207979).
- return ( isset( $overridable[$name] ) || strpos( $name, 'conversiontable/' ) === 0 );
+ return ( isset( $overridable[$msg] ) || strpos( $name, 'conversiontable/' ) === 0 );
}
/**
);
} else {
// Message page either does not exist or does not override a software message
- $name = $this->contLang->lcfirst( $title );
- if ( !$this->isMainCacheable( $name, $this->overridable ) ) {
+ if ( !$this->isMainCacheable( $title, $this->overridable ) ) {
// Message page does not override any software-defined message. A custom
// message might be defined to have content or settings specific to the wiki.
// Load the message page, utilizing the individual message cache as needed.
$this->wanCache->touchCheckKey( $this->getCheckKey( $code ) );
}
$this->cache->clear();
+ $this->loadedLanguages = [];
}
/**