Permalink
Browse files

FIX Correct Zend_Locale fallbacks in i18n/DateField/DateTimeField

Due to the recent change of translations to transifex, some
locales changed their names, which prompted a fix to
i18n::get_available_translations() (see 00ffe72).
This caused a regression where short locales are determined
from the YAML file names (e.g. "en"), but weren't matched up
with fully qualified locales from get_available_translations() (e.g. "en_US").
Since this list is used in the admin/myprofile dropdown for the Member.Locale value,
it didn't match up with any entries and defaulted to the first one ("Africaans").

Note that the behaviour of admin/myprofile is still a bit weird:
It defaults the locale on new members to the one set for the current administrator.
So if a site defaults to en_US in _config.php, but the admin happens to view
his backend in de_DE, all members he creates default to de_DE as well.

Thanks to @tractorcow for contributing and peer reviewing!
  • Loading branch information...
chillu committed Aug 20, 2013
1 parent c396645 commit 1c31c098ee2cd4c8365d233fe134b0f228657340
Showing with 30 additions and 28 deletions.
  1. +9 −7 forms/DateField.php
  2. +9 −7 forms/DatetimeField.php
  3. +6 −8 i18n/i18n.php
  4. +3 −3 security/Member.php
  5. +3 −3 tests/i18n/i18nTest.php
View
@@ -217,6 +217,8 @@ public function Type() {
* @param String|Array $val
*/
public function setValue($val) {
+ $locale = new Zend_Locale($this->locale);
+
if(empty($val)) {
$this->value = null;
$this->valueObj = null;
@@ -226,16 +228,16 @@ public function setValue($val) {
if(is_array($val) && $this->validateArrayValue($val)) {
// set() gets confused with custom date formats when using array notation
if(!(empty($val['day']) || empty($val['month']) || empty($val['year']))) {
- $this->valueObj = new Zend_Date($val, null, $this->locale);
+ $this->valueObj = new Zend_Date($val, null, $locale);
$this->value = $this->valueObj->toArray();
} else {
$this->value = $val;
$this->valueObj = null;
}
}
// load ISO date from database (usually through Form->loadDataForm())
- else if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $this->locale)) {
- $this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'), $this->locale);
+ else if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $locale)) {
+ $this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'), $locale);
$this->value = $this->valueObj->toArray();
}
else {
@@ -247,15 +249,15 @@ public function setValue($val) {
// Caution: Its important to have this check *before* the ISO date fallback,
// as some dates are falsely detected as ISO by isDate(), e.g. '03/04/03'
// (en_NZ for 3rd of April, definetly not yyyy-MM-dd)
- if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('dateformat'), $this->locale)) {
- $this->valueObj = new Zend_Date($val, $this->getConfig('dateformat'), $this->locale);
- $this->value = $this->valueObj->get($this->getConfig('dateformat'), $this->locale);
+ if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('dateformat'), $locale)) {
+ $this->valueObj = new Zend_Date($val, $this->getConfig('dateformat'), $locale);
+ $this->value = $this->valueObj->get($this->getConfig('dateformat'), $locale);
}
// load ISO date from database (usually through Form->loadDataForm())
else if(!empty($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'))) {
$this->valueObj = new Zend_Date($val, $this->getConfig('datavalueformat'));
- $this->value = $this->valueObj->get($this->getConfig('dateformat'), $this->locale);
+ $this->value = $this->valueObj->get($this->getConfig('dateformat'), $locale);
}
else {
$this->value = $val;
View
@@ -115,6 +115,8 @@ public function Field($properties = array()) {
* the 'date' value may contain array notation was well (see {@link DateField->setValue()}).
*/
public function setValue($val) {
+ $locale = new Zend_Locale($this->locale);
+
// If timezones are enabled, assume user data needs to be reverted to server timezone
if($this->getConfig('usertimezone')) {
// Accept user input on timezone, but only when timezone support is enabled
@@ -130,7 +132,7 @@ public function setValue($val) {
$this->timeField->setValue(null);
} else {
// Case 1: String setting from database, in ISO date format
- if(is_string($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $this->locale)) {
+ if(is_string($val) && Zend_Date::isDate($val, $this->getConfig('datavalueformat'), $locale)) {
$this->value = $val;
}
// Case 2: Array form submission with user date format
@@ -145,13 +147,13 @@ public function setValue($val) {
$this->dateField->setValue($val['date']);
$this->timeField->setValue($val['time']);
if($this->dateField->dataValue() && $this->timeField->dataValue()) {
- $userValueObj = new Zend_Date(null, null, $this->locale);
+ $userValueObj = new Zend_Date(null, null, $locale);
$userValueObj->setDate($this->dateField->dataValue(),
$this->dateField->getConfig('datavalueformat'));
$userValueObj->setTime($this->timeField->dataValue(),
$this->timeField->getConfig('datavalueformat'));
if($userTz) $userValueObj->setTimezone($dataTz);
- $this->value = $userValueObj->get($this->getConfig('datavalueformat'), $this->locale);
+ $this->value = $userValueObj->get($this->getConfig('datavalueformat'), $locale);
unset($userValueObj);
} else {
// Validation happens later, so set the raw string in case Zend_Date doesn't accept it
@@ -168,18 +170,18 @@ public function setValue($val) {
}
// view settings (dates might differ from $this->value based on user timezone settings)
- if (Zend_Date::isDate($this->value, $this->getConfig('datavalueformat'), $this->locale)) {
- $valueObj = new Zend_Date($this->value, $this->getConfig('datavalueformat'), $this->locale);
+ if (Zend_Date::isDate($this->value, $this->getConfig('datavalueformat'), $locale)) {
+ $valueObj = new Zend_Date($this->value, $this->getConfig('datavalueformat'), $locale);
if($userTz) $valueObj->setTimezone($userTz);
// Set view values in sub-fields
if($this->dateField->getConfig('dmyfields')) {
$this->dateField->setValue($valueObj->toArray());
} else {
$this->dateField->setValue(
- $valueObj->get($this->dateField->getConfig('dateformat'), $this->locale));
+ $valueObj->get($this->dateField->getConfig('dateformat'), $locale));
}
- $this->timeField->setValue($valueObj->get($this->timeField->getConfig('timeformat'), $this->locale));
+ $this->timeField->setValue($valueObj->get($this->timeField->getConfig('timeformat'), $locale));
}
}
View
@@ -2231,13 +2231,11 @@ public static function get_existing_translations() {
// TODO Replace with CLDR list of actually available languages/regions
// Only allow explicitly registered locales, otherwise we'll get into trouble
// if the locale doesn't exist in Zend's CLDR data
- $labelLocale = str_replace('-', '_', self::get_locale_from_lang($locale));
- if(isset(self::$all_locales[$locale])) {
- $locales[$locale] = self::$all_locales[$locale];
- } else if(isset(self::$all_locales[$labelLocale])) {
- $locales[$locale] = self::$all_locales[$labelLocale];
- }
- }
+ $fullLocale = self::get_locale_from_lang($locale);
+ if(isset($allLocales[$fullLocale])) {
+ $locales[$fullLocale] = $allLocales[$fullLocale];
+ }
+ }
}
}
@@ -2354,7 +2352,7 @@ public static function get_lang_from_locale($locale) {
public static function get_locale_from_lang($lang) {
$subtags = Config::inst()->get('i18n', 'likely_subtags');
if(preg_match('/\-|_/', $lang)) {
- return $lang;
+ return str_replace('-', '_', $lang);
} else if(isset($subtags[$lang])) {
return $subtags[$lang];
} else {
View
@@ -1169,7 +1169,7 @@ public function getCMSFields() {
$password->setCanBeEmpty(true);
if(!$this->ID) $password->showOnClick = false;
$mainFields->replaceField('Password', $password);
-
+
$mainFields->replaceField('Locale', new DropdownField(
"Locale",
_t('Member.INTERFACELANG', "Interface Language", 'Language of the CMS'),
@@ -1231,7 +1231,7 @@ public function getCMSFields() {
$permissionsTab = $fields->fieldByName("Root")->fieldByName('Permissions');
if($permissionsTab) $permissionsTab->addExtraClass('readonly');
- $defaultDateFormat = Zend_Locale_Format::getDateFormat($this->Locale);
+ $defaultDateFormat = Zend_Locale_Format::getDateFormat(new Zend_Locale($this->Locale));
$dateFormatMap = array(
'MMM d, yyyy' => Zend_Date::now()->toString('MMM d, yyyy'),
'yyyy/MM/dd' => Zend_Date::now()->toString('yyyy/MM/dd'),
@@ -1249,7 +1249,7 @@ public function getCMSFields() {
);
$dateFormatField->setValue($this->DateFormat);
- $defaultTimeFormat = Zend_Locale_Format::getTimeFormat($this->Locale);
+ $defaultTimeFormat = Zend_Locale_Format::getTimeFormat(new Zend_Locale($this->Locale));
$timeFormatMap = array(
'h:mm a' => Zend_Date::now()->toString('h:mm a'),
'H:mm' => Zend_Date::now()->toString('H:mm'),
View
@@ -97,9 +97,9 @@ public function testTimeFormatCustom() {
public function testGetExistingTranslations() {
$translations = i18n::get_existing_translations();
- $this->assertTrue(isset($translations['en']), 'Checking for en translation');
- $this->assertEquals($translations['en'], 'English (United States)');
- $this->assertTrue(isset($translations['de']), 'Checking for de_DE translation');
+ $this->assertTrue(isset($translations['en_US']), 'Checking for en translation');
+ $this->assertEquals($translations['en_US'], 'English (United States)');
+ $this->assertTrue(isset($translations['de_DE']), 'Checking for de_DE translation');
}
public function testDataObjectFieldLabels() {

0 comments on commit 1c31c09

Please sign in to comment.