| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link https://cakephp.org CakePHP(tm) Project
- * @since 3.0.0
- * @license https://opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\Console;
- use Cake\Log\Engine\ConsoleLog;
- use Cake\Log\Log;
- /**
- * A wrapper around the various IO operations shell tasks need to do.
- *
- * Packages up the stdout, stderr, and stdin streams providing a simple
- * consistent interface for shells to use. This class also makes mocking streams
- * easy to do in unit tests.
- */
- class ConsoleIo
- {
- /**
- * The output stream
- *
- * @var \Cake\Console\ConsoleOutput
- */
- protected $_out;
- /**
- * The error stream
- *
- * @var \Cake\Console\ConsoleOutput
- */
- protected $_err;
- /**
- * The input stream
- *
- * @var \Cake\Console\ConsoleInput
- */
- protected $_in;
- /**
- * The helper registry.
- *
- * @var \Cake\Console\HelperRegistry
- */
- protected $_helpers;
- /**
- * Output constant making verbose shells.
- *
- * @var int
- */
- const VERBOSE = 2;
- /**
- * Output constant for making normal shells.
- *
- * @var int
- */
- const NORMAL = 1;
- /**
- * Output constants for making quiet shells.
- *
- * @var int
- */
- const QUIET = 0;
- /**
- * The current output level.
- *
- * @var int
- */
- protected $_level = ConsoleIo::NORMAL;
- /**
- * The number of bytes last written to the output stream
- * used when overwriting the previous message.
- *
- * @var int
- */
- protected $_lastWritten = 0;
- /**
- * Constructor
- *
- * @param \Cake\Console\ConsoleOutput|null $out A ConsoleOutput object for stdout.
- * @param \Cake\Console\ConsoleOutput|null $err A ConsoleOutput object for stderr.
- * @param \Cake\Console\ConsoleInput|null $in A ConsoleInput object for stdin.
- * @param \Cake\Console\HelperRegistry|null $helpers A HelperRegistry instance
- */
- public function __construct(ConsoleOutput $out = null, ConsoleOutput $err = null, ConsoleInput $in = null, HelperRegistry $helpers = null)
- {
- $this->_out = $out ?: new ConsoleOutput('php://stdout');
- $this->_err = $err ?: new ConsoleOutput('php://stderr');
- $this->_in = $in ?: new ConsoleInput('php://stdin');
- $this->_helpers = $helpers ?: new HelperRegistry();
- $this->_helpers->setIo($this);
- }
- /**
- * Get/set the current output level.
- *
- * @param null|int $level The current output level.
- * @return int The current output level.
- */
- public function level($level = null)
- {
- if ($level !== null) {
- $this->_level = $level;
- }
- return $this->_level;
- }
- /**
- * Output at the verbose level.
- *
- * @param string|array $message A string or an array of strings to output
- * @param int $newlines Number of newlines to append
- * @return int|bool 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 an array of strings to output
- * @param int $newlines Number of newlines to append
- * @return int|bool 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 an array of strings to output
- * @param int $newlines Number of newlines to append
- * @param int $level The message's output level, see above.
- * @return int|bool The number of bytes returned from writing to stdout.
- */
- public function out($message = '', $newlines = 1, $level = ConsoleIo::NORMAL)
- {
- if ($level <= $this->_level) {
- $this->_lastWritten = $this->_out->write($message, $newlines);
- return $this->_lastWritten;
- }
- return true;
- }
- /**
- * Overwrite some already output text.
- *
- * Useful for building progress bars, or when you want to replace
- * text already output to the screen with new text.
- *
- * **Warning** You cannot overwrite text that contains newlines.
- *
- * @param array|string $message The message to output.
- * @param int $newlines Number of newlines to append.
- * @param int|null $size The number of bytes to overwrite. Defaults to the
- * length of the last message output.
- * @return void
- */
- public function overwrite($message, $newlines = 1, $size = null)
- {
- $size = $size ?: $this->_lastWritten;
- // Output backspaces.
- $this->out(str_repeat("\x08", $size), 0);
- $newBytes = $this->out($message, 0);
- // Fill any remaining bytes with spaces.
- $fill = $size - $newBytes;
- if ($fill > 0) {
- $this->out(str_repeat(' ', $fill), 0);
- }
- if ($newlines) {
- $this->out($this->nl($newlines), 0);
- }
- // Store length of content + fill so if the new content
- // is shorter than the old content the next overwrite
- // will work.
- if ($fill > 0) {
- $this->_lastWritten = $newBytes + $fill;
- }
- }
- /**
- * 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 an array of strings to output
- * @param int $newlines Number of newlines to append
- * @return int|bool The number of bytes returned from writing to stderr.
- */
- public function err($message = '', $newlines = 1)
- {
- return $this->_err->write($message, $newlines);
- }
- /**
- * Returns a single or multiple linefeeds sequences.
- *
- * @param int $multiplier Number of times the linefeed sequence should be repeated
- * @return string
- */
- 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 int $newlines Number of newlines to pre- and append
- * @param int $width Width of the line, defaults to 79
- * @return void
- */
- public function hr($newlines = 0, $width = 79)
- {
- $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|null $default Default input value.
- * @return mixed Either the default value, or the user-provided input.
- */
- public function ask($prompt, $default = null)
- {
- return $this->_getInput($prompt, null, $default);
- }
- /**
- * Change the output mode of the stdout stream
- *
- * @param int $mode The output mode.
- * @return void
- * @see \Cake\Console\ConsoleOutput::setOutputAs()
- */
- public function setOutputAs($mode)
- {
- $this->_out->setOutputAs($mode);
- }
- /**
- * Change the output mode of the stdout stream
- *
- * @deprecated 3.5.0 Use setOutputAs() instead.
- * @param int $mode The output mode.
- * @return void
- * @see \Cake\Console\ConsoleOutput::outputAs()
- */
- public function outputAs($mode)
- {
- $this->_out->setOutputAs($mode);
- }
- /**
- * Add a new output style or get defined styles.
- *
- * @param string|null $style The style to get or create.
- * @param array|bool|null $definition The array definition of the style to change or create a style
- * or false to remove a style.
- * @return mixed If you are getting styles, the style or null will be returned. If you are creating/modifying
- * styles true will be returned.
- * @see \Cake\Console\ConsoleOutput::styles()
- */
- public function styles($style = null, $definition = null)
- {
- $this->_out->styles($style, $definition);
- }
- /**
- * 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|null $default Default input value.
- * @return mixed Either the default value, or the user-provided input.
- */
- public function askChoice($prompt, $options, $default = null)
- {
- if ($options && is_string($options)) {
- if (strpos($options, ',')) {
- $options = explode(',', $options);
- } elseif (strpos($options, '/')) {
- $options = explode('/', $options);
- } else {
- $options = [$options];
- }
- }
- $printOptions = '(' . implode('/', $options) . ')';
- $options = array_merge(
- array_map('strtolower', $options),
- array_map('strtoupper', $options),
- $options
- );
- $in = '';
- while ($in === '' || !in_array($in, $options)) {
- $in = $this->_getInput($prompt, $printOptions, $default);
- }
- return $in;
- }
- /**
- * Prompts the user for input, and returns it.
- *
- * @param string $prompt Prompt text.
- * @param string|null $options String of options. Pass null to omit.
- * @param string|null $default Default input value. Pass null to omit.
- * @return string Either the default value, or the user-provided input.
- */
- protected function _getInput($prompt, $options, $default)
- {
- $optionsText = '';
- if (isset($options)) {
- $optionsText = " $options ";
- }
- $defaultText = '';
- if ($default !== null) {
- $defaultText = "[$default] ";
- }
- $this->_out->write('<question>' . $prompt . "</question>$optionsText\n$defaultText> ", 0);
- $result = $this->_in->read();
- $result = trim($result);
- if ($default !== null && ($result === '' || $result === null)) {
- return $default;
- }
- return $result;
- }
- /**
- * Connects or disconnects the loggers to the console output.
- *
- * Used to enable or disable logging stream output to stdout and stderr
- * If you don't wish all log output in stdout or stderr
- * through Cake's Log class, call this function with `$enable=false`.
- *
- * @param int|bool $enable Use a boolean to enable/toggle all logging. Use
- * one of the verbosity constants (self::VERBOSE, self::QUIET, self::NORMAL)
- * to control logging levels. VERBOSE enables debug logs, NORMAL does not include debug logs,
- * QUIET disables notice, info and debug logs.
- * @return void
- */
- public function setLoggers($enable)
- {
- Log::drop('stdout');
- Log::drop('stderr');
- if ($enable === false) {
- return;
- }
- $outLevels = ['notice', 'info'];
- if ($enable === static::VERBOSE || $enable === true) {
- $outLevels[] = 'debug';
- }
- if ($enable !== static::QUIET) {
- $stdout = new ConsoleLog([
- 'types' => $outLevels,
- 'stream' => $this->_out
- ]);
- Log::setConfig('stdout', ['engine' => $stdout]);
- }
- $stderr = new ConsoleLog([
- 'types' => ['emergency', 'alert', 'critical', 'error', 'warning'],
- 'stream' => $this->_err,
- ]);
- Log::setConfig('stderr', ['engine' => $stderr]);
- }
- /**
- * Render a Console Helper
- *
- * Create and render the output for a helper object. If the helper
- * object has not already been loaded, it will be loaded and constructed.
- *
- * @param string $name The name of the helper to render
- * @param array $settings Configuration data for the helper.
- * @return \Cake\Console\Helper The created helper instance.
- */
- public function helper($name, array $settings = [])
- {
- $name = ucfirst($name);
- return $this->_helpers->load($name, $settings);
- }
- }
|