1: <?php
2: 3: 4: 5: 6: 7: 8: 9:
10:
11: namespace Kotchasan;
12:
13: 14: 15: 16: 17: 18: 19:
20: final class Language extends \Kotchasan\KBase
21: {
22: 23: 24: 25: 26:
27: private static $installed_languages;
28: 29: 30: 31: 32:
33: private static $language_name;
34: 35: 36: 37: 38:
39: private static $languages = null;
40:
41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55:
56: public static function find($key, $default = null, $value_key = null)
57: {
58: if (null === self::$languages) {
59: new static();
60: }
61: if (isset(self::$languages->{$key})) {
62: $item = self::$languages->$key;
63: if (is_array($item)) {
64: if ($value_key !== null && isset($item[$value_key])) {
65: return $item[$value_key];
66: }
67: } else {
68: return $item;
69: }
70: }
71: return $default === null ? $key : $default;
72: }
73:
74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87:
88: public static function get($key, $default = null)
89: {
90: if (null === self::$languages) {
91: new static();
92: }
93: return isset(self::$languages->{$key}) ? self::$languages->{$key} : ($default === null ? $key : $default);
94: }
95:
96: 97: 98: 99: 100: 101: 102:
103: public static function getItems(array $keys = array())
104: {
105: if (null === self::$languages) {
106: new static();
107: }
108: $result = array();
109: foreach ($keys as $i => $key) {
110: $result[is_int($i) ? $key : $i] = isset(self::$languages->{$key}) ? self::$languages->{$key} : $key;
111: }
112: return $result;
113: }
114:
115: 116: 117: 118: 119: 120: 121: 122:
123: public static function installed($type)
124: {
125: $language_folder = self::languageFolder();
126: $datas = array();
127: foreach (self::installedLanguage() as $lng) {
128: if ($type == 'php') {
129: if (is_file($language_folder.$lng.'.php')) {
130:
131: $datas[$lng] = include $language_folder.$lng.'.php';
132: }
133: } elseif (is_file($language_folder.$lng.'.js')) {
134:
135: $list = file($language_folder.$lng.'.js');
136: foreach ($list as $item) {
137: if (preg_match('/var\s+(.*)\s+=\s+[\'"](.*)[\'"];/', $item, $values)) {
138: $datas[$lng][$values[1]] = $values[2];
139: }
140: }
141: }
142: }
143:
144: $languages = array();
145: foreach ($datas as $language => $values) {
146: foreach ($values as $key => $value) {
147: $languages[$key][$language] = $value;
148: if (is_array($value)) {
149: $languages[$key]['array'] = true;
150: }
151: }
152: }
153:
154: $datas = array();
155: $i = 0;
156: foreach ($languages as $key => $row) {
157: $datas[$i] = ArrayTool::replace(array('id' => $i, 'key' => $key), $row);
158: ++$i;
159: }
160: return $datas;
161: }
162:
163: 164: 165: 166: 167:
168: public static function installedLanguage()
169: {
170: if (!isset(self::$installed_languages)) {
171: $language_folder = self::languageFolder();
172: $files = array();
173: File::listFiles($language_folder, $files);
174: foreach ($files as $file) {
175: if (preg_match('/(.*\/([a-z]{2,2}))\.(php|js)$/', $file, $match)) {
176: self::$installed_languages[$match[2]] = $match[2];
177: }
178: }
179: }
180: return self::$installed_languages;
181: }
182:
183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195:
196: public static function keyExists($languages, $key)
197: {
198: foreach ($languages as $item) {
199: if (strcasecmp($item['key'], $key) == 0) {
200: return $item['id'];
201: }
202: }
203: return -1;
204: }
205:
206: 207: 208: 209: 210:
211: public static function languageFolder()
212: {
213: return ROOT_PATH.'language/';
214: }
215:
216: 217: 218: 219: 220: 221: 222:
223: public static function name()
224: {
225: if (null === self::$languages) {
226: new static();
227: }
228: return self::$language_name;
229: }
230:
231: 232: 233: 234: 235: 236: 237:
238: public static function setName($language)
239: {
240: if (null === self::$languages || $language !== self::$languages) {
241: new static($language);
242: }
243:
244: return self::$language_name;
245: }
246:
247: 248: 249: 250: 251: 252: 253: 254: 255:
256: public static function parse($match)
257: {
258: return self::get($match[1]);
259: }
260:
261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271:
272: public static function replace($key, $replace)
273: {
274: if (null === self::$languages) {
275: new static();
276: }
277: $value = isset(self::$languages->$key) ? self::$languages->$key : $key;
278: foreach ($replace as $k => $v) {
279: $v = isset(self::$languages->$v) ? self::$languages->$v : $v;
280: $value = str_replace($k, $v, $value);
281: }
282: return $value;
283: }
284:
285: 286: 287: 288: 289: 290: 291: 292:
293: public static function save($languages, $type)
294: {
295: $datas = array();
296: foreach ($languages as $items) {
297: foreach ($items as $key => $value) {
298: if (!in_array($key, array('id', 'key', 'array', 'owner', 'type', 'js'))) {
299: $datas[$key][$items['key']] = $value;
300: }
301: }
302: }
303: $language_folder = self::languageFolder();
304: foreach ($datas as $lang => $items) {
305: $list = array();
306: foreach ($items as $key => $value) {
307: if ($type == 'js') {
308: if (is_string($value)) {
309: $list[] = "var $key = '$value';";
310: } else {
311: $list[] = "var $key = $value;";
312: }
313: } elseif (is_array($value)) {
314: $save = array();
315: foreach ($value as $k => $v) {
316: $data = '';
317: if (preg_match('/^[0-9]+$/', $k)) {
318: $data = $k.' => ';
319: } else {
320: $data = '\''.$k.'\' => ';
321: }
322: if (is_string($v)) {
323: $data .= '\''.$v.'\'';
324: } else {
325: $data .= $v;
326: }
327: $save[] = $data;
328: }
329: $list[] = '\''.$key."' => array(\n ".implode(",\n ", $save)."\n )";
330: } elseif (is_string($value)) {
331: $list[] = '\''.$key.'\' => \''.($value).'\'';
332: } else {
333: $list[] = '\''.$key.'\' => '.$value;
334: }
335: }
336: $f = @fopen($language_folder.$lang.'.'.$type, 'wb');
337: if ($f !== false) {
338: if ($type == 'php') {
339: $content = '<'."?php\n/* language/$lang.php */\nreturn array(\n ".implode(",\n ", $list)."\n);";
340: } else {
341: $content = implode("\n", $list);
342: }
343: fwrite($f, $content);
344: fclose($f);
345: } else {
346: return sprintf(self::get('File %s cannot be created or is read-only.'), $lang.'.'.$type);
347: }
348: }
349: return '';
350: }
351:
352: 353: 354: 355: 356: 357: 358: 359: 360:
361: public static function trans($content)
362: {
363: return preg_replace_callback('/{LNG_([^}]+)}/', function ($match) {
364: return Language::get($match[1]);
365: }, $content);
366: }
367:
368: 369: 370: 371: 372:
373: public static function load($lang)
374: {
375:
376: $language_folder = self::languageFolder();
377: if (is_file($language_folder.$lang.'.php')) {
378: $language = include $language_folder.$lang.'.php';
379: if (isset($language)) {
380: self::$languages = (object) $language;
381: self::$language_name = $lang;
382: }
383: }
384: }
385:
386: 387: 388: 389: 390:
391: private function __construct($lang = null)
392: {
393:
394: $language_folder = self::languageFolder();
395:
396: if ($lang === null) {
397: $lang = self::$request->get('lang', self::$request->cookie('my_lang', '')->toString())->filter('a-z');
398: }
399: if (empty($lang)) {
400: if (defined('AUTO_LANGUAGE') && AUTO_LANGUAGE === true) {
401:
402: $languages = self::$request->getAcceptableLanguages();
403: if (!empty($languages) && preg_match('/^([a-z]{2,2}).*?$/', strtolower($languages[0]), $match)) {
404: $lang = $match[1];
405: } else {
406: $lang = 'th';
407: }
408: }
409: }
410:
411: foreach (ArrayTool::replace(array($lang => $lang), self::$cfg->languages) as $item) {
412: if (!empty($item)) {
413: if (is_file($language_folder.$item.'.php')) {
414: $language = include $language_folder.$item.'.php';
415: if (isset($language)) {
416: self::$languages = (object) $language;
417: self::$language_name = $item;
418:
419: setcookie('my_lang', $item, time() + 2592000, '/');
420: break;
421: }
422: }
423: }
424: }
425: if (null === self::$languages) {
426:
427: self::$language_name = 'th';
428: self::$languages = (object) array(
429: 'DATE_FORMAT' => 'd M Y เวลา H:i น.',
430: 'DATE_LONG' => array(
431: 0 => 'อาทิตย์',
432: 1 => 'จันทร์',
433: 2 => 'อังคาร',
434: 3 => 'พุธ',
435: 4 => 'พฤหัสบดี',
436: 5 => 'ศุกร์',
437: 6 => 'เสาร์',
438: ),
439: 'DATE_SHORT' => array(
440: 0 => 'อา.',
441: 1 => 'จ.',
442: 2 => 'อ.',
443: 3 => 'พ.',
444: 4 => 'พฤ.',
445: 5 => 'ศ.',
446: 6 => 'ส.',
447: ),
448: 'YEAR_OFFSET' => 543,
449: 'MONTH_LONG' => array(
450: 1 => 'มกราคม',
451: 2 => 'กุมภาพันธ์',
452: 3 => 'มีนาคม',
453: 4 => 'เมษายน',
454: 5 => 'พฤษภาคม',
455: 6 => 'มิถุนายน',
456: 7 => 'กรกฎาคม',
457: 8 => 'สิงหาคม',
458: 9 => 'กันยายน',
459: 10 => 'ตุลาคม',
460: 11 => 'พฤศจิกายน',
461: 12 => 'ธันวาคม',
462: ),
463: 'MONTH_SHORT' => array(
464: 1 => 'ม.ค.',
465: 2 => 'ก.พ.',
466: 3 => 'มี.ค.',
467: 4 => 'เม.ย.',
468: 5 => 'พ.ค.',
469: 6 => 'มิ.ย.',
470: 7 => 'ก.ค.',
471: 8 => 'ส.ค.',
472: 9 => 'ก.ย.',
473: 10 => 'ต.ค.',
474: 11 => 'พ.ย.',
475: 12 => 'ธ.ค.',
476: ),
477: );
478: }
479: if (!defined('LANGUAGE')) {
480:
481: define('LANGUAGE', self::$language_name);
482: }
483: }
484: }
485: