// +---------------------------------------------------------------------- namespace think\console\output; class Stream { const VERBOSITY_QUIET = 0; const VERBOSITY_NORMAL = 1; const VERBOSITY_VERBOSE = 2; const VERBOSITY_VERY_VERBOSE = 3; const VERBOSITY_DEBUG = 4; const OUTPUT_NORMAL = 0; const OUTPUT_RAW = 1; const OUTPUT_PLAIN = 2; private $verbosity = self::VERBOSITY_NORMAL; private $formatter; private $stream; /** * 构造方法 */ public function __construct($stream, Formatter $formatter = null) { if (!is_resource($stream) || 'stream' !== get_resource_type($stream)) { throw new \InvalidArgumentException('The StreamOutput class needs a stream as its first argument.'); } $this->stream = $stream; $decorated = $this->hasColorSupport(); $this->formatter = $formatter ?: new Formatter(); $this->formatter->setDecorated($decorated); } /** * {@inheritdoc} */ public function setFormatter(Formatter $formatter) { $this->formatter = $formatter; } /** * {@inheritdoc} */ public function getFormatter() { return $this->formatter; } /** * {@inheritdoc} */ public function setDecorated($decorated) { $this->formatter->setDecorated($decorated); } /** * {@inheritdoc} */ public function isDecorated() { return $this->formatter->isDecorated(); } /** * {@inheritdoc} */ public function setVerbosity($level) { $this->verbosity = (int)$level; } /** * {@inheritdoc} */ public function getVerbosity() { return $this->verbosity; } public function isQuiet() { return self::VERBOSITY_QUIET === $this->verbosity; } public function isVerbose() { return self::VERBOSITY_VERBOSE <= $this->verbosity; } public function isVeryVerbose() { return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity; } public function isDebug() { return self::VERBOSITY_DEBUG <= $this->verbosity; } /** * {@inheritdoc} */ public function writeln($messages, $type = self::OUTPUT_NORMAL) { $this->write($messages, true, $type); } /** * {@inheritdoc} */ public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL) { if (self::VERBOSITY_QUIET === $this->verbosity) { return; } $messages = (array)$messages; foreach ($messages as $message) { switch ($type) { case self::OUTPUT_NORMAL: $message = $this->formatter->format($message); break; case self::OUTPUT_RAW: break; case self::OUTPUT_PLAIN: $message = strip_tags($this->formatter->format($message)); break; default: throw new \InvalidArgumentException(sprintf('Unknown output type given (%s)', $type)); } $this->doWrite($message, $newline); } } /** * 将消息写入到输出。 * @param string $message 消息 * @param bool $newline 是否另起一行 */ protected function doWrite($message, $newline) { if (false === @fwrite($this->stream, $message . ($newline ? PHP_EOL : ''))) { throw new \RuntimeException('Unable to write output.'); } fflush($this->stream); } /** * @return resource */ public function getStream() { return $this->stream; } /** * 是否支持着色 * @return bool */ protected function hasColorSupport() { if (DIRECTORY_SEPARATOR == '\\') { return false !== getenv('ANSICON') || 'ON' === getenv('ConEmuANSI'); } return function_exists('posix_isatty') && @posix_isatty($this->stream); } }