Adding function to basics.php to allow specifying a catalog to use for translation.

This should be used when LC_MESSAGES does not contain the translation strings.
Added doc comments to I18n and I10n classes.
Refactored I18n class

git-svn-id: https://svn.cakephp.org/repo/branches/1.2.x.x@4188 3807eeeb-6ff5-0310-8944-8be069107fe0
This commit is contained in:
phpnut 2006-12-25 04:42:47 +00:00
parent 287c858bb0
commit 3eac55449e
3 changed files with 175 additions and 115 deletions

View file

@ -1041,11 +1041,11 @@
*
* Returns a translated string if one is found, or the submitted message if not found.
*
* @param string $msg
* @param string $singular
* @param boolean $return
* @return translated string if $return is false string will be echoed
*/
function __($msg, $return = false) {
function __($singular, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
@ -1053,23 +1053,23 @@
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg, null, null, null, null, $dir);
echo I18n::translate($singular, null, null, 5, null, $dir);
} else {
return I18n::translate($msg, null, null, null, null, $dir);
return I18n::translate($singular, null, null, 5, null, $dir);
}
}
/**
*
* Returns correct plural form of message identified by $msg1 and $msg2 for count $count.
* Returns correct plural form of message identified by $singular and $plural for count $count.
* Some languages have more than one form for plural messages dependent on the count.
*
* @param string $msg1
* @param string $msg2
* @param string $singular
* @param string $plural
* @param integer $count
* @param boolean $return
* @return plural form of translated string if $return is false string will be echoed
*/
function __n($msg1, $msg2, $count, $return = false) {
function __n($singular, $plural, $count, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
@ -1077,25 +1077,25 @@
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg1, $msg2, null, null, $count, $dir);
echo I18n::translate($singular, $plural, null, 5, $count, $dir);
} else {
return I18n::translate($msg1, $msg2, null, null, $count, $dir);
return I18n::translate($singular, $plural, null, 5, $count, $dir);
}
}
/**
*
* Allows you to override the current domain for a single plural message lookup
* Returns correct plural form of message identified by $msg1 and $msg2 for count $count
* Returns correct plural form of message identified by $singular and $plural for count $count
* from domain $domain
*
* @param string $domain
* @param string $msg1
* @param string $msg2
* @param string $singular
* @param string $plural
* @param integer $count
* @param boolean $return
* @return plural form of translated string if $return is false string will be echoed
*/
function __dn($domain, $msg1, $msg2, $count, $return = false) {
function __dn($domain, $singular, $plural, $count, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
@ -1103,16 +1103,16 @@
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg1, $msg2, $domain, null, $count, $dir);;
echo I18n::translate($singular, $plural, $domain, 5, $count, $dir);;
} else {
return I18n::translate($msg1, $msg2, $domain, null, $count, $dir);
return I18n::translate($singular, $plural, $domain, 5, $count, $dir);
}
}
/**
*
* Allows you to override the current domain for a single plural message lookup.
* It also allows you to specify a category.
* Returns correct plural form of message identified by $msg1 and $msg2 for count $count
* Returns correct plural form of message identified by $singular and $plural for count $count
* from domain $domain
*
* The category argument allows a specific category of the locale settings to be used for fetching a message.
@ -1128,14 +1128,14 @@
* LC_ALL 6
*
* @param string $domain
* @param string $msg1
* @param string $msg2
* @param string $singular
* @param string $plural
* @param integer $count
* @param string $category
* @param boolean $return
* @return plural form of translated string if $return is false string will be echoed
*/
function __dcn($domain, $msg1, $msg2, $count, $category, $return = false) {
function __dcn($domain, $singular, $plural, $count, $category, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
@ -1143,9 +1143,9 @@
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg1, $msg2, $domain, $category, $count, $dir);
echo I18n::translate($singular, $plural, $domain, $category, $count, $dir);
} else {
return I18n::translate($msg1, $msg2, $domain, $category, $count, $dir);
return I18n::translate($singular, $plural, $domain, $category, $count, $dir);
}
}
/**
@ -1188,12 +1188,12 @@
*
* Allows you to override the current domain for a single message lookup.
*
* @param unknown_type $domain
* @param unknown_type $msg
* @param unknown_type $return
* @return unknown
* @param string $domain
* @param string $msg
* @param string $return
* @return translated string if $return is false string will be echoed
*/
function __d($domain, $msg, $return = false) {
function __d($domain, $msg, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
@ -1201,9 +1201,41 @@
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg, null, $domain, null, null, $dir);
echo I18n::translate($msg, null, $domain, 5, null, $dir);
} else {
return I18n::translate($msg, null, $domain, null, null, $dir);
return I18n::translate($msg, null, $domain, 5, null, $dir);
}
}
/**
*
* The category argument allows a specific category of the locale settings to be used for fetching a message.
* Valid categories are: LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES and LC_ALL.
*
* Note that the category must be specified with a numeric value, instead of the constant name. The values are:
* LC_CTYPE 0
* LC_NUMERIC 1
* LC_TIME 2
* LC_COLLATE 3
* LC_MONETARY 4
* LC_MESSAGES 5
* LC_ALL 6
*
* @param string $domain
* @param string $msg
* @param string $return
* @return translated string if $return is false string will be echoed
*/
function __c($category, $msg, $return = false) {
if(!class_exists('I18n')) {
uses('i18n');
}
$calledFrom = debug_backtrace();
$dir = dirname($calledFrom[0]['file']);
if($return === false) {
echo I18n::translate($msg, null, null, $category, null, $dir);
} else {
return I18n::translate($msg, null, null, $category, null, $dir);
}
}
/**

View file

@ -40,37 +40,47 @@ uses('l10n');
*/
class I18n extends Object {
/**
* Enter description here...
* Instance of the I10n class for localization
*
* @var unknown_type
* @var object
* @access private
*/
var $__l10n = null;
/**
* Enter description here...
* The locale for current translation
*
* @var unknown_type
* @var string
* @access public
*/
var $locale = null;
/**
* Enter description here...
* Translation strings for a specific domain read from the .mo or .po files
*
* @var unknown_type
* @var array
* @access private
*/
var $__domains = array();
/**
* Enter description here...
* Set to true when I18N::__bindTextDomain() is called for the first time.
* If a translation file is found it is set to false again
*
* @var unknown_type
* @var boolean
* @access private
*/
var $__noLocal = null;
var $__noLocale = false;
/**
* Enter description here...
* Set to true when I18N::__bindTextDomain() is called for the first time.
* If a translation file is found it is set to false again
*
* @return unknown
* @var array
* @access private
*/
var $__categories = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL');
/**
* Return a static instance of the I18n class
*
* @return object I18n
* @access public
*/
function &getInstance() {
static $instance = array();
@ -81,18 +91,22 @@ class I18n extends Object {
return $instance[0];
}
/**
* Enter description here...
*
* @param unknown_type $message
* @param unknown_type $message2
* @param unknown_type $domain
* @param unknown_type $category
* @param unknown_type $count
* @param unknown_type $directory
* @return unknown
* Used by the translation functions in basics.php
* Can also be used like I18n::translate(); but only if the uses('i18n'); has been used to load the class.
*
* @param string $singular
* @param string $plural
* @param string $domain
* @param string $category
* @param integer $count
* @param string $directory
* @return translated strings.
* @access public
*/
function translate($message, $message2 = null, $domain = null, $category = null, $count = null, $directory) {
function translate($singular, $plural = null, $domain = null, $category, $count = null, $directory) {
$_this =& I18n::getInstance();
$_this->category = $_this->__categories[$category];
if(is_null($domain) && $_this->__l10n->found === false) {
$language = Configure::read('Config.language');
@ -107,25 +121,28 @@ class I18n extends Object {
if(is_null($domain)) {
if (preg_match('/views{0,1}\\'.DS.'([^\/]*)/', $directory, $regs)) {
$domain = $regs[1];
$directory = null;
} elseif (preg_match('/controllers{0,1}\\'.DS.'([^\/]*)/', $directory, $regs)) {
$domain = ($regs[1]);
$directory = null;
}
if(isset($domain) && $domain == 'templates') {
if (preg_match('/templates{0,1}\\'.DS.'([^\/]*)/', $directory, $regs)) {
$domain = ($regs[1]);
$directory = null;
}
}
}
if(!isset($_this->__domains[$domain])) {
$_this->__bindTextDomain($domain);
if(!isset($_this->__domains[$_this->category][$domain])) {
$_this->__bindTextDomain($domain, $directory);
}
if (!isset($count)) {
$pli = 0;
} elseif (!empty($_this->__domains[$domain]["%plural-c"]) && is_null($_this->__noLocal)) {
$ph = $_this->__domains[$domain]["%plural-c"];
} elseif (!empty($_this->__domains[$_this->category][$domain]["%plural-c"]) && $_this->__noLocale === false) {
$ph = $_this->__domains[$_this->category][$domain]["%plural-c"];
$pli = $_this->__pluralGuess($ph, $count);
} else {
if ($count != 1) {
@ -135,8 +152,8 @@ class I18n extends Object {
}
}
if(!empty($_this->__domains[$domain][$message])) {
if (($trans = $_this->__domains[$domain][$message]) || ($pli) && ($trans = $_this->__domains[$domain][$message2])) {
if(!empty($_this->__domains[$_this->category][$domain][$singular])) {
if (($trans = $_this->__domains[$_this->category][$domain][$singular]) || ($pli) && ($trans = $_this->__domains[$_this->category][$domain][$plural])) {
if (is_array($trans)) {
if (!isset($trans[$pli])) {
$pli = 0;
@ -144,23 +161,23 @@ class I18n extends Object {
$trans = $trans[$pli];
}
if (strlen($trans)) {
$message = $trans;
return $message;
$singular = $trans;
return $singular;
}
}
}
if(!empty($pli)) {
return($message2);
return($plural);
}
return($message);
return($singular);
}
/**
* Enter description here...
* Attempts to find the plural form of a string.
*
* @param unknown_type $type
* @param unknown_type $n
* @return unknown
* @param string $type
* @param integrer $n
* @return plural match
* @access private
*/
function __pluralGuess(&$type, $n) {
@ -283,76 +300,81 @@ class I18n extends Object {
return(0);
}
/**
* Enter description here...
* Binds the given domain to a file in the specified directory.
* If directory is null, will attempt to search default locations.
*
* @param unknown_type $domain
* @return unknown
* @param string $domain
* @return string
* @access private
*/
function __bindTextDomain($domain) {
function __bindTextDomain($domain, $directory = null) {
$_this =& I18n::getInstance();
$_this->__noLocal = true;
$searchPath[] = APP . 'locale';
$searchPath[] = CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'locale';
$_this->__noLocale = true;
if(is_null($directory)) {
$searchPath[] = APP . 'locale';
$searchPath[] = CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'locale';
} else {
$searchPath[] = $directory;
}
foreach ($searchPath as $directory) {
foreach ($_this->__l10n->languagePath as $lang) {
$file = $directory . DS . $lang . DS . 'LC_MESSAGES' . DS . $domain;
$default = APP . 'locale'. DS . $lang . DS . 'LC_MESSAGES' . DS . 'default';
$core = CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'locale'. DS . $lang . DS . 'LC_MESSAGES' . DS . 'core';
$file = $directory . DS . $lang . DS . $_this->category . DS . $domain;
$default = APP . 'locale'. DS . $lang . DS . $_this->category . DS . 'default';
$core = CAKE_CORE_INCLUDE_PATH . DS . 'cake' . DS . 'locale'. DS . $lang . DS . $_this->category . DS . 'core';
if (file_exists($fn = "$file.mo") && ($f = fopen($fn, "rb"))) {
$_this->__loadMo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
} elseif (file_exists($fn = "$default.mo") && ($f = fopen($fn, "rb"))) {
$_this->__loadMo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
} elseif (file_exists($fn = "$file.po") && ($f = fopen($fn, "r"))) {
$_this->__loadPo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
} elseif (file_exists($fn = "$default.po") && ($f = fopen($fn, "r"))) {
$_this->__loadPo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
} elseif (file_exists($fn = "$core.mo") && ($f = fopen($fn, "rb"))) {
$_this->__loadMo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
} elseif (file_exists($fn = "$core.po") && ($f = fopen($fn, "r"))) {
$_this->__loadPo($f, $domain);
$_this->__noLocal = null;
$_this->__noLocale = false;
break 2;
}
}
}
if(empty($_this->__domains[$domain])) {
if(empty($_this->__domains[$_this->category][$domain])) {
return($domain);
}
if ($head = $_this->__domains[$domain][""]) {
if ($head = $_this->__domains[$_this->category][$domain][""]) {
foreach (explode("\n", $head) as $line) {
$header = strtok($line,":");
$line = trim(strtok("\n"));
$_this->__domains[$domain]["%po-header"][strtolower($header)] = $line;
$_this->__domains[$_this->category][$domain]["%po-header"][strtolower($header)] = $line;
}
if(isset($_this->__domains[$domain]["%po-header"]["plural-forms"])) {
$switch = preg_replace("/[(){}\\[\\]^\\s*\\]]+/", "", $_this->__domains[$domain]["%po-header"]["plural-forms"]);
$_this->__domains[$domain]["%plural-c"] = $switch;
if(isset($_this->__domains[$_this->category][$domain]["%po-header"]["plural-forms"])) {
$switch = preg_replace("/[(){}\\[\\]^\\s*\\]]+/", "", $_this->__domains[$_this->category][$domain]["%po-header"]["plural-forms"]);
$_this->__domains[$_this->category][$domain]["%plural-c"] = $switch;
}
}
return($domain);
}
/**
* Enter description here...
*
* @param unknown_type $file
* @param unknown_type $domain
* Loads the binary .mo file for translation and sets the values for this translation in the var I18n::__domains
*
* @param resource $file
* @param string $domain
* @access private
*/
function __loadMo($file, $domain) {
@ -380,20 +402,20 @@ class I18n extends Object {
if (strpos($msgstr, "\000")) {
$msgstr = explode("\000", $msgstr);
}
$_this->__domains[$domain][$msgid] = $msgstr;
$_this->__domains[$_this->category][$domain][$msgid] = $msgstr;
if (isset($msgid_plural)) {
$_this->__domains[$domain][$msgid_plural] = &$_this->__domains[$domain][$msgid];
$_this->__domains[$_this->category][$domain][$msgid_plural] = &$_this->__domains[$_this->category][$domain][$msgid];
}
}
}
}
}
/**
* Enter description here...
* Loads the text .po file for translation and sets the values for this translation in the var I18n::__domains
*
* @param unknown_type $file
* @param unknown_type $domain
* @param resource $file
* @param string $domain
* @return unknown
* @access private
*/
@ -459,18 +481,18 @@ class I18n extends Object {
fclose($file);
$merge[""] = $header;
return $_this->__domains[$domain] = array_merge($merge ,$translations);
return $_this->__domains[$_this->category][$domain] = array_merge($merge ,$translations);
}
/**
* Enter description here...
* Not implemented
*
* @param unknown_type $domain
* @param unknown_type $codeset
* @param string $domain
* @param string $codeset
* @return unknown
* @access private
* @todo Not implemented
*/
function __bindTextDomainCodeset($domain, $codeset) {
function __bindTextDomainCodeset($domain, $codeset = null) {
return($domain);
}
}

View file

@ -36,56 +36,58 @@
*/
class L10n extends Object {
/**
* Enter description here...
* The language for current locale
*
* @var string
* @access public
*/
var $language = 'English (United States)';
/**
* Enter description here...
* Locale search paths
*
* @var array
* @access public
*/
var $languagePath = array('eng');
/**
* Enter description here...
* ISO 639-3 for current locale
*
* @var string
* @access public
*/
var $lang = 'eng';
/**
* Enter description here...
* Locale
*
* @var string
* @access public
*/
var $locale = 'en_us';
/**
* Enter description here...
* Default ISO 639-3 language.
*
* DEFAULT_LANGUAGE is defined in an application this will be set as a fall back
*
* @var string
* @access public
*/
var $default = null;
/**
* Enter description here...
* Encoding used for current locale
*
* @var string
* @access public
*/
var $charset = 'utf-8';
/**
* Enter description here...
* Set to true if a locale is found
*
* @var string
* @access public
*/
var $found = false;
/**
* Enter description here...
* Maps ISO 639-3 to I10n::__l10nCatalog
*
* @var array
* @access private
@ -168,9 +170,11 @@ class L10n extends Object {
/* Yiddish */ 'yid' => 'yi',
/* Zulu */ 'zul' => 'zu');
/**
* Enter description here...
* HTTP_ACCEPT_LANGUAGE catalog
*
* @var unknown_type
* holds all information related to a language
*
* @var array
* @access private
*/
var $__l10nCatalog = array('af' => array('language' => 'Afrikaans', 'locale' => 'afr', 'localeFallback' => 'afr', 'charset' => 'utf-8'),
@ -312,8 +316,7 @@ class L10n extends Object {
'zh-tw' => array('language' => 'Chinese (Taiwan)', 'locale' => 'zh_tw', 'localeFallback' => 'chi', 'charset' => 'utf-8'),
'zu' => array('language' => 'Zulu', 'locale' => 'zul', 'localeFallback' => 'zul', 'charset' => 'utf-8'));
/**
* Enter description here...
*
* Class constructor
*/
function __construct() {
if (defined('DEFAULT_LANGUAGE')) {
@ -322,10 +325,12 @@ class L10n extends Object {
parent::__construct();
}
/**
* Enter description here...
* Gets the settings for $language.
* If $language is null it attempt to get settings from I10n::__autoLanguage(); if this fails
* the method will get the settings from I10n::__setLanguage();
*
* @param string $language
* @return unknown
* @return void
* @access private
*/
function get($language = null) {
@ -336,7 +341,8 @@ class L10n extends Object {
}
}
/**
* Enter description here...
* Sets the class vars to correct values for $language.
* If $language is null it will use the DEFAULT_LANGUAGE if defined
*
* @param string $language
* @access private
@ -375,7 +381,7 @@ class L10n extends Object {
Configure::write('charset', $this->charset);
}
/**
* Enter description here...
* Attempts to find the locale settings based on the HTTP_ACCEPT_LANGUAGE variable
* @access private
*/
function __autoLanguage() {