}
/**
- * Get a message from either the content language or the user language. The fallback
- * language order is the users language fallback union the content language fallback.
- * This list is then applied to find keys in the following order
- * 1) MediaWiki:$key/$langcode (for every language except the content language where
- * we look at MediaWiki:$key)
- * 2) Built-in messages via the l10n cache which is also in fallback order
+ * Get a message from either the content language or the user language.
*
- * @param string $key the message cache key
- * @param $useDB Boolean: If true will look for the message in the DB, false only
- * get the message from the DB, false to use only the compiled l10n cache.
- * @param bool|string|object $langcode Code of the language to get the message for.
- * - If string and a valid code, will create a standard language object
- * - If string but not a valid code, will create a basic language object
- * - If boolean and false, create object from the current users language
- * - If boolean and true, create object from the wikis content language
- * - If language object, use it as given
+ * @param $key String: the message cache key
+ * @param $useDB Boolean: get the message from the DB, false to use only
+ * the localisation
+ * @param bool|string $langcode Code of the language to get the message for, if
+ * it is a valid code create a language for that language,
+ * if it is a string but not a valid code then make a basic
+ * language object, if it is a false boolean then use the
+ * current users language (as a fallback for the old
+ * parameter functionality), or if it is a true boolean
+ * then use the wikis content language (also as a
+ * fallback).
* @param $isFullKey Boolean: specifies whether $key is a two part key
* "msg/lang".
*
* @throws MWException
- * @return string|bool False if the message doesn't exist, otherwise the message
+ * @return string|bool
*/
function get( $key, $useDB = true, $langcode = true, $isFullKey = false ) {
global $wgLanguageCode, $wgContLang;
- wfProfileIn( __METHOD__ );
-
if ( is_int( $key ) ) {
// "Non-string key given" exception sometimes happens for numerical strings that become ints somewhere on their way here
$key = strval( $key );
}
if ( !is_string( $key ) ) {
- wfProfileOut( __METHOD__ );
throw new MWException( 'Non-string key given' );
}
if ( strval( $key ) === '' ) {
# Shortcut: the empty key is always missing
- wfProfileOut( __METHOD__ );
return false;
}
-
- # Obtain the initial language object
- if ( $isFullKey ) {
- $keyParts = explode( '/', $key );
- if ( count( $keyParts ) < 2 ) {
- throw new MWException( "Message key '$key' does not appear to be a full key." );
- }
-
- $langcode = array_pop( $keyParts );
- $key = implode( '/', $keyParts );
- }
-
- # Obtain a language object for the requested language from the passed language code
- # Note that the language code could in fact be a language object already but we assume
- # it's a string further below.
- $requestedLangObj = wfGetLangObj( $langcode );
- if ( !$requestedLangObj ) {
- wfProfileOut( __METHOD__ );
+ $lang = wfGetLangObj( $langcode );
+ if ( !$lang ) {
throw new MWException( "Bad lang code $langcode given" );
}
- $langcode = $requestedLangObj->getCode();
+
+ $langcode = $lang->getCode();
+
+ $message = false;
# Normalise title-case input (with some inlining)
$lckey = str_replace( ' ', '_', $key );
$uckey = $wgContLang->ucfirst( $lckey );
}
- # Loop through each language in the fallback list until we find something useful
- $message = false;
-
# Try the MediaWiki namespace
- if ( !$this->mDisable && $useDB ) {
- $fallbackChain = Language::getFallbacksIncludingSiteLanguage( $langcode );
- array_unshift( $fallbackChain, $langcode );
-
- foreach ( $fallbackChain as $langcode ) {
- if ( $langcode === $wgLanguageCode ) {
- # Messages created in the content language will not have the /lang extension
- $message = $this->getMsgFromNamespace( $uckey, $langcode );
- } else {
- $message = $this->getMsgFromNamespace( "$uckey/$langcode", $langcode );
- }
-
- if ( $message !== false ) {
- break;
- }
+ if( !$this->mDisable && $useDB ) {
+ $title = $uckey;
+ if( !$isFullKey && ( $langcode != $wgLanguageCode ) ) {
+ $title .= '/' . $langcode;
}
+ $message = $this->getMsgFromNamespace( $title, $langcode );
}
# Try the array in the language object
if ( $message === false ) {
- $message = $requestedLangObj->getMessage( $lckey );
- if ( is_null ( $message ) ) {
+ $message = $lang->getMessage( $lckey );
+ if ( is_null( $message ) ) {
$message = false;
}
}
- # If we still have no message, maybe the key was in fact a full key so try that
+ # Try the array of another language
if( $message === false ) {
$parts = explode( '/', $lckey );
# We may get calls for things that are http-urls from sidebar
}
}
+ # Is this a custom message? Try the default language in the db...
+ if( ( $message === false || $message === '-' ) &&
+ !$this->mDisable && $useDB &&
+ !$isFullKey && ( $langcode != $wgLanguageCode ) ) {
+ $message = $this->getMsgFromNamespace( $uckey, $wgLanguageCode );
+ }
+
# Final fallback
if( $message === false ) {
- wfProfileOut( __METHOD__ );
return false;
}
' ' => "\xc2\xa0",
) );
- wfProfileOut( __METHOD__ );
return $message;
}
}
}
- /**
- * Get the ordered list of fallback languages, ending with the fallback
- * language chain for the site language.
- *
- * @since 1.21
- * @param $code string Language code
- * @return array
- */
- public static function getFallbacksIncludingSiteLanguage( $code ) {
- global $wgLanguageCode;
-
- // Usually, we will only store a tiny number of fallback chains, so we
- // keep them in static memory.
- static $fallbackLanguageCache = array();
- $cacheKey = "{$code}-{$wgLanguageCode}";
-
- if ( !array_key_exists( $cacheKey, $fallbackLanguageCache ) ) {
- $fallbacks = self::getFallbacksFor( $code );
-
- // Take the final 'en' off of the array before splicing
- if ( end( $fallbacks ) === 'en' ) {
- array_pop( $fallbacks );
- }
- // Append the site's fallback chain, including the site language itself
- $siteFallbacks = self::getFallbacksFor( $wgLanguageCode );
- array_unshift( $siteFallbacks, $wgLanguageCode );
-
- // Eliminate any languages already included in the chain
- $siteFallbacks = array_intersect( array_diff( $siteFallbacks, $fallbacks ), $siteFallbacks );
- if ( $siteFallbacks ) {
- $fallbacks = array_merge( $fallbacks, $siteFallbacks );
- }
- if ( end( $fallbacks ) !== 'en' ) {
- $fallbacks[] = 'en';
- }
- $fallbackLanguageCache[$cacheKey] = $fallbacks;
- }
- return $fallbackLanguageCache[$cacheKey];
- }
-
/**
* Get all messages for a given language
* WARNING: this may take a long time. If you just need all message *keys*
+++ /dev/null
-<?php
-
-/**
- * @group Database
- * @group Cache
- */
-class MessageCacheTest extends MediaWikiLangTestCase {
-
- protected function setUp() {
- parent::setUp();
- $this->configureLanguages();
- MessageCache::singleton()->enable();
- }
-
- /**
- * Helper function -- setup site language for testing
- */
- protected function configureLanguages() {
- // for the test, we need the content language to be anything but English,
- // let's choose e.g. German (de)
- $langCode = 'de';
- $langObj = Language::factory( $langCode );
-
- $this->setMwGlobals( array(
- 'wgLanguageCode' => $langCode,
- 'wgLang' => $langObj,
- 'wgContLang' => $langObj,
- ) );
- }
-
- function addDBData() {
- $this->configureLanguages();
-
- // Set up messages and fallbacks ab -> ru -> de -> en
- $this->makePage( 'FallbackLanguageTest-Full', 'ab' );
- $this->makePage( 'FallbackLanguageTest-Full', 'ru' );
- $this->makePage( 'FallbackLanguageTest-Full', 'de' );
- $this->makePage( 'FallbackLanguageTest-Full', 'en' );
-
- // Fallbacks where ab does not exist
- $this->makePage( 'FallbackLanguageTest-Partial', 'ru' );
- $this->makePage( 'FallbackLanguageTest-Partial', 'de' );
- $this->makePage( 'FallbackLanguageTest-Partial', 'en' );
-
- // Fallback to the content language
- $this->makePage( 'FallbackLanguageTest-ContLang', 'de' );
- $this->makePage( 'FallbackLanguageTest-ContLang', 'en' );
-
- // Fallback to english
- $this->makePage( 'FallbackLanguageTest-English', 'en' );
-
- // Full key tests -- always want russian
- $this->makePage( 'MessageCacheTest-FullKeyTest', 'ab' );
- $this->makePage( 'MessageCacheTest-FullKeyTest', 'ru' );
- }
-
- /**
- * Helper function for addDBData -- adds a simple page to the database
- *
- * @param string $title Title of page to be created
- * @param string $lang Language and content of the created page
- */
- protected function makePage( $title, $lang ) {
- global $wgContLang;
-
- $title = Title::newFromText(
- ( $lang == $wgContLang->getCode() ) ? $title : "$title/$lang",
- NS_MEDIAWIKI
- );
- $wikiPage = new WikiPage( $title );
- $content = ContentHandler::makeContent( $lang, $title );
- $wikiPage->doEditContent( $content, "$lang translation test case" );
- }
-
- /**
- * Test message fallbacks, bug #1495
- *
- * @dataProvider provideMessagesForFallback
- */
- function testMessageFallbacks( $message, $lang, $expectedContent ) {
- $result = MessageCache::singleton()->get( $message, true, $lang );
- $this->assertEquals( $expectedContent, $result, "Message fallback failed." );
- }
-
- public static function provideMessagesForFallback() {
- return array(
- array( 'FallbackLanguageTest-Full', 'ab', 'ab' ),
- array( 'FallbackLanguageTest-Partial', 'ab', 'ru' ),
- array( 'FallbackLanguageTest-ContLang', 'ab', 'de' ),
- array( 'FallbackLanguageTest-English', 'ab', 'en' ),
- array( 'FallbackLanguageTest-None', 'ab', false ),
- );
- }
-
- /**
- * There's a fallback case where the message key is given as fully qualified -- this
- * should ignore the passed $lang and use the language from the key
- *
- * @dataProvider provideMessagesForFullKeys
- */
- function testFullKeyBehaviour( $message, $lang, $expectedContent ) {
- $result = MessageCache::singleton()->get( $message, true, $lang, true );
- $this->assertEquals( $expectedContent, $result, "Full key message fallback failed." );
- }
-
- public static function provideMessagesForFullKeys() {
- return array(
- array( 'MessageCacheTest-FullKeyTest/ru', 'ru', 'ru' ),
- array( 'MessageCacheTest-FullKeyTest/ru', 'ab', 'ru' ),
- array( 'MessageCacheTest-FullKeyTest/ru/foo', 'ru', false ),
- );
- }
-
-}