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