language: Use fallback chain to create NumberFormatter
php8.4 validates the locale and rejects invalid one. Just use the fallback chain to find an usable language, mostly en. Cache the created NumberFormatter instance, to avoid performance impact for some languages due to more attempts to create a NumberFormatter. Also C is rejected, so resolve it directly with Locale::getDefault() Bug: T376711 Change-Id: I686f77baea33ea2852c546e30e9cc08618d44321 (cherry picked from commit 8b2cc12bd3724cd213ac581d220b50f91e282630)
This commit is contained in:
parent
dff35eaa42
commit
398fdb85b8
1 changed files with 56 additions and 14 deletions
|
|
@ -36,6 +36,7 @@ use DateTime;
|
|||
use DateTimeImmutable;
|
||||
use DateTimeZone;
|
||||
use InvalidArgumentException;
|
||||
use Locale;
|
||||
use LocalisationCache;
|
||||
use MediaWiki\Config\Config;
|
||||
use MediaWiki\Context\RequestContext;
|
||||
|
|
@ -175,6 +176,12 @@ class Language implements Bcp47Code {
|
|||
*/
|
||||
private $overrideUcfirstCharacters;
|
||||
|
||||
/**
|
||||
* @var NumberFormatter|null
|
||||
* @noVarDump
|
||||
*/
|
||||
private $numberFormatter = null;
|
||||
|
||||
/**
|
||||
* @since 1.35
|
||||
*/
|
||||
|
|
@ -3177,20 +3184,7 @@ class Language implements Bcp47Code {
|
|||
|
||||
if ( !$noSeparators ) {
|
||||
$separatorTransformTable = $this->separatorTransformTable();
|
||||
$digitGroupingPattern = $this->digitGroupingPattern();
|
||||
$code = $this->getCode();
|
||||
if ( !( $translateNumerals && $this->langNameUtils->isValidCode( $code ) ) ) {
|
||||
$code = 'C'; // POSIX system default locale
|
||||
}
|
||||
|
||||
if ( $digitGroupingPattern ) {
|
||||
$fmt = new NumberFormatter(
|
||||
$code, NumberFormatter::PATTERN_DECIMAL, $digitGroupingPattern
|
||||
);
|
||||
} else {
|
||||
/** @suppress PhanParamTooFew Phan thinks this always requires 3 parameters, that's wrong */
|
||||
$fmt = new NumberFormatter( $code, NumberFormatter::DECIMAL );
|
||||
}
|
||||
$fmt = $this->getNumberFormatter();
|
||||
|
||||
// minimumGroupingDigits can be used to suppress groupings below a certain value.
|
||||
// This is used for languages such as Polish, where one would only write the grouping
|
||||
|
|
@ -3224,6 +3218,8 @@ class Language implements Bcp47Code {
|
|||
// but it does not know all languages MW
|
||||
// supports. Example: arq. Also, languages like pl have
|
||||
// customisation. So manually set it.
|
||||
$fmt = clone $fmt;
|
||||
|
||||
if ( $noTranslate ) {
|
||||
$fmt->setSymbol(
|
||||
NumberFormatter::DECIMAL_SEPARATOR_SYMBOL,
|
||||
|
|
@ -4450,6 +4446,52 @@ class Language implements Bcp47Code {
|
|||
$this->msg( 'parentheses' )->rawParams( $details )->escaped();
|
||||
}
|
||||
|
||||
private function getNumberFormatter(): NumberFormatter {
|
||||
if ( $this->numberFormatter === null ) {
|
||||
$digitGroupingPattern = $this->digitGroupingPattern();
|
||||
$code = $this->getCode();
|
||||
if ( !( $this->config->get( MainConfigNames::TranslateNumerals )
|
||||
&& $this->langNameUtils->isValidCode( $code ) )
|
||||
) {
|
||||
$code = Locale::getDefault(); // POSIX system default locale
|
||||
}
|
||||
|
||||
$fmt = $this->createNumberFormatter( $code, $digitGroupingPattern );
|
||||
if ( !$fmt ) {
|
||||
$fallbacks = $this->getFallbackLanguages();
|
||||
foreach ( $fallbacks as $fallbackCode ) {
|
||||
$fmt = $this->createNumberFormatter( $fallbackCode, $digitGroupingPattern );
|
||||
if ( $fmt ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !$fmt ) {
|
||||
throw new RuntimeException(
|
||||
'Could not instance NumberFormatter for ' . $code . ' and all fallbacks'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->numberFormatter = $fmt;
|
||||
}
|
||||
return $this->numberFormatter;
|
||||
}
|
||||
|
||||
private function createNumberFormatter( string $code, ?string $digitGroupingPattern ): ?NumberFormatter {
|
||||
try {
|
||||
if ( $digitGroupingPattern ) {
|
||||
return new NumberFormatter(
|
||||
$code, NumberFormatter::PATTERN_DECIMAL, $digitGroupingPattern
|
||||
);
|
||||
}
|
||||
// @suppress PhanParamTooFew Phan thinks this always requires 3 parameters, that's wrong
|
||||
return new NumberFormatter( $code, NumberFormatter::DECIMAL );
|
||||
} catch ( \ValueError $_ ) {
|
||||
// Value Errors are thrown since php8.4 for invalid locales
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the compiled plural rules for the language
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue