NotifySmtpCheck.php
[Pman.Core] / NotifySmtpCheck.php
1 <?php
2
3 require_once 'Pman.php';
4
5 class Pman_Core_NotifySmtpCheck extends Pman
6 {
7     function getAuth() 
8     {
9         $ff = HTML_FlexyFramework::get();
10         if (!empty($ff->cli)) {
11             $this->cli = true;
12             return true;
13         }
14         
15         return false;
16         
17     }
18      
19     function get($args, $opts)
20     {
21         PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($this, 'onPearError'));
22    
23 //        $this->checkSystem();
24    
25         $ff = HTML_FlexyFramework::get();
26         
27         if(!empty($ff->Core_Notify)){
28             $x = new Pman_Core_NotifySmtpCheck();
29         }
30         
31         EXIT;
32         
33         $this->disabled = explode(',', $ff->disable);
34         
35         //$this->fixSequencesPgsql();exit;
36         $this->opts = $opts;
37         
38         // ask all the modules to verify the opts
39         
40         $this->checkOpts($opts);
41         
42         if (empty($opts['data-only'])) {
43             $this->importSQL();
44         }
45         if (!empty($opts['only-module-sql'])) {
46             return;
47         }
48         
49         $this->runUpdateModulesData();
50         
51         
52         if (!empty($opts['add-company']) && !in_array('Core', $this->disabled)) {
53             // make sure we have a good cache...?
54            
55             DB_DataObject::factory('companies')->initCompanies($this, $opts);
56         }
57         
58         $this->runExtensions();
59          
60          
61     }
62     function output() {
63         return '';
64     }
65      /**
66      * imports SQL files from all DataObjects directories....
67      * 
68      * except any matching /migrate/
69      */
70     function importSQL()
71     {
72         
73         // loop through all the modules, and see if they have a importSQL method?
74         
75         
76         $ff = HTML_Flexyframework::get();
77         
78         $dburl = parse_url($ff->DB_DataObject['database']);
79         
80         //$this->{'import' . $url['scheme']}($url);
81         
82         $dbtype = $dburl['scheme'];
83         $dirmethod = 'import' . $dburl['scheme'] . 'dir';
84         
85         
86        
87         
88         $ar = $this->modulesList();
89         
90         foreach($ar as $m) {
91             
92             if(in_array($m, $this->disabled)){
93                 echo "module $m is disabled \n";
94                 continue;
95             }
96             
97             echo "Importing SQL from module $m\n";
98             if (!empty($this->opts['only-module-sql']) && $m != $this->opts['only-module-sql']) {
99                 continue;
100             }
101             
102             
103             // check to see if the class has
104             
105             
106             
107             $file = $this->rootDir. "/Pman/$m/UpdateDatabase.php";
108             if($m != 'Core' && file_exists($file)){
109                 
110                 require_once $file;
111                 $class = "Pman_{$m}_UpdateDatabase";
112                 $x = new $class;
113                 if(method_exists($x, 'importModuleSQL')){
114                     echo "Importing SQL from module $m using Module::importModuleSQL\n";
115                     $x->opts = $this->opts;
116                     $x->rootDir = $this->rootDir;
117                     $x->importModuleSQL($dburl);
118                     continue;
119                 }
120             };
121
122             echo "Importing SQL from module $m\n";
123             
124             
125             // if init has been called
126             // look in pgsql.ini
127             if (!empty($this->opts['init'])) {
128                 $this->{$dirmethod}($dburl, $this->rootDir. "/Pman/$m/{$dbtype}.init");
129                 
130             }
131             
132             
133             
134             $fd = $this->rootDir. "/Pman/$m/DataObjects";
135             
136             $this->{$dirmethod}($dburl, $fd);
137             
138             
139             // new -- sql directory..
140             // new style will not support migrate ... they have to go into mysql-migrate.... directories..
141             // new style will not support pg.sql etc.. naming - that's what the direcotries are for..
142             
143             $this->{$dirmethod}($dburl, $this->rootDir. "/Pman/$m/sql");
144             $this->{$dirmethod}($dburl, $this->rootDir. "/Pman/$m/{$dbtype}");
145             
146             
147             
148             if (!empty($this->opts['init']) && file_exists($this->rootDir. "/Pman/$m/{$dbtype}.initdata")) {
149                 HTML_FlexyFramework::get()->generateDataobjectsCache(true);
150                 
151                 $this->{$dirmethod}($dburl, $this->rootDir. "/Pman/$m/{$dbtype}.initdata");
152                 $this->{'fixSequences'. $dbtype}();
153                 
154             }
155               
156             
157         }
158         
159     }
160     
161     
162     
163      
164     /** -------------- code to handle importing a whole directory of files into the database  -------  **/
165     
166     
167     function importpgsqldir($url, $dir, $disable_triggers = false)
168     {
169         $ff = HTML_FlexyFramework::get();
170         
171         require_once 'System.php';
172         $cat = System::which('cat');
173         $psql = System::which('psql');
174         
175          
176         if (!empty($url['pass'])) { 
177             putenv("PGPASSWORD=". $url['pass']);
178         }
179            
180         $psql_cmd = $psql .
181             ' -h ' . $url['host'] .
182             ' -U' . escapeshellarg($url['user']) .
183              ' ' . basename($url['path']);
184         
185         
186         echo $psql_cmd . "\n" ;
187         echo "scan : $dir\n";
188         
189         if (is_file($dir)) {
190             $files = array($dir);
191
192         } else {
193         
194         
195             $files = glob($dir.'/*.sql');
196             uksort($files, 'strcasecmp');
197         }
198         //$lsort = create_function('$a,$b','return strlen($a) > strlen($b) ? 1 : -1;');
199         //usort($files, $lsort);
200         
201         
202         foreach($files as $bfn) {
203
204
205             if (preg_match('/migrate/i', basename($bfn))) { // skip migration scripts at present..
206                 continue;
207             }
208             if (preg_match('#\.[a-z]{2}\.sql#i', basename($bfn))
209                 && !preg_match('#\.pg\.sql#i', basename($bfn))
210             ) { // skip migration scripts at present..
211                 continue;
212             }
213             $fn = false;
214
215             if (!preg_match('/pgsql/', basename($dir) )) {
216                  if ( !preg_match('#\.pg\.sql$#', basename($bfn))) {
217                     $fn = $this->convertToPG($bfn);
218                 }
219             }
220
221             // files ending in .pg.sql are native postgres files.. ## depricated
222
223
224             $cmd = "$psql_cmd  < " . escapeshellarg($fn ? $fn : $bfn) . ' 2>&1' ;
225
226             echo "$bfn:   $cmd ". ($ff->cli ? "\n" : "<BR>\n");
227
228             passthru($cmd);
229
230             if ($fn) {
231                 unlink($fn);
232             }
233         }
234
235               
236              
237         
238     }
239     
240     
241     /**
242      * mysql - does not support conversions.
243      * 
244      *
245      */
246     
247     
248     function importmysqldir($dburl, $dir)
249     {
250         
251         $this->fixMysqlInnodb(); /// run once 
252         
253         echo "Import MYSQL :: $dir\n";
254         
255         
256         require_once 'System.php';
257         $cat = System::which('cat');
258         $mysql = System::which('mysql');
259         
260        
261            
262         $mysql_cmd = $mysql .
263             ' -h ' . $dburl['host'] .
264             ' -u' . escapeshellarg($dburl['user']) .
265             (!empty($dburl['pass']) ? ' -p' . escapeshellarg($dburl['pass'])  :  '') .
266             ' ' . basename($dburl['path']);
267         //echo $mysql_cmd . "\n" ;
268         
269         $files = glob($dir.'/*.sql');
270         uksort($files, 'strcasecmp');
271         
272        
273         foreach($files as $fn) {
274                 
275                  
276                 if (preg_match('/migrate/i', basename($fn))) { // skip migration scripts at present..
277                     continue;
278                 }
279                 // .my.sql but not .pg.sql
280                 if (preg_match('#\.[a-z]{2}\.sql#i', basename($fn))
281                     && !preg_match('#\.my\.sql#i', basename($fn))
282                 ) { // skip migration scripts at present..
283                     continue;
284                 }
285                 if (!strlen(trim($fn))) {
286                     continue;
287                 }
288                 
289                 $cmd = "$mysql_cmd -f < " . escapeshellarg($fn) ;
290                 
291                 echo basename($dir).'/'. basename($fn) .    '::' .  $cmd. ($this->cli ? "\n" : "<BR>\n");
292                 
293                 passthru($cmd);
294             
295                 
296         }
297        
298         
299         
300     }
301     
302     
303     /**
304      * simple regex based convert mysql to pgsql...
305      */
306     function convertToPG($src)
307     {
308         //echo "Convert $src\n";
309                
310         $fn = $this->tempName('sql');
311         
312         $ret = array( ); // pad it a bit.
313         $extra = array("", "" );
314         
315         $tbl = false;
316         foreach(file($src) as $l) {
317             $l = trim($l);
318             
319             if (!strlen($l) || $l[0] == '#') {
320                 continue;
321             }
322             $m = array();
323             if (preg_match('#create\s+table\s+([a-z0-9_]+)#i',  $l, $m)) {
324                 $tbl = $m[1];
325              }
326             if (preg_match('#create\s+table\s+\`([a-z0-9_]+)\`#i',  $l, $m)) {
327                 $tbl = 'shop_' . strtolower($m[1]);
328                 $l = preg_replace('#create\s+table\s+\`([a-z0-9_]+)\`#i', "CREATE TABLE {$tbl}", $l);
329             }
330             if (preg_match('#\`([a-z0-9_]+)\`#i',  $l, $m) && !preg_match('#alter\s+table\s+#i',  $l)) {
331                 $l = preg_replace('#\`([a-z0-9_]+)\`#i', "{$m[1]}_name", $l);
332             }
333             // autoinc
334             if ($tbl && preg_match('#auto_increment#i',  $l, $m)) {
335                 $l = preg_replace('#auto_increment#i', "default nextval('{$tbl}_seq')", $l);
336                 $extra[]  =   "create sequence {$tbl}_seq;";
337               
338             }
339             
340             if (preg_match('#alter\s+table\s+(\`[a-z0-9_]+\`)#i',  $l, $m)){
341                 $l = preg_replace('#alter\s+table\s+(\`[a-z0-9_]+\`)#i', "ALTER TABLE {$tbl}", $l);
342             }
343             
344             // enum value -- use the text instead..
345             
346             if ($tbl && preg_match('#([\w]+)\s+(enum\([\w|\W]+\))#i',  $l, $m)) {
347                 $l = preg_replace('#enum\([\w|\W]+\)#i', "TEXT", $l);
348             }
349             // ignore the alter enum
350             if ($tbl && preg_match('#alter\s+table\s+([\w|\W]+)\s+enum\([\w|\W]+\)#i',  $l, $m)) {
351                 continue;
352             }
353             
354             // UNIQUE KEY .. ignore
355             if ($tbl && preg_match('#UNIQUE KEY#i',  $l, $m)) {
356                 $last = array_pop($ret);
357                 $ret[] = trim($last, ",");
358                 continue;
359             }
360             
361             if ($tbl && preg_match('#RENAME\s+TO#i',  $l, $m)) {
362                 continue;
363             }
364             
365             if ($tbl && preg_match('#change\s+column#i',  $l, $m)) {
366                 continue;
367             }
368             
369             // INDEX lookup ..ignore
370             if ($tbl && preg_match('#INDEX lookup+([\w|\W]+)#i',  $l, $m)) {
371                $last = array_pop($ret);
372                $ret[] = trim($last, ",");
373                continue;
374                
375             }
376             
377             // CREATE INDEX ..ignore
378             if (preg_match('#alter\s+table\s+([a-z0-9_]+)\s+add\s+index\s+#i',  $l, $m)) {
379 //               $l = "CREATE INDEX  {$m[1]}_{$m[2]} ON {$m[1]} {$m[3]}";
380                 continue;
381              }
382              
383             // basic types..
384             $l = preg_replace('#int\([0-9]+\)#i', 'INT', $l);
385             
386             $l = preg_replace('# datetime#i', ' TIMESTAMP WITHOUT TIME ZONE', $l);
387             $l = preg_replace('# blob#i', ' TEXT', $l);
388             $l = preg_replace('# longtext#i', ' TEXT', $l);
389             $l = preg_replace('# tinyint#i', ' INT', $l);
390             
391             $ret[] = $l;
392             
393         }
394         
395         $ret = array_merge($extra,$ret);
396 //        echo implode("\n", $ret); exit;
397         
398         file_put_contents($fn, implode("\n", $ret));
399         
400         return $fn;
401     }
402     
403     
404     function checkOpts($opts)
405     {
406         
407         
408         foreach($opts as $o=>$v) {
409             if (!preg_match('/^json-/', $o) || empty($v)) {
410                 continue;
411             }
412             if (!file_exists($v)) {
413                 die("File does not exist : OPTION --{$o} = {$v} \n");
414             }
415         }
416         
417         $modules = array_reverse($this->modulesList());
418         
419         // move 'project' one to the end...
420         
421         foreach ($modules as $module){
422             $file = $this->rootDir. "/Pman/$module/UpdateDatabase.php";
423             if($module == 'Core' || !file_exists($file)){
424                 continue;
425             }
426             require_once $file;
427             $class = "Pman_{$module}_UpdateDatabase";
428             $x = new $class;
429             if(!method_exists($x, 'checkOpts')){
430                 continue;
431             };
432             $x->checkOpts($opts);
433         }
434                 
435     }
436     static function jsonImportFromArray($opts)
437     {
438         foreach($opts as $o=>$v) {
439             if (!preg_match('/^json-/', $o) || empty($v)) {
440                 continue;
441             }
442             $type = str_replace('_', '-', substr($o,5));
443             
444             $data= json_decode(file_get_contents($v),true);
445             $pg = HTML_FlexyFramework::get()->page;
446             DB_DataObject::factory($type)->importFromArray($pg ,$data,$opts);
447             
448         }
449         
450         
451         
452     }
453     
454     
455     
456     function runUpdateModulesData()
457     {
458         HTML_FlexyFramework::get()->generateDataobjectsCache(true);
459         
460         if(!in_array('Core', $this->disabled)){
461             echo "Running jsonImportFromArray\n";
462             Pman_Core_UpdateDatabase::jsonImportFromArray($this->opts);
463
464
465             echo "Running updateData on modules\n";
466             // runs core...
467             echo "Core\n";
468             $this->updateData(); 
469         }
470         
471         $modules = array_reverse($this->modulesList());
472         
473         // move 'project' one to the end...
474         
475         foreach ($modules as $module){
476             if(in_array($module, $this->disabled)){
477                 continue;
478             }
479             $file = $this->rootDir. "/Pman/$module/UpdateDatabase.php";
480             if($module == 'Core' || !file_exists($file)){
481                 continue;
482             }
483             
484             require_once $file;
485             $class = "Pman_{$module}_UpdateDatabase";
486             $x = new $class;
487             if(!method_exists($x, 'updateData')){
488                 continue;
489             };
490             echo "$module\n";
491             $x->updateData();
492         }
493                 
494     }
495     
496     
497     function updateDataEnums()
498     {
499         
500         $enum = DB_DataObject::Factory('core_enum');
501         //DB_DAtaObject::debugLevel(1);
502         $enum->initEnums(
503             array(
504                 array(
505                     'etype' => '',
506                     'name' => 'COMPTYPE',
507                     'display_name' =>  'Company Types',
508                     'is_system_enum' => 1,
509                     'cn' => array(
510                         array(
511                             'name' => 'OWNER',
512                             'display_name' => 'Owner',
513                             'seqid' => 999, // last...
514                             'is_system_enum' => 1,
515                         )
516                         
517                     )
518                 ),
519                 array(
520                     'etype' => '',
521                     'name' => 'HtmlEditor.font-family',
522                     'display_name' =>  'HTML Editor font families',
523                     'is_system_enum' => 1,
524                     'cn' => array(
525                         array(
526                             'name' => 'Helvetica,Arial,sans-serif',
527                             'display_name' => 'Helvetica',
528                             
529                         ),
530                         
531                         array(
532                             'name' => 'Courier New',
533                             'display_name' => 'Courier',
534                              
535                         ),
536                         array(
537                             'name' => 'Tahoma',
538                             'display_name' => 'Tahoma',
539                             
540                         ),
541                         array(
542                             'name' => 'Times New Roman,serif',
543                             'display_name' => 'Times',
544                            
545                         ),
546                         array(
547                             'name' => 'Verdana',
548                             'display_name' => 'Verdana',
549                             
550                         ),
551                         
552                             
553                         
554                     )
555                 ),
556             )
557         ); 
558         
559     }
560     function updateDataGroups()
561     {
562          
563         $groups = DB_DataObject::factory('groups');
564         $groups->initGroups();
565         
566         $groups->initDatabase($this,array(
567             array(
568                 'name' => 'bcc-email', // group who are bcc'ed on all requests.
569                 'type' => 0, // system
570             ),
571             array(
572                 'name' => 'system-email-from',
573                 'type' => 0, // system
574             ),
575             array(
576                 'name' => 'core-person-signup-bcc',
577                 'type' => 0, // system
578             ),
579         ));
580         
581     }
582     
583     function updateDataCompanies()
584     {
585          
586         // fix comptypes enums..
587         $c = DB_DataObject::Factory('Companies');
588         $c->selectAdd();
589         $c->selectAdd('distinct(comptype) as comptype');
590         $c->whereAdd("comptype != ''");
591         
592         $ctb = array();
593         foreach($c->fetchAll('comptype') as $cts) {
594             
595             
596             
597            $ctb[]= array( 'etype'=>'COMPTYPE', 'name' => $cts, 'display_name' => ucfirst(strtolower($cts)));
598         
599         }
600          $c = DB_DataObject::Factory('core_enum');
601          
602         $c->initEnums($ctb);
603         //DB_DataObject::debugLevel(1);
604         // fix comptypeid
605         $c = DB_DataObject::Factory('Companies');
606         $c->query("
607             UPDATE Companies 
608                 SET
609                     comptype_id = (SELECT id FROM core_enum where etype='comptype' and name=Companies.comptype LIMIT 1)
610                 WHERE
611                     comptype_id = 0
612                     AND
613                     LENGTH(comptype) > 0
614                   
615                   
616                   ");
617          
618         
619         
620     }
621     
622     
623     function initEmails($templateDir, $emails)
624     {
625       
626         $pg = HTML_FlexyFramework::get()->page;
627         foreach($emails as $name=>$data) {
628             $cm = DB_DataObject::factory('core_email');
629             $update = $cm->get('name', $name);
630             $old = clone($cm);
631             
632             if (empty($cm->bcc_group)) {
633                 if (empty($data['bcc_group'])) {
634                     $this->jerr("missing bcc_group for template $name");
635                 }
636                 $g = DB_DataObject::Factory('Groups')->lookup('name',$data['bcc_group']);
637                 
638                 if (!$g) {
639                     $this->jerr("bcc_group {$data['bcc_group']} does not exist when importing template $name");
640                 }
641                 if (!$g->members('email')) {
642                       $this->jerr("bcc_group {$data['bcc_group']} does not have any members");
643                 }
644                 
645                 
646                 $cm->bcc_group = $g->id;
647             }
648             if (empty($cm->test_class)) {
649                 if (empty($data['test_class'])) {
650                     $this->jerr("missing test_class for template $name");
651                 }
652                 $cm->test_class = $data['test_class'];
653             }
654             require_once $cm->test_class . '.php';
655             
656             $clsname = str_replace('/','_', $cm->test_class);
657             try {
658                 $method = new ReflectionMethod($clsname , 'test_'. $name) ;
659                 $got_it = $method->isStatic();
660             } catch(Exception $e) {
661                 $got_it = false;
662                 
663             }
664             if (!$got_it) {
665                 $this->jerr("template {$name} does not have a test method {$clsname}::test_{$name}");
666             }
667             if ($update) {
668                 $cm->update($old);
669                 echo "email: {$name} - checked\n";
670                 continue; /// we do not import the body content of templates that exist...
671             } else {
672                 $cm->insert();
673             }
674             
675             
676     //        $basedir = $this->bootLoader->rootDir . $mail_template_dir;
677             
678             $opts = array(
679                 'update' => 1,
680                 'file' => $templateDir. $name .'.html'
681             );
682             
683             if (!empty($data['master'])) {
684                 $opts['master'] = $templateDir . $master .'.html';
685             }
686             require_once 'Pman/Core/Import/Core_email.php';
687             $x = new Pman_Core_Import_Core_email();
688             $x->get('', $opts);
689             
690             echo "email: {$name} - CREATED\n";
691         }
692     }
693     
694     
695     function updateData()
696     {
697         // fill i18n data..
698         HTML_FlexyFramework::get()->generateDataobjectsCache(true);
699         $this->updateDataEnums();
700         $this->updateDataGroups();
701         $this->updateDataCompanies();
702         
703         $c = DB_DataObject::Factory('I18n');
704         $c->buildDB();
705          
706        
707         
708         
709     }
710     
711     function fixMysqlInnodb()
712     {
713         
714         static $done_check = false;
715         if ($done_check) {
716             return;
717         }
718         // innodb in single files is far more efficient that MYD or one big innodb file.
719         // first check if database is using this format.
720         $db = DB_DataObject::factory('core_enum');
721         $db->query("show variables like 'innodb_file_per_table'");
722         $db->fetch();
723         if ($db->Value == 'OFF') {
724             die("Error: set innodb_file_per_table = 1 in my.cnf\n\n");
725         }
726         
727         $done_check = true;;
728
729  
730         
731         
732         
733         
734         
735     }
736     
737     
738     /** ------------- schema fixing ... there is an issue with data imported having the wrong sequence names... --- */
739     
740     function fixSequencesMysql()
741     {
742         // not required...
743     }
744     
745     function fixSequencesPgsql()
746     {
747      
748      
749         //DB_DataObject::debugLevel(1);
750         $cs = DB_DataObject::factory('core_enum');
751         $cs->query("
752          SELECT
753                     'ALTER SEQUENCE '||
754                     CASE WHEN strpos(seq_name, '.') > 0 THEN
755                         min(seq_name)
756                     ELSE 
757                         quote_ident(min(schema_name)) ||'.'|| quote_ident(min(seq_name))
758                     END 
759                     
760                     ||' OWNED BY '|| quote_ident(min(schema_name)) || '.' ||
761                     quote_ident(min(table_name)) ||'.'|| quote_ident(min(column_name)) ||';' as cmd
762              FROM (
763                       
764                        SELECT 
765                      n.nspname AS schema_name,
766                      c.relname AS table_name,
767                      a.attname AS column_name, 
768                      regexp_replace(regexp_replace(d.adsrc, E'nextval\\\\(+[''\\\"]*', ''),E'[''\\\"]*::.*\$','') AS seq_name 
769                  FROM pg_class c 
770                  JOIN pg_attribute a ON (c.oid=a.attrelid) 
771                  JOIN pg_attrdef d ON (a.attrelid=d.adrelid AND a.attnum=d.adnum) 
772                  JOIN pg_namespace n ON (c.relnamespace=n.oid)
773                  WHERE has_schema_privilege(n.oid,'USAGE')
774                    AND n.nspname NOT LIKE 'pg!_%' escape '!'
775                    AND has_table_privilege(c.oid,'SELECT')
776                    AND (NOT a.attisdropped)
777                    AND d.adsrc ~ '^nextval'
778               
779              ) seq
780              WHERE
781                  CASE WHEN strpos(seq_name, '.') > 0 THEN
782                      substring(seq_name, 1,strpos(seq_name,'.')-1)
783                 ELSE
784                     schema_name
785                 END = schema_name
786              
787              GROUP BY seq_name HAVING count(*)=1
788              ");
789         $cmds = array();
790         while ($cs->fetch()) {
791             $cmds[] = $cs->cmd;
792         }
793         foreach($cmds as $cmd) {
794             $cs = DB_DataObject::factory('core_enum');
795             echo "$cmd\n";
796             $cs->query($cmd);
797         }
798         $cs = DB_DataObject::factory('core_enum');
799          $cs->query("
800                SELECT  'SELECT SETVAL(' ||
801                          quote_literal(quote_ident(nspname) || '.' || quote_ident(S.relname)) ||
802                         ', MAX(' || quote_ident(C.attname)|| ')::integer )  FROM ' || nspname || '.' || quote_ident(T.relname)|| ';' as cmd 
803                 FROM pg_class AS S,
804                     pg_depend AS D,
805                     pg_class AS T,
806                     pg_attribute AS C,
807                     pg_namespace AS NS
808                 WHERE S.relkind = 'S'
809                     AND S.oid = D.objid
810                     AND D.refobjid = T.oid
811                     AND D.refobjid = C.attrelid
812                     AND D.refobjsubid = C.attnum
813                     AND NS.oid = T.relnamespace
814                 ORDER BY S.relname   
815         ");
816          $cmds = array();
817         while ($cs->fetch()) {
818             $cmds[] = $cs->cmd;
819         }
820         foreach($cmds as $cmd) {
821             $cs = DB_DataObject::factory('core_enum');
822             echo "$cmd\n";
823             $cs->query($cmd);
824         }
825        
826     }
827     
828     var $extensions = array(
829         'EngineCharset',
830         'Links',
831     );
832     
833     function runExtensions()
834     {
835         
836         $ff = HTML_Flexyframework::get();
837         
838         $dburl = parse_url($ff->DB_DataObject['database']);
839         
840         $dbtype = $dburl['scheme'];
841        
842         foreach($this->extensions as $ext) {
843        
844             $scls = ucfirst($dbtype). $ext;
845             $cls = __CLASS__ . '_'. $scls;
846             $fn = implode('/',explode('_', $cls)).'.php';
847             if (!file_exists(__DIR__.'/UpdateDatabase/'. $scls .'.php')) {
848                 return;
849             }
850             require_once $fn;
851             $c = new $cls();
852             
853         }
854         
855     }
856     
857     
858     function checkSystem()
859     {
860         // most of these are from File_Convert...
861         
862         // these are required - and have simple dependancies.
863         require_once 'System.php';
864         $req = array( 
865             'convert',
866             'grep',
867             'pdfinfo',
868             'pdftoppm',
869             'rsvg-convert',  //librsvg2-bin
870             'strings',
871         );
872          
873          
874          
875         // these are prefered - but may have complicated depenacies
876         $pref= array(
877             'abiword',
878             'faad',
879             'ffmpeg',
880             'html2text', // not availabe in debian squeeze
881             'pdftocairo',  //poppler-utils - not available in debian squeeze.
882
883             'lame',
884             'ssconvert',
885             'unoconv',
886             'wkhtmltopdf',
887             'xvfb-run',
888         );
889         $res = array();
890         $fail = false;
891         foreach($req as $r) {
892             if (!System::which($r)) {
893                 $res[] = $r;
894             }
895             $fail = true;
896         }
897         if ($res) {
898             $this->jerr("Missing these programs - need installing\n" . implode("\n",$res));
899         }
900         foreach($pref as $r) {
901             if (!System::which($r)) {
902                 $res[] = $r;
903             }
904             $fail = true;
905         }
906         if ($res) {
907             echo "WARNING: Missing these programs - they may need installing\n". implode("\n",$res);
908             sleep(5);
909         }
910         
911         
912     }
913     
914     
915 }