From a9b02d4e2ec87b6342028204f8915470447e294c Mon Sep 17 00:00:00 2001 From: Qiang Xue Date: Fri, 11 May 2012 22:03:30 -0400 Subject: [PATCH] ... --- framework/console/Command.php | 279 -------------------------- framework/console/Controller.php | 279 ++++++++++++++++++++++++++ framework/console/commands/HelpController.php | 9 +- 3 files changed, 286 insertions(+), 281 deletions(-) delete mode 100644 framework/console/Command.php create mode 100644 framework/console/Controller.php diff --git a/framework/console/Command.php b/framework/console/Command.php deleted file mode 100644 index cd4f746..0000000 --- a/framework/console/Command.php +++ /dev/null @@ -1,279 +0,0 @@ - - * yiic CommandName ActionName --Option1=Value1 --Option2=Value2 ... - * - * - * Child classes mainly needs to implement various action methods whose name must be - * prefixed with "action". The parameters to an action method are considered as options - * for that specific action. The action specified as {@link defaultAction} will be invoked - * when a user does not specify the action name in his command. - * - * Options are bound to action parameters via parameter names. For example, the following - * action method will allow us to run a command with yiic sitemap --type=News: - *
- * class SitemapCommand {
- *     public function actionIndex($type) {
- *         ....
- *     }
- * }
- * 
- * - * @property string $name The command name. - * @property CommandRunner $commandRunner The command runner instance. - * @property string $help The command description. Defaults to 'Usage: php entry-script.php command-name'. - * @property array $optionHelp The command option help information. Each array element describes - * the help information for a single action. - * - * @author Qiang Xue - * @since 2.0 - */ -class Command extends \yii\base\Controller -{ - /** - * Executes the command. - * The default implementation will parse the input parameters and - * dispatch the command request to an appropriate action with the corresponding - * option values - * @param array $args command line parameters for this command. - */ - public function run($args) - { - list($action, $options, $args) = $this->resolveRequest($args); - $methodName = 'action' . $action; - if (!preg_match('/^\w+$/', $action) || !method_exists($this, $methodName)) - { - $this->usageError("Unknown action: " . $action); - } - - $method = new \ReflectionMethod($this, $methodName); - $params = array(); - // named and unnamed options - foreach ($method->getParameters() as $param) { - $name = $param->getName(); - if (isset($options[$name])) { - if ($param->isArray()) - $params[] = is_array($options[$name]) ? $options[$name] : array($options[$name]); - else if (!is_array($options[$name])) - $params[] = $options[$name]; - else - $this->usageError("Option --$name requires a scalar. Array is given."); - } else if ($name === 'args') - $params[] = $args; - else if ($param->isDefaultValueAvailable()) - $params[] = $param->getDefaultValue(); - else - $this->usageError("Missing required option --$name."); - unset($options[$name]); - } - - // try global options - if (!empty($options)) { - $class = new \ReflectionClass(get_class($this)); - foreach ($options as $name => $value) { - if ($class->hasProperty($name)) { - $property = $class->getProperty($name); - if ($property->isPublic() && !$property->isStatic()) { - $this->$name = $value; - unset($options[$name]); - } - } - } - } - - if (!empty($options)) - $this->usageError("Unknown options: " . implode(', ', array_keys($options))); - - if ($this->beforeAction($action, $params)) { - $method->invokeArgs($this, $params); - $this->afterAction($action, $params); - } - } - - /** - * Parses the command line arguments and determines which action to perform. - * @param array $args command line arguments - * @return array the action name, named options (name=>value), and unnamed options - */ - protected function resolveRequest($args) - { - $options = array(); // named parameters - $params = array(); // unnamed parameters - foreach ($args as $arg) { - if (preg_match('/^--(\w+)(=(.*))?$/', $arg, $matches)) // an option - { - $name = $matches[1]; - $value = isset($matches[3]) ? $matches[3] : true; - if (isset($options[$name])) { - if (!is_array($options[$name])) - $options[$name] = array($options[$name]); - $options[$name][] = $value; - } else - $options[$name] = $value; - } else if (isset($action)) - $params[] = $arg; - else - $action = $arg; - } - if (!isset($action)) - $action = $this->defaultAction; - - return array($action, $options, $params); - } - - /** - * @return string the command name. - */ - public function getName() - { - return $this->_name; - } - - /** - * Provides the command description. - * This method may be overridden to return the actual command description. - * @return string the command description. Defaults to 'Usage: php entry-script.php command-name'. - */ - public function getHelp() - { - $help = 'Usage: ' . $this->getCommandRunner()->getScriptName() . ' ' . $this->getName(); - $options = $this->getOptionHelp(); - if (empty($options)) - return $help; - if (count($options) === 1) - return $help . ' ' . $options[0]; - $help .= " \nActions:\n"; - foreach ($options as $option) - $help .= ' ' . $option . "\n"; - return $help; - } - - /** - * Provides the command option help information. - * The default implementation will return all available actions together with their - * corresponding option information. - * @return array the command option help information. Each array element describes - * the help information for a single action. - */ - public function getOptionHelp() - { - $options = array(); - $class = new \ReflectionClass(get_class($this)); - foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { - $name = $method->getName(); - if (!strncasecmp($name, 'action', 6) && strlen($name) > 6) { - $name = substr($name, 6); - $name[0] = strtolower($name[0]); - $help = $name; - - foreach ($method->getParameters() as $param) { - $optional = $param->isDefaultValueAvailable(); - $defaultValue = $optional ? $param->getDefaultValue() : null; - $name = $param->getName(); - if ($optional) - $help .= " [--$name=$defaultValue]"; - else - $help .= " --$name=value"; - } - $options[] = $help; - } - } - return $options; - } - - /** - * Displays a usage error. - * This method will then terminate the execution of the current application. - * @param string $message the error message - */ - public function usageError($message) - { - echo "Error: $message\n\n" . $this->getHelp() . "\n"; - exit(1); - } - - /** - * Renders a view file. - * @param string $_viewFile_ view file path - * @param array $_data_ optional data to be extracted as local view variables - * @param boolean $_return_ whether to return the rendering result instead of displaying it - * @return mixed the rendering result if required. Null otherwise. - */ - public function renderFile($_viewFile_, $_data_ = null, $_return_ = false) - { - if (is_array($_data_)) - extract($_data_, EXTR_PREFIX_SAME, 'data'); - else - $data = $_data_; - if ($_return_) { - ob_start(); - ob_implicit_flush(false); - require($_viewFile_); - return ob_get_clean(); - } else - require($_viewFile_); - } - - /** - * Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed. - * - * @param string $message to echo out before waiting for user input - * @param string $default the default string to be returned when user does not write anything. - * Defaults to null, means that default string is disabled. - * @return mixed line read as a string, or false if input has been closed - */ - public function prompt($message, $default = null) - { - if ($default !== null) { - $message .= " [$default] "; - } - else { - $message .= ' '; - } - - if (extension_loaded('readline')) { - $input = readline($message); - if ($input) { - readline_add_history($input); - } - } else { - echo $message; - $input = fgets(STDIN); - } - if ($input === false) { - return false; - } - else { - $input = trim($input); - return ($input === '' && $default !== null) ? $default : $input; - } - } - - /** - * Asks user to confirm by typing y or n. - * - * @param string $message to echo out before waiting for user input - * @return bool if user confirmed - */ - public function confirm($message) - { - echo $message . ' [yes|no] '; - return !strncasecmp(trim(fgets(STDIN)), 'y', 1); - } -} \ No newline at end of file diff --git a/framework/console/Controller.php b/framework/console/Controller.php new file mode 100644 index 0000000..e488181 --- /dev/null +++ b/framework/console/Controller.php @@ -0,0 +1,279 @@ + + * yiic CommandName ActionName --Option1=Value1 --Option2=Value2 ... + * + * + * Child classes mainly needs to implement various action methods whose name must be + * prefixed with "action". The parameters to an action method are considered as options + * for that specific action. The action specified as {@link defaultAction} will be invoked + * when a user does not specify the action name in his command. + * + * Options are bound to action parameters via parameter names. For example, the following + * action method will allow us to run a command with yiic sitemap --type=News: + *
+ * class SitemapCommand {
+ *     public function actionIndex($type) {
+ *         ....
+ *     }
+ * }
+ * 
+ * + * @property string $name The command name. + * @property CommandRunner $commandRunner The command runner instance. + * @property string $help The command description. Defaults to 'Usage: php entry-script.php command-name'. + * @property array $optionHelp The command option help information. Each array element describes + * the help information for a single action. + * + * @author Qiang Xue + * @since 2.0 + */ +class Controller extends \yii\base\Controller +{ + /** + * Executes the command. + * The default implementation will parse the input parameters and + * dispatch the command request to an appropriate action with the corresponding + * option values + * @param array $args command line parameters for this command. + */ + public function run($args) + { + list($action, $options, $args) = $this->resolveRequest($args); + $methodName = 'action' . $action; + if (!preg_match('/^\w+$/', $action) || !method_exists($this, $methodName)) + { + $this->usageError("Unknown action: " . $action); + } + + $method = new \ReflectionMethod($this, $methodName); + $params = array(); + // named and unnamed options + foreach ($method->getParameters() as $param) { + $name = $param->getName(); + if (isset($options[$name])) { + if ($param->isArray()) + $params[] = is_array($options[$name]) ? $options[$name] : array($options[$name]); + else if (!is_array($options[$name])) + $params[] = $options[$name]; + else + $this->usageError("Option --$name requires a scalar. Array is given."); + } else if ($name === 'args') + $params[] = $args; + else if ($param->isDefaultValueAvailable()) + $params[] = $param->getDefaultValue(); + else + $this->usageError("Missing required option --$name."); + unset($options[$name]); + } + + // try global options + if (!empty($options)) { + $class = new \ReflectionClass(get_class($this)); + foreach ($options as $name => $value) { + if ($class->hasProperty($name)) { + $property = $class->getProperty($name); + if ($property->isPublic() && !$property->isStatic()) { + $this->$name = $value; + unset($options[$name]); + } + } + } + } + + if (!empty($options)) + $this->usageError("Unknown options: " . implode(', ', array_keys($options))); + + if ($this->beforeAction($action, $params)) { + $method->invokeArgs($this, $params); + $this->afterAction($action, $params); + } + } + + /** + * Parses the command line arguments and determines which action to perform. + * @param array $args command line arguments + * @return array the action name, named options (name=>value), and unnamed options + */ + protected function resolveRequest($args) + { + $options = array(); // named parameters + $params = array(); // unnamed parameters + foreach ($args as $arg) { + if (preg_match('/^--(\w+)(=(.*))?$/', $arg, $matches)) // an option + { + $name = $matches[1]; + $value = isset($matches[3]) ? $matches[3] : true; + if (isset($options[$name])) { + if (!is_array($options[$name])) + $options[$name] = array($options[$name]); + $options[$name][] = $value; + } else + $options[$name] = $value; + } else if (isset($action)) + $params[] = $arg; + else + $action = $arg; + } + if (!isset($action)) + $action = $this->defaultAction; + + return array($action, $options, $params); + } + + /** + * @return string the command name. + */ + public function getName() + { + return $this->_name; + } + + /** + * Provides the command description. + * This method may be overridden to return the actual command description. + * @return string the command description. Defaults to 'Usage: php entry-script.php command-name'. + */ + public function getHelp() + { + $help = 'Usage: ' . $this->getCommandRunner()->getScriptName() . ' ' . $this->getName(); + $options = $this->getOptionHelp(); + if (empty($options)) + return $help; + if (count($options) === 1) + return $help . ' ' . $options[0]; + $help .= " \nActions:\n"; + foreach ($options as $option) + $help .= ' ' . $option . "\n"; + return $help; + } + + /** + * Provides the command option help information. + * The default implementation will return all available actions together with their + * corresponding option information. + * @return array the command option help information. Each array element describes + * the help information for a single action. + */ + public function getOptionHelp() + { + $options = array(); + $class = new \ReflectionClass(get_class($this)); + foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) { + $name = $method->getName(); + if (!strncasecmp($name, 'action', 6) && strlen($name) > 6) { + $name = substr($name, 6); + $name[0] = strtolower($name[0]); + $help = $name; + + foreach ($method->getParameters() as $param) { + $optional = $param->isDefaultValueAvailable(); + $defaultValue = $optional ? $param->getDefaultValue() : null; + $name = $param->getName(); + if ($optional) + $help .= " [--$name=$defaultValue]"; + else + $help .= " --$name=value"; + } + $options[] = $help; + } + } + return $options; + } + + /** + * Displays a usage error. + * This method will then terminate the execution of the current application. + * @param string $message the error message + */ + public function usageError($message) + { + echo "Error: $message\n\n" . $this->getHelp() . "\n"; + exit(1); + } + + /** + * Renders a view file. + * @param string $_viewFile_ view file path + * @param array $_data_ optional data to be extracted as local view variables + * @param boolean $_return_ whether to return the rendering result instead of displaying it + * @return mixed the rendering result if required. Null otherwise. + */ + public function renderFile($_viewFile_, $_data_ = null, $_return_ = false) + { + if (is_array($_data_)) + extract($_data_, EXTR_PREFIX_SAME, 'data'); + else + $data = $_data_; + if ($_return_) { + ob_start(); + ob_implicit_flush(false); + require($_viewFile_); + return ob_get_clean(); + } else + require($_viewFile_); + } + + /** + * Reads input via the readline PHP extension if that's available, or fgets() if readline is not installed. + * + * @param string $message to echo out before waiting for user input + * @param string $default the default string to be returned when user does not write anything. + * Defaults to null, means that default string is disabled. + * @return mixed line read as a string, or false if input has been closed + */ + public function prompt($message, $default = null) + { + if ($default !== null) { + $message .= " [$default] "; + } + else { + $message .= ' '; + } + + if (extension_loaded('readline')) { + $input = readline($message); + if ($input) { + readline_add_history($input); + } + } else { + echo $message; + $input = fgets(STDIN); + } + if ($input === false) { + return false; + } + else { + $input = trim($input); + return ($input === '' && $default !== null) ? $default : $input; + } + } + + /** + * Asks user to confirm by typing y or n. + * + * @param string $message to echo out before waiting for user input + * @return bool if user confirmed + */ + public function confirm($message) + { + echo $message . ' [yes|no] '; + return !strncasecmp(trim(fgets(STDIN)), 'y', 1); + } +} \ No newline at end of file diff --git a/framework/console/commands/HelpController.php b/framework/console/commands/HelpController.php index 43b9eeb..ba2f38e 100644 --- a/framework/console/commands/HelpController.php +++ b/framework/console/commands/HelpController.php @@ -8,7 +8,7 @@ * @license http://www.yiiframework.com/license/ */ -namespace yii\console; +namespace yii\console\commands; /** * HelpCommand represents a console help command. @@ -28,8 +28,13 @@ namespace yii\console; * @author Qiang Xue * @since 2.0 */ -class HelpCommand extends Command +class HelpController extends \yii\console\Controller { + public function actionIndex($args = array()) + { + + } + /** * Execute the action. * @param array $args command line parameters specific for this command