summaryrefslogtreecommitdiff
path: root/includes/cache/LocalisationCache.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/cache/LocalisationCache.php')
-rw-r--r--includes/cache/LocalisationCache.php71
1 files changed, 37 insertions, 34 deletions
diff --git a/includes/cache/LocalisationCache.php b/includes/cache/LocalisationCache.php
index ae27fba3..dc5a2eb6 100644
--- a/includes/cache/LocalisationCache.php
+++ b/includes/cache/LocalisationCache.php
@@ -20,6 +20,10 @@
* @file
*/
+use Cdb\Exception as CdbException;
+use Cdb\Reader as CdbReader;
+use Cdb\Writer as CdbWriter;
+
/**
* Class for caching the contents of localisation files, Messages*.php
* and *.i18n.php.
@@ -33,7 +37,7 @@
* as grammatical transformation, is done by the caller.
*/
class LocalisationCache {
- const VERSION = 2;
+ const VERSION = 3;
/** Configuration associative array */
private $conf;
@@ -253,9 +257,7 @@ class LocalisationCache {
*/
public function getItem( $code, $key ) {
if ( !isset( $this->loadedItems[$code][$key] ) ) {
- wfProfileIn( __METHOD__ . '-load' );
$this->loadItem( $code, $key );
- wfProfileOut( __METHOD__ . '-load' );
}
if ( $key === 'fallback' && isset( $this->shallowFallbacks[$code] ) ) {
@@ -276,9 +278,7 @@ class LocalisationCache {
if ( !isset( $this->loadedSubitems[$code][$key][$subkey] ) &&
!isset( $this->loadedItems[$code][$key] )
) {
- wfProfileIn( __METHOD__ . '-load' );
$this->loadSubitem( $code, $key, $subkey );
- wfProfileOut( __METHOD__ . '-load' );
}
if ( isset( $this->data[$code][$key][$subkey] ) ) {
@@ -505,7 +505,6 @@ class LocalisationCache {
* @return array
*/
protected function readPHPFile( $_fileName, $_fileType ) {
- wfProfileIn( __METHOD__ );
// Disable APC caching
wfSuppressWarnings();
$_apcEnabled = ini_set( 'apc.cache_by_default', '0' );
@@ -522,10 +521,8 @@ class LocalisationCache {
} elseif ( $_fileType == 'aliases' ) {
$data = compact( 'aliases' );
} else {
- wfProfileOut( __METHOD__ );
throw new MWException( __METHOD__ . ": Invalid file type: $_fileType" );
}
- wfProfileOut( __METHOD__ );
return $data;
}
@@ -537,24 +534,20 @@ class LocalisationCache {
* @return array Array with a 'messages' key, or empty array if the file doesn't exist
*/
public function readJSONFile( $fileName ) {
- wfProfileIn( __METHOD__ );
if ( !is_readable( $fileName ) ) {
- wfProfileOut( __METHOD__ );
return array();
}
$json = file_get_contents( $fileName );
if ( $json === false ) {
- wfProfileOut( __METHOD__ );
return array();
}
$data = FormatJson::decode( $json, true );
if ( $data === null ) {
- wfProfileOut( __METHOD__ );
throw new MWException( __METHOD__ . ": Invalid JSON file: $fileName" );
}
@@ -566,8 +559,6 @@ class LocalisationCache {
}
}
- wfProfileOut( __METHOD__ );
-
// The JSON format only supports messages, none of the other variables, so wrap the data
return array( 'messages' => $data );
}
@@ -650,10 +641,16 @@ class LocalisationCache {
* rules, and save the compiled rules in a process-local cache.
*
* @param string $fileName
+ * @throws MWException
*/
protected function loadPluralFile( $fileName ) {
+ // Use file_get_contents instead of DOMDocument::load (T58439)
+ $xml = file_get_contents( $fileName );
+ if ( !$xml ) {
+ throw new MWException( "Unable to read plurals file $fileName" );
+ }
$doc = new DOMDocument;
- $doc->load( $fileName );
+ $doc->loadXML( $xml );
$rulesets = $doc->getElementsByTagName( "pluralRules" );
foreach ( $rulesets as $ruleset ) {
$codes = $ruleset->getAttribute( 'locales' );
@@ -687,7 +684,6 @@ class LocalisationCache {
*/
protected function readSourceFilesAndRegisterDeps( $code, &$deps ) {
global $IP;
- wfProfileIn( __METHOD__ );
// This reads in the PHP i18n file with non-messages l10n data
$fileName = Language::getMessagesFileName( $code );
@@ -708,8 +704,6 @@ class LocalisationCache {
$deps['plurals'] = new FileDependency( "$IP/languages/data/plurals.xml" );
$deps['plurals-mw'] = new FileDependency( "$IP/languages/data/plurals-mediawiki.xml" );
- wfProfileOut( __METHOD__ );
-
return $data;
}
@@ -790,17 +784,31 @@ class LocalisationCache {
}
/**
+ * Gets the combined list of messages dirs from
+ * core and extensions
+ *
+ * @since 1.25
+ * @return array
+ */
+ public function getMessagesDirs() {
+ global $wgMessagesDirs, $IP;
+ return array(
+ 'core' => "$IP/languages/i18n",
+ 'api' => "$IP/includes/api/i18n",
+ 'oojs-ui' => "$IP/resources/lib/oojs-ui/i18n",
+ ) + $wgMessagesDirs;
+ }
+
+ /**
* Load localisation data for a given language for both core and extensions
* and save it to the persistent cache store and the process cache
* @param string $code
* @throws MWException
*/
public function recache( $code ) {
- global $wgExtensionMessagesFiles, $wgMessagesDirs;
- wfProfileIn( __METHOD__ );
+ global $wgExtensionMessagesFiles;
if ( !$code ) {
- wfProfileOut( __METHOD__ );
throw new MWException( "Invalid language code requested" );
}
$this->recachedLangs[$code] = true;
@@ -843,15 +851,14 @@ class LocalisationCache {
}
$codeSequence = array_merge( array( $code ), $coreData['fallbackSequence'] );
-
- wfProfileIn( __METHOD__ . '-fallbacks' );
+ $messageDirs = $this->getMessagesDirs();
# Load non-JSON localisation data for extensions
$extensionData = array_combine(
$codeSequence,
array_fill( 0, count( $codeSequence ), $initialData ) );
foreach ( $wgExtensionMessagesFiles as $extension => $fileName ) {
- if ( isset( $wgMessagesDirs[$extension] ) ) {
+ if ( isset( $messageDirs[$extension] ) ) {
# This extension has JSON message data; skip the PHP shim
continue;
}
@@ -879,7 +886,7 @@ class LocalisationCache {
$csData = $initialData;
# Load core messages and the extension localisations.
- foreach ( $wgMessagesDirs as $dirs ) {
+ foreach ( $messageDirs as $dirs ) {
foreach ( (array)$dirs as $dir ) {
$fileName = "$dir/$csCode.json";
$data = $this->readJSONFile( $fileName );
@@ -924,7 +931,7 @@ class LocalisationCache {
# Allow extensions an opportunity to adjust the data for this
# fallback
- wfRunHooks( 'LocalisationCacheRecacheFallback', array( $this, $csCode, &$csData ) );
+ Hooks::run( 'LocalisationCacheRecacheFallback', array( $this, $csCode, &$csData ) );
# Merge the data for this fallback into the final array
if ( $csCode === $code ) {
@@ -942,10 +949,9 @@ class LocalisationCache {
}
}
- wfProfileOut( __METHOD__ . '-fallbacks' );
-
# Add cache dependencies for any referenced globals
$deps['wgExtensionMessagesFiles'] = new GlobalDependency( 'wgExtensionMessagesFiles' );
+ // $wgMessagesDirs is used in LocalisationCache::getMessagesDirs()
$deps['wgMessagesDirs'] = new GlobalDependency( 'wgMessagesDirs' );
$deps['version'] = new ConstantDependency( 'LocalisationCache::VERSION' );
@@ -981,10 +987,9 @@ class LocalisationCache {
}
# Run hooks
$purgeBlobs = true;
- wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData, &$purgeBlobs ) );
+ Hooks::run( 'LocalisationCacheRecache', array( $this, $code, &$allData, &$purgeBlobs ) );
if ( is_null( $allData['namespaceNames'] ) ) {
- wfProfileOut( __METHOD__ );
throw new MWException( __METHOD__ . ': Localisation data failed sanity check! ' .
'Check that your languages/messages/MessagesEn.php file is intact.' );
}
@@ -999,7 +1004,6 @@ class LocalisationCache {
}
# Save to the persistent cache
- wfProfileIn( __METHOD__ . '-write' );
$this->store->startWrite( $code );
foreach ( $allData as $key => $value ) {
if ( in_array( $key, self::$splitKeys ) ) {
@@ -1011,16 +1015,15 @@ class LocalisationCache {
}
}
$this->store->finishWrite();
- wfProfileOut( __METHOD__ . '-write' );
# Clear out the MessageBlobStore
# HACK: If using a null (i.e. disabled) storage backend, we
# can't write to the MessageBlobStore either
if ( $purgeBlobs && !$this->store instanceof LCStoreNull ) {
- MessageBlobStore::getInstance()->clear();
+ $blobStore = new MessageBlobStore();
+ $blobStore->clear();
}
- wfProfileOut( __METHOD__ );
}
/**