mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-13 04:38:03 +08:00
Finished help ccommand.
This commit is contained in:
@@ -9,31 +9,139 @@
|
||||
|
||||
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
|
||||
* about a specific command.
|
||||
* This command displays the available command list in
|
||||
* 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]
|
||||
* ~~~
|
||||
*
|
||||
* In the above, if the command name is not provided, it will display all
|
||||
* available commands.
|
||||
*
|
||||
* @property string $help The command description.
|
||||
* In the above, if the command name is not provided, all
|
||||
* available commands will be displayed.
|
||||
*
|
||||
* @author Qiang Xue <qiang.xue@gmail.com>
|
||||
* @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())
|
||||
{
|
||||
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();
|
||||
if ($commands !== array()) {
|
||||
echo "\n Usage: yiic <command-name> [...options...]\n\n";
|
||||
@@ -46,40 +154,202 @@ class HelpController extends \yii\console\Controller
|
||||
} else {
|
||||
echo "\nNo commands are found.\n";
|
||||
}
|
||||
}
|
||||
|
||||
protected function getCommands()
|
||||
{
|
||||
$commands = $this->getModuleCommands(\Yii::$application);
|
||||
sort($commands);
|
||||
return array_unique($commands);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \yii\base\Module $module
|
||||
* Displays the overall information of the command.
|
||||
* @param Controller $controller the controller instance
|
||||
* @return integer the exit status
|
||||
*/
|
||||
protected function helpController($controller)
|
||||
{
|
||||
$class = new \ReflectionClass($controller);
|
||||
$comment = strtr(trim(preg_replace('/^\s*\**( |\t)?/m', '', trim($class->getDocComment(), '/'))), "\r", '');
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the detailed information of a command action.
|
||||
* @param Controller $controller the controller instance
|
||||
* @param string $actionID action ID
|
||||
* @return integer the exit status
|
||||
*/
|
||||
protected function helpAction($controller, $actionID)
|
||||
{
|
||||
$action = $controller->createAction($actionID);
|
||||
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 = '';
|
||||
}
|
||||
|
||||
if ($comment !== '') {
|
||||
echo "\nDESCRIPTION";
|
||||
echo "\n-----------\n\n";
|
||||
echo $comment . "\n";
|
||||
}
|
||||
|
||||
$options = $this->getOptions($method, $meta);
|
||||
if ($options !== array()) {
|
||||
echo "\nOPTIONS";
|
||||
echo "\n-------\n\n";
|
||||
foreach ($options as $name => $description) {
|
||||
echo " --$name";
|
||||
if ($description != '') {
|
||||
echo ": $description\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \ReflectionMethod $method
|
||||
* @param string $meta
|
||||
* @return array
|
||||
*/
|
||||
protected function getModuleCommands($module)
|
||||
protected function getOptions($method, $meta)
|
||||
{
|
||||
if ($module === null) {
|
||||
return array();
|
||||
$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++;
|
||||
}
|
||||
}
|
||||
|
||||
$commands = array_keys($module->controllers);
|
||||
|
||||
foreach ($module->getModules() as $id => $module) {
|
||||
foreach ($this->getModuleCommands($module->getModule($id)) as $command) {
|
||||
$commands[] = $command;
|
||||
if ($count < count($params)) {
|
||||
for ($i = $count; $i < count($params); ++$i) {
|
||||
$options[$params[$i]->getName()] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$files = scandir($module->getControllerPath());
|
||||
foreach ($files as $file) {
|
||||
if(strcmp(substr($file,-14),'Controller.php') === 0 && is_file($file)) {
|
||||
$commands[] = lcfirst(substr(basename($file), 0, -14));
|
||||
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] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $commands;
|
||||
ksort($options);
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user