enble generator to be used without framework
[pear] / HTML / FlexyFramework / Cli.php
index 7ac7340..3d6c4f6 100644 (file)
 <?php
 
-
+/**
+ *
+ * handles the cli features of Flexy Framework.
+ *
+ *
+ * usage :
+ *
+ *   $x = new HTML_FlexyFramework_Cli($ff);
+ *   $x->cliHelp(); // summary of all classes which can be run with cli.
+ *             (contain static $cli_desc)
+ *   $x->cliParse($classname);
+ *
+ *
+ */
 class HTML_FlexyFramework_Cli
 {
     
-    function help()
+    /**
+     * Default options that allow modification of the framewoek behaviour
+     * 
+     *
+     */
+    
+      
+    static $cli_opts = array(
+        
+        // this is a flag argument
+        'pman-nodatabase' => array(
+            'desc' => 'Turn off database',
+            'max' => 0,
+        )
+         
+    );
+    
+    
+    
+    
+    
+    
+    
+    var $ff; // the Framework instance.
+    
+    
+    function __construct($ff)
+    {
+        $this->ff = $ff;
+    }
+    /**
+      * looks for Cli.php files and runs available() on them
+     * this should return a list of classes that can be used.
+     * - we should the load each one, and find the summary..
+     *
+     *
+     */
+    function cliHelp()
+    {
+     
+        $fn = basename($_SERVER["SCRIPT_FILENAME"]);
+      
+        echo "\n-------------------------------------------------
+FlexyFramework Cli Application Usage:
+
+#php -d include_path=.:/var/www/pear $fn [COMMAND] --help
+or
+#php  $fn [COMMAND] --help
+
+-------------------------------------------------
+Available commands:
+
+";
+        // add cli files..
+        //$this->cliShortHelp('Database');
+        
+        
+        $p = dirname(realpath($_SERVER["SCRIPT_FILENAME"])); 
+        $pr = $this->ff->project;
+        
+        $this->cliHelpSearch($p,$pr);
+        if (!empty($this->ff->projectExtends)) {
+            foreach($this->ff->projectExtends as $pr) {
+                $this->cliHelpSearch($p,$pr);
+            }
+        }
+        
+        echo "\n\n";
+        exit;
+    }
+    
+    
+    function cliHelpSearch($p,$pr, $path=false) {
+        
+        
+        
+        $full_path = array($p,$pr);
+        $class_path = array();
+        if ($path !== false)  {
+            $full_path= array_merge($full_path, $path);
+            $class_path = array_merge($class_path, $path);
+        }
+        //print_r("CHKDIR:    ". implode('/', $full_path)."\n");
+        
+        foreach(scandir(implode('/', $full_path)) as $d) {
+            
+            if (!strlen($d) || $d[0] == '.') {
+                continue;
+            }
+            $chk = $full_path;
+            $chk[] = $d;
+            
+            $clp = $class_path;
+            
+            
+            
+            //print_r("CHK:          " . implode('/', $chk)."\n");
+            // is it a file.. and .PHP...
+            if (!is_dir(implode('/', $chk))) {
+                if (!preg_match('/\.php$/',$d)) {
+                    continue;
+                }
+                $clp[] = preg_replace('/\.php$/','', $d);
+                
+                //print_r("CLP:          " . implode('/', $clp)."\n");
+                $this->cliShortHelp(implode('/', $clp ));
+                continue;
+            }
+            // skip special directories..
+            if ($d == 'templates') {
+                continue;
+            }
+            if ($d == 'DataObjects') {
+                continue;
+            }
+            
+            
+            $clp[] = $d;
+            // otherwise recurse...
+            //print_r("RECURSE:        " . implode('/', $clp)."\n");
+            
+            $this->cliHelpSearch($p,$pr, $clp);
+            
+            
+        }
+        
+        //print_r("COMPLETE:    ". implode('/', $full_path)."\n");
+        
+        
+        
+        
+    }
+    
+    
+    
+    
+    /**
+     * creates an instance of all the CLI classes and prints out class + title..
+     *
+     */
+    function cliShortHelp($p) { 
+        ////print_r("CHKFILE:         $p\n ");
+        list($classname,$subRequest) = $this->ff->requestToClassName($p,FALSE);
+        //var_dump($classname);
+        // does it have a description.
+        try { 
+            $cls = new ReflectionClass($classname);        
+            $val = $cls->getStaticPropertyValue('cli_desc');
+        } catch (Exception $e) {
+            return;
+        }
+        if (empty($val)) {
+            return;
+        }
+        echo str_pad($p,40," ") . $val ."\n";
+        
+        
+         
+    }
+     
+    /**
+    * cliParse - parse command line arguments, and return the values.
+    *  Will die with help message if --help or error is found..
+    * 
+    * @param {String} $classname name of class - should be loaded..
+    * @return {Array|false} array of key=>value arguments.. or false if not parsed
+    * 
+    */
+    function cliParse($classname)
     {
+    
+    // cli static $classname::$cli_opts
+    
+        try {
+            // look up the parent tree for core opts.
+            $val = array();
+            //var_dump($classname);
+            $cls = new ReflectionClass($classname);
+            if (method_exists($classname, 'cli_opts')) {
+                $val = $classname::cli_opts();
+            } else {
+                $ar = $cls->getStaticProperties();
+                 if (isset($ar['cli_opts'])) {
+                    //echo "getting cli opts?\n";
+                    $val = $cls->getStaticPropertyValue('cli_opts');
+                }
+            }
+             
+            $val = is_array($val) ? $val : array();
+            while ($cls = $cls->getParentClass()) {
+                //var_dump($cls->name);
+                 
+                try {
+                    $vadd  = array();
+                    if (method_exists($cls->name, 'cli_opts')) {
+                        $cn = $cls->name;
+                        $vadd = $cn::cli_opts();
+                    } else {
+                        $ar = $cls->getStaticProperties();
+                        if (isset($ar['cli_opts'])) {
+                            $vadd = $cls->getStaticPropertyValue('cli_opts');
+                        }
+                         
+                    }
+                    $val = array_merge($val, is_array($vadd) ? $vadd : array()  );
+                } catch (ReflectionException $e) {
+                    continue;
+                }
+            }
+            
+            
+            
+        } catch (ReflectionException $e) {
+            //print_r($e);
+            echo "cliParse:Warning:  {$e->getMessage()}\n";
+            exit;
+        }
+        if (empty($val)) {
+            return false;
+        }
+        
+        $val = array_merge(self::$cli_opts, $val);
+        
+        
+        require_once 'Console/Getargs.php';
+        $ar = $_SERVER['argv'];
+        $call = array(array_shift($ar)); // remove index.php
+        $call[] = array_shift($ar); // remove our class...
+        //var_dump($ar);
+        
+        $newargs = Console_Getargs::factory($val, $ar);
+        
+  
+        if (!is_a($newargs, 'PEAR_Error')) {
+            return $newargs->getValues();
+        }
+        
+        list($optional, $required, $params) = Console_Getargs::getOptionalRequired($val);
+        
+        $helpHeader = 'Usage: php ' . implode (' ', $call) . ' '. 
+              $optional . ' ' . $required . ' ' . $params . "\n\n";           
+        
+        
+        if ($newargs->getCode() === CONSOLE_GETARGS_ERROR_USER) {
+            // User put illegal values on the command line.
+            echo Console_Getargs::getHelp($val,
+                    $helpHeader, "\n\n".$newargs->getMessage(), 78, 4)."\n\n";
+            exit;
+        }
+        if ($newargs->getCode() === CONSOLE_GETARGS_HELP) {
+            // User needs help.
+            echo Console_Getargs::getHelp($val,
+                    $helpHeader, NULL, 78, 4)."\n\n";
+            exit;
+        }
         
+        die($newargs->getMessage()); 
+        
+            
     }
     
+    
+    
+    /**
+     * the framework can be run without a database even if it's configured.
+     * to support this, we need to handle things like
+     *  --pman-nodatabase=1 on the command line.
+     *
+     *  
+     * @returns   array() - args, false - nothing matched / invalid, true = help! 
+     *
+     */
+    
+    function parseDefaultOpts()
+    {
+        require_once 'Console/Getargs.php';
+        $ar = $_SERVER['argv'];
+        $call = array(array_shift($ar)); // remove index.php
+        $has_class = false;
+        if (isset($ar[0]) && $ar[0][0] != '-') {
+            $call[] = array_shift($ar); // remove our class...
+            $has_class = true;
+        }  
+        $val = self::$cli_opts;
+        
+        $newargs = Console_Getargs::factory($val, $ar);
+        
+        // we need to read our 'special arguments' here - otherwise other arguments, cause getargs to fail
+        switch (true) {
+            case in_array('--pman-nodatabase', $ar):
+                echo "Turning off database\n";
+                $this->ff->nodatabase= true;
+                    
+                break;
+             
+        }
+        
+        
+        
+        if (!is_a($newargs, 'PEAR_Error')) {
+            return false;
+        }
+        list($optional, $required, $params) = Console_Getargs::getOptionalRequired($val);
+    
+        $helpHeader = 'Usage: php ' . implode (' ', $call) . ' '. 
+            $optional . ' ' . $required . ' ' . $params . "\n\n";           
+   
+        if ($newargs->getCode() === CONSOLE_GETARGS_ERROR_USER) {
+            // since we do not handle all the arguemnts here...
+            // skip errors if we find unknown arguments.
+            if (preg_match('/^Unknown argument/', $newargs->getMessage())) {
+                return false;
+            }
+            
+            // User put illegal values on the command line.
+            echo Console_Getargs::getHelp($val,
+                    $helpHeader, "\n\n".$newargs->getMessage(), 78, 4)."\n\n";
+            exit;
+        }
+        if ($newargs->getCode() === CONSOLE_GETARGS_HELP) {
+            if (!$has_class) {
+                
+                echo Console_Getargs::getHelp($val,
+                        $helpHeader, NULL, 78, 4)."\n\n";
+                exit;
+            }
+            return true;// help is handled later in the flow?
+        }
+        
+        return false;
+     
+        
+    }
+    
+    
+    
 }