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