DataObjects/Core_template.php
[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     function beforeUpdate($old, $q, $roo)
62     {
63         if (!empty($q['_rescan'])){
64             if ($this->filetype != 'html') {
65                 $roo->jerr("can not update a php source file currently - TDOD");
66             }
67             $pg = HTML_FlexyFramework::get()->page;
68             
69             $this->syncTemplatePage(array(
70                 'template_dir' => $pg->rootDir . '/'. str_replace('.', '/', $this->view_name). '/templates',
71                 'template' => $this->template,
72                 'base' => $this->view_name,
73                 'force' => true
74             ));
75             // update the different langage versions of this page.
76             $x = DB_Dataobject::Factory('core_templatestr');
77             $x->selectAdd();
78             $x->selectAdd('distinct(lang) as lang');
79             $x->whereAdd("lang != ''");
80             $langs  = $x->fetchAll('lang');
81             foreach($langs as $l) {
82                 $x = DB_Dataobject::Factory('core_templatestr');
83                 $x->syncLang($l, $this->id);
84             }
85            
86             
87             $roo->jok("updated -" .  $this->template);
88         }
89     }
90    
91     
92     
93     
94     /*
95      * USED? - this is in updateBJSTemplate ?
96      * @param base (should be full path to template directory)
97      * @param subdir = empty for top or subpath.
98      */
99     /*
100     function syncTemplateDir($base = false,  $subdir = '', $force = false)
101     {
102         echo "syncTemplateDir: $base , $subdir, $force \n";
103         //print_r(func_get_args());
104         if (!$base) {
105             $ff = HTML_FlexyFramework::get();
106             if (!isset($ff->Pman_Core)) {
107                 echo "[ERROR] Not scanning template directory - no set in Pman_Core[templateDir]\n";
108                 return;
109             }
110             $opts = $ff->Pman_Core;
111             if (is_array($opts['templateDir'])) {
112                 foreach($opts['templateDir'] as $type=>$dir) {
113                     $this->syncTemplateDir($dir, '', $force);
114                 }
115                 return;
116             }
117             
118             $base = $opts['templateDir'];
119             
120             
121         }
122         if($force){
123             $tmpls = DB_DataObject::factory('core_template');
124             $this->tmpls = $tmpls->fetchAll('template','id'); // dupes??
125         }
126         
127         $tmp_dir = $base . (empty($subdir) ? '' : '/') . $subdir;
128         
129         if(!is_dir($tmp_dir)){
130             return;
131         }
132         
133         $dh = opendir($tmp_dir);
134         if(!$dh){
135             return; // something went wrong!?
136         }
137         
138         while (($fn = readdir($dh)) !== false) {
139             // do we care that it will try and parse the template directory??? - not really..
140             // as we are only looking for php files..
141             if(empty($fn) || $fn[0] == '.'){
142                 continue;
143             }
144
145             $fullpath = $tmp_dir."/".$fn;
146 //            echo "filename: ".$fullpath." \n";    
147              
148             $relpath = $subdir . (empty($subdir) ? '' : '/') . $fn;
149             
150             if(is_dir($fullpath)){
151                 // then recursively call self...
152 //                var_Dump($base);
153 //                var_Dump($subdir . (empty($subdir) ? '' : '/') . $fn);
154                 $this->syncTemplateDir($base, $subdir . (empty($subdir) ? '' : '/') . $fn );
155                 
156                 continue;
157             }
158             if (!preg_match('/(\.html|\.txt|\.abw)$/', $fn)) {
159                 continue;
160             }
161             
162              
163 //            var_dump($tmp);
164 //            var_dump($tmp_path);
165 //            $fn = basename($fn);
166             if (isset($this->tmpls[$relpath])) {
167                 unset($this->tmpls[$relpath]);
168             }
169             
170             
171             
172                
173             $template = $this->syncTemplate($relpath, true, false);
174 //            var_dump($template);
175             if (is_a($template, 'PEAR_Error')) {
176                 continue;
177             }
178         }
179         closedir($dh);
180 //        
181  
182         if($force){
183             foreach($this->tmpls as $id) {
184                 $x = DB_DataObject::factory($this->tableName());
185                 if ($x->get($id)) {
186                     $x->delete();
187                 }
188             }
189         }
190     }
191     */
192     /* compile a html template NOT USED - in UpdateBJS tmpalte ?
193      *  
194      *  @param template_dir  << the path to the template dir ... Pman/XXX/template ...
195      *  @param template   << name of template used by name field)
196      *  @param base  << view name (module ? + templates?)
197      *  @param force << optional - forces even if database is newer.
198      *  
199      *  
200      */
201     /*
202     function syncTemplatePage($pgdata)
203     {
204         //print_r($pgdata);
205         
206         $force = true;
207          //echo "compiling:"; print_r($pgdata);
208         // read the template and extract the translatable strings.
209         ini_set('memory_limit', '512M');
210         
211         //var_dump($n);
212         $n = $pgdata['template'];  // remove trailing slash..
213         
214         $fopts = HTML_FlexyFramework::get()->HTML_Template_Flexy;
215         $opts = HTML_FlexyFramework::get()->Pman_Core;
216         //print_R($opts);
217         //$dir = $opts['templateDir'] . '/' . $node;
218         $oo = array(
219             'fatalError'    => PEAR_ERROR_EXCEPTION,  
220             'disableTranslate' => false,
221             'templateDir' => $pgdata['template_dir'],
222             'compileDir' => $fopts['compileDir'] . '_translation_files',
223             'forceCompile' => true, //?? only for force above???
224         );
225          
226         // non-html templates - treat as such..
227         // abiword - treat as html?
228         if (!preg_match('/\.(html|abw)$/i', $pgdata['template'])) {
229             $oo['nonHTML'] = true;
230         }
231         
232         //print_r(array($oo, $n));
233         
234         
235         $flexy = new HTML_Template_Flexy( $oo );
236           
237         if (!$flexy->resolvePath ($pgdata['template'])) {
238             //echo "SKIP - could not resolve path?\n"; print_r($oo);
239             return false;
240         }
241         
242         // attempt to find the template... record.
243         $tmpl = DB_DataObject::Factory($this->tableName());
244        
245         $tmpl->view_name = $pgdata['base'];
246         if ($tmpl->get('template',  $pgdata['template'])) {
247             clearstatcache();
248             if (strtotime($tmpl->updated) >= filemtime($flexy->resolvePath ($pgdata['template']) . '/'. $pgdata['template'])) {
249                 if ($tmpl->is_deleted != 0 ||  $tmpl->filetype != 'html') {
250                     $oo = clone($tmpl);
251                     $tmpl->is_deleted = 0;
252                     $tmpl->filetype = 'html';
253                     $tmpl->update($oo);
254                 }
255                 if (empty($pgdata['force'])) {
256                   //  echo "SKIP NO UPDATE: " . $pgdata['template'] ."\n";
257                    // echo $flexy->resolvePath ($pgdata['template']).  ':'. $tmpl->updated  . ">=" .  date('Y-m-d H:i:s',filemtime($flexy->resolvePath ($pgdata['template']))) . "\n";
258                     return $tmpl;
259                 }
260             }
261         }
262         
263         //die("got here");
264         
265         try {
266             $r = $flexy->compile($pgdata['template']);
267            
268             
269         } catch(Exception $e) {
270             $old = clone($tmpl);
271             $tmpl->updated   = date('Y-m-d H:i:s',filemtime($flexy->resolvePath ($pgdata['template']) . '/'. $pgdata['template']));
272             if ($tmpl->id) {
273                 $tmpl->is_deleted = 0;
274                 $tmpl->filetype = 'html';
275                 $tmpl->update($tmpl);
276             } else {
277                 $tmpl->is_deleted = 0;
278                 $tmpl->filetype = 'html';
279                 $tmpl->lang = 'en';
280                 $tmpl->insert();
281             }
282             //echo "SKIP: " . $pgdata['template'] ."\n";
283            //   echo "SKIP - exception\n"; print_r($e);
284             return false;
285         }
286        
287       
288         if (is_a($r,'PEAR_Error')) {
289             //echo "SKIP: " . $pgdata['template'] ."\n";
290             //echo $r->toString(). "\n";
291             return $r;
292         }
293           
294         $tmpl = DB_DataObject::Factory($this->tableName());
295         $tmpl->words = file_exists($flexy->getTextStringsFile) ?
296                 unserialize(file_get_contents($flexy->getTextStringsFile)) :
297                 array();
298         
299         $tmpl->contentStrings   = $flexy->compiler->contentStrings;
300         //var_dump(file_exists($flexy->getTextStringsFile));
301         //print_r($tmpl->words);
302         $tmpl->currentTemplate  = $flexy->currentTemplate;
303         
304         $tmpl->view_name = $pgdata['base'];
305         
306         //echo $pgdata['template'] ."\n";
307         if (!$tmpl->get('template',  $pgdata['template'])) {
308             $tmpl->is_deleted = 0;
309             $tmpl->filetype = 'html';
310             $tmpl->template = $pgdata['template'];
311             $tmpl->lang = 'en'; /// ??? hard coded??
312             $tmpl->updated = date('Y-m-d H:i:s', filemtime($flexy->currentTemplate));
313             $tmpl->insert();
314         } else {
315             $xx =clone($tmpl);
316             // has it been cahnged...
317             //if (!$force && filemtime($flexy->currentTemplate) == strtotime($tmpl->updated)) {
318                 // nothing changed..
319             //    return $tmpl;
320             //}
321             if (empty($tmpl->lang))  {
322                 //echo "FIX LANG?";exit;
323                 $tmpl->lang = 'en'; /// ??? hard coded??
324             }
325             $tmpl->filetype = 'html';
326             $tmpl->is_deleted = 0;
327             $tmpl->updated = date('Y-m-d H:i:s', filemtime($flexy->currentTemplate));
328             $tmpl->update($xx);
329         }
330       
331         
332         $x = DB_DataObject::Factory('core_templatestr');
333         $x->syncTemplateWords($tmpl);
334         
335         // if file_exists ( template/path/name.php << eg. a matching view..)
336         // then create a system page for this. 
337         
338         
339         
340         $x = DB_DataObject::Factory('core_template_element');
341         $tmpl->elements = $x->syncTemplateElement($tmpl,
342                 file_get_contents($flexy->currentTemplate),
343                 $flexy->compiler->contentStrings,
344                 false);
345         
346         
347         
348         return clone($tmpl);
349     
350     }
351     
352     */
353     
354     
355     function syncPhpGetText($pgdata)
356     {
357         $tmpl = DB_DataObject::Factory($this->tableName());
358         $tmpl->view_name = $pgdata['base'];
359         $tmpl->currentTemplate = $pgdata['template_dir'] . '/'. $pgdata['template'];
360         
361         if ($tmpl->get('template',  $pgdata['template'])) {
362             if (strtotime($tmpl->updated) >= filemtime( $tmpl->currentTemplate )) {
363                 if ($tmpl->is_deleted != 0 ||  $tmpl->filetype != 'html') {
364                     $oo = clone($tmpl);
365                     $tmpl->is_deleted = 0;
366                     $tmpl->filetype = 'php';
367                     $tmpl->update($oo);
368                 }
369                 return $tmpl;
370             }
371         }
372         $words = array();
373         
374         $ar = token_get_all(file_get_contents( $tmpl->currentTemplate  ));
375         foreach( $ar as $i=> $tok) {
376             if (!is_array($tok) || $tok[0] != T_CONSTANT_ENCAPSED_STRING) {
377                 continue;
378             }
379             if ($i < 2) {
380                 continue;
381             }
382             if (is_array($ar[$i-1]) || $ar[$i-1] != '(') {
383                 continue;
384             }
385             if (!is_array($ar[$i-2]) || $ar[$i-2][1] != '_') {
386                 continue;
387             }
388             $ct = $tok[1][0];
389             $words[] =  str_replace('\\'. $ct, $ct, trim($tok[1] , $ct));
390             
391         }
392         // create the template...
393         
394         
395         if (!$tmpl->id) {
396             
397             $tmpl->template = $pgdata['template'];
398             $tmpl->lang = 'en'; /// ??? hard coded??
399             $tmpl->filetype = 'php';
400             $tmpl->is_deleted = 0;
401             $tmpl->updated = date('Y-m-d H:i:s', filemtime($tmpl->currentTemplate));
402             $tmpl->insert();
403         } else {
404             $xx =clone($tmpl);
405             $tmpl->filetype = 'php';
406             $tmpl->is_deleted = 0;
407             $tmpl->lang = 'en'; /// ??? hard coded??
408             $tmpl->updated = date('Y-m-d H:i:s', filemtime($tmpl->currentTemplate));
409             $tmpl->update($xx);
410         }
411       
412         $words = array_unique($words);
413         
414         if (!count($words)) {
415             return;
416         }
417         
418              
419         $tmpl->words = $words;
420             
421         $x = DB_DataObject::Factory('core_templatestr');
422         $x->syncTemplateWords($tmpl);    
423          
424         
425         return $tmpl;
426         
427         
428         
429     }
430     
431     /**
432      * plain JS files use ._(....) to flag 
433      *
434      */ 
435     
436     function syncJS($pgdata)
437     {
438         $tmpl = DB_DataObject::Factory($this->tableName());
439         $tmpl->view_name = $pgdata['base'];
440         $tmpl->currentTemplate = $pgdata['template_dir'] . '/'. $pgdata['template'];
441         
442         if ($tmpl->get('template',  $pgdata['template'])) {
443             if (strtotime($tmpl->updated) >= filemtime( $tmpl->currentTemplate )) {
444                 if ($tmpl->is_deleted != 0 ||  $tmpl->filetype != 'js') {
445                     $oo = clone($tmpl);
446                     $tmpl->is_deleted = 0;
447                     $tmpl->filetype = 'js';
448                     $tmpl->update($oo);
449                 }
450                 return $tmpl;
451             }
452         }
453         $words = array();
454         
455         $fc = file_get_contents( $tmpl->currentTemplate );
456         
457         $ar = preg_match('/\.\("^("+)"\)/g', $fc, $outd);
458         print_R($outd);
459         $ar = preg_match('/\.\('. "'" . '(^"+)'. "'" . '\)/g', $fc, $outs);
460         print_R($outs);exit;
461         
462         $words[] =  str_replace('\\'. $ct, $ct, trim($tok[1] , $ct));
463         $words = array_unique($words);
464         
465         if (!count($words)) {
466             return;
467         }
468         
469              
470         $tmpl->words = $words;
471             
472         $x = DB_DataObject::Factory('core_templatestr');
473         $x->syncTemplateWords($tmpl);    
474          
475         
476         return $tmpl;
477         
478         
479         
480     }
481     
482     /*
483     SELECT LOWER(
484 CONCAT(
485 REPLACE(view_name, '.','_'),
486 '_',
487 REPLACE(template,'/','_')
488 )
489 )
490 FROM core_template
491
492 WHERE (
493  = 'release_pressrelease_distributionreportnew_journalistdistribution.php'
494 )
495 */
496
497     
498     function genGetText($clsname, $lang=false)
499     {
500         static $done = array();
501         $clsname = strtolower($clsname);
502
503         textdomain($clsname);
504      
505
506         $ff = HTML_FlexyFramework::get();
507         $lang = $lang ? $lang : (isset($ff->locale) ? $ff->locale : 'en');
508         
509
510         if (!empty($done[$clsname.':'.$lang])) {
511             return true; // already sent headers and everything.
512         }
513         
514         putenv("LANGUAGE=$lang");
515         if ($lang != 'en') {
516             if (!setlocale(LC_ALL, $lang.'.UTF-8')) {
517                 $ff->page->jerr("Language is not available {$lang}");
518             }
519         }
520         
521         
522         $d = DB_DataObject::factory($this->tableName());
523         $d->whereAdd("
524             LOWER(
525                 CONCAT(
526                       REPLACE(view_name, '.','_'),
527                     '_',
528                     REPLACE(template,'/','_')
529                 )
530             ) = '{$clsname}.php'
531        ");
532         $d->filetype = 'php';
533         if (! $d->find(true) ){
534             $done[$clsname.':'.$lang] = true;
535             return false;
536         }
537         $user = 'www-data'; // ?? do we need other ones
538         $compileDir = ini_get('session.save_path') .'/' . 
539             $user . '_gettext_' . $ff->project;
540         
541         if ($ff->appNameShort) {
542             $compileDir .= '_' . $ff->appNameShort;
543         }
544         if ($ff->version) {
545             $compileDir .= '.' . $ff->version;
546         }
547         $lang = $lang ? $lang : $ff->locale;
548         $fdir = "{$compileDir}/{$lang}/LC_MESSAGES";
549         $fname = "{$fdir}/{$clsname}.mo";
550         
551          
552         //exit;
553         bindtextdomain($clsname, $compileDir) ;
554         bind_textdomain_codeset($clsname, 'UTF-8');
555
556         textdomain($clsname);
557
558         
559         //textdomain($clsname);
560         
561         $done[$clsname.':'.$lang] = 1;
562         
563         // do we need to compile the file..
564         $ts = DB_DataObject::Factory('core_templatestr');
565         $ts->selectAdd('COALESCE(MAX(updated), "1000-01-01") as updated');
566         $ts->lang = $lang;
567         $ts->template_id = $d->id;
568         if (!$ts->find(true)) {
569             // then in theory there are no translations
570             return false;
571         }
572         if (file_exists($fname) && strtotime($ts->updated) < filemtime($fname)) {
573             return $fname; // file exists and is newer than our updated line.
574         }
575         //DB_DataObject::debugLevel(1);
576
577         $ts = DB_DataObject::Factory('core_templatestr');
578         $ts->autoJoin();
579         $ts->selectAdd('join_src_id_id.txt as src_id_txt, core_templatestr.txt as txt');
580         $ts->lang = $lang;
581         $ts->template_id = $d->id;
582         $ts->whereAdd("LENGTH(join_src_id_id.txt) > 0 AND LENGTH(core_templatestr.txt) > 0");
583         $words = $ts->fetchAll('src_id_txt', 'txt' );
584                
585         if (!file_exists($fdir)) {
586             //var_dump($fdir);
587             mkdir($fdir, 0700, true);
588         }
589         
590         require_once 'File/Gettext.php';
591         $gt = File_Gettext::factory('PO', preg_replace('/\.mo$/', '.po', $fname));
592         $gt->fromArray(
593             
594             array(
595                 'meta' => array(
596                     "Language" =>  $lang,
597                     'Content-Type'      => 'text/plain; charset=UTF-8',
598                     'Content-Transfer-Encoding'      => ' 8bit',
599                      'PO-Revision-Date'  => date('Y-m-d H:iO'),
600                  ),
601                 'strings' => $words
602             )
603             
604         );
605         $gt->save();
606         
607         // mo DOESNT WORK!!
608         require_once 'System.php';
609         $poname = preg_replace('/\.mo$/', '.po', $fname);
610         $msgfmt = System::which('msgfmt');
611         $cmd = "{$msgfmt} {$poname}  -o {$fname}";
612         //echo $cmd;
613         
614         `$cmd`;
615         
616         
617          
618         
619         return $fname;
620         
621         require_once 'File/Gettext.php';
622         $gt = File_Gettext::factory('MO', $fname);
623         $gt->fromArray(
624             
625             array(
626                 'meta' => array(
627                      "Language" =>  $lang,
628                     'Content-Type'      => 'text/plain; charset=UTF-8',
629                     'Content-Transfer-Encoding'      => ' 8bit',
630                      'PO-Revision-Date'  => date('Y-m-d H:iO'),
631                 ),
632                 'strings' => $words
633             )
634             
635         );
636         $gt->save(); 
637         
638     }
639 }