var $mKeys, $mParserOptions, $mParser;
var $mExtensionMessages = array();
var $mInitialised = false;
- var $mAllMessagesLoaded; // Extension messages
+ var $mAllMessagesLoaded = array(); // Extension messages
// Variable for tracking which variables are loaded
var $mLoadedLanguages = array();
/**
* ParserOptions is lazy initialised.
- * Access should probably be protected.
*/
function getParserOptions() {
if ( !$this->mParserOptions ) {
global $wgLocalMessageCache;
$filename = "$wgLocalMessageCache/messages-" . wfWikiID() . "-$code";
- wfMkdirParents( $wgLocalMessageCache, 0777 ); // might fail
+ wfMkdirParents( $wgLocalMessageCache ); // might fail
wfSuppressWarnings();
$file = fopen( $filename, 'w' );
$filename = "$wgLocalMessageCache/messages-" . wfWikiID() . "-$code";
$tempFilename = $filename . '.tmp';
- wfMkdirParents( $wgLocalMessageCache, 0777 ); // might fail
+ wfMkdirParents( $wgLocalMessageCache ); // might fail
wfSuppressWarnings();
$file = fopen( $tempFilename, 'w');
$this->lock($cacheKey);
- $cache = $this->loadFromDB( $code );
- $success = $this->setCache( $cache, $code );
+ # Limit the concurrency of loadFromDB to a single process
+ # This prevents the site from going down when the cache expires
+ $statusKey = wfMemcKey( 'messages', $code, 'status' );
+ $success = $this->mMemc->add( $statusKey, 'loading', MSG_LOAD_TIMEOUT );
if ( $success ) {
- $this->saveToCaches( $cache, true, $code );
+ $cache = $this->loadFromDB( $code );
+ $success = $this->setCache( $cache, $code );
+ }
+ if ( $success ) {
+ $success = $this->saveToCaches( $cache, true, $code );
+ if ( $success ) {
+ $this->mMemc->delete( $statusKey );
+ } else {
+ $this->mMemc->set( $statusKey, 'error', 60*5 );
+ wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" );
+ }
}
-
$this->unlock($cacheKey);
}
$sidebarKey = wfMemcKey( 'sidebar', $code );
$parserMemc->delete( $sidebarKey );
+ wfRunHooks( "MessageCacheReplace", array( $title, $text ) );
+
wfProfileOut( __METHOD__ );
}
global $wgLocalMessageCache, $wgLocalMessageCacheSerialized;
$cacheKey = wfMemcKey( 'messages', $code );
- $statusKey = wfMemcKey( 'messages', $code, 'status' );
-
- $success = $this->mMemc->add( $statusKey, 'loading', MSG_LOAD_TIMEOUT );
- if ( !$success ) return true; # Other process should be updating them now
$i = 0;
if ( $memc ) {
}
if ( $i == 20 ) {
- $this->mMemc->set( $statusKey, 'error', 60*5 );
- wfDebug( "MemCached set error in MessageCache: restart memcached server!\n" );
$success = false;
} else {
- $this->mMemc->delete( $statusKey );
$success = true;
}
wfProfileOut( __METHOD__ );
return $message;
}
- function transform( $message, $interface = false ) {
+ function transform( $message, $interface = false, $language = null ) {
// Avoid creating parser if nothing to transfrom
if( strpos( $message, '{{' ) === false ) {
return $message;
}
- global $wgParser;
+ global $wgParser, $wgParserConf;
if ( !$this->mParser && isset( $wgParser ) ) {
# Do some initialisation so that we don't have to do it twice
$wgParser->firstCallInit();
# Clone it and store it
- $this->mParser = clone $wgParser;
+ $class = $wgParserConf['class'];
+ if ( $class == 'Parser_DiffTest' ) {
+ # Uncloneable
+ $this->mParser = new $class( $wgParserConf );
+ } else {
+ $this->mParser = clone $wgParser;
+ }
#wfDebug( __METHOD__ . ": following contents triggered transform: $message\n" );
}
if ( $this->mParser ) {
$popts = $this->getParserOptions();
$popts->setInterfaceMessage( $interface );
+ $popts->setTargetLanguage( $language );
$message = $this->mParser->transformMsg( $message, $popts );
}
return $message;
* @param string $lang The messages language, English by default
*/
function addMessage( $key, $value, $lang = 'en' ) {
- $this->mExtensionMessages[$lang][$key] = $value;
+ global $wgContLang;
+ # Normalise title-case input
+ $lckey = str_replace( ' ', '_', $wgContLang->lcfirst( $key ) );
+ $this->mExtensionMessages[$lang][$lckey] = $value;
}
/**
}
}
- function loadAllMessages() {
+ function loadAllMessages( $lang = false ) {
global $wgExtensionMessagesFiles;
- if ( $this->mAllMessagesLoaded ) {
+ $key = $lang === false ? '*' : $lang;
+ if ( isset( $this->mAllMessagesLoaded[$key] ) ) {
return;
}
- $this->mAllMessagesLoaded = true;
+ $this->mAllMessagesLoaded[$key] = true;
# Some extensions will load their messages when you load their class file
wfLoadAllExtensions();
wfRunHooks( 'LoadAllMessages' );
# Some register their messages in $wgExtensionMessagesFiles
foreach ( $wgExtensionMessagesFiles as $name => $file ) {
- wfLoadExtensionMessages( $name );
+ wfLoadExtensionMessages( $name, $lang );
}
# Still others will respond to neither, they are EVIL. We sometimes need to know!
}
*/
function loadMessagesFile( $filename, $langcode = false ) {
global $wgLang, $wgContLang;
+ wfProfileIn( __METHOD__ );
$messages = $magicWords = false;
require( $filename );
global $wgContLang;
$wgContLang->addMagicWordsByLang( $magicWords );
}
+ wfProfileOut( __METHOD__ );
}
/**
* @param string $langcode Language code to process.
*/
function processMessagesArray( $messages, $langcode ) {
+ wfProfileIn( __METHOD__ );
$fallbackCode = $langcode;
$mergedMessages = array();
do {
if ( !empty($mergedMessages) )
$this->addMessages( $mergedMessages, $langcode );
+ wfProfileOut( __METHOD__ );
}
public function figureMessage( $key ) {
global $wgContLanguageCode;
- $pieces = explode('/', $key, 2);
+ $pieces = explode( '/', $key );
+ if( count( $pieces ) < 2 )
+ return array( $key, $wgContLanguageCode );
- $key = $pieces[0];
+ $lang = array_pop( $pieces );
+ $validCodes = Language::getLanguageNames();
+ if( !array_key_exists( $lang, $validCodes ) )
+ return array( $key, $wgContLanguageCode );
- # Language the user is translating to
- $langCode = isset($pieces[1]) ? $pieces[1] : $wgContLanguageCode;
- return array( $key, $langCode );
+ $message = implode( '/', $pieces );
+ return array( $message, $lang );
}
}