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