Generator.php
[Pman.Core] / Generator.php
1 <?php
2  
3  
4 /**
5  * 
6  * Generate DataObjects...
7  * 
8  * This does not generate ini files any more - as that is done on the fly by the framework.
9  * 
10  * note - we write to a temporary directory first...
11  * 
12  * 
13  */
14  
15 require_once 'DB/DataObject/Generator.php';
16
17
18 /** basic thing now works... 
19
20 * it needs a bit more intelligence to work out what to do...
21
22
23 * Basically we need to build up all the formats for each db column
24 * then 
25 *   - overlay any mapping stuff.
26 *   
27 *   - overlay user defined settings
28 *   = write it out to file..
29 *   
30 *  Strucutres:
31 $this->def['order'][$table][] = $t->name;
32 $this->def['readers'][$table][$t->name] = $reader;
33 $this->def['colmodels'][$table][$t->name] = $colmodel;
34 $this->def['forms'][$table][$t->name] = $form;
35
36 *   Readers
37 *       readersDef[table.col]
38
39
40
41 * **/
42
43
44
45 class Pman_Core_Generator extends DB_DataObject_Generator
46 {
47     
48     static $cli_desc = "Generate the dataobjects";
49     
50    
51     // inherrited..
52     // $tablekeys
53     // $tables
54     // $_definitions
55     /**
56      * def[order]  
57      *      [tablename] => array( list of columns ones with '-' indicate lookup
58      *    [readers]
59      *       [tablename][colname] -> reader foramt
60      *    [forms]
61      *        [tablename][colname] => xtype / name etc...
62      *    [readerArgs]
63      *        [tablename] => data for reader args (eg. id / total prop etc.)
64      *  readers =>
65      *         [tablename] => array of cols with types
66      *  forms =>
67      *        [tablename] -> array of cols
68      * 
69      */ 
70     var $def;
71     
72       
73     var $page = false; // page container when run from cli.
74     
75     // dont do usual stuff!!!
76     var $rootDir = '';
77     var $tablekeys = array();
78     
79     var $overwrite = array(); // default dont overwrite any of the files..
80     //  array('master', 'corejs', 'corephp', 'index', 'Roo')
81     // and ('js-?????' where ??? is the table name) <- for all the generated js classes.
82     // we always overwrite the definition!!!
83     // set to array('all') to overwrite everything!!!
84     
85     function start($cli=false, $mods='', $overwrite=array())
86     {
87         
88         $ff = HTML_Flexyframework::get();
89         $this->scanModules();
90         //echo '<PRE>'; print_r($this->modtables); exit;
91         
92         $options = &PEAR::getStaticProperty('DB_DataObject','options');
93         
94         
95         $proj = 'pman'; //ucfirst(basename($options['database']));
96         // we are going to generate all of the code into a temporay foldler..
97         $user = posix_getpwuid(posix_getuid());
98         
99         $options['rootDir'] = ini_get('session.save_path').'/temp_'. $proj.'_'. $user['name'];
100         $options['cli'] = $cli;
101         $options['mods'] = empty($mods) ? array() : explode('/',$mods);
102        
103         if (!file_exists($options['rootDir'])) {
104             mkdir($options['rootDir'], 0775, true);
105         }
106         
107         $this->rootDir = $options['rootDir'];
108         $options['schema_location'] =  $this->rootDir .'/'.$proj.'/DataObjects';
109         $options['class_location'] = $this->rootDir .'/'.$proj.'/DataObjects';
110         $options['require_prefix'] =    $proj . '/DataObjects/';
111         $options['class_prefix'] =    $proj . '_DataObjects_';
112        //  print_r($this);exit;
113        
114        
115         $standard_database = $options['database'];
116        
117        
118          
119        
120        
121        
122        
123        
124        
125         parent::start();
126         
127         $this->scanModules();
128         require_once 'System.php';
129         $diff = System::which('diff');
130         // now for each of the directories copy/show diffs..
131         echo $cli ? '' : '<PRE>';
132         $flist =   $overwrite;
133         foreach($this->modtables as $m=>$ar) {
134             if ($options['database'] !=  $standard_database) {
135                 $options['database'] =  $standard_database ;
136                 
137                 parent::start();
138             }
139             
140             $options['database'] =  $standard_database ;
141             if (isset($options['database_'. $m])) {
142                 $options['database'] =  $options['database_'. $m];
143                 //var_dump($url);exit;
144                 
145                 // start again?
146                 parent::start();
147             }
148             
149             
150             if (!empty($options['mods'] ) && !in_array($m,  $options['mods'] )) {
151                 continue;
152             }
153             // this happens when we have no database tables from a module,
154             // but module code has been defined.
155             if (!file_exists($options['rootDir'].'/'.$m)) {
156                 continue;
157             }
158             foreach(scandir($options['rootDir'].'/'.$m) as $f) {
159                 
160                 echo "SCAN {$options['rootDir']} $f\n";
161                 
162                 if (!strlen($f) || $f[0] == '.') {
163                     continue;
164                 }
165                 // does it exist!!!
166                 $src = $options['rootDir']."/$m/$f";
167                 $tg = $ff->page->rootDir."/Pman/$m/DataObjects/$f";
168                 if (preg_match('/\.js$/', $f)) {
169                     $tg = $ff->page->rootDir."/Pman/$m/$f";
170                 }
171                 
172                 if (!file_exists($tg) || !filesize($tg) ) {
173                   
174                     if ($cli && file_exists($tg) || in_array($f, $flist) || in_array('_all_', $flist )) {
175                         echo "COPY $src $tg" . ($cli ? "\n" : "<BR>");
176                         copy($src, $tg);
177                         continue;
178                     }
179                     echo "!!!!MISSING!!! $tg" . ($cli ? "\n" : "<BR>");
180                     
181                     continue;
182                 }
183                 // always copy readers and ini file.=  nope - not on live..
184                 if ($cli && in_array($f, $flist) || in_array('_all_', $flist )) {
185                     
186                    //|| $f=='pman.ini' || preg_match('/\.js$/', $f))) {
187                     echo "COPY $src $tg". ($cli ? "\n" : "<BR>");
188                     copy($src, $tg);
189                     continue;
190                 }
191                 
192                 // diff the two..
193                 $cmd = "$diff -u -w ". escapeshellarg($tg) . ' ' . escapeshellarg($src);
194                  
195                 $out = array(); $ret = 0;
196                 exec($cmd, $out, $ret);
197                 if ($ret ==0) { // files match..
198                     continue;
199                 }
200                 // var_dump($ret);
201                 echo "\n" .implode( "\n" , $out) . "\n";
202                
203                 
204             }
205             
206             
207         }
208         
209         
210         
211         
212     }
213      
214     /**
215      * Scan the folders for DataObjects
216      * - Use the list of php files in DataObjects folders 
217      *   to determine which module owns which database table.
218      * 
219      */
220     
221     
222     function scanModules()
223     {
224         
225         $options = &PEAR::getStaticProperty('DB_DataObject','options');
226         if (isset($options['modtables'])) {
227             $this->modtables = $options['modtables'];
228             $this->modmap = $options['modmap'];
229             $this->modsql = $options['modsql'];
230             return;
231         }
232         
233         $ff = HTML_Flexyframework::get();
234         
235         $top = $ff->page->rootDir .'/Pman';
236         $this->modtables = array();
237         $this->modmap = array();
238         $this->modmapsql = array();
239         
240         foreach(scandir($top) as $m) {
241             
242             if (!strlen($m) || 
243                     $m[0] == '.' || 
244                     !is_dir($top .'/'.$m) || 
245                     !file_exists($top .'/'.$m.'/DataObjects')
246                 ) {
247                 continue;
248             }
249             $this->modtables[$m] = array();
250             $this->modsql[$m] = array();
251             foreach(scandir($top .'/'.$m.'/DataObjects') as $f) {
252                 if (!strlen($f) ||   $m[0] == '.') {
253                     continue;
254                 }
255                 if (preg_match('/\.sql$/', $f))  {
256                     $this->modsql[$m][] = $f;
257                 }
258                                 
259                 if (preg_match('/\.php$/', $f))  {
260                     $tn = strtolower(preg_replace('/\.php$/', '', $f));
261                     $this->modtables[$m][] = $tn;
262                     $this->modmap[$tn] = $m;
263                     continue;
264                 }
265             }
266         }
267         $options['modtables'] = $this->modtables;
268         $options['modmap'] = $this->modmap;
269         $options['modsql'] = $this->modsql;
270        // print_r($options);
271         
272     }
273     /**
274      * 
275      * this is run first, so picks up any missing dataobject files..
276      */
277     
278     function generateDefinitions()
279     {
280         if (!$this->tables) {
281             $this->debug("-- NO TABLES -- \n");
282             return;
283         }
284         if (!isset($this->modmap)) {
285             $this->scanModules();
286         }
287          $options = &PEAR::getStaticProperty('DB_DataObject','options');
288         $builder_options = PEAR::getStaticProperty('Pman_Builder','options');
289         $ignore = empty($builder_options['skip_tables']) ? array() : $builder_options['skip_tables'];
290         
291          $mods = $options['mods'];
292         $inis = array();
293         $this->_newConfig = '';
294         foreach($this->tables as $this->table) {
295             
296             $tn  = strtolower($this->table);
297             //print_r($this->modmap);//[$tn]);//
298             
299             
300             
301             if (!isset($this->modmap[$tn])) {
302                 
303                 if (in_array($this->table, $ignore)) {
304                     continue;
305                 }
306                 if (empty($mods)) {
307                 
308                 
309                    die("No existing DataObject file found for table {$this->table} 
310             
311 - either add it to Pman_Builder[skip_tables] or\n
312 - run generator and specify that module..
313 - create an empty file in the related Module/DataObjects directory
314 eg. 
315 touch Pman/????/DataObjects/".ucfirst($this->table).".php
316    
317    ");
318                 }
319                 // use mods to determine where it should output to..
320                 //var_dump($mods);exit;
321                 $this->modmap[$tn] = $mods[0];
322                 
323                 
324             }
325             $mod = $this->modmap[$tn];
326             $inis[$mod] = isset($inis[$mod]) ? $inis[$mod] : '';
327             
328             
329             $this->_newConfig = '';
330             $this->_generateDefinitionsTable();
331             
332             
333             $inis[$mod] .= $this->_newConfig;
334         }
335         return; // we do not generate in ifiles any more..
336          
337     }
338     
339     function generateClasses() 
340     {
341       // print_R($this->modmap);
342        // die("generateClasses");
343         $options = &PEAR::getStaticProperty('DB_DataObject','options');
344         
345         $ff = HTML_Flexyframework::get();
346         
347         $rd = $options['rootDir'];
348         $mods = $options['mods'];
349         $this->_extends = 'DB_DataObject';
350         $this->_extendsFile = 'DB/DataObject.php';
351         $cli = $options['cli'];
352
353         foreach($this->tables as $this->table) {
354             
355             $this->table        = trim($this->table);
356             $tn  = strtolower($this->table);
357             $mod = $this->modmap[$tn];
358             
359              if (!empty($mods) && !in_array($mod, $mods)) {
360                 continue;
361             }
362             
363             $clean_table = preg_replace('/[^A-Z0-9]+/i','_',ucfirst(trim($this->table)));
364             
365             $this->classname    = 'Pman_'.$mod . '_DataObjects_'. $clean_table; // replace odd chars?
366            
367            
368             $outfilename    = $rd.'/'.$mod.'/'. $clean_table .'.php';
369             $orig           = $ff->page->rootDir .'/Pman/'.$mod.'/DataObjects/'.  $clean_table.'.php';
370             
371            
372                 // file_get_contents???
373             
374             $oldcontents = file_exists($orig) ? file_get_contents($orig) : '';
375             
376              
377             echo "GENERATE: " .   $this->classname  . ($cli ? "\n" : "<BR>");
378             
379             $out = $this->_generateClassTable($oldcontents);
380             
381             // get rid of static GET!!!
382             $out = preg_replace('/(\n|\r\n)\s*function staticGet[^\n]+(\n|\r\n)/s', '', $out);
383             $out = preg_replace('#/\* Static get \*/#s', '', $out);
384               
385             if (!file_exists(dirname($outfilename))) {
386                 mkdir(dirname($outfilename), 0755, true);
387             }
388            // $this->debug( "writing $this->classname\n");
389             //$tmpname = tempnam(session_save_path(),'DataObject_');
390             file_put_contents($outfilename, $out);
391             
392         }
393     }
394     
395     
396         
397    // function generateDefinitions() { }
398     ////function generateForeignKeys() { }
399    // function generateClasses() { }
400    
401       
402      
403      
404    
405     function parseConfig()
406     {
407          $options = &PEAR::getStaticProperty('DB_DataObject','options');
408         
409         if (isset($options['modtables'])) {
410             $this->modtables = $options['modtables'];
411             $this->modmap = $options['modmap'];
412             $this->modsql = $options['modsql'];
413         }
414         
415         $ff = HTML_Flexyframework::get();
416         $dirs = array($ff->page->rootDir.'/Pman/DataObjects'); // not used anymore!
417         foreach($this->modtables as $m=>$ts) {
418             $dirs[] = $ff->page->rootDir.'/Pman/'.$m.'/DataObjects';
419         }
420         
421          //echo '<PRE>';print_R($ini);//exit;
422         
423         
424          
425     }
426      
427         //var_dump($table);
428         //print_r( $this->def['readers'][$table]);
429        // print_r( $this->def['colmodels'][$table]);
430         //print_r($this->def['readers'][$table]); exit;
431         
432       
433        
434     function writeFileEx($n, $f, $str) 
435     {
436         if (file_exists($f)) {
437             // all - will not overwrite stuff.. (only being specific willl)
438             if (!in_array($n, $this->overwrite)) {
439                 $this->writeFile($f.'.generated',$str);
440                 return;
441             }
442         }
443         $this->writeFile($f,$str);
444         
445         
446     }
447     function writeFile($f, $str)
448     {
449         require_once 'System.php';
450         System::mkdir(array('-p', dirname($f)));
451         // overwrite???
452         echo "write: $f\n";
453         file_put_contents($f, $str);
454     } 
455    
456 }
457