[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