You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
355 lines
9.3 KiB
355 lines
9.3 KiB
<?php |
|
/** |
|
* HelpController class file. |
|
* |
|
* @link http://www.yiiframework.com/ |
|
* @copyright Copyright © 2008-2012 Yii Software LLC |
|
* @license http://www.yiiframework.com/license/ |
|
*/ |
|
|
|
namespace yii\console\commands; |
|
|
|
use yii\base\Application; |
|
use yii\base\InlineAction; |
|
use yii\console\Controller; |
|
|
|
/** |
|
* This command provides help information about console commands. |
|
* |
|
* This command displays the available command list in |
|
* the application or the detailed instructions about using |
|
* a specific command. |
|
* |
|
* This command can be used as follows on command line: |
|
* |
|
* ~~~ |
|
* yiic help [command name] |
|
* ~~~ |
|
* |
|
* 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 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()) |
|
{ |
|
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"; |
|
echo "The following commands are available:\n"; |
|
foreach ($commands as $command) { |
|
echo " - $command\n"; |
|
} |
|
echo "\nTo see individual command help, enter:\n"; |
|
echo "\n yiic help <command-name>\n"; |
|
} else { |
|
echo "\nNo commands are found.\n"; |
|
} |
|
return 0; |
|
} |
|
|
|
/** |
|
* 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 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()] = ''; |
|
} |
|
} |
|
|
|
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() === 'yii\base\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; |
|
} |
|
} |