Rev 229 Rev 236
1 <?php 1 <?php
2   2  
3 /** 3 /**
4 * Translation class. 4 * Translation class.
5 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License 5 * @license http://opensource.org/licenses/gpl-license.php GNU General Public License
6 * @copyright (c)2003-2005 Tamlyn Rhodes 6 * @copyright (c)2003-2005 Tamlyn Rhodes
7 * @version $Id: translator.class.php,v 1.5 2006/02/06 18:47:57 tamlyn Exp $ 7 * @version $Id: translator.class.php,v 1.5 2006/02/06 18:47:57 tamlyn Exp $
8 */ 8 */
9 9
10 /** 10 /**
11 * Provides functions for translating strings using GNU Gettext PO files 11 * Provides functions for translating strings using GNU Gettext PO files
12 * @package singapore 12 * @package singapore
13 * @author Joel Sjögren <joel dot sjogren at nonea dot se> 13 * @author Joel Sjögren <joel dot sjogren at nonea dot se>
14 * @author Tamlyn Rhodes <tam at zenology dot co dot uk> 14 * @author Tamlyn Rhodes <tam at zenology dot co dot uk>
15 * @copyright (c)2003, 2004 Tamlyn Rhodes 15 * @copyright (c)2003, 2004 Tamlyn Rhodes
16 */ 16 */
17 class Translator 17 class Translator
18 { 18 {
19 /** 19 /**
20 * Array of language strings in the form 20 * Array of language strings in the form
21 * "english string" => "foreign string" 21 * "english string" => "foreign string"
22 * @private 22 * @private
23 * @var array 23 * @var array
24 */ 24 */
25 var $languageStrings = array(); 25 var $languageStrings = array();
26 26
27 var $language = "en"; 27 var $language = "en";
28 28
29 /** 29 /**
30 * Constructor 30 * Constructor
31 * @param string language code 31 * @param string language code
32 * @private 32 * @private
33 */ 33 */
34 function Translator($language) 34 function Translator($language)
35 { 35 {
36 $this->language = $language; 36 $this->language = $language;
37 } 37 }
38 38
39 /** 39 /**
40 * Implements a version of the Singleton design pattern by always returning 40 * Implements a version of the Singleton design pattern by always returning
41 * a reference to the same Translator object for each language. If no 41 * a reference to the same Translator object for each language. If no
42 * language is specified then the first loaded Translator is returned. 42 * language is specified then the first loaded Translator is returned.
43 * @param string language code (optional) 43 * @param string language code (optional)
44 * @static 44 * @static
45 */ 45 */
46 function &getInstance($language = 0) 46 function &getInstance($language = 0)
47 { 47 {
48 static $instances = array(); 48 static $instances = array();
49 49
50 $key = empty($instances) ? 0 : $language; 50 $key = empty($instances) ? 0 : $language;
51 51
52 if(!isset($instances[$key])) 52 if(!isset($instances[$key]))
53 //note that the new object is NOT assigned by reference as 53 //note that the new object is NOT assigned by reference as
54 //references are not stored in static variables (don't ask me...) 54 //references are not stored in static variables (don't ask me...)
55 $instances[$key] = new Translator($language); 55 $instances[$key] = new Translator($language);
56 return $instances[$key]; 56 return $instances[$key];
57 } 57 }
58 58
59 /** 59 /**
60 * Reads a language file and saves the strings in an array. 60 * Reads a language file and saves the strings in an array.
61 * Note that the language code is used in the filename for the 61 * Note that the language code is used in the filename for the
62 * datafile, and is case sensitive. 62 * datafile, and is case sensitive.
63 * 63 *
64 * @author Joel Sjögren <joel dot sjogren at nonea dot se> 64 * @author Joel Sjögren <joel dot sjogren at nonea dot se>
65 * @param string file to load 65 * @param string file to load
66 * @return bool success 66 * @return bool success
67 */ 67 */
68 function readLanguageFile($languageFile) 68 function readLanguageFile($languageFile)
69 { 69 {
70 // Look for the language file 70 // Look for the language file
71 if(!file_exists($languageFile)) 71 if(!file_exists($languageFile))
72 return false; 72 return false;
73 73
74 // Open the file 74 // Open the file
75 $fp = @fopen($languageFile, "r"); 75 $fp = @fopen($languageFile, "r");
76 if (!$fp) return false; 76 if (!$fp) return false;
77 77
78 // Read contents 78 // Read contents
79 $str = ''; 79 $str = '';
80 while (!feof($fp)) $str .= fread($fp, 1024); 80 while (!feof($fp)) $str .= fread($fp, 1024);
81 // Unserialize 81 // Unserialize
82 $newStrings = @unserialize($str); 82 $newStrings = @unserialize($str);
83 83
84 //Append new strings to current languageStrings array 84 //Append new strings to current languageStrings array
85 $this->languageStrings = array_merge($this->languageStrings, $newStrings); 85 $this->languageStrings = array_merge($this->languageStrings, $newStrings);
86 86
87 // Return successful 87 // Return successful
88 return (bool) $newStrings; 88 return (bool) $newStrings;
89 } 89 }
90 90
91 /** 91 /**
92 * Returns a translated string, or the same if no language is chosen. 92 * Returns a translated string, or the same if no language is chosen.
93 * You can pass more arguments to use for replacement within the 93 * You can pass more arguments to use for replacement within the
94 * string - just like sprintf(). It also removes anything before 94 * string - just like sprintf(). It also removes anything before
95 * the first | in the text to translate. This is used to distinguish 95 * the first | in the text to translate. This is used to distinguish
96 * strings with different meanings, but with the same spelling. 96 * strings with different meanings, but with the same spelling.
97 * Examples: 97 * Examples:
98 * _g("Text"); 98 * _g("Text");
99 * _g("Use a %s to drink %s", _g("glass"), "water"); 99 * _g("Use a %s to drink %s", _g("glass"), "water");
100 * 100 *
101 * @author Joel Sjögren <joel dot sjogren at nonea dot se> 101 * @author Joel Sjögren <joel dot sjogren at nonea dot se>
102 * @param string text to translate 102 * @param string text to translate
103 * @return string translated string 103 * @return string translated string
104 */ 104 */
105 function _g ($text) 105 function _g ($text)
106 { 106 {
107 // String exists and is not empty? 107 // String exists and is not empty?
108 if(!empty($this->languageStrings[$text])) { 108 if(!empty($this->languageStrings[$text])) {
109 $text = $this->languageStrings[$text]; 109 $text = $this->languageStrings[$text];
110 } else { 110 } else {
111 $text = preg_replace("/^[^\|]*\|/", "", $text); 111 $text = preg_replace("/^[^\|]*\|/", "", $text);
112 } 112 }
113 113
114 // More arguments were passed? sprintf() them... 114 // More arguments were passed? sprintf() them...
115 if (func_num_args() > 1) { 115 if (func_num_args() > 1) {
116 $args = func_get_args(); 116 $args = func_get_args();
117 array_shift($args); 117 array_shift($args);
118 //preg_match_all("/%((\d+\\\$)|.)/", str_replace("%%", "", $text), $m); 118 //preg_match_all("/%((\d+\\\$)|.)/", str_replace("%%", "", $text), $m);
119 //while (count($args) < count($m[0])) $args[] = ''; 119 //while (count($args) < count($m[0])) $args[] = '';
120 $text = vsprintf($text, $args); 120 $text = vsprintf($text, $args);
121 } 121 }
122 return $text; 122 return $text;
123 } 123 }
124 124
125 /** 125 /**
126 * Plural form of _g(). 126 * Plural form of _g().
127 * 127 *
128 * @param string singular form of text to translate 128 * @param string singular form of text to translate
129 * @param string plural form of text to translate 129 * @param string plural form of text to translate
130 * @param string number 130 * @param string number
131 * @return string translated string 131 * @return string translated string
132 */ 132 */
133 function _ng ($msgid1, $msgid2, $n) 133 function _ng ($msgid1, $msgid2, $n)
134 { 134 {
135 //calculate which plural to use 135 //calculate which plural to use
136 if(!empty($this->languageStrings[0]["plural"])) 136 if(!empty($this->languageStrings[0]["plural"]))
137 eval($this->languageStrings[0]["plural"]); 137 eval($this->languageStrings[0]["plural"]);
138 else 138 else
139 $plural = $n==1?0:1; 139 $plural = $n==1?0:1;
140 140
141 // String exists and is not empty? 141 // String exists and is not empty?
142 if (!empty($this->languageStrings[$msgid1][$plural])) { 142 if (!empty($this->languageStrings[$msgid1][$plural])) {
143 $text = $this->languageStrings[$msgid1][$plural]; 143 $text = $this->languageStrings[$msgid1][$plural];
144 } else { 144 } else {
145 $text = preg_replace("/^[^\|]*\|/", "", ($n == 1 ? $msgid1 : $msgid2)); 145 $text = preg_replace("/^[^\|]*\|/", "", ($n == 1 ? $msgid1 : $msgid2));
146 } 146 }
147 147
148 if (func_num_args() > 3) { 148 if (func_num_args() > 3) {
149 $args = func_get_args(); 149 $args = func_get_args();
150 array_shift($args); 150 array_shift($args);
151 array_shift($args); 151 array_shift($args);
152 return vsprintf($text, $args); 152 return vsprintf($text, $args);
153 } 153 }
154 154
155 return sprintf($text, $n); 155 return sprintf($text, $n);
156 } 156 }
157 157
158 } 158 }
159   159  
160 ?> 160 ?>