| <?php |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| namespace think\console; |
|
|
| use think\Console; |
| use think\console\input\Argument; |
| use think\console\input\Definition; |
| use think\console\input\Option; |
|
|
| class Command |
| { |
|
|
| |
| private $console; |
| private $name; |
| private $aliases = []; |
| private $definition; |
| private $help; |
| private $description; |
| private $ignoreValidationErrors = false; |
| private $consoleDefinitionMerged = false; |
| private $consoleDefinitionMergedWithArgs = false; |
| private $code; |
| private $synopsis = []; |
| private $usages = []; |
|
|
| |
| protected $input; |
|
|
| |
| protected $output; |
|
|
| |
| |
| |
| |
| |
| |
| public function __construct($name = null) |
| { |
| $this->definition = new Definition(); |
|
|
| if (null !== $name) { |
| $this->setName($name); |
| } |
|
|
| $this->configure(); |
|
|
| if (!$this->name) { |
| throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this))); |
| } |
| } |
|
|
| |
| |
| |
| public function ignoreValidationErrors() |
| { |
| $this->ignoreValidationErrors = true; |
| } |
|
|
| |
| |
| |
| |
| public function setConsole(Console $console = null) |
| { |
| $this->console = $console; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getConsole() |
| { |
| return $this->console; |
| } |
|
|
| |
| |
| |
| |
| public function isEnabled() |
| { |
| return true; |
| } |
|
|
| |
| |
| |
| protected function configure() |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| protected function execute(Input $input, Output $output) |
| { |
| throw new \LogicException('You must override the execute() method in the concrete command class.'); |
| } |
|
|
| |
| |
| |
| |
| |
| protected function interact(Input $input, Output $output) |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| protected function initialize(Input $input, Output $output) |
| { |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function run(Input $input, Output $output) |
| { |
| $this->input = $input; |
| $this->output = $output; |
|
|
| $this->getSynopsis(true); |
| $this->getSynopsis(false); |
|
|
| $this->mergeConsoleDefinition(); |
|
|
| try { |
| $input->bind($this->definition); |
| } catch (\Exception $e) { |
| if (!$this->ignoreValidationErrors) { |
| throw $e; |
| } |
| } |
|
|
| $this->initialize($input, $output); |
|
|
| if ($input->isInteractive()) { |
| $this->interact($input, $output); |
| } |
|
|
| $input->validate(); |
|
|
| if ($this->code) { |
| $statusCode = call_user_func($this->code, $input, $output); |
| } else { |
| $statusCode = $this->execute($input, $output); |
| } |
|
|
| return is_numeric($statusCode) ? (int) $statusCode : 0; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function setCode(callable $code) |
| { |
| if (!is_callable($code)) { |
| throw new \InvalidArgumentException('Invalid callable provided to Command::setCode.'); |
| } |
|
|
| if (PHP_VERSION_ID >= 50400 && $code instanceof \Closure) { |
| $r = new \ReflectionFunction($code); |
| if (null === $r->getClosureThis()) { |
| $code = \Closure::bind($code, $this); |
| } |
| } |
|
|
| $this->code = $code; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function mergeConsoleDefinition($mergeArgs = true) |
| { |
| if (null === $this->console |
| || (true === $this->consoleDefinitionMerged |
| && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs)) |
| ) { |
| return; |
| } |
|
|
| if ($mergeArgs) { |
| $currentArguments = $this->definition->getArguments(); |
| $this->definition->setArguments($this->console->getDefinition()->getArguments()); |
| $this->definition->addArguments($currentArguments); |
| } |
|
|
| $this->definition->addOptions($this->console->getDefinition()->getOptions()); |
|
|
| $this->consoleDefinitionMerged = true; |
| if ($mergeArgs) { |
| $this->consoleDefinitionMergedWithArgs = true; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function setDefinition($definition) |
| { |
| if ($definition instanceof Definition) { |
| $this->definition = $definition; |
| } else { |
| $this->definition->setDefinition($definition); |
| } |
|
|
| $this->consoleDefinitionMerged = false; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getDefinition() |
| { |
| return $this->definition; |
| } |
|
|
| |
| |
| |
| |
| public function getNativeDefinition() |
| { |
| return $this->getDefinition(); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function addArgument($name, $mode = null, $description = '', $default = null) |
| { |
| $this->definition->addArgument(new Argument($name, $mode, $description, $default)); |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null) |
| { |
| $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default)); |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function setName($name) |
| { |
| $this->validateName($name); |
|
|
| $this->name = $name; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function getName() |
| { |
| return $this->name; |
| } |
|
|
| |
| |
| |
| |
| |
| public function setDescription($description) |
| { |
| $this->description = $description; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function getDescription() |
| { |
| return $this->description; |
| } |
|
|
| |
| |
| |
| |
| |
| public function setHelp($help) |
| { |
| $this->help = $help; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function getHelp() |
| { |
| return $this->help; |
| } |
|
|
| |
| |
| |
| |
| public function getProcessedHelp() |
| { |
| $name = $this->name; |
|
|
| $placeholders = [ |
| '%command.name%', |
| '%command.full_name%', |
| ]; |
| $replacements = [ |
| $name, |
| $_SERVER['PHP_SELF'] . ' ' . $name, |
| ]; |
|
|
| return str_replace($placeholders, $replacements, $this->getHelp()); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function setAliases($aliases) |
| { |
| if (!is_array($aliases) && !$aliases instanceof \Traversable) { |
| throw new \InvalidArgumentException('$aliases must be an array or an instance of \Traversable'); |
| } |
|
|
| foreach ($aliases as $alias) { |
| $this->validateName($alias); |
| } |
|
|
| $this->aliases = $aliases; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function getAliases() |
| { |
| return $this->aliases; |
| } |
|
|
| |
| |
| |
| |
| |
| public function getSynopsis($short = false) |
| { |
| $key = $short ? 'short' : 'long'; |
|
|
| if (!isset($this->synopsis[$key])) { |
| $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short))); |
| } |
|
|
| return $this->synopsis[$key]; |
| } |
|
|
| |
| |
| |
| |
| |
| public function addUsage($usage) |
| { |
| if (0 !== strpos($usage, $this->name)) { |
| $usage = sprintf('%s %s', $this->name, $usage); |
| } |
|
|
| $this->usages[] = $usage; |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| public function getUsages() |
| { |
| return $this->usages; |
| } |
|
|
| |
| |
| |
| |
| |
| private function validateName($name) |
| { |
| if (!preg_match('/^[^\:]++(\:[^\:]++)*$/', $name)) { |
| throw new \InvalidArgumentException(sprintf('Command name "%s" is invalid.', $name)); |
| } |
| } |
| } |
|
|