fix #8131 - chinese translations
[Pman.Core] / DataObjects / Core_template.php
1 <?php
2 /**
3  * Table Definition for core_template 
4  *
5  *
6  * The idea here is that it contains all the strings in the templates with a language '' (empty)
7  * , it then generates a matching set of strings
8  * 
9  */
10 class_exists('DB_DataObject') ? '' : require_once 'DB/DataObject.php';
11
12 class Pman_Core_DataObjects_Core_template  extends DB_DataObject 
13 {
14     ###START_AUTOCODE
15     /* the code below is auto generated do not remove the above tag */
16
17     public $__table = 'core_template';         // table name
18     public $id;                              // int(11)  not_null primary_key auto_increment
19     public $template;                           // string(64)  not_null
20
21     public $updated;                        // blob(65535)  blob
22     public $lang;    // text  NOT NULL;
23     public $view_name; // eg mobile or desktop
24     /* the code above is auto generated do not remove the tag below */
25     ###END_AUTOCODE
26     
27     
28     function applyFilters($q, $au, $roo)
29     {
30         //DB_DataObject::debugLEvel(1);
31 //        $x = DB_Dataobject::Factory($this->tableName());
32         
33         
34         // template scanning and syncing should be done by the UpdateDatabase Code.
35         //if (!$x->count() || !empty($q['_rescan'])) {
36             //DB_DataObject::debugLEvel(1);
37             //$tp = DB_DataObject::factory('core_template');
38             //$opts = HTML_FlexyFramework::get()->Pman_Core;
39             //$tp->syncTemplateDir(false, '', !empty($q['_rescan']));
40             //if (isset($q['lang'])) {
41             //    $this->syncLang($q['lang']);
42             //}
43         //} 
44 //        $this->whereAdd("
45 //                join_
46 //            ");
47         
48     }
49         
50     function toRooArray($req)
51     {
52         $ret = $this->toArray();
53         if (!empty($req['_clean_name']) ) {
54             $ret['template_clean'] = preg_replace('#\.html$#i', '', $this->template);
55             
56         }
57         return $ret;
58         
59     }
60     
61     /*
62      * @param base (should be full path to template directory)
63      * @param subdir = empty for top or subpath.
64      */
65     function syncTemplateDir($base = false,  $subdir = '', $force = false)
66     {
67         echo "syncTemplateDir: $base , $subdir, $force \n";
68         //print_r(func_get_args());
69         if (!$base) {
70             $ff = HTML_FlexyFramework::get();
71             if (!isset($ff->Pman_Core)) {
72                 echo "[ERROR] Not scanning template directory - no set in Pman_Core[templateDir]\n";
73                 return;
74             }
75             $opts = $ff->Pman_Core;
76             if (is_array($opts['templateDir'])) {
77                 foreach($opts['templateDir'] as $type=>$dir) {
78                     $this->syncTemplateDir($dir, '', $force);
79                 }
80                 return;
81             }
82             
83             $base = $opts['templateDir'];
84             
85             
86         }
87         if($force){
88             $tmpls = DB_DataObject::factory('core_template');
89             $this->tmpls = $tmpls->fetchAll('template','id'); // dupes??
90         }
91         
92         $tmp_dir = $base . (empty($subdir) ? '' : '/') . $subdir;
93         
94         if(!is_dir($tmp_dir)){
95             return;
96         }
97         
98         $dh = opendir($tmp_dir);
99         if(!$dh){
100             return; // something went wrong!?
101         }
102         
103         while (($fn = readdir($dh)) !== false) {
104             // do we care that it will try and parse the template directory??? - not really..
105             // as we are only looking for php files..
106             if(empty($fn) || $fn[0] == '.'){
107                 continue;
108             }
109
110             $fullpath = $tmp_dir."/".$fn;
111 //            echo "filename: ".$fullpath." \n";    
112              
113             $relpath = $subdir . (empty($subdir) ? '' : '/') . $fn;
114             
115             if(is_dir($fullpath)){
116                 // then recursively call self...
117 //                var_Dump($base);
118 //                var_Dump($subdir . (empty($subdir) ? '' : '/') . $fn);
119                 $this->syncTemplateDir($base, $subdir . (empty($subdir) ? '' : '/') . $fn );
120                 
121                 continue;
122             }
123             if (!preg_match('/(\.html|\.txt|\.abw)$/', $fn)) {
124                 continue;
125             }
126             
127              
128 //            var_dump($tmp);
129 //            var_dump($tmp_path);
130 //            $fn = basename($fn);
131             if (isset($this->tmpls[$relpath])) {
132                 unset($this->tmpls[$relpath]);
133             }
134             
135             
136             
137                
138             $template = $this->syncTemplate($relpath, true, false);
139 //            var_dump($template);
140             if (is_a($template, 'PEAR_Error')) {
141                 continue;
142             }
143         }
144         closedir($dh);
145 //        
146  
147         if($force){
148             foreach($this->tmpls as $id) {
149                 $x = DB_DataObject::factory($this->tableName());
150                 if ($x->get($id)) {
151                     $x->delete();
152                 }
153             }
154         }
155     }
156     
157     /* compile a html template
158      *  
159      *  @param template_dir  << the path to the template dir ... Pman/XXX/template ...
160      *  @param template   << name of template used by name field)
161      *  @param base  << view name (module ? + templates?)
162      *  
163      *  
164      */
165     function syncTemplatePage($pgdata)
166     {
167         //print_r($pgdata);
168         
169         $force = true;
170          //echo "compiling:"; print_r($pgdata);
171         // read the template and extract the translatable strings.
172         ini_set('memory_limit', '512M');
173         
174         //var_dump($n);
175         $n= $pgdata['template'];  // remove trailing slash..
176         
177         $fopts = HTML_FlexyFramework::get()->HTML_Template_Flexy;
178         $opts = HTML_FlexyFramework::get()->Pman_Core;
179         //print_R($opts);
180         //$dir = $opts['templateDir'] . '/' . $node;
181         $oo = array(
182             'fatalError'    => PEAR_ERROR_EXCEPTION,  
183             'disableTranslate' => false,
184             'templateDir' => $pgdata['template_dir'],
185             'compileDir' => $fopts['compileDir'] . '_translation_files',
186             'forceCompile' => true, //?? only for force above???
187         );
188          
189         // non-html templates - treat as such..
190         // abiword - treat as html?
191         if (!preg_match('/\.(html|abw)$/i', $pgdata['template'])) {
192             $oo['nonHTML'] = true;
193         }
194         
195         //print_r(array($oo, $n));
196         
197         
198         $flexy = new HTML_Template_Flexy( $oo );
199           
200         if (!$flexy->resolvePath ($pgdata['template'])) {
201             //echo "SKIP - could not resolve path?\n"; print_r($oo);
202             return false;
203         }
204         
205         // attempt to find the template... record.
206         $tmpl = DB_DataObject::Factory($this->tableName());
207        
208         $tmpl->view_name = $pgdata['base'];
209         if ($tmpl->get('template',  $pgdata['template'])) {
210             if (strtotime($tmpl->updated) >= filemtime($flexy->resolvePath ($pgdata['template']))) {
211                 if ($tmpl->is_deleted != 0 ||  $tmpl->filetype != 'html') {
212                     $oo = clone($tmpl);
213                     $tmpl->is_deleted = 0;
214                     $tmpl->filetype = 'html';
215                     $tmpl->update($oo);
216                 }
217                 
218                 
219                 
220                 return $tmpl;
221             }
222         }
223         
224         
225         
226         try {
227             $r = $flexy->compile($pgdata['template']);
228         } catch(Exception $e) {
229             $old = clone($tmpl);
230             $tmpl->updated   = date('Y-m-d H:i:s',filemtime($flexy->resolvePath ($pgdata['template'])));
231             if ($tmpl->id) {
232                 $tmpl->is_deleted = 0;
233                 $tmpl->filetype = 'html';
234                 $tmpl->update($tmpl);
235             } else {
236                 $tmpl->is_deleted = 0;
237                 $tmpl->filetype = 'html';
238                 $tmpl->lang = 'en';
239                 $tmpl->insert();
240             }
241             
242             
243             return false;
244         }
245        
246       
247         if (is_a($r,'PEAR_Error')) {
248             
249            // echo $r->toString(). "\n";
250             return $r;
251         }
252           
253         $tmpl = DB_DataObject::Factory($this->tableName());
254         $tmpl->words = file_exists($flexy->getTextStringsFile) ?
255                 unserialize(file_get_contents($flexy->getTextStringsFile)) :
256                 array();
257         
258         $tmpl->contentStrings   = $flexy->compiler->contentStrings;
259         //var_dump(file_exists($flexy->getTextStringsFile));
260         //print_r($tmpl->words);
261         $tmpl->currentTemplate  = $flexy->currentTemplate;
262         
263         $tmpl->view_name = $pgdata['base'];
264         
265         
266         if (!$tmpl->get('template',  $pgdata['template'])) {
267             $tmpl->is_deleted = 0;
268             $tmpl->filetype = 'html';
269             $tmpl->template = $pgdata['template'];
270             $tmpl->lang = 'en'; /// ??? hard coded??
271             $tmpl->updated = date('Y-m-d H:i:s', filemtime($flexy->currentTemplate));
272             $tmpl->insert();
273         } else {
274             $xx =clone($tmpl);
275             // has it been cahnged...
276             //if (!$force && filemtime($flexy->currentTemplate) == strtotime($tmpl->updated)) {
277                 // nothing changed..
278             //    return $tmpl;
279             //}
280             if (empty($tmpl->lang))  {
281                 //echo "FIX LANG?";exit;
282                 $tmpl->lang = 'en'; /// ??? hard coded??
283             }
284             $tmpl->filetype = 'html';
285             $tmpl->is_deleted = 0;
286             $tmpl->updated = date('Y-m-d H:i:s', filemtime($flexy->currentTemplate));
287             $tmpl->update($xx);
288         }
289       
290         
291         $x = DB_DataObject::Factory('core_templatestr');
292         $x->syncTemplateWords($tmpl);
293         
294         // if file_exists ( template/path/name.php << eg. a matching view..)
295         // then create a system page for this. 
296         
297         
298         
299         $x = DB_DataObject::Factory('core_template_element');
300         $tmpl->elements = $x->syncTemplateElement($tmpl,
301                 file_get_contents($flexy->currentTemplate),
302                 $flexy->compiler->contentStrings,
303                 false);
304         
305         
306         
307         return clone($tmpl);
308     
309     }
310     function syncPhpGetText($pgdata)
311     {
312         $tmpl = DB_DataObject::Factory($this->tableName());
313         $tmpl->view_name = $pgdata['base'];
314         $tmpl->currentTemplate = $pgdata['template_dir'] . '/'. $pgdata['template'];
315         
316         if ($tmpl->get('template',  $pgdata['template'])) {
317             if (strtotime($tmpl->updated) >= filemtime( $tmpl->currentTemplate )) {
318                 if ($tmpl->is_deleted != 0 ||  $tmpl->filetype != 'html') {
319                     $oo = clone($tmpl);
320                     $tmpl->is_deleted = 0;
321                     $tmpl->filetype = 'php';
322                     $tmpl->update($oo);
323                 }
324                 return $tmpl;
325             }
326         }
327         $words = array();
328         
329         $ar = token_get_all(file_get_contents( $tmpl->currentTemplate  ));
330         foreach( $ar as $i=> $tok) {
331             if (!is_array($tok) || $tok[0] != T_CONSTANT_ENCAPSED_STRING) {
332                 continue;
333             }
334             if ($i < 2) {
335                 continue;
336             }
337             if (is_array($ar[$i-1]) || $ar[$i-1] != '(') {
338                 continue;
339             }
340             if (!is_array($ar[$i-2]) || $ar[$i-2][1] != '_') {
341                 continue;
342             }
343             $ct = $tok[1][0];
344             $words[] =  str_replace('\\'. $ct, $ct, trim($tok[1] , $ct));
345             
346         }
347         // create the template...
348         
349         
350          if (!$tmpl->id) {
351             
352             $tmpl->template = $pgdata['template'];
353             $tmpl->lang = 'en'; /// ??? hard coded??
354             $tmpl->filetype = 'php';
355             $tmpl->is_deleted = 0;
356             $tmpl->updated = date('Y-m-d H:i:s', filemtime($tmpl->currentTemplate));
357             $tmpl->insert();
358         } else {
359             $xx =clone($tmpl);
360             $tmpl->filetype = 'php';
361             $tmpl->is_deleted = 0;
362             $tmpl->lang = 'en'; /// ??? hard coded??
363             $tmpl->updated = date('Y-m-d H:i:s', filemtime($tmpl->currentTemplate));
364             $tmpl->update($xx);
365         }
366       
367         $words = array_unique($words);
368         
369         if (!count($words)) {
370             return;
371         }
372         
373              
374         $tmpl->words = $words;
375             
376         $x = DB_DataObject::Factory('core_templatestr');
377         $x->syncTemplateWords($tmpl);    
378          
379         
380         return $tmpl;
381         
382         
383         
384     }
385     /*
386     SELECT LOWER(
387 CONCAT(
388 REPLACE(view_name, '.','_'),
389 '_',
390 REPLACE(template,'/','_')
391 )
392 )
393 FROM core_template
394
395 WHERE (
396  = 'release_pressrelease_distributionreportnew_journalistdistribution.php'
397 )
398 */
399
400     
401     function genGetText($clsname, $lang=false)
402     {
403         static $done = false;
404         $clsname = strtolower($clsname);
405
406         textdomain($clsname);
407      
408
409         $ff = HTML_FlexyFramework::get();
410         $lang = $lang ? $lang : (isset($ff->locale) ? $ff->locale : 'en');
411         
412
413         if (!empty($done[$clsname.':'.$lang])) {
414             return; // already sent headers and everything.
415         }
416         
417         putenv("LANGUAGE=$lang");
418         if ($lang != 'en') {
419             if (!setlocale(LC_ALL, $lang.'.UTF-8')) {
420                 $ff->page->jerr("Language is not available {$lang}");
421             }
422         }
423         
424         
425         $d = DB_DataObject::factory($this->tableName());
426         $d->whereAdd("
427             LOWER(
428                 CONCAT(
429                       REPLACE(view_name, '.','_'),
430                     '_',
431                     REPLACE(template,'/','_')
432                 )
433             ) = '{$clsname}.php'
434        ");
435         $d->filetype = 'php';
436         if (! $d->find(true) ){
437             $done[$clsname.':'.$lang] = true;
438             return;
439         }
440         $user = 'www-data'; // ?? do we need other ones
441         $compileDir = ini_get('session.save_path') .'/' . 
442             $user . '_gettext_' . $ff->project;
443         
444         if ($ff->appNameShort) {
445             $compileDir .= '_' . $ff->appNameShort;
446         }
447         if ($ff->version) {
448             $compileDir .= '.' . $ff->version;
449         }
450         $lang = $lang ? $lang : $ff->locale;
451         $fdir = "{$compileDir}/{$lang}/LC_MESSAGES";
452         $fname = "{$fdir}/{$clsname}.mo";
453         
454          
455         //exit;
456         bindtextdomain($clsname, $compileDir) ;
457         bind_textdomain_codeset($clsname, 'UTF-8');
458
459         textdomain($clsname);
460
461         
462         //textdomain($clsname);
463         
464         $done[$clsname.':'.$lang] = 1;
465         
466         // do we need to compile the file..
467         $ts = DB_DataObject::Factory('core_templatestr');
468         $ts->selectAdd('MAX(updated) as updated');
469         $ts->lang = $lang;
470         $ts->template_id = $d->id;
471         if (!$ts->find(true)) {
472             // then in theory there are no translations
473             return;
474         }
475         if (file_exists($fname) && strtotime($ts->updated) < filemtime($fname)) {
476             return; // file exists and is newer than our updated line.
477         }
478         //DB_DataObject::debugLevel(1);
479
480         $ts = DB_DataObject::Factory('core_templatestr');
481         $ts->autoJoin();
482         $ts->selectAdd('join_src_id_id.txt as src_id_txt, core_templatestr.txt as txt');
483         $ts->lang = $lang;
484         $ts->template_id = $d->id;
485         $words = $ts->fetchAll('src_id_txt', 'txt' );
486                
487         if (!file_exists($fdir)) {
488             //var_dump($fdir);
489             mkdir($fdir, 0700, true);
490         }
491         
492         require_once 'File/Gettext.php';
493         $gt = File_Gettext::factory('PO', preg_replace('/\.mo$/', '.po', $fname));
494         $gt->fromArray(
495             
496             array(
497                 'meta' => array(
498                     "Language" =>  $lang,
499                     'Content-Type'      => 'text/plain; charset=UTF-8',
500                     'Content-Transfer-Encoding'      => ' 8bit',
501                      'PO-Revision-Date'  => date('Y-m-d H:iO'),
502                  ),
503                 'strings' => $words
504             )
505             
506         );
507         $gt->save();
508         
509         // mo DOESNT WORK!!
510         require_once 'System.php';
511         $poname = preg_replace('/\.mo$/', '.po', $fname);
512         $msgfmt = System::which('msgfmt');
513         $cmd = "{$msgfmt} {$poname}  -o {$fname}";
514         //echo $cmd;
515         
516         `$cmd`;
517         
518         
519          
520         
521         return;
522         
523         require_once 'File/Gettext.php';
524         $gt = File_Gettext::factory('MO', $fname);
525         $gt->fromArray(
526             
527             array(
528                 'meta' => array(
529                      "Language" =>  $lang,
530                     'Content-Type'      => 'text/plain; charset=UTF-8',
531                     'Content-Transfer-Encoding'      => ' 8bit',
532                      'PO-Revision-Date'  => date('Y-m-d H:iO'),
533                 ),
534                 'strings' => $words
535             )
536             
537         );
538         $gt->save(); 
539         
540     }
541 }