use CLDRPluralRuleParser\Evaluator;
use CLDRPluralRuleParser\Error as CLDRPluralRuleError;
use MediaWiki\Config\ServiceOptions;
-use MediaWiki\Languages\LanguageNameUtils;
use Psr\Log\LoggerInterface;
/**
/** @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 = [];
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',
* @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' );
$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;
# 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.' );
* @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 ) {
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 {
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 );
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 );
# 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
# 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 ] );
}
}
}