1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
17:
18: 19: 20: 21: 22: 23:
24: class cI18n {
25:
26: 27: 28: 29:
30: protected static $_i18nData = array(
31: 'language' => null,
32: 'domains' => array(),
33: 'files' => array(),
34: 'cache' => array()
35: );
36:
37: 38: 39: 40: 41: 42: 43:
44: public static function init($localePath, $langCode, $domain = 'contenido') {
45: if (function_exists('bindtextdomain')) {
46:
47: bindtextdomain($domain, $localePath);
48:
49:
50: textdomain($domain);
51:
52:
53: if (!ini_get('safe_mode')) {
54: putenv("LANG=$langCode");
55: }
56:
57: if (defined('LC_MESSAGES')) {
58: setlocale(LC_MESSAGES, $langCode);
59: }
60:
61: setlocale(LC_CTYPE, $langCode);
62: }
63:
64: self::$_i18nData['domains'][$domain] = $localePath;
65: self::$_i18nData['language'] = $langCode;
66: }
67:
68: 69: 70: 71: 72: 73: 74:
75: public static function __($string, $domain = 'contenido') {
76: return self::translate($string, $domain);
77: }
78:
79: 80: 81: 82: 83: 84: 85: 86:
87: public static function translate($string, $domain = 'contenido') {
88: global $cfg, $belang, $contenido;
89:
90:
91: if (!self::$_i18nData['language']) {
92: if (!isset($belang)) {
93: if ($contenido) {
94: throw new cException('init $belang is not set');
95: }
96:
97: $belang = false;
98: }
99:
100: self::init($cfg['path']['contenido_locale'], $belang, $domain);
101: }
102:
103:
104: if (!$cfg['native_i18n']) {
105: $ret = self::emulateGettext($string, $domain);
106:
107:
108:
109: $ret = htmlspecialchars_decode(utf8_decode(conHtmlentities($ret, ENT_COMPAT, 'utf-8', false)));
110: return $ret;
111: }
112:
113:
114: if (extension_loaded('gettext')) {
115: if (function_exists('dgettext')) {
116: if ($domain != 'contenido') {
117: $translation = dgettext($domain, $string);
118: return $translation;
119: } else {
120: return gettext($string);
121: }
122: }
123: }
124:
125:
126: $ret = self::emulateGettext($string, $domain);
127: if (isUtf8($ret)) {
128: $ret = utf8_decode($ret);
129: }
130: return $ret;
131: }
132:
133: 134: 135: 136:
137: public static function getLanguage() {
138: return (self::$_i18nData['language']) ? self::$_i18nData['language'] : false;
139: }
140:
141: 142: 143: 144:
145: public static function getDomains() {
146: return self::$_i18nData['domains'];
147: }
148:
149: 150: 151: 152:
153: public static function getFiles() {
154: return self::$_i18nData['files'];
155: }
156:
157: 158: 159: 160:
161: public static function getCache() {
162: return self::$_i18nData['cache'];
163: }
164:
165: 166: 167:
168: public static function reset() {
169: self::$_i18nData['language'] = null;
170: self::$_i18nData['domains'] = array();
171: self::$_i18nData['files'] = array();
172: self::$_i18nData['cache'] = array();
173: }
174:
175: 176: 177: 178: 179: 180: 181:
182: public static function emulateGettext($string, $domain = 'contenido') {
183: if ($string == '') {
184: return '';
185: }
186:
187: if (!isset(self::$_i18nData['cache'][$domain])) {
188: self::$_i18nData['cache'][$domain] = array();
189: }
190: if (isset(self::$_i18nData['cache'][$domain][$string])) {
191: return self::$_i18nData['cache'][$domain][$string];
192: }
193:
194: $translationFile = self::$_i18nData['domains'][$domain] . self::$_i18nData['language'] . '/LC_MESSAGES/' . $domain . '.po';
195:
196: if (!cFileHandler::exists($translationFile)) {
197: return $string;
198: }
199:
200: if (!isset(self::$_i18nData['files'][$domain])) {
201: self::$_i18nData['files'][$domain] = self::_loadTranslationFile($translationFile);
202: }
203:
204: $stringStart = strpos(self::$_i18nData['files'][$domain], '"' . str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $string) . '"');
205: if ($stringStart === false) {
206: return $string;
207: }
208:
209: $matches = array();
210: $quotedString = preg_quote(str_replace(array("\n", "\r", "\t"), array('\n', '\r', '\t'), $string), '/');
211: $result = preg_match("/msgid.*\"(" . $quotedString . ")\"(?:\s*)?\nmsgstr(?:\s*)\"(.*)\"/", self::$_i18nData['files'][$domain], $matches);
212:
213:
214: if ($result && !empty($matches[2])) {
215:
216: self::$_i18nData['cache'][$domain][$string] = stripslashes(str_replace(array('\n', '\r', '\t'), array("\n", "\r", "\t"), $matches[2]));
217: } else {
218:
219: self::$_i18nData['cache'][$domain][$string] = $string;
220: }
221:
222: return self::$_i18nData['cache'][$domain][$string];
223: }
224:
225: 226: 227: 228: 229: 230: 231:
232: public static function registerDomain($domain, $localePath) {
233: if (function_exists('bindtextdomain')) {
234:
235: bindtextdomain($domain, $localePath);
236: }
237: self::$_i18nData['domains'][$domain] = $localePath;
238: }
239:
240: 241: 242: 243: 244:
245: protected static function _loadTranslationFile($translationFile) {
246: $content = cFileHandler::read($translationFile);
247:
248:
249: $content = str_replace("\n\r", "\n", $content);
250: $content = str_replace("\r\n", "\n", $content);
251:
252:
253: $content = preg_replace('/^#.+\n/m', '', $content);
254:
255:
256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276:
277:
278: $content = preg_replace('/(""\\s+")/m', '"', $content);
279:
280: $content = preg_replace('/\\n"\\s+"/m', '\\n', $content);
281:
282: $content = preg_replace('/("\n+")/m', '', $content);
283:
284: $content = preg_replace('/(\\\")/m', '"', $content);
285:
286: return $content;
287: }
288:
289: }