Follow-up I087c2729 (750936f): factorise common code
[lhc/web/wiklou.git] / includes / LocalisationCache.php
index c1ac848..94e823e 100644 (file)
@@ -110,7 +110,7 @@ class LocalisationCache {
                'dateFormats', 'datePreferences', 'datePreferenceMigrationMap',
                'defaultDateFormat', 'extraUserToggles', 'specialPageAliases',
                'imageFiles', 'preloadedMessages', 'namespaceGenderAliases',
-               'digitGroupingPattern', 'pluralRules'
+               'digitGroupingPattern', 'pluralRules', 'compiledPluralRules',
        );
 
        /**
@@ -118,7 +118,7 @@ class LocalisationCache {
         * by a fallback sequence.
         */
        static public $mergeableMapKeys = array( 'messages', 'namespaceNames',
-               'dateFormats', 'imageFiles', 'preloadedMessages', 'pluralRules'
+               'dateFormats', 'imageFiles', 'preloadedMessages'
        );
 
        /**
@@ -168,6 +168,7 @@ class LocalisationCache {
         * for $wgLocalisationCacheConf.
         *
         * @param $conf Array
+        * @throws MWException
         */
        function __construct( $conf ) {
                global $wgCacheDirectory;
@@ -378,7 +379,7 @@ class LocalisationCache {
                }
 
                $deps = $this->store->get( $code, 'deps' );
-               $keys = $this->store->get( $code, 'list', 'messages' );
+               $keys = $this->store->get( $code, 'list' );
                $preload = $this->store->get( $code, 'preload' );
                // Different keys may expire separately, at least in LCStore_Accel
                if ( $deps === null || $keys === null || $preload === null ) {
@@ -404,6 +405,7 @@ class LocalisationCache {
        /**
         * Initialise a language in this object. Rebuild the cache if necessary.
         * @param $code
+        * @throws MWException
         */
        protected function initLanguage( $code ) {
                if ( isset( $this->initialisedLangs[$code] ) ) {
@@ -474,6 +476,7 @@ class LocalisationCache {
         * Read a PHP file containing localisation data.
         * @param $_fileName
         * @param $_fileType
+        * @throws MWException
         * @return array
         */
        protected function readPHPFile( $_fileName, $_fileType ) {
@@ -498,6 +501,9 @@ class LocalisationCache {
         */
        public function getCompiledPluralRules( $code ) {
                $rules = $this->getPluralRules( $code );
+               if ( $rules === null ) {
+                       return null;
+               }
                try {
                        $compiledRules = CLDRPluralRuleEvaluator::compile( $rules );
                } catch( CLDRPluralRuleError $e ) {
@@ -524,17 +530,18 @@ class LocalisationCache {
                        }
                }
                if ( !isset( $this->pluralRules[$code] ) ) {
-                       return array();
+                       return null;
                } else {
                        return $this->pluralRules[$code];
                }
        }
 
+
        /**
         * Load a plural XML file with the given filename, compile the relevant
         * rules, and save the compiled rules in a process-local cache.
         */
-       private function loadPluralFile( $fileName ) {
+       protected function loadPluralFile( $fileName ) {
                $doc = new DOMDocument;
                $doc->load( $fileName );
                $rulesets = $doc->getElementsByTagName( "pluralRules" );
@@ -551,6 +558,30 @@ class LocalisationCache {
                }
        }
 
+       /**
+        * Read the data from the source files for a given language, and register
+        * the relevant dependencies in the $deps array. If the localisation
+        * exists, the data array is returned, otherwise false is returned.
+        */
+       protected function readSourceFilesAndRegisterDeps( $code, &$deps ) {
+               $fileName = Language::getMessagesFileName( $code );
+               if ( !file_exists( $fileName ) ) {
+                       return false;
+               }
+
+               $deps[] = new FileDependency( $fileName );
+               $data = $this->readPHPFile( $fileName, 'core' );
+
+               # Load CLDR plural rules for JavaScript
+               $data['pluralRules'] = $this->getPluralRules( $code );
+               # And for PHP
+               $data['compiledPluralRules'] = $this->getCompiledPluralRules( $code );
+
+               $deps['plurals'] = new FileDependency( __DIR__ . "/../languages/data/plurals.xml" );
+               $deps['plurals-mw'] = new FileDependency( __DIR__ . "/../languages/data/plurals-mediawiki.xml" );
+               return $data;
+       }
+
        /**
         * Merge two localisation values, a primary and a fallback, overwriting the
         * primary value in place.
@@ -631,6 +662,7 @@ class LocalisationCache {
         * 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 $code
+        * @throws MWException
         */
        public function recache( $code ) {
                global $wgExtensionMessagesFiles;
@@ -649,13 +681,11 @@ class LocalisationCache {
                $deps = array();
 
                # Load the primary localisation from the source file
-               $fileName = Language::getMessagesFileName( $code );
-               if ( !file_exists( $fileName ) ) {
+               $data = $this->readSourceFilesAndRegisterDeps( $code, $deps );
+               if ( $data === false ) {
                        wfDebug( __METHOD__ . ": no localisation file for $code, using fallback to en\n" );
                        $coreData['fallback'] = 'en';
                } else {
-                       $deps[] = new FileDependency( $fileName );
-                       $data = $this->readPHPFile( $fileName, 'core' );
                        wfDebug( __METHOD__ . ": got localisation for $code from source\n" );
 
                        # Merge primary localisation
@@ -684,15 +714,11 @@ class LocalisationCache {
                        foreach ( $coreData['fallbackSequence'] as $fbCode ) {
                                # Load the secondary localisation from the source file to
                                # avoid infinite cycles on cyclic fallbacks
-                               $fbFilename = Language::getMessagesFileName( $fbCode );
-
-                               if ( !file_exists( $fbFilename ) ) {
+                               $fbData = $this->readSourceFilesAndRegisterDeps( $fbCode, $deps );
+                               if ( $fbData === false ) {
                                        continue;
                                }
 
-                               $deps[] = new FileDependency( $fbFilename );
-                               $fbData = $this->readPHPFile( $fbFilename, 'core' );
-
                                foreach ( self::$allKeys as $key ) {
                                        if ( !isset( $fbData[$key] ) ) {
                                                continue;
@@ -749,15 +775,19 @@ class LocalisationCache {
                # Decouple the reference to prevent accidental damage
                unset( $page );
 
+               # If there were no plural rules, return an empty array
+               if ( $allData['pluralRules'] === null ) {
+                       $allData['pluralRules'] = array();
+               }
+               if ( $allData['compiledPluralRules'] === null ) {
+                       $allData['compiledPluralRules'] = array();
+               }
+
                # Set the list keys
                $allData['list'] = array();
                foreach ( self::$splitKeys as $key ) {
                        $allData['list'][$key] = array_keys( $allData[$key] );
                }
-               # Load CLDR plural rules for JavaScript
-               $allData['pluralRules'] = $this->getPluralRules( $code );
-               # And for PHP
-               $allData['compiledPluralRules'] = $this->getCompiledPluralRules( $code );
                # Run hooks
                wfRunHooks( 'LocalisationCacheRecache', array( $this, $code, &$allData ) );