Browse Source

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

phpnut 19 years ago
parent
commit
3eac55449e
3 changed files with 175 additions and 115 deletions
  1. 61 29
      cake/basics.php
  2. 92 70
      cake/libs/i18n.php
  3. 22 16
      cake/libs/l10n.php

+ 61 - 29
cake/basics.php

@@ -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,44 @@
  *
  * 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) {
+		if(!class_exists('I18n')) {
+			uses('i18n');
+		}
+		$calledFrom = debug_backtrace();
+		$dir = dirname($calledFrom[0]['file']);
+
+		if($return === false) {
+			echo I18n::translate($msg, null, $domain, 5, null, $dir);
+		} else {
+			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 __d($domain, $msg, $return = false) {
+	function __c($category, $msg, $return = false) {
 		if(!class_exists('I18n')) {
 			uses('i18n');
 		}
@@ -1201,9 +1233,9 @@
 		$dir = dirname($calledFrom[0]['file']);
 
 		if($return === false) {
-			echo I18n::translate($msg, null, $domain, null, null, $dir);
+			echo I18n::translate($msg, null, null, $category, null, $dir);
 		} else {
-			return I18n::translate($msg, null, $domain, null, null, $dir);
+			return I18n::translate($msg, null, null, $category, null, $dir);
 		}
     }
 /**

+ 92 - 70
cake/libs/i18n.php

@@ -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);
 	}
 }

+ 22 - 16
cake/libs/l10n.php

@@ -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
+ *
+ * holds all information related to a language
  *
- * @var unknown_type
+ * @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() {