BUG Default Member.Locale now chooses a better default value when i18n.locale is not a valid translation

This will resolve issues in cases where the site locale may be assigned a value that does not have an explicit translation. E.g. if the locale is en_NZ (and it's appropriate for this to be the assigned locale), Afrikaans will no longer be the default selected locale when creating members. Now en_US is chosen as a better fallback default.

This is a minor ease of use fix that means fewer CMS users can be accidentally created in Afrikaans within NZ based sites.

Test cases included.
This commit is contained in:
Damian Mooyman 2014-01-30 15:55:14 +13:00
parent 6d9d53059c
commit 293c672fa7
3 changed files with 45 additions and 1 deletions

View File

@ -2208,6 +2208,24 @@ class i18n extends Object implements TemplateGlobalProvider {
return (array)Config::inst()->get('i18n', 'all_locales');
}
/**
* Matches a given locale with the closest translation available in the system
*
* @param string $locale locale code
* @return string Locale of closest available translation, if available
*/
public static function get_closest_translation($locale) {
// Check if exact match
$pool = self::get_existing_translations();
if(isset($pool[$locale])) return $locale;
// Fallback to best locale for common language
$lang = self::get_lang_from_locale($locale);
$candidate = self::get_locale_from_lang($lang);
if(isset($pool[$candidate])) return $candidate;
}
/**
* Searches the root-directory for module-directories
* (identified by having a _config.php on their first directory-level).

View File

@ -158,7 +158,7 @@ class Member extends DataObject implements TemplateGlobalProvider {
*/
public function populateDefaults() {
parent::populateDefaults();
$this->Locale = i18n::get_locale();
$this->Locale = i18n::get_closest_translation(i18n::get_locale());
}
public function requireDefaultRecords() {

View File

@ -102,6 +102,32 @@ class i18nTest extends SapphireTest {
$this->assertTrue(isset($translations['de_DE']), 'Checking for de_DE translation');
}
public function testGetClosestTranslation() {
// Validate necessary assumptions for this test
$translations = i18n::get_existing_translations();
$this->assertTrue(isset($translations['en_US']));
$this->assertTrue(isset($translations['en_GB']));
$this->assertTrue(isset($translations['es_ES']));
$this->assertTrue(isset($translations['es_AR']));
$this->assertFalse(isset($translations['en_ZZ']));
$this->assertFalse(isset($translations['es_ZZ']));
$this->assertFalse(isset($translations['zz_ZZ']));
// Test indeterminate locales
$this->assertEmpty(i18n::get_closest_translation('zz_ZZ'));
// Test english fallback
$this->assertEquals('en_US', i18n::get_closest_translation('en_US'));
$this->assertEquals('en_GB', i18n::get_closest_translation('en_GB'));
$this->assertEquals('en_US', i18n::get_closest_translation('en_ZZ'));
// Test spanish fallbacks
$this->assertEquals('es_AR', i18n::get_closest_translation('es_AR'));
$this->assertEquals('es_ES', i18n::get_closest_translation('es_ES'));
$this->assertEquals('es_ES', i18n::get_closest_translation('es_XX'));
}
public function testDataObjectFieldLabels() {
$oldLocale = i18n::get_locale();
i18n::set_locale('de_DE');