Merge "Show the revision list immediately on "umerge" log action links"
[lhc/web/wiklou.git] / includes / cache / LocalisationCache.php
index e2e304a..ae27fba 100644 (file)
@@ -200,9 +200,6 @@ class LocalisationCache {
                                case 'db':
                                        $storeClass = 'LCStoreDB';
                                        break;
-                               case 'accel':
-                                       $storeClass = 'LCStoreAccel';
-                                       break;
                                case 'detect':
                                        $storeClass = $wgCacheDirectory ? 'LCStoreCDB' : 'LCStoreDB';
                                        break;
@@ -404,7 +401,7 @@ class LocalisationCache {
                $deps = $this->store->get( $code, 'deps' );
                $keys = $this->store->get( $code, 'list' );
                $preload = $this->store->get( $code, 'preload' );
-               // Different keys may expire separately, at least in LCStoreAccel
+               // Different keys may expire separately for some stores
                if ( $deps === null || $keys === null || $preload === null ) {
                        wfDebug( __METHOD__ . "($code): cache missing, need to make one\n" );
 
@@ -686,6 +683,7 @@ class LocalisationCache {
         *
         * @param string $code
         * @param array $deps
+        * @return array
         */
        protected function readSourceFilesAndRegisterDeps( $code, &$deps ) {
                global $IP;
@@ -842,73 +840,109 @@ class LocalisationCache {
                        if ( $coreData['fallbackSequence'][$len - 1] !== 'en' ) {
                                $coreData['fallbackSequence'][] = 'en';
                        }
+               }
 
-                       # Load the fallback localisation item by item and merge it
-                       foreach ( $coreData['fallbackSequence'] as $fbCode ) {
-                               # Load the secondary localisation from the source file to
-                               # avoid infinite cycles on cyclic fallbacks
-                               $fbData = $this->readSourceFilesAndRegisterDeps( $fbCode, $deps );
-                               if ( $fbData === false ) {
-                                       continue;
-                               }
+               $codeSequence = array_merge( array( $code ), $coreData['fallbackSequence'] );
 
-                               foreach ( self::$allKeys as $key ) {
-                                       if ( !isset( $fbData[$key] ) ) {
-                                               continue;
-                                       }
+               wfProfileIn( __METHOD__ . '-fallbacks' );
+
+               # 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] ) ) {
+                               # This extension has JSON message data; skip the PHP shim
+                               continue;
+                       }
 
-                                       if ( is_null( $coreData[$key] ) || $this->isMergeableKey( $key ) ) {
-                                               $this->mergeItem( $key, $coreData[$key], $fbData[$key] );
+                       $data = $this->readPHPFile( $fileName, 'extension' );
+                       $used = false;
+
+                       foreach ( $data as $key => $item ) {
+                               foreach ( $codeSequence as $csCode ) {
+                                       if ( isset( $item[$csCode] ) ) {
+                                               $this->mergeItem( $key, $extensionData[$csCode][$key], $item[$csCode] );
+                                               $used = true;
                                        }
                                }
                        }
-               }
 
-               $codeSequence = array_merge( array( $code ), $coreData['fallbackSequence'] );
+                       if ( $used ) {
+                               $deps[] = new FileDependency( $fileName );
+                       }
+               }
 
-               # Load core messages and the extension localisations.
-               wfProfileIn( __METHOD__ . '-extensions' );
+               # Load the localisation data for each fallback, then merge it into the full array
                $allData = $initialData;
-               foreach ( $wgMessagesDirs as $dirs ) {
-                       foreach ( (array)$dirs as $dir ) {
-                               foreach ( $codeSequence as $csCode ) {
+               foreach ( $codeSequence as $csCode ) {
+                       $csData = $initialData;
+
+                       # Load core messages and the extension localisations.
+                       foreach ( $wgMessagesDirs as $dirs ) {
+                               foreach ( (array)$dirs as $dir ) {
                                        $fileName = "$dir/$csCode.json";
                                        $data = $this->readJSONFile( $fileName );
 
                                        foreach ( $data as $key => $item ) {
-                                               $this->mergeItem( $key, $allData[$key], $item );
+                                               $this->mergeItem( $key, $csData[$key], $item );
                                        }
 
                                        $deps[] = new FileDependency( $fileName );
                                }
                        }
-               }
 
-               foreach ( $wgExtensionMessagesFiles as $extension => $fileName ) {
-                       if ( isset( $wgMessagesDirs[$extension] ) ) {
-                               # Already loaded the JSON files for this extension; skip the PHP shim
-                               continue;
+                       # Merge non-JSON extension data
+                       if ( isset( $extensionData[$csCode] ) ) {
+                               foreach ( $extensionData[$csCode] as $key => $item ) {
+                                       $this->mergeItem( $key, $csData[$key], $item );
+                               }
                        }
 
-                       $data = $this->readPHPFile( $fileName, 'extension' );
-                       $used = false;
-
-                       foreach ( $data as $key => $item ) {
-                               if ( $this->mergeExtensionItem( $codeSequence, $key, $allData[$key], $item ) ) {
-                                       $used = true;
+                       if ( $csCode === $code ) {
+                               # Merge core data into extension data
+                               foreach ( $coreData as $key => $item ) {
+                                       $this->mergeItem( $key, $csData[$key], $item );
+                               }
+                       } else {
+                               # Load the secondary localisation from the source file to
+                               # avoid infinite cycles on cyclic fallbacks
+                               $fbData = $this->readSourceFilesAndRegisterDeps( $csCode, $deps );
+                               if ( $fbData !== false ) {
+                                       # Only merge the keys that make sense to merge
+                                       foreach ( self::$allKeys as $key ) {
+                                               if ( !isset( $fbData[$key] ) ) {
+                                                       continue;
+                                               }
+
+                                               if ( is_null( $coreData[$key] ) || $this->isMergeableKey( $key ) ) {
+                                                       $this->mergeItem( $key, $csData[$key], $fbData[$key] );
+                                               }
+                                       }
                                }
                        }
 
-                       if ( $used ) {
-                               $deps[] = new FileDependency( $fileName );
+                       # Allow extensions an opportunity to adjust the data for this
+                       # fallback
+                       wfRunHooks( 'LocalisationCacheRecacheFallback', array( $this, $csCode, &$csData ) );
+
+                       # Merge the data for this fallback into the final array
+                       if ( $csCode === $code ) {
+                               $allData = $csData;
+                       } else {
+                               foreach ( self::$allKeys as $key ) {
+                                       if ( !isset( $csData[$key] ) ) {
+                                               continue;
+                                       }
+
+                                       if ( is_null( $allData[$key] ) || $this->isMergeableKey( $key ) ) {
+                                               $this->mergeItem( $key, $allData[$key], $csData[$key] );
+                                       }
+                               }
                        }
                }
 
-               # Merge core data into extension data
-               foreach ( $coreData as $key => $item ) {
-                       $this->mergeItem( $key, $allData[$key], $item );
-               }
-               wfProfileOut( __METHOD__ . '-extensions' );
+               wfProfileOut( __METHOD__ . '-fallbacks' );
 
                # Add cache dependencies for any referenced globals
                $deps['wgExtensionMessagesFiles'] = new GlobalDependency( 'wgExtensionMessagesFiles' );
@@ -983,7 +1017,7 @@ class LocalisationCache {
                # 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::clear();
+                       MessageBlobStore::getInstance()->clear();
                }
 
                wfProfileOut( __METHOD__ );
@@ -1097,56 +1131,6 @@ interface LCStore {
        function set( $key, $value );
 }
 
-/**
- * LCStore implementation which uses PHP accelerator to store data.
- * This will work if one of XCache, WinCache or APC cacher is configured.
- * (See ObjectCache.php)
- */
-class LCStoreAccel implements LCStore {
-       private $currentLang;
-       private $keys;
-
-       public function __construct() {
-               $this->cache = wfGetCache( CACHE_ACCEL );
-       }
-
-       public function get( $code, $key ) {
-               $k = wfMemcKey( 'l10n', $code, 'k', $key );
-               $r = $this->cache->get( $k );
-
-               return $r === false ? null : $r;
-       }
-
-       public function startWrite( $code ) {
-               $k = wfMemcKey( 'l10n', $code, 'l' );
-               $keys = $this->cache->get( $k );
-               if ( $keys ) {
-                       foreach ( $keys as $k ) {
-                               $this->cache->delete( $k );
-                       }
-               }
-               $this->currentLang = $code;
-               $this->keys = array();
-       }
-
-       public function finishWrite() {
-               if ( $this->currentLang ) {
-                       $k = wfMemcKey( 'l10n', $this->currentLang, 'l' );
-                       $this->cache->set( $k, array_keys( $this->keys ) );
-               }
-               $this->currentLang = null;
-               $this->keys = array();
-       }
-
-       public function set( $key, $value ) {
-               if ( $this->currentLang ) {
-                       $k = wfMemcKey( 'l10n', $this->currentLang, 'k', $key );
-                       $this->keys[$k] = true;
-                       $this->cache->set( $k, $value );
-               }
-       }
-}
-
 /**
  * LCStore implementation which uses the standard DB functions to store data.
  * This will work on any MediaWiki installation.