1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
19:
20: 21: 22: 23: 24:
25: class i81n{
26: 27: 28: 29:
30: protected $lang = NULL;
31:
32: 33: 34: 35:
36: protected $localeDir = './locale';
37:
38: 39: 40: 41: 42:
43: protected $translateTable = array();
44:
45: 46: 47: 48:
49: protected $domain = '*';
50:
51: 52: 53: 54: 55: 56: 57:
58: public function __construct($lang = NULL, $domain = '*') {
59: if($lang == NULL){
60: throw new Exception('Undefined language!');
61: }
62: $this->setLang($lang);
63:
64: $this->setDomain($domain);
65:
66: $this->parseLang();
67: }
68:
69: 70: 71: 72: 73: 74: 75: 76: 77:
78: public function setDomain($domain){
79: switch ($domain){
80: case '*':
81: $this->domain = $domain;
82: break;
83: default:
84: if(!file_exists($this->getLocaleDir().'/'.$this->getLang().'/'.$domain.'.ini')){
85: throw new Exception("The domain $domain was not found.");
86: }else{
87: $this->domain = $domain;
88: }
89: break;
90: }
91: return true;
92: }
93:
94: 95: 96: 97:
98: public function getDomain(){
99: return $this->domain;
100: }
101:
102: 103: 104: 105: 106:
107: public function getLang(){
108: return $this->lang;
109: }
110:
111: 112: 113: 114: 115: 116:
117: public function setLang($lang){
118: $this->lang = $lang;
119: return $this->getLang();
120: }
121:
122: 123: 124: 125:
126: public function getLocaleDir(){
127: return realpath($this->localeDir);
128: }
129:
130: 131: 132: 133: 134: 135: 136:
137: public function setLocaleDir($dirname){
138:
139: if(!is_dir($dirname)){
140: throw new Exception("$dirname is not a directory.");
141: }elseif(!file_exists($dirname)){
142: throw new Exception("The $dirname directory does not exist.");
143: }
144:
145:
146: $this->localeDir = realpath($dirname);
147:
148: return $this->getLocaleDir();
149: }
150:
151: 152: 153: 154: 155: 156:
157: protected function parseLang(){
158: if($this->getDomain() === '*'){
159: try{
160: $dir = glob($this->getLocaleDir().'/'.$this->getLang()."/*.ini");
161: } catch (Exception $ex) {
162: throw $ex;
163: }
164: }else{
165: $dir = array($this->getLocaleDir().'/'.$this->getLang().'/'.$this->getDomain().'.ini');
166: }
167: $table = array();
168: foreach($dir as $path){
169: if(is_file($path)){
170: try{
171: $ini = parse_ini_file($path, true);
172: $table = array_merge($table, $ini);
173: } catch (Exception $ex) {
174: throw $ex;
175: }
176: }
177: }
178: $this->translateTable = $table;
179:
180: return true;
181: }
182:
183: 184: 185: 186: 187: 188: 189: 190: 191:
192: protected static function hash($msg){
193: return sha1($msg);
194: }
195:
196: 197: 198: 199: 200: 201:
202: protected function searchInTranslateTable($hash){
203:
204: if(count($this->translateTable) == 0){
205: return '';
206: }else{
207: if(array_key_exists($hash, $this->translateTable)){
208: return $this->translateTable[$hash]['tmsg'];
209: }else{
210: return '';
211: }
212: }
213: }
214:
215: 216: 217: 218: 219: 220:
221: public function translate($msg){
222: if(count($this->translateTable) == 0){
223: return $msg;
224: }else{
225: $hash = self::hash($msg);
226: $translated = $this->searchInTranslateTable($hash);
227: if(strlen($translated) > 0){
228: return $translated;
229: }else{
230: return $msg;
231: }
232: }
233: }
234:
235:
236:
237: 238: 239: 240: 241: 242: 243: 244:
245: protected static function parseFileSource($file, $pattern = '->translate'){
246:
247:
248: if(!file_exists($file)){
249: throw new Exception("File $file not found.");
250: }
251:
252:
253:
254: try {
255: $source = file($file);
256: } catch (Exception $ex) {
257: throw $ex;
258: }
259:
260: $msg = array();
261: foreach($source as $line){
262: $explode = explode($pattern, $line);
263: if(count($explode) > 0){
264: foreach ($explode as $row){
265: preg_match_all("/\(\'(.*)\'\)/", $row, $matches);
266: if(count($matches) > 0){
267: foreach ($matches[1] as $m){
268: $msg[] = $m;
269: }
270: }
271: }
272: }
273: }
274:
275: $inistr = array();
276: foreach ($msg as $str){
277: $hash = self::hash($str);
278: $inistr[] = "[$hash]".PHP_EOL;
279: $inistr[] = "omsg = '$str'".PHP_EOL;
280: $inistr[] = "tmsg = '$str'".PHP_EOL;
281: }
282:
283: return $inistr;
284: }
285:
286: public static function parseDir($configfile){
287: printf("Starting the scan".PHP_EOL);
288:
289: try {
290: $conf = parse_ini_file($configfile, true);
291: } catch (Exception $ex) {
292: throw $ex;
293: }
294:
295: $input = realpath($conf['general']['input']);
296: $output = realpath($conf['general']['output']);
297: $domain = $conf['general']['domain'];
298: $pattern = $conf['general']['pattern'];
299: $recursive = $conf['general']['recursive'];
300: $exclude = $conf['exclude'];
301: printf("%s loaded".PHP_EOL, $configfile);
302:
303: if(!file_exists($input)){
304: throw new Exception("Source directory does not exist!");
305: }
306:
307: if(!file_exists($output)){
308: throw new Exception("Destination directory does not exist!");
309: }
310:
311: $sources = self::getFileSources($input, $recursive, $exclude);
312: printf("Sources found".PHP_EOL);
313: echo '<pre>';
314: print_r($sources);
315: echo '</pre>';
316:
317: foreach($sources as $filename){
318: printf("Processing file %s with pattern %s ".PHP_EOL, $filename, $pattern);
319: $parsed = self::parseFileSource($filename, $pattern);
320:
321: switch ($domain) {
322: case 'FILE_DOMAIN':
323: $d = basename($filename, '.php');
324: $mode = 'w';
325: break;
326:
327: case 'UNIQUE_DOMAIN':
328: $d = 'main';
329: $mode = 'a';
330: break;
331:
332: case 'DIR_DOMAIN':
333: $d = str_replace(dirname($input), '', dirname($filename));
334: $d = str_replace('/', '.', $d);
335: $d = str_replace('\\', '.', $d);
336: if($d[0] == '.');
337: $d = substr($d, 1);
338: $mode = 'w';
339: break;
340:
341: default:
342: throw new Exception("The choice for a domain name is not valid!");
343: break;
344: }
345: printf("Selected domain %s based on option %s".PHP_EOL, $d, $domain);
346: $o = "$output/$d.ini";
347: try{
348: $handle = fopen($o, $mode);
349: foreach ($parsed as $str){
350: fwrite($handle, "$str".PHP_EOL);
351: }
352: fclose($handle);
353: } catch (Exception $ex) {
354: throw $ex;
355: }
356: printf("Save translation in %s".PHP_EOL, $o);
357: }
358:
359: printf("Process completed".PHP_EOL);
360:
361: return true;
362:
363:
364: }
365:
366: protected static function getFileSources($sourcedir, $recursive, $exclude){
367: printf("Starting search for files in %s".PHP_EOL, $sourcedir);
368: reset($exclude);
369: $sources = array();
370:
371: $glob = glob("$sourcedir/*");
372:
373: foreach($glob as $f){
374: printf("Analyzing the file %s".PHP_EOL, $f);
375: $ex = false;
376: foreach($exclude as $pattern){
377: if(preg_match($pattern, $f) === 1){
378: $ex = true;
379: printf("Deleted file %s by pattern %s".PHP_EOL, $f, $pattern);
380: }
381: }
382: if($ex == false){
383: if(is_dir($f)){
384: if($recursive == 1){
385: printf("%s is a directory. Recursion starting".PHP_EOL, $f);
386: $child = self::getFileSources($f, $recursive, $exclude);
387: $sources = array_merge($sources, $child);
388: printf("Recursion of %s terminated".PHP_EOL, $f);
389: }else{
390: printf("%s is a directory. Recursion not initialised".PHP_EOL, $f);
391: }
392: }else{
393: $sources[] = $f;
394: printf("Adding %s the list".PHP_EOL, $f);
395: }
396: }
397: }
398:
399: return $sources;
400: }
401: }