implement localizations based on punic

This commit is contained in:
Thomas Müller 2014-10-13 17:44:57 +02:00
parent 8da6e4b9f0
commit c8e8945efb
7 changed files with 100 additions and 95 deletions

@ -1 +1 @@
Subproject commit f6d7a519e4dca5189963abb15e5c9858b03bf98d Subproject commit 0c0fb2a67dfa0392ebcea2fab558513f00006258

View File

@ -39,7 +39,7 @@ $array = array(
"oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false', "oc_isadmin" => OC_User::isAdminUser(OC_User::getUser()) ? 'true' : 'false',
"oc_webroot" => "\"".OC::$WEBROOT."\"", "oc_webroot" => "\"".OC::$WEBROOT."\"",
"oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution "oc_appswebroots" => str_replace('\\/', '/', json_encode($apps_paths)), // Ugly unescape slashes waiting for better solution
"datepickerFormatDate" => json_encode($l->l('jsdate', 'jsdate')), "datepickerFormatDate" => json_encode($l->getDateFormat()),
"dayNames" => json_encode( "dayNames" => json_encode(
array( array(
(string)$l->t('Sunday'), (string)$l->t('Sunday'),
@ -67,7 +67,7 @@ $array = array(
(string)$l->t('December') (string)$l->t('December')
) )
), ),
"firstDay" => json_encode($l->l('firstday', 'firstday')) , "firstDay" => json_encode($l->getFirstWeekDay()) ,
"oc_config" => json_encode( "oc_config" => json_encode(
array( array(
'session_lifetime' => min(\OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), ini_get('session.gc_maxlifetime')), 'session_lifetime' => min(\OCP\Config::getSystemValue('session_lifetime', ini_get('session.gc_maxlifetime')), ini_get('session.gc_maxlifetime')),

View File

@ -1,7 +0,0 @@
<?php
$LOCALIZATIONS = array(
'jsdate' => 'dd.mm.yy',
'date' => '%d.%m.%Y',
'datetime' => '%d.%m.%Y %H:%M:%S',
'time' => '%H:%M:%S',
'firstday' => 0 );

View File

@ -1,7 +0,0 @@
<?php
$LOCALIZATIONS = array(
'jsdate' => 'MM d, yy',
'date' => '%B %e, %Y',
'datetime' => '%B %e, %Y %H:%M',
'time' => '%H:%M:%S',
'firstday' => 0 );

View File

@ -1,7 +0,0 @@
<?php
$LOCALIZATIONS = array(
'jsdate' => "d 'de' MM 'de' yy",
'date' => '%e de %B de %Y',
'datetime' => '%e de %B de %Y %H:%M',
'time' => '%H:%M:%S',
'firstday' => 1 );

View File

@ -61,16 +61,6 @@ class OC_L10N implements \OCP\IL10N {
*/ */
private $plural_form_function = null; private $plural_form_function = null;
/**
* Localization
*/
private $localizations = array(
'jsdate' => 'dd.mm.yy',
'date' => '%d.%m.%Y',
'datetime' => '%d.%m.%Y %H:%M:%S',
'time' => '%H:%M:%S',
'firstday' => 0);
/** /**
* get an L10N instance * get an L10N instance
* @param string $app * @param string $app
@ -126,13 +116,10 @@ class OC_L10N implements \OCP\IL10N {
// Use cache if possible // Use cache if possible
if(array_key_exists($app.'::'.$lang, self::$cache)) { if(array_key_exists($app.'::'.$lang, self::$cache)) {
$this->translations = self::$cache[$app.'::'.$lang]['t']; $this->translations = self::$cache[$app.'::'.$lang]['t'];
$this->localizations = self::$cache[$app.'::'.$lang]['l']; } else{
}
else{
$i18ndir = self::findI18nDir($app); $i18ndir = self::findI18nDir($app);
// Localization is in /l10n, Texts are in $i18ndir // Texts are in $i18ndir
// (Just no need to define date/time format etc. twice) // (Just no need to define date/time format etc. twice)
if((OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/') if((OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
|| OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/') || OC_Helper::isSubDirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/')
@ -162,16 +149,7 @@ class OC_L10N implements \OCP\IL10N {
} }
} }
if(file_exists(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php') && OC_Helper::isSubDirectory(OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')) {
// Include the file, save the data from $CONFIG
include OC::$SERVERROOT.'/core/l10n/l10n-'.$lang.'.php';
if(isset($LOCALIZATIONS) && is_array($LOCALIZATIONS)) {
$this->localizations = array_merge($this->localizations, $LOCALIZATIONS);
}
}
self::$cache[$app.'::'.$lang]['t'] = $this->translations; self::$cache[$app.'::'.$lang]['t'] = $this->translations;
self::$cache[$app.'::'.$lang]['l'] = $this->localizations;
} }
} }
@ -312,17 +290,6 @@ class OC_L10N implements \OCP\IL10N {
return $this->plural_form_function; return $this->plural_form_function;
} }
/**
* get localizations
* @return array Fetch all localizations
*
* Returns an associative array with all localizations
*/
public function getLocalizations() {
$this->init();
return $this->localizations;
}
/** /**
* Localization * Localization
* @param string $type Type of localization * @param string $type Type of localization
@ -334,45 +301,45 @@ class OC_L10N implements \OCP\IL10N {
* Implemented types: * Implemented types:
* - date * - date
* - Creates a date * - Creates a date
* - l10n-field: date
* - params: timestamp (int/string) * - params: timestamp (int/string)
* - datetime * - datetime
* - Creates date and time * - Creates date and time
* - l10n-field: datetime
* - params: timestamp (int/string) * - params: timestamp (int/string)
* - time * - time
* - Creates a time * - Creates a time
* - l10n-field: time
* - params: timestamp (int/string) * - params: timestamp (int/string)
*/ */
public function l($type, $data) { public function l($type, $data, $options = array()) {
if ($type === 'firstday') {
return $this->getFirstWeekDay();
}
if ($type === 'jsdate') {
return $this->getDateFormat();
}
$this->init(); $this->init();
$value = new DateTime();
if($data instanceof DateTime) {
$value = $data;
} elseif(is_string($data) && !is_numeric($data)) {
$data = strtotime($data);
$value->setTimestamp($data);
} else {
$value->setTimestamp($data);
}
$locale = self::findLanguage();
$options = array_merge(array('width' => 'long'), $options);
$width = $options['width'];
switch($type) { switch($type) {
// If you add something don't forget to add it to $localizations
// at the top of the page
case 'date': case 'date':
case 'datetime': return Punic\Calendar::formatDate($value, $width, $locale);
case 'time': break;
if($data instanceof DateTime) { case 'datetime':
$data = $data->getTimestamp(); return Punic\Calendar::formatDatetime($value, $width, $locale);
} elseif(is_string($data) && !is_numeric($data)) { break;
$data = strtotime($data); case 'time':
} return Punic\Calendar::formatTime($value, $width, $locale);
$locales = array(self::findLanguage());
if (strlen($locales[0]) == 2) {
$locales[] = $locales[0].'_'.strtoupper($locales[0]);
}
setlocale(LC_TIME, $locales);
$format = $this->localizations[$type];
// Check for Windows to find and replace the %e modifier correctly
if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
$format = preg_replace('#(?<!%)((?:%%)*)%e#', '\1%#d', $format);
}
return strftime($format, $data);
break; break;
case 'firstday':
case 'jsdate':
return $this->localizations[$type];
default: default:
return false; return false;
} }
@ -495,7 +462,7 @@ class OC_L10N implements \OCP\IL10N {
/** /**
* find the l10n directory * find the l10n directory
* @param string $app App that needs to be translated * @param string $app App that needs to be translated
* @return directory * @return string directory
*/ */
protected static function findI18nDir($app) { protected static function findI18nDir($app) {
// find the i18n dir // find the i18n dir
@ -547,4 +514,21 @@ class OC_L10N implements \OCP\IL10N {
} }
return false; return false;
} }
/**
* @return string
* @throws \Punic\Exception\ValueNotInList
*/
public function getDateFormat() {
$locale = self::findLanguage();
return Punic\Calendar::getDateFormat('short', $locale);
}
/**
* @return int
*/
public function getFirstWeekDay() {
$locale = self::findLanguage();
return Punic\Calendar::getFirstWeekday($locale);
}
} }

View File

@ -52,17 +52,59 @@ class Test_L10n extends PHPUnit_Framework_TestCase {
$this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5)); $this->assertEquals('5 oken', (string)$l->n('%n window', '%n windows', 5));
} }
/** public function localizationDataProvider() {
* Issue #4360: Do not call strtotime() on numeric strings. return array(
*/ // timestamp as string
public function testNumericStringToDateTime() { array('February 13, 2009 at 11:31:30 PM GMT+0', 'en', 'datetime', '1234567890'),
$l = new OC_L10N('test'); array('13. Februar 2009 um 23:31:30 GMT+0', 'de', 'datetime', '1234567890'),
$this->assertSame('February 13, 2009 23:31', $l->l('datetime', '1234567890')); array('February 13, 2009', 'en', 'date', '1234567890'),
array('13. Februar 2009', 'de', 'date', '1234567890'),
array('11:31:30 PM GMT+0', 'en', 'time', '1234567890'),
array('23:31:30 GMT+0', 'de', 'time', '1234567890'),
// timestamp as int
array('February 13, 2009 at 11:31:30 PM GMT+0', 'en', 'datetime', 1234567890),
array('13. Februar 2009 um 23:31:30 GMT+0', 'de', 'datetime', 1234567890),
array('February 13, 2009', 'en', 'date', 1234567890),
array('13. Februar 2009', 'de', 'date', 1234567890),
array('11:31:30 PM GMT+0', 'en', 'time', 1234567890),
array('23:31:30 GMT+0', 'de', 'time', 1234567890),
// DateTime object
array('February 13, 2009 at 11:31:30 PM GMT+0', 'en', 'datetime', new DateTime('@1234567890')),
array('13. Februar 2009 um 23:31:30 GMT+0', 'de', 'datetime', new DateTime('@1234567890')),
array('February 13, 2009', 'en', 'date', new DateTime('@1234567890')),
array('13. Februar 2009', 'de', 'date', new DateTime('@1234567890')),
array('11:31:30 PM GMT+0', 'en', 'time', new DateTime('@1234567890')),
array('23:31:30 GMT+0', 'de', 'time', new DateTime('@1234567890')),
);
} }
public function testNumericToDateTime() { /**
* @dataProvider localizationDataProvider
*/
public function testNumericStringLocalization($expectedDate, $lang, $type, $value) {
$l = new OC_L10N('test'); $l = new OC_L10N('test');
$this->assertSame('February 13, 2009 23:31', $l->l('datetime', 1234567890)); $l->forceLanguage($lang);
$this->assertSame($expectedDate, $l->l($type, $value));
}
public function firstDayDataProvider() {
return array(
array(1, 'de'),
array(0, 'en'),
);
}
/**
* @dataProvider firstDayDataProvider
* @param $expected
* @param $lang
*/
public function testFirstWeekDay($expected, $lang) {
$l = new OC_L10N('test');
$l->forceLanguage($lang);
$this->assertSame($expected, $l->l('firstday', 'firstday'));
} }
/** /**