diff --git a/src/Console/ConsoleIo.php b/src/Console/ConsoleIo.php new file mode 100644 index 00000000000..abd0d8bedcf --- /dev/null +++ b/src/Console/ConsoleIo.php @@ -0,0 +1,256 @@ +_out = $out ? $out : new ConsoleOutput('php://stdout'); + $this->_err = $err ? $err : new ConsoleOutput('php://stderr'); + $this->_in = $in ? $in : new ConsoleInput('php://stdin'); + } + +/** + * Output only at the verbose level. + * + * @param string|array $message A string or a an array of strings to output + * @param integer $newlines Number of newlines to append + * @return integer|boolean Returns the number of bytes returned from writing to stdout. + */ + public function verbose($message, $newlines = 1) { + return $this->out($message, $newlines, self::VERBOSE); + } + +/** + * Output at all levels. + * + * @param string|array $message A string or a an array of strings to output + * @param integer $newlines Number of newlines to append + * @return integer|boolean Returns the number of bytes returned from writing to stdout. + */ + public function quiet($message, $newlines = 1) { + return $this->out($message, $newlines, self::QUIET); + } + +/** + * Outputs a single or multiple messages to stdout. If no parameters + * are passed outputs just a newline. + * + * ### Output levels + * + * There are 3 built-in output level. Shell::QUIET, Shell::NORMAL, Shell::VERBOSE. + * The verbose and quiet output levels, map to the `verbose` and `quiet` output switches + * present in most shells. Using Shell::QUIET for a message means it will always display. + * While using Shell::VERBOSE means it will only display when verbose output is toggled. + * + * @param string|array $message A string or a an array of strings to output + * @param integer $newlines Number of newlines to append + * @param integer $level The message's output level, see above. + * @return integer|boolean Returns the number of bytes returned from writing to stdout. + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::out + */ + public function out($message = null, $newlines = 1, $level = Shell::NORMAL) { + if ($level <= $this->_level) { + return $this->_out->write($message, $newlines); + } + return true; + } + +/** + * Outputs a single or multiple error messages to stderr. If no parameters + * are passed outputs just a newline. + * + * @param string|array $message A string or a an array of strings to output + * @param integer $newlines Number of newlines to append + * @return void + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::err + */ + public function err($message = null, $newlines = 1) { + $this->_err->write($message, $newlines); + } + +/** + * Returns a single or multiple linefeeds sequences. + * + * @param integer $multiplier Number of times the linefeed sequence should be repeated + * @return string + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::nl + */ + public function nl($multiplier = 1) { + return str_repeat(ConsoleOutput::LF, $multiplier); + } + +/** + * Outputs a series of minus characters to the standard output, acts as a visual separator. + * + * @param integer $newlines Number of newlines to pre- and append + * @param integer $width Width of the line, defaults to 63 + * @return void + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::hr + */ + public function hr($newlines = 0, $width = 63) { + $this->out(null, $newlines); + $this->out(str_repeat('-', $width)); + $this->out(null, $newlines); + } + +/** + * Prompts the user for input, and returns it. + * + * @param string $prompt Prompt text. + * @param string $default Default input value. + * @return mixed Either the default value, or the user-provided input. + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::in + */ + public function ask($prompt, $default = null) { + $in = $this->_getInput($prompt, null, $default); + return $in; + } + +/** + * Prompts the user for input based on a list of options, and returns it. + * + * @param string $prompt Prompt text. + * @param string|array $options Array or string of options. + * @param string $default Default input value. + * @return mixed Either the default value, or the user-provided input. + * @link http://book.cakephp.org/2.0/en/console-and-shells.html#Shell::in + */ + public function askChoice($prompt, $options, $default = null) { + $originalOptions = $options; + $in = $this->_getInput($prompt, $originalOptions, $default); + + if ($options && is_string($options)) { + if (strpos($options, ',')) { + $options = explode(',', $options); + } elseif (strpos($options, '/')) { + $options = explode('/', $options); + } else { + $options = [$options]; + } + } + if (is_array($options)) { + $options = array_merge( + array_map('strtolower', $options), + array_map('strtoupper', $options), + $options + ); + while ($in === '' || !in_array($in, $options)) { + $in = $this->_getInput($prompt, $originalOptions, $default); + } + } + return $in; + } + +/** + * Prompts the user for input, and returns it. + * + * @param string $prompt Prompt text. + * @param string|array $options Array or string of options. + * @param string $default Default input value. + * @return string Either the default value, or the user-provided input. + */ + protected function _getInput($prompt, $options, $default) { + if (!is_array($options)) { + $printOptions = ''; + } else { + $printOptions = '(' . implode('/', $options) . ')'; + } + + if ($default === null) { + $this->_out->write('' . $prompt . '' . " $printOptions \n" . '> ', 0); + } else { + $this->_out->write('' . $prompt . '' . " $printOptions \n" . "[$default] > ", 0); + } + $result = $this->_in->read(); + + if ($result === false) { + return false; + } + $result = trim($result); + + if ($default !== null && ($result === '' || $result === null)) { + return $default; + } + return $result; + } + +}