Browse Source

Finished help ccommand.

tags/2.0.0-beta
Qiang Xue 13 years ago
parent
commit
38dcae3d6b
  1. 8
      framework/YiiBase.php
  2. 18
      framework/console/Controller.php
  3. 326
      framework/console/commands/HelpController.php
  4. 2
      framework/util/ReflectionHelper.php

8
framework/YiiBase.php

@ -531,11 +531,13 @@ class YiiBase
*/ */
public static function t($category, $message, $params = array(), $source = null, $language = null) public static function t($category, $message, $params = array(), $source = null, $language = null)
{ {
if (self::$app !== null) // todo;
return $params !== array() ? strtr($message, $params) : $message;
if (self::$application !== null)
{ {
if ($source === null) if ($source === null)
$source = $category === 'yii' ? 'coreMessages' : 'messages'; $source = $category === 'yii' ? 'coreMessages' : 'messages';
if (($source = self::$app->getComponent($source)) !== null) if (($source = self::$application->getComponent($source)) !== null)
$message = $source->translate($category, $message, $language); $message = $source->translate($category, $message, $language);
} }
if ($params === array()) if ($params === array())
@ -549,7 +551,7 @@ class YiiBase
if (strpos($message, '#') === false) if (strpos($message, '#') === false)
{ {
$chunks = explode('|', $message); $chunks = explode('|', $message);
$expressions = self::$app->getLocale($language)->getPluralRules(); $expressions = self::$application->getLocale($language)->getPluralRules();
if ($n = min(count($chunks), count($expressions))) if ($n = min(count($chunks), count($expressions)))
{ {
for ($i = 0;$i < $n;$i++) for ($i = 0;$i < $n;$i++)

18
framework/console/Controller.php

@ -29,12 +29,23 @@ use yii\base\Exception;
class Controller extends \yii\base\Controller class Controller extends \yii\base\Controller
{ {
/** /**
* This method is invoked when the request parameters do not satisfy the requirement of the specified action.
* The default implementation will throw an exception.
* @param Action $action the action being executed
* @param Exception $exception the exception about the invalid parameters
*/
public function invalidActionParams($action, $exception)
{
echo "Error: " . $exception->getMessage() . "\n";
\Yii::$application->end(1);
}
/**
* This method is invoked when extra parameters are provided to an action when it is executed. * This method is invoked when extra parameters are provided to an action when it is executed.
* The default implementation does nothing. * The default implementation does nothing.
* @param Action $action the action being executed * @param Action $action the action being executed
* @param array $expected the expected action parameters (name => value) * @param array $expected the expected action parameters (name => value)
* @param array $actual the actual action parameters (name => value) * @param array $actual the actual action parameters (name => value)
* @throws Exception if any unrecognized parameters are provided
*/ */
public function extraActionParams($action, $expected, $actual) public function extraActionParams($action, $expected, $actual)
{ {
@ -42,9 +53,10 @@ class Controller extends \yii\base\Controller
$keys = array_diff(array_keys($actual), array_keys($expected)); $keys = array_diff(array_keys($actual), array_keys($expected));
if (!empty($keys)) { if (!empty($keys)) {
throw new Exception(\Yii::t('yii', 'Unknown parameters: {params}', array( echo "Error: " . \Yii::t('yii', 'Unknown parameters: {params}', array(
'{params}' => implode(', ', $keys), '{params}' => implode(', ', $keys),
))); )) . "\n";
\Yii::$application->end(1);
} }
} }
} }

326
framework/console/commands/HelpController.php

@ -9,31 +9,139 @@
namespace yii\console\commands; namespace yii\console\commands;
use yii\base\Application;
use yii\base\InlineAction;
use yii\console\Controller;
/** /**
* HelpCommand represents a console help command. * This command provides help information about console commands.
* *
* HelpCommand displays the available command list or the help instructions * This command displays the available command list in
* about a specific command. * the application or the detailed instructions about using
* a specific command.
* *
* To use this command, enter the following on the command line: * This command can be used as follows on command line:
* *
* ~~~ * ~~~
* yiic help [command name] * yiic help [command name]
* ~~~ * ~~~
* *
* In the above, if the command name is not provided, it will display all * In the above, if the command name is not provided, all
* available commands. * available commands will be displayed.
*
* @property string $help The command description.
* *
* @author Qiang Xue <qiang.xue@gmail.com> * @author Qiang Xue <qiang.xue@gmail.com>
* @since 2.0 * @since 2.0
*/ */
class HelpController extends \yii\console\Controller class HelpController extends Controller
{ {
/**
* Displays available commands or the detailed information
* about a particular command. For example,
*
* ~~~
* yiic help # list available commands
* yiic help message # display help info about "message"
* ~~~
*
* @param array $args additional anonymous command line arguments.
* You may provide a command-name to display its detailed information.
* @return integer the exit status
*/
public function actionIndex($args = array()) public function actionIndex($args = array())
{ {
echo "Yii console command helper (based on Yii v" . \Yii::getVersion() . ").\n"; if (empty($args)) {
$status = $this->helpIndex();
} else {
$result = \Yii::$application->createController($args[0]);
if ($result === false) {
echo "Unknown command: " . $args[0] . "\n";
return 1;
}
list($controller, $action) = $result;
if ($action === '') {
$status = $this->helpController($controller);
} else {
$status = $this->helpAction($controller, $action);
}
}
return $status;
}
/**
* Returns all available command names.
* @return array all available command names
*/
public function getCommands()
{
$commands = $this->getModuleCommands(\Yii::$application);
sort($commands);
return array_unique($commands);
}
/**
* Returns all available actions of the specified controller.
* @param Controller $controller the controller instance
* @return array all available action IDs.
*/
public function getActions($controller)
{
$actions = array_keys($controller->actions);
$class = new \ReflectionClass($controller);
foreach ($class->getMethods() as $method) {
$name = $method->getName();
if ($method->isPublic() && !$method->isStatic() && strpos($name, 'action') === 0) {
$actions[] = lcfirst(substr($name, 6));
}
}
sort($actions);
return array_unique($actions);
}
/**
* Returns available commands of a specified module.
* @param \yii\base\Module $module the module instance
* @return array the available command names
*/
protected function getModuleCommands($module)
{
if ($module instanceof Application) {
$prefix = '';
} else {
$prefix = $module->getUniqueId() . '/';
}
$commands = array();
foreach (array_keys($module->controllers) as $id) {
$commands[] = $prefix . $id;
}
foreach ($module->getModules() as $id => $child) {
if (($child = $module->getModule($id)) === null) {
continue;
}
foreach ($this->getModuleCommands($child) as $command) {
$commands[] = $prefix . $id . '/' . $command;
}
}
$files = scandir($module->getControllerPath());
foreach ($files as $file) {
if(strcmp(substr($file,-14),'Controller.php') === 0 && is_file($file)) {
$commands[] = $prefix . lcfirst(substr(basename($file), 0, -14));
}
}
return $commands;
}
/**
* Displays all available commands.
* @return integer the exit status
*/
protected function helpIndex()
{
$commands = $this->getCommands(); $commands = $this->getCommands();
if ($commands !== array()) { if ($commands !== array()) {
echo "\n Usage: yiic <command-name> [...options...]\n\n"; echo "\n Usage: yiic <command-name> [...options...]\n\n";
@ -46,40 +154,202 @@ class HelpController extends \yii\console\Controller
} else { } else {
echo "\nNo commands are found.\n"; echo "\nNo commands are found.\n";
} }
return 0;
} }
protected function getCommands() /**
* Displays the overall information of the command.
* @param Controller $controller the controller instance
* @return integer the exit status
*/
protected function helpController($controller)
{ {
$commands = $this->getModuleCommands(\Yii::$application); $class = new \ReflectionClass($controller);
sort($commands); $comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($class->getDocComment(), '/'))), "\r", '');
return array_unique($commands); if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
$comment = trim(substr($comment, 0, $matches[0][1]));
}
if ($comment !== '') {
echo "\nDESCRIPTION";
echo "\n-----------\n\n";
echo $comment . "\n";
}
$options = $this->getGlobalOptions($class, $controller);
if ($options !== array()) {
echo "\nGLOBAL OPTIONS";
echo "\n--------------\n\n";
foreach ($options as $name => $description) {
echo " --$name";
if ($description != '') {
echo ": $description\n";
}
}
echo "\n";
}
$actions = $this->getActions($controller);
if ($actions !== array()) {
echo "\nSUB-COMMANDS";
echo "\n------------\n\n";
$prefix = $controller->getUniqueId();
foreach ($actions as $action) {
if ($controller->defaultAction === $action) {
echo " * $prefix/$action (default)\n";
} else {
echo " * $prefix/$action\n";
}
}
echo "\n";
}
return 0;
} }
/** /**
* @param \yii\base\Module $module * Displays the detailed information of a command action.
* @return array * @param Controller $controller the controller instance
* @param string $actionID action ID
* @return integer the exit status
*/ */
protected function getModuleCommands($module) protected function helpAction($controller, $actionID)
{ {
if ($module === null) { $action = $controller->createAction($actionID);
return array(); if ($action === null) {
echo "Unknown sub-command: " . $controller->getUniqueId() . "/$actionID\n";
return 1;
}
if ($action instanceof InlineAction) {
$method = new \ReflectionMethod($controller, 'action' . $action->id);
} else {
$method = new \ReflectionMethod($action, 'run');
}
$comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($method->getDocComment(), '/'))), "\r", '');
if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
$meta = substr($comment, $matches[0][1]);
$comment = trim(substr($comment, 0, $matches[0][1]));
} else {
$meta = '';
} }
$commands = array_keys($module->controllers); if ($comment !== '') {
echo "\nDESCRIPTION";
echo "\n-----------\n\n";
echo $comment . "\n";
}
foreach ($module->getModules() as $id => $module) { $options = $this->getOptions($method, $meta);
foreach ($this->getModuleCommands($module->getModule($id)) as $command) { if ($options !== array()) {
$commands[] = $command; echo "\nOPTIONS";
echo "\n-------\n\n";
foreach ($options as $name => $description) {
echo " --$name";
if ($description != '') {
echo ": $description\n";
} }
} }
echo "\n";
}
$files = scandir($module->getControllerPath()); return 0;
foreach ($files as $file) { }
if(strcmp(substr($file,-14),'Controller.php') === 0 && is_file($file)) {
$commands[] = lcfirst(substr(basename($file), 0, -14)); /**
* @param \ReflectionMethod $method
* @param string $meta
* @return array
*/
protected function getOptions($method, $meta)
{
$params = $method->getParameters();
$tags = preg_split('/^\s*@/m', $meta, -1, PREG_SPLIT_NO_EMPTY);
$options = array();
$count = 0;
foreach ($tags as $tag) {
$parts = preg_split('/\s+/', trim($tag), 2);
if ($parts[0] === 'param' && isset($params[$count])) {
$param = $params[$count];
$comment = isset($parts[1]) ? $parts[1] : '';
if (preg_match('/^([^\s]+)\s+(\$\w+\s+)?(.*)/s', $comment, $matches)) {
$type = $matches[1];
$doc = $matches[3];
} else {
$type = $comment;
$doc = '';
}
$comment = $type === '' ? '' : ($type . ', ');
if ($param->isDefaultValueAvailable()) {
$value = $param->getDefaultValue();
if (!is_array($value)) {
$comment .= 'optional (defaults to ' . var_export($value, true) . ').';
} else {
$comment .= 'optional.';
}
} else {
$comment .= 'required.';
}
if (trim($doc) !== '') {
$comment .= "\n" . preg_replace("/^/m", " ", $doc);
}
$options[$param->getName()] = $comment;
$count++;
}
}
if ($count < count($params)) {
for ($i = $count; $i < count($params); ++$i) {
$options[$params[$i]->getName()] = '';
} }
} }
return $commands; ksort($options);
return $options;
}
/**
* @param \ReflectionClass $class
* @param Controller $controller
* @return array
*/
protected function getGlobalOptions($class, $controller)
{
$options = array();
foreach ($class->getProperties() as $property) {
if (!$property->isPublic() || $property->isStatic() || $property->getDeclaringClass()->getName() !== get_class($controller)) {
continue;
}
$name = $property->getName();
$comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($property->getDocComment(), '/'))), "\r", '');
if (preg_match('/^\s*@\w+/m', $comment, $matches, PREG_OFFSET_CAPTURE)) {
$meta = substr($comment, $matches[0][1]);
} else {
$meta = '';
}
$tags = preg_split('/^\s*@/m', $meta, -1, PREG_SPLIT_NO_EMPTY);
foreach ($tags as $tag) {
$parts = preg_split('/\s+/', trim($tag), 2);
$comment = isset($parts[1]) ? $parts[1] : '';
if ($parts[0] === 'var' || $parts[0] === 'property') {
if (preg_match('/^([^\s]+)(\s+.*)?/s', $comment, $matches)) {
$type = $matches[1];
$doc = trim($matches[2]);
} else {
$type = $comment;
$doc = '';
}
$comment = $type === '' ? '' : ($type . '.');
if (trim($doc) !== '') {
$comment .= "\n" . preg_replace("/^/m", " ", $doc);
}
$options[$name] = $comment;
break;
}
}
if (!isset($options[$name])) {
$options[$name] = '';
}
}
ksort($options);
return $options;
} }
} }

2
framework/util/ReflectionHelper.php

@ -54,7 +54,7 @@ class ReflectionHelper
} elseif ($param->isDefaultValueAvailable()) { } elseif ($param->isDefaultValueAvailable()) {
$ps[$name] = $param->getDefaultValue(); $ps[$name] = $param->getDefaultValue();
} else { } else {
throw new Exception(\Yii::t('yii', 'Missing required parameter "{name}".', array('{name' => $name))); throw new Exception(\Yii::t('yii', 'Missing required parameter "{name}".', array('{name}' => $name)));
} }
} }
return $ps; return $ps;

Loading…
Cancel
Save