diff --git a/src/i18n/Data/Intl/IntlLocales.php b/src/i18n/Data/Intl/IntlLocales.php index 1a672df21..8dd7cd5a8 100644 --- a/src/i18n/Data/Intl/IntlLocales.php +++ b/src/i18n/Data/Intl/IntlLocales.php @@ -1605,6 +1605,18 @@ class IntlLocales implements Locales, Resettable if (!$lang || !$region) { return false; } + + // Check the configurable whitelist + $localeCode = strtolower($lang) . '_' . strtoupper($region); + $locales = $this->getLocales(); + + if (array_key_exists($localeCode, $locales) + || array_key_exists(strtolower($localeCode), $locales) + ) { + return true; + } + + // Fallback return strcasecmp($lang, $region) && strcasecmp($lang, $locale) && strcasecmp($region, $locale); diff --git a/tests/php/i18n/i18nTest.php b/tests/php/i18n/i18nTest.php index cc16807a2..f7547828c 100644 --- a/tests/php/i18n/i18nTest.php +++ b/tests/php/i18n/i18nTest.php @@ -376,6 +376,9 @@ class i18nTest extends SapphireTest $this->assertFalse(i18n::getData()->validate('en'), 'Short lang format is not valid'); $this->assertFalse(i18n::getData()->validate('xx_XX'), 'Unknown locale in correct format is not valid'); $this->assertFalse(i18n::getData()->validate(''), 'Empty string is not valid'); + $this->assertTrue(i18n::getData()->validate('de_DE'), 'Known locale where language is same as region'); + $this->assertTrue(i18n::getData()->validate('fr-FR'), 'Known locale where language is same as region'); + $this->assertTrue(i18n::getData()->validate('zh_cmn'), 'Known locale with all lowercase letters'); } public function testTranslate()