Services: Convert LocalisationCache's static to a const now HHVM is gone
[lhc/web/wiklou.git] / includes / cache / localisation / LocalisationCache.php
index fb4675e..a9e6969 100644 (file)
@@ -23,7 +23,6 @@
 use CLDRPluralRuleParser\Evaluator;
 use CLDRPluralRuleParser\Error as CLDRPluralRuleError;
 use MediaWiki\Config\ServiceOptions;
-use MediaWiki\Languages\LanguageNameUtils;
 use Psr\Log\LoggerInterface;
 
 /**
@@ -74,15 +73,13 @@ class LocalisationCache {
        /** @var callable[] See comment for parameter in constructor */
        private $clearStoreCallbacks;
 
-       /** @var LanguageNameUtils */
-       private $langNameUtils;
-
        /**
         * A 2-d associative array, code/key, where presence indicates that the item
         * is loaded. Value arbitrary.
         *
         * For split items, if set, this indicates that all of the subitems have been
         * loaded.
+        *
         */
        private $loadedItems = [];
 
@@ -191,12 +188,43 @@ class LocalisationCache {
        private $mergeableKeys = null;
 
        /**
-        * @todo Make this a const when HHVM support is dropped (T192166)
+        * Return a suitable LCStore as specified by the given configuration.
         *
+        * @since 1.34
+        * @param array $conf In the format of $wgLocalisationCacheConf
+        * @param string|false|null $fallbackCacheDir In case 'storeDirectory' isn't specified
+        * @return LCStore
+        */
+       public static function getStoreFromConf( array $conf, $fallbackCacheDir ) : LCStore {
+               $storeArg = [];
+               $storeArg['directory'] =
+                       $conf['storeDirectory'] ?: $fallbackCacheDir;
+
+               if ( !empty( $conf['storeClass'] ) ) {
+                       $storeClass = $conf['storeClass'];
+               } elseif ( $conf['store'] === 'files' || $conf['store'] === 'file' ||
+                       ( $conf['store'] === 'detect' && $storeArg['directory'] )
+               ) {
+                       $storeClass = LCStoreCDB::class;
+               } elseif ( $conf['store'] === 'db' || $conf['store'] === 'detect' ) {
+                       $storeClass = LCStoreDB::class;
+                       $storeArg['server'] = $conf['storeServer'] ?? [];
+               } elseif ( $conf['store'] === 'array' ) {
+                       $storeClass = LCStoreStaticArray::class;
+               } else {
+                       throw new MWException(
+                               'Please set $wgLocalisationCacheConf[\'store\'] to something sensible.'
+                       );
+               }
+
+               return new $storeClass( $storeArg );
+       }
+
+       /**
         * @var array
         * @since 1.34
         */
-       public static $constructorOptions = [
+       public const CONSTRUCTOR_OPTIONS = [
                // True to treat all files as expired until they are regenerated by this object.
                'forceRecache',
                'manualRecache',
@@ -216,23 +244,20 @@ class LocalisationCache {
         * @param callable[] $clearStoreCallbacks To be called whenever the cache is cleared. Can be
         *   used to clear other caches that depend on this one, such as ResourceLoader's
         *   MessageBlobStore.
-        * @param LanguageNameUtils $langNameUtils
         * @throws MWException
         */
        function __construct(
                ServiceOptions $options,
                LCStore $store,
                LoggerInterface $logger,
-               array $clearStoreCallbacks,
-               LanguageNameUtils $langNameUtils
+               array $clearStoreCallbacks = []
        ) {
-               $options->assertRequiredOptions( self::$constructorOptions );
+               $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
 
                $this->options = $options;
                $this->store = $store;
                $this->logger = $logger;
                $this->clearStoreCallbacks = $clearStoreCallbacks;
-               $this->langNameUtils = $langNameUtils;
 
                // Keep this separate from $this->options so it can be mutable
                $this->manualRecache = $options->get( 'manualRecache' );
@@ -445,7 +470,7 @@ class LocalisationCache {
                $this->initialisedLangs[$code] = true;
 
                # If the code is of the wrong form for a Messages*.php file, do a shallow fallback
-               if ( !$this->langNameUtils->isValidBuiltInCode( $code ) ) {
+               if ( !Language::isValidBuiltInCode( $code ) ) {
                        $this->initShallowFallback( $code, 'en' );
 
                        return;
@@ -453,7 +478,7 @@ class LocalisationCache {
 
                # Recache the data if necessary
                if ( !$this->manualRecache && $this->isExpired( $code ) ) {
-                       if ( $this->langNameUtils->isSupportedLanguage( $code ) ) {
+                       if ( Language::isSupportedLanguage( $code ) ) {
                                $this->recache( $code );
                        } elseif ( $code === 'en' ) {
                                throw new MWException( 'MessagesEn.php is missing.' );
@@ -513,17 +538,8 @@ class LocalisationCache {
         * @return array
         */
        protected function readPHPFile( $_fileName, $_fileType ) {
-               // Disable APC caching
-               Wikimedia\suppressWarnings();
-               $_apcEnabled = ini_set( 'apc.cache_by_default', '0' );
-               Wikimedia\restoreWarnings();
-
                include $_fileName;
 
-               Wikimedia\suppressWarnings();
-               ini_set( 'apc.cache_by_default', $_apcEnabled );
-               Wikimedia\restoreWarnings();
-
                $data = [];
                if ( $_fileType == 'core' || $_fileType == 'extension' ) {
                        foreach ( self::$allKeys as $key ) {
@@ -691,7 +707,7 @@ class LocalisationCache {
                global $IP;
 
                // This reads in the PHP i18n file with non-messages l10n data
-               $fileName = $this->langNameUtils->getMessagesFileName( $code );
+               $fileName = Language::getMessagesFileName( $code );
                if ( !file_exists( $fileName ) ) {
                        $data = [];
                } else {
@@ -725,6 +741,7 @@ class LocalisationCache {
                                if ( in_array( $key, self::$mergeableMapKeys ) ) {
                                        $value = $value + $fallbackValue;
                                } elseif ( in_array( $key, self::$mergeableListKeys ) ) {
+                                       // @phan-suppress-next-line PhanTypeMismatchArgumentInternal
                                        $value = array_unique( array_merge( $fallbackValue, $value ) );
                                } elseif ( in_array( $key, self::$mergeableAliasListKeys ) ) {
                                        $value = array_merge_recursive( $value, $fallbackValue );
@@ -816,7 +833,7 @@ class LocalisationCache {
                if ( !$code ) {
                        throw new MWException( "Invalid language code requested" );
                }
-               $this->recachedLangs[$code] = true;
+               $this->recachedLangs[ $code ] = true;
 
                # Initial values
                $initialData = array_fill_keys( self::$allKeys, null );
@@ -825,16 +842,11 @@ class LocalisationCache {
 
                # Load the primary localisation from the source file
                $data = $this->readSourceFilesAndRegisterDeps( $code, $deps );
-               if ( $data === false ) {
-                       $this->logger->debug( __METHOD__ . ": no localisation file for $code, using fallback to en" );
-                       $coreData['fallback'] = 'en';
-               } else {
-                       $this->logger->debug( __METHOD__ . ": got localisation for $code from source" );
+               $this->logger->debug( __METHOD__ . ": got localisation for $code from source" );
 
-                       # Merge primary localisation
-                       foreach ( $data as $key => $value ) {
-                               $this->mergeItem( $key, $coreData[$key], $value );
-                       }
+               # Merge primary localisation
+               foreach ( $data as $key => $value ) {
+                       $this->mergeItem( $key, $coreData[ $key ], $value );
                }
 
                # Fill in the fallback if it's not there already
@@ -922,16 +934,14 @@ class LocalisationCache {
                                # 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] );
-                                               }
+                               # 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 ] );
                                        }
                                }
                        }