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