Skip to content

Commit a933e62

Browse files
committed
feat(siteStats): ✨ always use NumberFormatter for site stats
- Use fallback chain to create NumberFormatter (T376711) - Drop `$wgCitizenUseNumberFormatter` - Minor refactor
1 parent 6d5d03c commit a933e62

4 files changed

Lines changed: 72 additions & 43 deletions

File tree

docs/src/config/index.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,16 +78,6 @@ $wgCitizenEnableDrawerSiteStats = true;
7878

7979
**Values**: `true`, `false`
8080

81-
### `$wgCitizenUseNumberFormatter`
82-
83-
Formats numbers in site statistics according to the wiki's language rules (e.g., using commas or dots as separators).
84-
85-
```php [LocalSettings.php]
86-
$wgCitizenUseNumberFormatter = true;
87-
```
88-
89-
**Values**: `true`, `false`
90-
9181
### `$wgCitizenThemeColor`
9282

9383
Sets the color of the browser address bar on mobile devices to match your brand.

includes/Components/CitizenComponentSiteStats.php

Lines changed: 67 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44

55
namespace MediaWiki\Skins\Citizen\Components;
66

7-
use IntlException;
87
use MediaWiki\Config\Config;
98
use MediaWiki\Language\Language;
9+
use MediaWiki\Languages\LanguageNameUtils;
10+
use MediaWiki\MainConfigNames;
1011
use MediaWiki\SiteStats\SiteStats;
12+
use Locale;
1113
use MessageLocalizer;
1214
use NumberFormatter;
15+
use RuntimeException;
16+
use ValueError;
1317

1418
/**
1519
* CitizenComponentSiteStats component
@@ -24,51 +28,92 @@ class CitizenComponentSiteStats implements CitizenComponent {
2428
'edits' => 'edit'
2529
];
2630

31+
private ?NumberFormatter $fmt = null;
32+
2733
public function __construct(
2834
private readonly Config $config,
2935
private readonly MessageLocalizer $localizer,
30-
private readonly Language $lang
36+
private readonly Language $lang,
37+
private readonly LanguageNameUtils $langNameUtils
3138
) {
3239
}
3340

34-
/**
35-
* Get and format sitestat value
36-
*/
37-
private function getSiteStatValue( string $key, ?NumberFormatter $fmt ): string {
41+
private function createNumberFormatter( string $locale ): ?NumberFormatter {
42+
try {
43+
return new NumberFormatter(
44+
$locale,
45+
// PHP 8.4 introduced NumberFormatter::DECIMAL_COMPACT_SHORT
46+
defined( 'NumberFormatter::DECIMAL_COMPACT_SHORT' )
47+
? NumberFormatter::DECIMAL_COMPACT_SHORT
48+
: 14
49+
);
50+
} catch ( ValueError $exception ) {
51+
// Value Errors are thrown since php8.4 for invalid locales (T376711)
52+
return null;
53+
}
54+
}
55+
56+
private function getNumberFormatter(): NumberFormatter {
57+
if ( $this->fmt ) {
58+
return $this->fmt;
59+
}
60+
61+
$locale = $this->lang->getCode();
62+
63+
if ( !(
64+
$this->config->get( MainConfigNames::TranslateNumerals )
65+
&& $this->langNameUtils->isValidCode( $locale )
66+
) ) {
67+
$locale = Locale::getDefault(); // POSIX system default locale
68+
}
69+
70+
$fmt = $this->createNumberFormatter( $locale );
71+
72+
if ( !$fmt ) {
73+
$fallbacks = $this->lang->getFallbackLanguages( $locale );
74+
foreach ( $fallbacks as $fallbackCode ) {
75+
$fmt = $this->createNumberFormatter( $fallbackCode );
76+
if ( $fmt ) {
77+
break;
78+
}
79+
}
80+
if ( !$fmt ) {
81+
throw new RuntimeException(
82+
'Could not instance NumberFormatter for ' . $locale . ' and all fallbacks'
83+
);
84+
}
85+
}
86+
87+
$fmt->setAttribute( NumberFormatter::ROUNDING_MODE, NumberFormatter::ROUND_DOWN );
88+
$fmt->setAttribute( NumberFormatter::MAX_FRACTION_DIGITS, 1 );
89+
90+
$this->fmt = $fmt;
91+
92+
return $this->fmt;
93+
}
94+
95+
private function getSiteStatValue( string $key ): string {
3896
$value = SiteStats::$key();
3997

4098
if ( !$value ) {
4199
return '';
42100
}
43101

44-
return $fmt ? $fmt->format( $value ) : number_format( $value );
102+
return (string)$this->getNumberFormatter()->format( $value );
45103
}
46104

47105
public function getTemplateData(): array {
48-
$config = $this->config;
49-
if ( !$config->get( 'CitizenEnableDrawerSiteStats' ) ) {
106+
if ( !$this->config->get( 'CitizenEnableDrawerSiteStats' ) ) {
50107
return [];
51108
}
52109

53110
$items = [];
54-
$fmt = null;
55-
56-
// Get NumberFormatter here so that we don't have to call it for every stats
57-
if ( $config->get( 'CitizenUseNumberFormatter' ) && class_exists( NumberFormatter::class ) ) {
58-
$locale = $this->lang->getHtmlCode() ?? 'en_US';
59-
60-
try {
61-
$fmt = new NumberFormatter( $locale, NumberFormatter::PADDING_POSITION );
62-
$fmt->setAttribute( NumberFormatter::ROUNDING_MODE, NumberFormatter::ROUND_DOWN );
63-
$fmt->setAttribute( NumberFormatter::MAX_FRACTION_DIGITS, 1 );
64-
} catch ( IntlException $exception ) {}
65-
}
66111

67112
foreach ( self::SITESTATS_ICON_MAP as $key => $icon ) {
68113
$items[] = [
69114
'id' => $key,
70115
'icon' => $icon,
71-
'value' => $this->getSiteStatValue( $key, $fmt ),
116+
'value' => $this->getSiteStatValue( $key ),
72117
'label' => $this->localizer->msg( "citizen-sitestats-$key-label" )->text(),
73118
];
74119
}

includes/SkinCitizen.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
namespace MediaWiki\Skins\Citizen;
66

77
use MediaWiki\Cache\GenderCache;
8-
use MediaWiki\Language\Language;
98
use MediaWiki\Languages\LanguageConverterFactory;
9+
use MediaWiki\Languages\LanguageNameUtils;
1010
use MediaWiki\Permissions\PermissionManager;
1111
use MediaWiki\Registration\ExtensionRegistry;
1212
use MediaWiki\Skins\Citizen\Components\CitizenComponentBodyContent;
@@ -50,7 +50,7 @@ public function __construct(
5050
private readonly GenderCache $genderCache,
5151
private readonly UserIdentityLookup $userIdentityLookup,
5252
private readonly LanguageConverterFactory $languageConverterFactory,
53-
private readonly Language $contentLanguage,
53+
private readonly LanguageNameUtils $languageNameUtils,
5454
private readonly PermissionManager $permissionManager,
5555
private readonly ExtensionRegistry $extensionRegistry,
5656
private readonly UserGroupManager $userGroupManager,
@@ -102,7 +102,6 @@ public function getTemplateData(): array {
102102
$out = $this->getOutput();
103103
$title = $this->getTitle();
104104
$user = $this->getUser();
105-
$pageLang = $title->getPageLanguage();
106105

107106
$sidebar = $parentData['data-portlets-sidebar'];
108107
$pageToolsMenu = [];
@@ -155,7 +154,8 @@ public function getTemplateData(): array {
155154
'data-site-stats' => new CitizenComponentSiteStats(
156155
$config,
157156
$localizer,
158-
$lang
157+
$lang,
158+
$this->languageNameUtils
159159
),
160160
'data-user-info' => new CitizenComponentUserInfo(
161161
$this->userGroupManager,

skin.json

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"GenderCache",
3535
"UserIdentityLookup",
3636
"LanguageConverterFactory",
37-
"ContentLanguage",
37+
"LanguageNameUtils",
3838
"PermissionManager",
3939
"ExtensionRegistry",
4040
"UserGroupManager",
@@ -846,12 +846,6 @@
846846
"descriptionmsg": "citizen-config-enabledrawersitestats",
847847
"public": true
848848
},
849-
"UseNumberFormatter": {
850-
"value": true,
851-
"description": "Use NumberFormatter for site statistics",
852-
"descriptionmsg": "citizen-config-usenumberformatter",
853-
"public": true
854-
},
855849
"EnableCJKFonts": {
856850
"value": false,
857851
"description": "Enable included Noto Sans CJK for wikis that serves CJK languages",

0 commit comments

Comments
 (0)