larastan fix last commit

pull/7330/head
Your Name 1 week ago
parent 3de36431bb
commit 0aa4da98e3

@ -6,6 +6,92 @@ use Illuminate\Support\Arr;
class Localization
{
/**
* Legacy two-letter (and legacy region) language codes mapped to the
* current locale-coded folder names under lang/.
*
* Pixelfed historically shipped translations under short codes (e.g. "es",
* "zh-cn"). Those folders were renamed to full locale codes (e.g. "es-ES",
* "zh-CN"). An instance upgrading with an old APP_LOCALE would otherwise
* resolve to a missing folder and silently fall back to English. This map
* lets an old APP_LOCALE keep working without any .env change on upgrade.
*
* The two codes that were ambiguous after the rename are pinned:
* - "en" => "en-US" (not the "en-x-pirate" novelty locale)
* - "sr" => "sr-CS" (Serbian; the prior single Serbian translation)
*
* DELETE NEXT MAJOR RELEASE
*
* @var array<string, string>
*/
const LEGACY_LOCALE_MAP = [
'af' => 'af-ZA',
'ar' => 'ar-SA',
'bn' => 'bn-BD',
'bs' => 'bs-BA',
'ca' => 'ca-ES',
'cs' => 'cs-CZ',
'cy' => 'cy-GB',
'da' => 'da-DK',
'de' => 'de-DE',
'el' => 'el-GR',
'en' => 'en-US',
'eo' => 'eo-UY',
'es' => 'es-ES',
'eu' => 'eu-ES',
'fa' => 'fa-IR',
'fi' => 'fi-FI',
'fr' => 'fr-FR',
'gd' => 'gd-GB',
'gl' => 'gl-ES',
'he' => 'he-IL',
'hi' => 'hi-IN',
'hr' => 'hr-HR',
'hu' => 'hu-HU',
'id' => 'id-ID',
'it' => 'it-IT',
'ja' => 'ja-JP',
'ko' => 'ko-KR',
'me' => 'me-ME',
'mk' => 'mk-MK',
'ms' => 'ms-MY',
'nl' => 'nl-NL',
'no' => 'no-NO',
'oc' => 'oc-FR',
'pl' => 'pl-PL',
'pt' => 'pt-PT',
'ro' => 'ro-RO',
'ru' => 'ru-RU',
'sk' => 'sk-SK',
'sr' => 'sr-CS',
'sv' => 'sv-SE',
'th' => 'th-TH',
'tr' => 'tr-TR',
'uk' => 'uk-UA',
'vi' => 'vi-VN',
'zh-cn' => 'zh-CN',
'zh-tw' => 'zh-TW',
];
/**
* Normalize a configured locale to a current locale-coded value.
*
* Empty input returns "en-US"; a known legacy short code is mapped;
* anything else (already-current or custom codes) is returned unchanged so
* the framework's own fallback_locale still applies. Always returns a
* plain string, so it is safe to use in config values that get cached.
*/
public static function normalizeLocale(?string $locale): string
{
$locale = is_string($locale) ? trim($locale) : '';
if ($locale === '') {
return 'en-US';
}
return self::LEGACY_LOCALE_MAP[strtolower($locale)] ?? $locale;
}
/**
* List of available UI language codes.
*

@ -1,6 +1,7 @@
<?php
use App\Util\Lexer\PrettyNumber;
use App\Util\Localization\Localization;
use Illuminate\Support\Facades\Facade;
return [
@ -74,7 +75,7 @@ return [
|
*/
'locale' => pixelfed_normalize_locale($pixelfedLegacyLocaleMap, env('APP_LOCALE', 'en-US')),
'locale' => Localization::normalizeLocale(env('APP_LOCALE', 'en-US')),
/*
|--------------------------------------------------------------------------
@ -87,7 +88,7 @@ return [
|
*/
'fallback_locale' => pixelfed_normalize_locale($pixelfedLegacyLocaleMap, env('APP_FALLBACK_LOCALE', 'en-US')),
'fallback_locale' => Localization::normalizeLocale(env('APP_FALLBACK_LOCALE', 'en-US')),
/*
|--------------------------------------------------------------------------

@ -319,70 +319,57 @@ describe('locale-aware caching of rendered site pages', function () {
})->skip(fn () => firstNonDefaultLocale() === 'en-US', 'needs a second locale');
});
describe('legacy APP_LOCALE normalization (config/app.php)', function () {
describe('legacy locale normalization', function () {
/*
| The normalization lives in config/app.php: it maps a legacy short code
| (e.g. "es") from APP_LOCALE to the current locale folder (e.g. "es-ES")
| so instances upgrading with an old APP_LOCALE do not silently fall back
| to English. The config value is resolved once at boot, so these tests
| re-run the config file with a given APP_LOCALE and assert the result.
| Localization::normalizeLocale maps a legacy short code (e.g. "es") to the
| current locale folder (e.g. "es-ES"). config/app.php runs APP_LOCALE and
| APP_FALLBACK_LOCALE through it so instances upgrading with an old
| APP_LOCALE do not silently fall back to English.
*/
$resolveLocale = function (?string $appLocale): string {
// Set APP_LOCALE the way the config file reads it (via env()).
if ($appLocale === null) {
putenv('APP_LOCALE');
unset($_ENV['APP_LOCALE'], $_SERVER['APP_LOCALE']);
} else {
putenv('APP_LOCALE='.$appLocale);
$_ENV['APP_LOCALE'] = $appLocale;
$_SERVER['APP_LOCALE'] = $appLocale;
}
try {
$config = require base_path('config/app.php');
return $config['locale'];
} finally {
putenv('APP_LOCALE');
unset($_ENV['APP_LOCALE'], $_SERVER['APP_LOCALE']);
}
};
it('maps a legacy two-letter APP_LOCALE to its current locale code', function () use ($resolveLocale) {
expect($resolveLocale('es'))->toBe('es-ES')
->and($resolveLocale('de'))->toBe('de-DE')
->and($resolveLocale('fr'))->toBe('fr-FR');
it('maps a legacy two-letter code to its current locale code', function () {
expect(Localization::normalizeLocale('es'))->toBe('es-ES')
->and(Localization::normalizeLocale('de'))->toBe('de-DE')
->and(Localization::normalizeLocale('fr'))->toBe('fr-FR');
});
it('maps a legacy region APP_LOCALE to its current locale code', function () use ($resolveLocale) {
expect($resolveLocale('zh-cn'))->toBe('zh-CN')
->and($resolveLocale('zh-tw'))->toBe('zh-TW');
it('maps a legacy region code to its current locale code', function () {
expect(Localization::normalizeLocale('zh-cn'))->toBe('zh-CN')
->and(Localization::normalizeLocale('zh-tw'))->toBe('zh-TW');
});
it('pins the ambiguous legacy codes deliberately', function () use ($resolveLocale) {
it('pins the ambiguous legacy codes deliberately', function () {
// "en" must resolve to en-US, not the en-x-pirate novelty locale.
expect($resolveLocale('en'))->toBe('en-US')
expect(Localization::normalizeLocale('en'))->toBe('en-US')
// "sr" must resolve to the prior single Serbian translation.
->and($resolveLocale('sr'))->toBe('sr-CS');
->and(Localization::normalizeLocale('sr'))->toBe('sr-CS');
});
it('is case-insensitive on legacy short codes', function () use ($resolveLocale) {
expect($resolveLocale('ES'))->toBe('es-ES')
->and($resolveLocale('Zh-Cn'))->toBe('zh-CN');
it('is case-insensitive on legacy short codes', function () {
expect(Localization::normalizeLocale('ES'))->toBe('es-ES')
->and(Localization::normalizeLocale('Zh-Cn'))->toBe('zh-CN');
});
it('leaves an already-current locale code unchanged', function () use ($resolveLocale) {
expect($resolveLocale('es-ES'))->toBe('es-ES')
->and($resolveLocale('en-US'))->toBe('en-US');
it('leaves an already-current locale code unchanged', function () {
expect(Localization::normalizeLocale('es-ES'))->toBe('es-ES')
->and(Localization::normalizeLocale('en-US'))->toBe('en-US');
});
it('leaves unknown or custom locale codes unchanged', function () use ($resolveLocale) {
expect($resolveLocale('xx-YY'))->toBe('xx-YY')
->and($resolveLocale('en-x-pirate'))->toBe('en-x-pirate');
it('leaves unknown or custom locale codes unchanged', function () {
expect(Localization::normalizeLocale('xx-YY'))->toBe('xx-YY')
->and(Localization::normalizeLocale('en-x-pirate'))->toBe('en-x-pirate');
});
it('falls back to en-US when APP_LOCALE is unset', function () use ($resolveLocale) {
expect($resolveLocale(null))->toBe('en-US');
it('falls back to en-US for empty or whitespace input', function () {
expect(Localization::normalizeLocale(''))->toBe('en-US')
->and(Localization::normalizeLocale(' '))->toBe('en-US')
->and(Localization::normalizeLocale(null))->toBe('en-US');
});
it('resolves the configured app locale from a legacy APP_LOCALE', function () {
// Simulate an upgraded instance whose APP_LOCALE is still "es".
Config::set('app.locale', Localization::normalizeLocale('es'));
expect(config('app.locale'))->toBe('es-ES');
});
});

Loading…
Cancel
Save