[Solar-svn] Revision 2583

pmjones at solarphp.com pmjones at solarphp.com
Tue Jul 10 15:59:08 CDT 2007


Solar_Controller_Command
--------------------------------------

[NEW] This is the page-controller equivalent for the command line, a single command that can be invoked.  Based on work originally from Clay in Sungrazr_Controller_Console and Sungrazr_ConsoleApp, then significantly refactored.


Added: trunk/Solar/Controller/Command/Exception.php
===================================================================
--- trunk/Solar/Controller/Command/Exception.php	                        (rev 0)
+++ trunk/Solar/Controller/Command/Exception.php	2007-07-10 20:59:08 UTC (rev 2583)
@@ -0,0 +1,27 @@
+<?php
+/**
+ * 
+ * Command controller exception.
+ * 
+ * @category Solar
+ * 
+ * @package Solar_Controller
+ * 
+ * @author Paul M. Jones <pmjones at solarphp.com>
+ * 
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * 
+ * @version $Id: Exception.php 2440 2007-04-21 14:33:44Z pmjones $
+ * 
+ */
+
+/**
+ * 
+ * Command controller exception.
+ * 
+ * @category Solar
+ * 
+ * @package Solar_Controller
+ * 
+ */
+class Solar_Controller_Command_Exception extends Solar_Controller_Exception {}

Added: trunk/Solar/Controller/Command.php
===================================================================
--- trunk/Solar/Controller/Command.php	                        (rev 0)
+++ trunk/Solar/Controller/Command.php	2007-07-10 20:59:08 UTC (rev 2583)
@@ -0,0 +1,401 @@
+<?php
+/**
+ * 
+ * The CLI equivalent of a page-controller; a single command to be invoked from
+ * the command-line.
+ * 
+ * @category Solar
+ * 
+ * @package Solar_Controller
+ * 
+ * @author Clay Loveless <clay at killersoft.com>
+ * 
+ * @author Paul M. Jones <pmjones at solarphp.com>
+ * 
+ * @license http://opensource.org/licenses/bsd-license.php BSD
+ * 
+ * @version $Id$
+ * 
+ */
+
+/**
+ * 
+ * The CLI equivalent of a page-controller; a single command to be invoked from
+ * the command-line.
+ * 
+ * @category Solar
+ * 
+ * @package Solar_Controller
+ * 
+ */
+class Solar_Controller_Command extends Solar_Base {
+    
+    /**
+     * 
+     * Array of format conversions for use on a variety of pre-set console
+     * style combinations.
+     * 
+     * Based on ANSI VT100 Color/Style Codes, according to the VT100 
+     * User Guide[1] and the ANSI/VT100 Terminal Control[2] reference.
+     * 
+     * [1]: http://vt100.net/docs/vt100-ug
+     * [2]: http://www.termsys.demon.co.uk/vtansi.htm
+     * 
+     * @var array
+     * 
+     */
+    protected $_vt100 = array(
+        // color, normal weight
+        '%k'    => "\033[30m",      // black
+        '%r'    => "\033[31m",      // red
+        '%g'    => "\033[32m",      // green
+        '%y'    => "\033[33m",      // yellow
+        '%b'    => "\033[34m",      // blue
+        '%m'    => "\033[35m",      // magenta/purple
+        '%p'    => "\033[35m",      // magenta/purple
+        '%c'    => "\033[36m",      // cyan/light blue
+        '%w'    => "\033[37m",      // white
+        '%n'    => "\033[0m",       // reset to terminal default
+        // color, bold
+        '%K'    => "\033[30;1m",    // black, bold
+        '%R'    => "\033[31;1m",    // red, bold
+        '%G'    => "\033[32;1m",    // green, bold
+        '%Y'    => "\033[33;1m",    // yellow, bold
+        '%B'    => "\033[34;1m",    // blue, bold
+        '%M'    => "\033[35;1m",    // magenta/purple, bold
+        '%P'    => "\033[35;1m",    // magenta/purple, bold
+        '%C'    => "\033[36;1m",    // cyan/light blue, bold
+        '%W'    => "\033[37;1m",    // white, bold
+        '%N'    => "\033[0;1m",     // terminal default, bold
+        // background color
+        '%0'    => "\033[40m",      // black background
+        '%1'    => "\033[41m",      // red background
+        '%2'    => "\033[42m",      // green background
+        '%3'    => "\033[43m",      // yellow background
+        '%4'    => "\033[44m",      // blue background
+        '%5'    => "\033[45m",      // magenta/purple background
+        '%6'    => "\033[46m",      // cyan/light blue background
+        '%7'    => "\033[47m",      // white background
+        // assorted style shortcuts
+        '%F'    => "\033[5m",       // blink/flash
+        '%_'    => "\033[5m",       // blink/flash
+        '%U'    => "\033[4m",       // underline
+        '%I'    => "\033[7m",       // reverse/inverse
+        '%*'    => "\033[1m",       // bold
+        '%d'    => "\033[2m",       // dim        
+    );
+    
+    /**
+     * 
+     * Option flags and values extracted from the command-line arguments.
+     * 
+     * @var array
+     * 
+     */
+    protected $_options = array();
+    
+    /**
+     * 
+     * A Solar_Getopt object to manage options and parameters.
+     * 
+     * @var Solar_Getopt
+     * 
+     */
+    protected $_getopt;
+    
+    /**
+     * 
+     * The Solar_Controller_Console object (if any) that invoked this command.
+     * 
+     * @var Solar_Controller_Console
+     * 
+     */
+    protected $_console;
+    
+    /**
+     * 
+     * Constructor.
+     * 
+     * @param array $config User-defined configuration values.
+     * 
+     */
+    public function __construct($config = null)
+    {
+        parent::__construct($config);
+        
+        // set the recognized options
+        $options = $this->_getOptionSettings();
+        $this->_getopt = Solar::factory('Solar_Getopt');
+        $this->_getopt->setOptions($options);
+        
+        // follow-on setup
+        $this->_setup();
+    }
+    
+    /**
+     * 
+     * Injects the console-controller object (if any) that invoked this command.
+     * 
+     * @param Solar_Controller_Console $console The console controller.
+     * 
+     * @return void
+     * 
+     */
+    public function setConsoleController($console)
+    {
+        $this->_console = $console;
+    }
+    
+    /**
+     * 
+     * Public interface to execute the command.
+     * 
+     * This method...
+     * 
+     * - populates and validates the option values
+     * - calls _preExec()
+     * - calls _exec() with the numeric parameters from the options
+     * - calls _postExec()
+     * 
+     * @param array $argv The command-line arguments from the user.
+     * 
+     * @return void
+     * 
+     * @todo Accept a Getopt object in addition to $argv array?
+     * 
+     */
+    public function exec($argv = null)
+    {
+        // get the command-line arguments
+        if ($argv === null) {
+            // use the $_SERVER values
+            $argv = $this->_request->server['argv'];
+            // remove the argument pointing to this command
+            array_shift($argv);
+        } else {
+            $argv = (array) $argv;
+        }
+        
+        // set options, populate values, and validate parameters
+        $this->_getopt->populate($argv);
+        if (! $this->_getopt->validate()) {
+            // need a better way to throw exceptions with specific error
+            // messages
+            throw $this->_exception(
+                'ERR_INVALID_OPTIONS',
+                $this->_getopt->getInvalid()
+            );
+        }
+        
+        // retain the option values, minus the numeric params
+        $this->_options = $this->_getopt->values();
+        $params = array();
+        foreach ($this->_options as $key => $val) {
+            if (is_int($key)) {
+                $params[] = $val;
+                unset($this->_options[$key]);
+            }
+        }
+        
+        // call pre-exec
+        $skip_exec = $this->_preExec();
+        
+        // should we skip the main execution?
+        if ($skip_exec !== true) {
+            // call _exec() with the numeric params from getopt
+            call_user_func_array(
+                array($this, '_exec'),
+                $params
+            );
+        }
+        
+        // call post-exec, and we're done
+        $this->_postExec();
+    }
+    
+    /**
+     * 
+     * Returns an array of option flags and descriptions for this command.
+     * 
+     * @return array An associative array where the key is the short + long
+     * option forms, and the value is the description for the option.
+     * 
+     */
+    public function getInfoOptions()
+    {
+        $options = array();
+        foreach ($this->_getopt->options as $name => $info) {
+            
+            $key = null;
+            
+            if ($info['short']) {
+                $key .= "-" . $info['short'];
+            }
+            
+            if ($key && $info['long']) {
+                $key .= " | --" . $info['long'];
+            } else {
+                $key .= "--" . $info['long'];
+            }
+            
+            $options[$key] = $info['descr'];
+        }
+        
+        ksort($options);
+        return $options;
+    }
+    
+    /**
+     * 
+     * Returns the help text for this command.
+     * 
+     * @return string The contents of "Info/help.txt" for this class, or null
+     * if the file does not exist.
+     * 
+     */
+    public function getInfoHelp()
+    {
+        // what would its help file be named?
+        $class = get_class($this);
+        $file = str_replace('_', DIRECTORY_SEPARATOR, $class)
+              . DIRECTORY_SEPARATOR . 'Info'
+              . DIRECTORY_SEPARATOR . 'help.txt';
+        
+        // does that file exist?
+        $file = Solar::fileExists($file);
+        if ($file) {
+            return file_get_contents($file);
+        }
+    }
+    
+    /**
+     * 
+     * Gets the option settings from the class hierarchy.
+     * 
+     * @return array
+     * 
+     */
+    protected function _getOptionSettings()
+    {
+        // the options to be set
+        $options = array();
+        
+        // find the parents of this class, including this class
+        $parents = array_reverse(Solar::parents(get_class($this), true));
+        array_shift($parents);
+        array_shift($parents);
+        
+        // get options.php for each parent class, as well as this class
+        foreach ($parents as $class) {
+            
+            $file  = str_replace('_', DIRECTORY_SEPARATOR, $class)
+                    . DIRECTORY_SEPARATOR . 'Info'
+                    . DIRECTORY_SEPARATOR . 'options.php';
+            
+            $file  = Solar::fileExists($file);
+            
+            if ($file) {
+                $options = array_merge(
+                    $options, 
+                    (array) include $file
+                );
+            }
+        }
+        
+        return $options;
+    }
+    
+    /**
+     * 
+     * Prints text to STDOUT **without** a trailing newline.
+     * 
+     * If the text is a locale key, that text will be used instead.
+     * 
+     * Automatically replaces style-format codes for shell output.
+     * 
+     * @param string $text The text to print to STDOUT.
+     * 
+     * @return void
+     * 
+     */
+    protected function _print($text = null, $num = 1, $replace = null)
+    {
+        static $vt100_keys;
+        if (! $vt100_keys) {
+            $vt100_keys = array_keys($this->_vt100);
+        }
+        
+        static $vt100_vals;
+        if (! $vt100_vals) {
+            $vt100_vals = array_values($this->_vt100);
+        }
+        
+        echo str_replace(
+            $vt100_keys,
+            $vt100_vals,
+            $this->locale($text, $num, $replace)
+        );
+    }
+    
+    /**
+     * 
+     * Prints text to STDOUT and appends a newline.
+     * 
+     * If the text is a locale key, that text will be used instead.
+     * 
+     * Automatically replaces style-format codes for shell output.
+     * 
+     * @param string $text The text to print to STDOUT.
+     * 
+     * @return void
+     * 
+     */
+    protected function _println($text = null, $num = 1, $replace = null)
+    {
+        echo $this->_print($text, $num, $replace) . "\n";
+    }
+    
+    /**
+     * 
+     * Post-construction setup logic.
+     * 
+     * @return void
+     * 
+     */
+    protected function _setup()
+    {
+    }
+    
+    /**
+     * 
+     * Runs just before the main _exec() method.
+     * 
+     * @return bool True to skip _exec(), null otherwise.
+     * 
+     */
+    protected function _preExec()
+    {
+    }
+    
+    /**
+     * 
+     * The main command method.
+     * 
+     * @return void
+     * 
+     */
+    protected function _exec()
+    {
+    }
+    
+    /**
+     * 
+     * Runs just after the main _exec() method.
+     * 
+     * @return void
+     * 
+     */
+    protected function _postExec()
+    {
+    }
+}
\ No newline at end of file




More information about the Solar-svn mailing list