Output.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: yunwuxin <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\console;
  12. use Exception;
  13. use think\console\output\Ask;
  14. use think\console\output\Descriptor;
  15. use think\console\output\driver\Buffer;
  16. use think\console\output\driver\Console;
  17. use think\console\output\driver\Nothing;
  18. use think\console\output\Question;
  19. use think\console\output\question\Choice;
  20. use think\console\output\question\Confirmation;
  21. /**
  22. * Class Output
  23. * @package think\console
  24. *
  25. * @see \think\console\output\driver\Console::setDecorated
  26. * @method void setDecorated($decorated)
  27. *
  28. * @see \think\console\output\driver\Buffer::fetch
  29. * @method string fetch()
  30. *
  31. * @method void info($message)
  32. * @method void error($message)
  33. * @method void comment($message)
  34. * @method void warning($message)
  35. * @method void highlight($message)
  36. * @method void question($message)
  37. */
  38. class Output
  39. {
  40. const VERBOSITY_QUIET = 0;
  41. const VERBOSITY_NORMAL = 1;
  42. const VERBOSITY_VERBOSE = 2;
  43. const VERBOSITY_VERY_VERBOSE = 3;
  44. const VERBOSITY_DEBUG = 4;
  45. const OUTPUT_NORMAL = 0;
  46. const OUTPUT_RAW = 1;
  47. const OUTPUT_PLAIN = 2;
  48. private $verbosity = self::VERBOSITY_NORMAL;
  49. /** @var Buffer|Console|Nothing */
  50. private $handle = null;
  51. protected $styles = [
  52. 'info',
  53. 'error',
  54. 'comment',
  55. 'question',
  56. 'highlight',
  57. 'warning'
  58. ];
  59. public function __construct($driver = 'console')
  60. {
  61. $class = '\\think\\console\\output\\driver\\' . ucwords($driver);
  62. $this->handle = new $class($this);
  63. }
  64. public function ask(Input $input, $question, $default = null, $validator = null)
  65. {
  66. $question = new Question($question, $default);
  67. $question->setValidator($validator);
  68. return $this->askQuestion($input, $question);
  69. }
  70. public function askHidden(Input $input, $question, $validator = null)
  71. {
  72. $question = new Question($question);
  73. $question->setHidden(true);
  74. $question->setValidator($validator);
  75. return $this->askQuestion($input, $question);
  76. }
  77. public function confirm(Input $input, $question, $default = true)
  78. {
  79. return $this->askQuestion($input, new Confirmation($question, $default));
  80. }
  81. /**
  82. * {@inheritdoc}
  83. */
  84. public function choice(Input $input, $question, array $choices, $default = null)
  85. {
  86. if (null !== $default) {
  87. $values = array_flip($choices);
  88. $default = $values[$default];
  89. }
  90. return $this->askQuestion($input, new Choice($question, $choices, $default));
  91. }
  92. protected function askQuestion(Input $input, Question $question)
  93. {
  94. $ask = new Ask($input, $this, $question);
  95. $answer = $ask->run();
  96. if ($input->isInteractive()) {
  97. $this->newLine();
  98. }
  99. return $answer;
  100. }
  101. protected function block($style, $message)
  102. {
  103. $this->writeln("<{$style}>{$message}</$style>");
  104. }
  105. /**
  106. * 输出空行
  107. * @param int $count
  108. */
  109. public function newLine($count = 1)
  110. {
  111. $this->write(str_repeat(PHP_EOL, $count));
  112. }
  113. /**
  114. * 输出信息并换行
  115. * @param string $messages
  116. * @param int $type
  117. */
  118. public function writeln($messages, $type = self::OUTPUT_NORMAL)
  119. {
  120. $this->write($messages, true, $type);
  121. }
  122. /**
  123. * 输出信息
  124. * @param string $messages
  125. * @param bool $newline
  126. * @param int $type
  127. */
  128. public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
  129. {
  130. $this->handle->write($messages, $newline, $type);
  131. }
  132. public function renderException(\Exception $e)
  133. {
  134. $this->handle->renderException($e);
  135. }
  136. /**
  137. * {@inheritdoc}
  138. */
  139. public function setVerbosity($level)
  140. {
  141. $this->verbosity = (int) $level;
  142. }
  143. /**
  144. * {@inheritdoc}
  145. */
  146. public function getVerbosity()
  147. {
  148. return $this->verbosity;
  149. }
  150. public function isQuiet()
  151. {
  152. return self::VERBOSITY_QUIET === $this->verbosity;
  153. }
  154. public function isVerbose()
  155. {
  156. return self::VERBOSITY_VERBOSE <= $this->verbosity;
  157. }
  158. public function isVeryVerbose()
  159. {
  160. return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
  161. }
  162. public function isDebug()
  163. {
  164. return self::VERBOSITY_DEBUG <= $this->verbosity;
  165. }
  166. public function describe($object, array $options = [])
  167. {
  168. $descriptor = new Descriptor();
  169. $options = array_merge([
  170. 'raw_text' => false,
  171. ], $options);
  172. $descriptor->describe($this, $object, $options);
  173. }
  174. public function __call($method, $args)
  175. {
  176. if (in_array($method, $this->styles)) {
  177. array_unshift($args, $method);
  178. return call_user_func_array([$this, 'block'], $args);
  179. }
  180. if ($this->handle && method_exists($this->handle, $method)) {
  181. return call_user_func_array([$this->handle, $method], $args);
  182. } else {
  183. throw new Exception('method not exists:' . __CLASS__ . '->' . $method);
  184. }
  185. }
  186. }