update Piwik to version 2.16 (fixes #91)
This commit is contained in:
parent
9abe039dc8
commit
47263617c5
59 changed files with 418860 additions and 226988 deletions
|
|
@ -1,3 +0,0 @@
|
|||
vendor/
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
|
|
@ -13,6 +13,9 @@ namespace Symfony\Component\Console;
|
|||
|
||||
use Symfony\Component\Console\Descriptor\TextDescriptor;
|
||||
use Symfony\Component\Console\Descriptor\XmlDescriptor;
|
||||
use Symfony\Component\Console\Helper\DebugFormatterHelper;
|
||||
use Symfony\Component\Console\Helper\ProcessHelper;
|
||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\ArgvInput;
|
||||
use Symfony\Component\Console\Input\ArrayInput;
|
||||
|
|
@ -67,6 +70,7 @@ class Application
|
|||
private $helperSet;
|
||||
private $dispatcher;
|
||||
private $terminalDimensions;
|
||||
private $defaultCommand;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
|
@ -80,6 +84,7 @@ class Application
|
|||
{
|
||||
$this->name = $name;
|
||||
$this->version = $version;
|
||||
$this->defaultCommand = 'list';
|
||||
$this->helperSet = $this->getDefaultHelperSet();
|
||||
$this->definition = $this->getDefaultInputDefinition();
|
||||
|
||||
|
|
@ -99,7 +104,7 @@ class Application
|
|||
* @param InputInterface $input An Input instance
|
||||
* @param OutputInterface $output An Output instance
|
||||
*
|
||||
* @return integer 0 if everything went fine, or an error code
|
||||
* @return int 0 if everything went fine, or an error code
|
||||
*
|
||||
* @throws \Exception When doRun returns Exception
|
||||
*
|
||||
|
|
@ -145,9 +150,8 @@ class Application
|
|||
if ($exitCode > 255) {
|
||||
$exitCode = 255;
|
||||
}
|
||||
// @codeCoverageIgnoreStart
|
||||
|
||||
exit($exitCode);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
return $exitCode;
|
||||
|
|
@ -159,7 +163,7 @@ class Application
|
|||
* @param InputInterface $input An Input instance
|
||||
* @param OutputInterface $output An Output instance
|
||||
*
|
||||
* @return integer 0 if everything went fine, or an error code
|
||||
* @return int 0 if everything went fine, or an error code
|
||||
*/
|
||||
public function doRun(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
|
@ -180,8 +184,8 @@ class Application
|
|||
}
|
||||
|
||||
if (!$name) {
|
||||
$name = 'list';
|
||||
$input = new ArrayInput(array('command' => 'list'));
|
||||
$name = $this->defaultCommand;
|
||||
$input = new ArrayInput(array('command' => $this->defaultCommand));
|
||||
}
|
||||
|
||||
// the command name MUST be the first element of the input
|
||||
|
|
@ -219,7 +223,7 @@ class Application
|
|||
}
|
||||
|
||||
/**
|
||||
* Set an input definition set to be used with this application
|
||||
* Set an input definition set to be used with this application.
|
||||
*
|
||||
* @param InputDefinition $definition The input definition
|
||||
*
|
||||
|
|
@ -247,48 +251,31 @@ class Application
|
|||
*/
|
||||
public function getHelp()
|
||||
{
|
||||
$messages = array(
|
||||
$this->getLongVersion(),
|
||||
'',
|
||||
'<comment>Usage:</comment>',
|
||||
' [options] command [arguments]',
|
||||
'',
|
||||
'<comment>Options:</comment>',
|
||||
);
|
||||
|
||||
foreach ($this->getDefinition()->getOptions() as $option) {
|
||||
$messages[] = sprintf(' %-29s %s %s',
|
||||
'<info>--'.$option->getName().'</info>',
|
||||
$option->getShortcut() ? '<info>-'.$option->getShortcut().'</info>' : ' ',
|
||||
$option->getDescription()
|
||||
);
|
||||
}
|
||||
|
||||
return implode(PHP_EOL, $messages);
|
||||
return $this->getLongVersion();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to catch exceptions or not during commands execution.
|
||||
*
|
||||
* @param Boolean $boolean Whether to catch exceptions or not during commands execution
|
||||
* @param bool $boolean Whether to catch exceptions or not during commands execution
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setCatchExceptions($boolean)
|
||||
{
|
||||
$this->catchExceptions = (Boolean) $boolean;
|
||||
$this->catchExceptions = (bool) $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether to automatically exit after a command execution or not.
|
||||
*
|
||||
* @param Boolean $boolean Whether to automatically exit after a command execution or not
|
||||
* @param bool $boolean Whether to automatically exit after a command execution or not
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setAutoExit($boolean)
|
||||
{
|
||||
$this->autoExit = (Boolean) $boolean;
|
||||
$this->autoExit = (bool) $boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -453,7 +440,7 @@ class Application
|
|||
*
|
||||
* @param string $name The command name or alias
|
||||
*
|
||||
* @return Boolean true if the command exists, false otherwise
|
||||
* @return bool true if the command exists, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
@ -473,10 +460,10 @@ class Application
|
|||
{
|
||||
$namespaces = array();
|
||||
foreach ($this->commands as $command) {
|
||||
$namespaces[] = $this->extractNamespace($command->getName());
|
||||
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));
|
||||
|
||||
foreach ($command->getAliases() as $alias) {
|
||||
$namespaces[] = $this->extractNamespace($alias);
|
||||
$namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -501,7 +488,7 @@ class Application
|
|||
if (empty($namespaces)) {
|
||||
$message = sprintf('There are no commands defined in the "%s" namespace.', $namespace);
|
||||
|
||||
if ($alternatives = $this->findAlternatives($namespace, $allNamespaces, array())) {
|
||||
if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {
|
||||
if (1 == count($alternatives)) {
|
||||
$message .= "\n\nDid you mean this?\n ";
|
||||
} else {
|
||||
|
|
@ -550,7 +537,7 @@ class Application
|
|||
|
||||
$message = sprintf('Command "%s" is not defined.', $name);
|
||||
|
||||
if ($alternatives = $this->findAlternatives($name, $allCommands, array())) {
|
||||
if ($alternatives = $this->findAlternatives($name, $allCommands)) {
|
||||
if (1 == count($alternatives)) {
|
||||
$message .= "\n\nDid you mean this?\n ";
|
||||
} else {
|
||||
|
|
@ -632,8 +619,8 @@ class Application
|
|||
/**
|
||||
* Returns a text representation of the Application.
|
||||
*
|
||||
* @param string $namespace An optional namespace name
|
||||
* @param boolean $raw Whether to return raw command list
|
||||
* @param string $namespace An optional namespace name
|
||||
* @param bool $raw Whether to return raw command list
|
||||
*
|
||||
* @return string A string representing the Application
|
||||
*
|
||||
|
|
@ -651,8 +638,8 @@ class Application
|
|||
/**
|
||||
* Returns an XML representation of the Application.
|
||||
*
|
||||
* @param string $namespace An optional namespace name
|
||||
* @param Boolean $asDom Whether to return a DOM or an XML string
|
||||
* @param string $namespace An optional namespace name
|
||||
* @param bool $asDom Whether to return a DOM or an XML string
|
||||
*
|
||||
* @return string|\DOMDocument An XML string representing the Application
|
||||
*
|
||||
|
|
@ -675,34 +662,27 @@ class Application
|
|||
/**
|
||||
* Renders a caught exception.
|
||||
*
|
||||
* @param \Exception $e An exception instance
|
||||
* @param \Exception $e An exception instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
public function renderException($e, $output)
|
||||
{
|
||||
$strlen = function ($string) {
|
||||
if (!function_exists('mb_strlen')) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
if (false === $encoding = mb_detect_encoding($string)) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
return mb_strlen($string, $encoding);
|
||||
};
|
||||
|
||||
do {
|
||||
$title = sprintf(' [%s] ', get_class($e));
|
||||
$len = $strlen($title);
|
||||
|
||||
$len = $this->stringWidth($title);
|
||||
|
||||
$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;
|
||||
// HHVM only accepts 32 bits integer in str_split, even when PHP_INT_MAX is a 64 bit integer: https://github.com/facebook/hhvm/issues/1327
|
||||
$width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : (defined('HHVM_VERSION') ? 1 << 31 : PHP_INT_MAX);
|
||||
if (defined('HHVM_VERSION') && $width > 1 << 31) {
|
||||
$width = 1 << 31;
|
||||
}
|
||||
$formatter = $output->getFormatter();
|
||||
$lines = array();
|
||||
foreach (preg_split('/\r?\n/', $e->getMessage()) as $line) {
|
||||
foreach (str_split($line, $width - 4) as $line) {
|
||||
foreach ($this->splitStringByWidth($line, $width - 4) as $line) {
|
||||
// pre-format lines to get the right string length
|
||||
$lineLength = $strlen(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
|
||||
$lineLength = $this->stringWidth(preg_replace('/\[[^m]*m/', '', $formatter->format($line))) + 4;
|
||||
$lines[] = array($line, $lineLength);
|
||||
|
||||
$len = max($lineLength, $len);
|
||||
|
|
@ -711,7 +691,7 @@ class Application
|
|||
|
||||
$messages = array('', '');
|
||||
$messages[] = $emptyLine = $formatter->format(sprintf('<error>%s</error>', str_repeat(' ', $len)));
|
||||
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $strlen($title)))));
|
||||
$messages[] = $formatter->format(sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title)))));
|
||||
foreach ($lines as $line) {
|
||||
$messages[] = $formatter->format(sprintf('<error> %s %s</error>', $line[0], str_repeat(' ', $len - $line[1])));
|
||||
}
|
||||
|
|
@ -728,12 +708,12 @@ class Application
|
|||
$trace = $e->getTrace();
|
||||
array_unshift($trace, array(
|
||||
'function' => '',
|
||||
'file' => $e->getFile() != null ? $e->getFile() : 'n/a',
|
||||
'line' => $e->getLine() != null ? $e->getLine() : 'n/a',
|
||||
'args' => array(),
|
||||
'file' => $e->getFile() !== null ? $e->getFile() : 'n/a',
|
||||
'line' => $e->getLine() !== null ? $e->getLine() : 'n/a',
|
||||
'args' => array(),
|
||||
));
|
||||
|
||||
for ($i = 0, $count = count($trace); $i < $count; $i++) {
|
||||
for ($i = 0, $count = count($trace); $i < $count; ++$i) {
|
||||
$class = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';
|
||||
$type = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';
|
||||
$function = $trace[$i]['function'];
|
||||
|
|
@ -743,20 +723,20 @@ class Application
|
|||
$output->writeln(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line));
|
||||
}
|
||||
|
||||
$output->writeln("");
|
||||
$output->writeln("");
|
||||
$output->writeln('');
|
||||
$output->writeln('');
|
||||
}
|
||||
} while ($e = $e->getPrevious());
|
||||
|
||||
if (null !== $this->runningCommand) {
|
||||
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())));
|
||||
$output->writeln("");
|
||||
$output->writeln("");
|
||||
$output->writeln('');
|
||||
$output->writeln('');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal width in which this application runs
|
||||
* Tries to figure out the terminal width in which this application runs.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
|
|
@ -768,7 +748,7 @@ class Application
|
|||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal height in which this application runs
|
||||
* Tries to figure out the terminal height in which this application runs.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
|
|
@ -780,7 +760,7 @@ class Application
|
|||
}
|
||||
|
||||
/**
|
||||
* Tries to figure out the terminal dimensions based on the current environment
|
||||
* Tries to figure out the terminal dimensions based on the current environment.
|
||||
*
|
||||
* @return array Array containing width and height
|
||||
*/
|
||||
|
|
@ -790,7 +770,7 @@ class Application
|
|||
return $this->terminalDimensions;
|
||||
}
|
||||
|
||||
if (defined('PHP_WINDOWS_VERSION_BUILD')) {
|
||||
if ('\\' === DIRECTORY_SEPARATOR) {
|
||||
// extract [w, H] from "wxh (WxH)"
|
||||
if (preg_match('/^(\d+)x\d+ \(\d+x(\d+)\)$/', trim(getenv('ANSICON')), $matches)) {
|
||||
return array((int) $matches[1], (int) $matches[2]);
|
||||
|
|
@ -820,8 +800,8 @@ class Application
|
|||
*
|
||||
* Can be useful to force terminal dimensions for functional tests.
|
||||
*
|
||||
* @param integer $width The width
|
||||
* @param integer $height The height
|
||||
* @param int $width The width
|
||||
* @param int $height The height
|
||||
*
|
||||
* @return Application The current application
|
||||
*/
|
||||
|
|
@ -848,9 +828,9 @@ class Application
|
|||
|
||||
if (true === $input->hasParameterOption(array('--no-interaction', '-n'))) {
|
||||
$input->setInteractive(false);
|
||||
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('dialog')) {
|
||||
$inputStream = $this->getHelperSet()->get('dialog')->getInputStream();
|
||||
if (!@posix_isatty($inputStream)) {
|
||||
} elseif (function_exists('posix_isatty') && $this->getHelperSet()->has('question')) {
|
||||
$inputStream = $this->getHelperSet()->get('question')->getInputStream();
|
||||
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
|
||||
$input->setInteractive(false);
|
||||
}
|
||||
}
|
||||
|
|
@ -878,7 +858,9 @@ class Application
|
|||
* @param InputInterface $input An Input instance
|
||||
* @param OutputInterface $output An Output instance
|
||||
*
|
||||
* @return integer 0 if everything went fine, or an error code
|
||||
* @return int 0 if everything went fine, or an error code
|
||||
*
|
||||
* @throws \Exception when the command being run threw an exception
|
||||
*/
|
||||
protected function doRunCommand(Command $command, InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
|
@ -895,16 +877,20 @@ class Application
|
|||
$event = new ConsoleCommandEvent($command, $input, $output);
|
||||
$this->dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
|
||||
|
||||
try {
|
||||
$exitCode = $command->run($input, $output);
|
||||
} catch (\Exception $e) {
|
||||
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
|
||||
if ($event->commandShouldRun()) {
|
||||
try {
|
||||
$exitCode = $command->run($input, $output);
|
||||
} catch (\Exception $e) {
|
||||
$event = new ConsoleTerminateEvent($command, $input, $output, $e->getCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::TERMINATE, $event);
|
||||
|
||||
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $event->getExitCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
|
||||
$event = new ConsoleExceptionEvent($command, $input, $output, $e, $event->getExitCode());
|
||||
$this->dispatcher->dispatch(ConsoleEvents::EXCEPTION, $event);
|
||||
|
||||
throw $event->getException();
|
||||
throw $event->getException();
|
||||
}
|
||||
} else {
|
||||
$exitCode = ConsoleCommandEvent::RETURN_CODE_DISABLED;
|
||||
}
|
||||
|
||||
$event = new ConsoleTerminateEvent($command, $input, $output, $exitCode);
|
||||
|
|
@ -935,13 +921,13 @@ class Application
|
|||
return new InputDefinition(array(
|
||||
new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),
|
||||
|
||||
new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message.'),
|
||||
new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message.'),
|
||||
new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
|
||||
new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version.'),
|
||||
new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output.'),
|
||||
new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output.'),
|
||||
new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question.'),
|
||||
new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),
|
||||
new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),
|
||||
new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),
|
||||
new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this application version'),
|
||||
new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),
|
||||
new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),
|
||||
new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
@ -967,11 +953,14 @@ class Application
|
|||
new DialogHelper(),
|
||||
new ProgressHelper(),
|
||||
new TableHelper(),
|
||||
new DebugFormatterHelper(),
|
||||
new ProcessHelper(),
|
||||
new QuestionHelper(),
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs and parses stty -a if it's available, suppressing any error output
|
||||
* Runs and parses stty -a if it's available, suppressing any error output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
|
|
@ -994,7 +983,7 @@ class Application
|
|||
}
|
||||
|
||||
/**
|
||||
* Runs and parses mode CON if it's available, suppressing any error output
|
||||
* Runs and parses mode CON if it's available, suppressing any error output.
|
||||
*
|
||||
* @return string <width>x<height> or null if it could not be parsed
|
||||
*/
|
||||
|
|
@ -1050,10 +1039,10 @@ class Application
|
|||
|
||||
/**
|
||||
* Finds alternative of $name among $collection,
|
||||
* if nothing is found in $collection, try in $abbrevs
|
||||
* if nothing is found in $collection, try in $abbrevs.
|
||||
*
|
||||
* @param string $name The string
|
||||
* @param array|\Traversable $collection The collection
|
||||
* @param string $name The string
|
||||
* @param array|\Traversable $collection The collection
|
||||
*
|
||||
* @return array A sorted array of similar string
|
||||
*/
|
||||
|
|
@ -1078,7 +1067,7 @@ class Application
|
|||
}
|
||||
|
||||
$lev = levenshtein($subname, $parts[$i]);
|
||||
if ($lev <= strlen($subname) / 3 || false !== strpos($parts[$i], $subname)) {
|
||||
if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {
|
||||
$alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;
|
||||
} elseif ($exists) {
|
||||
$alternatives[$collectionName] += $threshold;
|
||||
|
|
@ -1093,9 +1082,92 @@ class Application
|
|||
}
|
||||
}
|
||||
|
||||
$alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2*$threshold; });
|
||||
$alternatives = array_filter($alternatives, function ($lev) use ($threshold) { return $lev < 2 * $threshold; });
|
||||
asort($alternatives);
|
||||
|
||||
return array_keys($alternatives);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default Command name.
|
||||
*
|
||||
* @param string $commandName The Command name
|
||||
*/
|
||||
public function setDefaultCommand($commandName)
|
||||
{
|
||||
$this->defaultCommand = $commandName;
|
||||
}
|
||||
|
||||
private function stringWidth($string)
|
||||
{
|
||||
if (!function_exists('mb_strwidth')) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
if (false === $encoding = mb_detect_encoding($string)) {
|
||||
return strlen($string);
|
||||
}
|
||||
|
||||
return mb_strwidth($string, $encoding);
|
||||
}
|
||||
|
||||
private function splitStringByWidth($string, $width)
|
||||
{
|
||||
// str_split is not suitable for multi-byte characters, we should use preg_split to get char array properly.
|
||||
// additionally, array_slice() is not enough as some character has doubled width.
|
||||
// we need a function to split string not by character count but by string width
|
||||
|
||||
if (!function_exists('mb_strwidth')) {
|
||||
return str_split($string, $width);
|
||||
}
|
||||
|
||||
if (false === $encoding = mb_detect_encoding($string)) {
|
||||
return str_split($string, $width);
|
||||
}
|
||||
|
||||
$utf8String = mb_convert_encoding($string, 'utf8', $encoding);
|
||||
$lines = array();
|
||||
$line = '';
|
||||
foreach (preg_split('//u', $utf8String) as $char) {
|
||||
// test if $char could be appended to current line
|
||||
if (mb_strwidth($line.$char, 'utf8') <= $width) {
|
||||
$line .= $char;
|
||||
continue;
|
||||
}
|
||||
// if not, push current line to array and make new line
|
||||
$lines[] = str_pad($line, $width);
|
||||
$line = $char;
|
||||
}
|
||||
if ('' !== $line) {
|
||||
$lines[] = count($lines) ? str_pad($line, $width) : $line;
|
||||
}
|
||||
|
||||
mb_convert_variables($encoding, 'utf8', $lines);
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all namespaces of the command name.
|
||||
*
|
||||
* @param string $name The full name of the command
|
||||
*
|
||||
* @return array The namespaces of the command
|
||||
*/
|
||||
private function extractAllNamespaces($name)
|
||||
{
|
||||
// -1 as third argument is needed to skip the command short name when exploding
|
||||
$parts = explode(':', $name, -1);
|
||||
$namespaces = array();
|
||||
|
||||
foreach ($parts as $part) {
|
||||
if (count($namespaces)) {
|
||||
$namespaces[] = end($namespaces).':'.$part;
|
||||
} else {
|
||||
$namespaces[] = $part;
|
||||
}
|
||||
}
|
||||
|
||||
return $namespaces;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,23 @@
|
|||
CHANGELOG
|
||||
=========
|
||||
|
||||
2.6.0
|
||||
-----
|
||||
|
||||
* added a Process helper
|
||||
* added a DebugFormatter helper
|
||||
|
||||
2.5.0
|
||||
-----
|
||||
|
||||
* deprecated the dialog helper (use the question helper instead)
|
||||
* deprecated TableHelper in favor of Table
|
||||
* deprecated ProgressHelper in favor of ProgressBar
|
||||
* added ConsoleLogger
|
||||
* added a question helper
|
||||
* added a way to set the process name of a command
|
||||
* added a way to set a default command instead of `ListCommand`
|
||||
|
||||
2.4.0
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class Command
|
|||
{
|
||||
private $application;
|
||||
private $name;
|
||||
private $processTitle;
|
||||
private $aliases = array();
|
||||
private $definition;
|
||||
private $help;
|
||||
|
|
@ -64,7 +65,7 @@ class Command
|
|||
$this->configure();
|
||||
|
||||
if (!$this->name) {
|
||||
throw new \LogicException('The command name cannot be empty.');
|
||||
throw new \LogicException(sprintf('The command defined in "%s" cannot have an empty name.', get_class($this)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,12 +129,12 @@ class Command
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks whether the command is enabled or not in the current environment
|
||||
* Checks whether the command is enabled or not in the current environment.
|
||||
*
|
||||
* Override this to check for x or y and return false if the command can not
|
||||
* run properly under the current conditions.
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
|
|
@ -158,10 +159,11 @@ class Command
|
|||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*
|
||||
* @return null|integer null or 0 if everything went fine, or an error code
|
||||
* @return null|int null or 0 if everything went fine, or an error code
|
||||
*
|
||||
* @throws \LogicException When this abstract method is not implemented
|
||||
* @see setCode()
|
||||
*
|
||||
* @see setCode()
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
{
|
||||
|
|
@ -171,6 +173,10 @@ class Command
|
|||
/**
|
||||
* Interacts with the user.
|
||||
*
|
||||
* This method is executed before the InputDefinition is validated.
|
||||
* This means that this is the only place where the command can
|
||||
* interactively ask for values of missing required arguments.
|
||||
*
|
||||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*/
|
||||
|
|
@ -201,7 +207,7 @@ class Command
|
|||
* @param InputInterface $input An InputInterface instance
|
||||
* @param OutputInterface $output An OutputInterface instance
|
||||
*
|
||||
* @return integer The command exit code
|
||||
* @return int The command exit code
|
||||
*
|
||||
* @throws \Exception
|
||||
*
|
||||
|
|
@ -229,6 +235,16 @@ class Command
|
|||
|
||||
$this->initialize($input, $output);
|
||||
|
||||
if (null !== $this->processTitle) {
|
||||
if (function_exists('cli_set_process_title')) {
|
||||
cli_set_process_title($this->processTitle);
|
||||
} elseif (function_exists('setproctitle')) {
|
||||
setproctitle($this->processTitle);
|
||||
} elseif (OutputInterface::VERBOSITY_VERY_VERBOSE === $output->getVerbosity()) {
|
||||
$output->writeln('<comment>Install the proctitle PECL to be able to change the process title.</comment>');
|
||||
}
|
||||
}
|
||||
|
||||
if ($input->isInteractive()) {
|
||||
$this->interact($input, $output);
|
||||
}
|
||||
|
|
@ -276,7 +292,7 @@ class Command
|
|||
*
|
||||
* This method is not part of public API and should not be used directly.
|
||||
*
|
||||
* @param Boolean $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
|
||||
* @param bool $mergeArgs Whether to merge or not the Application definition arguments to Command definition arguments
|
||||
*/
|
||||
public function mergeApplicationDefinition($mergeArgs = true)
|
||||
{
|
||||
|
|
@ -350,10 +366,10 @@ class Command
|
|||
/**
|
||||
* Adds an argument.
|
||||
*
|
||||
* @param string $name The argument name
|
||||
* @param integer $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
|
||||
* @param string $description A description text
|
||||
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
|
||||
* @param string $name The argument name
|
||||
* @param int $mode The argument mode: InputArgument::REQUIRED or InputArgument::OPTIONAL
|
||||
* @param string $description A description text
|
||||
* @param mixed $default The default value (for InputArgument::OPTIONAL mode only)
|
||||
*
|
||||
* @return Command The current instance
|
||||
*
|
||||
|
|
@ -369,11 +385,11 @@ class Command
|
|||
/**
|
||||
* Adds an option.
|
||||
*
|
||||
* @param string $name The option name
|
||||
* @param string $shortcut The shortcut (can be null)
|
||||
* @param integer $mode The option mode: One of the InputOption::VALUE_* constants
|
||||
* @param string $description A description text
|
||||
* @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
|
||||
* @param string $name The option name
|
||||
* @param string $shortcut The shortcut (can be null)
|
||||
* @param int $mode The option mode: One of the InputOption::VALUE_* constants
|
||||
* @param string $description A description text
|
||||
* @param mixed $default The default value (must be null for InputOption::VALUE_REQUIRED or InputOption::VALUE_NONE)
|
||||
*
|
||||
* @return Command The current instance
|
||||
*
|
||||
|
|
@ -411,6 +427,25 @@ class Command
|
|||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the process title of the command.
|
||||
*
|
||||
* This feature should be used only when creating a long process command,
|
||||
* like a daemon.
|
||||
*
|
||||
* PHP 5.5+ or the proctitle PECL library is required
|
||||
*
|
||||
* @param string $title The process title
|
||||
*
|
||||
* @return Command The current instance
|
||||
*/
|
||||
public function setProcessTitle($title)
|
||||
{
|
||||
$this->processTitle = $title;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the command name.
|
||||
*
|
||||
|
|
@ -483,7 +518,7 @@ class Command
|
|||
* Returns the processed help for the command replacing the %command.name% and
|
||||
* %command.full_name% patterns with the real values dynamically.
|
||||
*
|
||||
* @return string The processed help for the command
|
||||
* @return string The processed help for the command
|
||||
*/
|
||||
public function getProcessedHelp()
|
||||
{
|
||||
|
|
@ -491,11 +526,11 @@ class Command
|
|||
|
||||
$placeholders = array(
|
||||
'%command.name%',
|
||||
'%command.full_name%'
|
||||
'%command.full_name%',
|
||||
);
|
||||
$replacements = array(
|
||||
$name,
|
||||
$_SERVER['PHP_SELF'].' '.$name
|
||||
$_SERVER['PHP_SELF'].' '.$name,
|
||||
);
|
||||
|
||||
return str_replace($placeholders, $replacements, $this->getHelp());
|
||||
|
|
@ -504,7 +539,7 @@ class Command
|
|||
/**
|
||||
* Sets the aliases for the command.
|
||||
*
|
||||
* @param array $aliases An array of aliases for the command
|
||||
* @param string[] $aliases An array of aliases for the command
|
||||
*
|
||||
* @return Command The current instance
|
||||
*
|
||||
|
|
@ -514,6 +549,10 @@ class Command
|
|||
*/
|
||||
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);
|
||||
}
|
||||
|
|
@ -584,7 +623,7 @@ class Command
|
|||
/**
|
||||
* Returns an XML representation of the command.
|
||||
*
|
||||
* @param Boolean $asDom Whether to return a DOM or an XML string
|
||||
* @param bool $asDom Whether to return a DOM or an XML string
|
||||
*
|
||||
* @return string|\DOMDocument An XML string representing the command
|
||||
*
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ EOF
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets the command
|
||||
* Sets the command.
|
||||
*
|
||||
* @param Command $command The command to set
|
||||
*/
|
||||
|
|
@ -83,7 +83,7 @@ EOF
|
|||
$helper = new DescriptorHelper();
|
||||
$helper->describe($output, $this->command, array(
|
||||
'format' => $input->getOption('format'),
|
||||
'raw' => $input->getOption('raw'),
|
||||
'raw_text' => $input->getOption('raw'),
|
||||
));
|
||||
|
||||
$this->command = null;
|
||||
|
|
|
|||
|
|
@ -74,8 +74,8 @@ EOF
|
|||
|
||||
$helper = new DescriptorHelper();
|
||||
$helper->describe($output, $this->getApplication(), array(
|
||||
'format' => $input->getOption('format'),
|
||||
'raw_text' => $input->getOption('raw'),
|
||||
'format' => $input->getOption('format'),
|
||||
'raw_text' => $input->getOption('raw'),
|
||||
'namespace' => $input->getArgument('namespace'),
|
||||
));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ final class ConsoleEvents
|
|||
* The event listener method receives a Symfony\Component\Console\Event\ConsoleCommandEvent
|
||||
* instance.
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const COMMAND = 'console.command';
|
||||
|
|
@ -37,6 +39,8 @@ final class ConsoleEvents
|
|||
* The event listener method receives a Symfony\Component\Console\Event\ConsoleTerminateEvent
|
||||
* instance.
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const TERMINATE = 'console.terminate';
|
||||
|
|
@ -49,6 +53,8 @@ final class ConsoleEvents
|
|||
* a Symfony\Component\Console\Event\ConsoleExceptionEvent
|
||||
* instance.
|
||||
*
|
||||
* @Event
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const EXCEPTION = 'console.exception';
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ use Symfony\Component\Console\Command\Command;
|
|||
|
||||
/**
|
||||
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ApplicationDescription
|
||||
{
|
||||
|
|
@ -144,9 +146,11 @@ class ApplicationDescription
|
|||
}
|
||||
ksort($namespacedCommands);
|
||||
|
||||
foreach ($namespacedCommands as &$commands) {
|
||||
ksort($commands);
|
||||
foreach ($namespacedCommands as &$commandsSet) {
|
||||
ksort($commandsSet);
|
||||
}
|
||||
// unset reference to keep scope clear
|
||||
unset($commandsSet);
|
||||
|
||||
return $namespacedCommands;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||
|
||||
/**
|
||||
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
abstract class Descriptor implements DescriptorInterface
|
||||
{
|
||||
|
|
@ -59,8 +61,8 @@ abstract class Descriptor implements DescriptorInterface
|
|||
/**
|
||||
* Writes content to output.
|
||||
*
|
||||
* @param string $content
|
||||
* @param boolean $decorated
|
||||
* @param string $content
|
||||
* @param bool $decorated
|
||||
*/
|
||||
protected function write($content, $decorated = false)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Symfony\Component\Console\Input\InputOption;
|
|||
* JSON descriptor.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class JsonDescriptor extends Descriptor
|
||||
{
|
||||
|
|
@ -97,11 +99,11 @@ class JsonDescriptor extends Descriptor
|
|||
private function getInputArgumentData(InputArgument $argument)
|
||||
{
|
||||
return array(
|
||||
'name' => $argument->getName(),
|
||||
'name' => $argument->getName(),
|
||||
'is_required' => $argument->isRequired(),
|
||||
'is_array' => $argument->isArray(),
|
||||
'is_array' => $argument->isArray(),
|
||||
'description' => $argument->getDescription(),
|
||||
'default' => $argument->getDefault(),
|
||||
'default' => $argument->getDefault(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -113,13 +115,13 @@ class JsonDescriptor extends Descriptor
|
|||
private function getInputOptionData(InputOption $option)
|
||||
{
|
||||
return array(
|
||||
'name' => '--'.$option->getName(),
|
||||
'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
|
||||
'accept_value' => $option->acceptValue(),
|
||||
'name' => '--'.$option->getName(),
|
||||
'shortcut' => $option->getShortcut() ? '-'.implode('|-', explode('|', $option->getShortcut())) : '',
|
||||
'accept_value' => $option->acceptValue(),
|
||||
'is_value_required' => $option->isValueRequired(),
|
||||
'is_multiple' => $option->isArray(),
|
||||
'description' => $option->getDescription(),
|
||||
'default' => $option->getDefault(),
|
||||
'is_multiple' => $option->isArray(),
|
||||
'description' => $option->getDescription(),
|
||||
'default' => $option->getDefault(),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -154,12 +156,12 @@ class JsonDescriptor extends Descriptor
|
|||
$command->mergeApplicationDefinition(false);
|
||||
|
||||
return array(
|
||||
'name' => $command->getName(),
|
||||
'usage' => $command->getSynopsis(),
|
||||
'name' => $command->getName(),
|
||||
'usage' => $command->getSynopsis(),
|
||||
'description' => $command->getDescription(),
|
||||
'help' => $command->getProcessedHelp(),
|
||||
'aliases' => $command->getAliases(),
|
||||
'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
|
||||
'help' => $command->getProcessedHelp(),
|
||||
'aliases' => $command->getAliases(),
|
||||
'definition' => $this->getInputDefinitionData($command->getNativeDefinition()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Symfony\Component\Console\Input\InputOption;
|
|||
* Markdown descriptor.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class MarkdownDescriptor extends Descriptor
|
||||
{
|
||||
|
|
@ -103,7 +105,7 @@ class MarkdownDescriptor extends Descriptor
|
|||
$this->write($help);
|
||||
}
|
||||
|
||||
if ($definition = $command->getNativeDefinition()) {
|
||||
if ($command->getNativeDefinition()) {
|
||||
$this->write("\n\n");
|
||||
$this->describeInputDefinition($command->getNativeDefinition());
|
||||
}
|
||||
|
|
@ -128,7 +130,7 @@ class MarkdownDescriptor extends Descriptor
|
|||
$this->write("\n\n");
|
||||
$this->write(implode("\n", array_map(function ($commandName) {
|
||||
return '* '.$commandName;
|
||||
} , $namespace['commands'])));
|
||||
}, $namespace['commands'])));
|
||||
}
|
||||
|
||||
foreach ($description->getCommands() as $command) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Symfony\Component\Console\Input\InputOption;
|
|||
* Text descriptor.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class TextDescriptor extends Descriptor
|
||||
{
|
||||
|
|
@ -157,13 +159,37 @@ class TextDescriptor extends Descriptor
|
|||
$this->writeText("\n");
|
||||
}
|
||||
} else {
|
||||
if ('' != $help = $application->getHelp()) {
|
||||
$this->writeText("$help\n\n", $options);
|
||||
}
|
||||
|
||||
$this->writeText("<comment>Usage:</comment>\n", $options);
|
||||
$this->writeText(" command [options] [arguments]\n\n", $options);
|
||||
$this->writeText('<comment>Options:</comment>', $options);
|
||||
|
||||
$inputOptions = $application->getDefinition()->getOptions();
|
||||
|
||||
$width = 0;
|
||||
foreach ($inputOptions as $option) {
|
||||
$nameLength = strlen($option->getName()) + 2;
|
||||
if ($option->getShortcut()) {
|
||||
$nameLength += strlen($option->getShortcut()) + 3;
|
||||
}
|
||||
$width = max($width, $nameLength);
|
||||
}
|
||||
++$width;
|
||||
|
||||
foreach ($inputOptions as $option) {
|
||||
$this->writeText("\n", $options);
|
||||
$this->describeInputOption($option, array_merge($options, array('name_width' => $width)));
|
||||
}
|
||||
|
||||
$this->writeText("\n\n", $options);
|
||||
|
||||
$width = $this->getColumnWidth($description->getCommands());
|
||||
|
||||
$this->writeText($application->getHelp(), $options);
|
||||
$this->writeText("\n\n");
|
||||
|
||||
if ($describedNamespace) {
|
||||
$this->writeText(sprintf("<comment>Available commands for the \"%s\" namespace:</comment>", $describedNamespace), $options);
|
||||
$this->writeText(sprintf('<comment>Available commands for the "%s" namespace:</comment>', $describedNamespace), $options);
|
||||
} else {
|
||||
$this->writeText('<comment>Available commands:</comment>', $options);
|
||||
}
|
||||
|
|
@ -177,7 +203,7 @@ class TextDescriptor extends Descriptor
|
|||
|
||||
foreach ($namespace['commands'] as $name) {
|
||||
$this->writeText("\n");
|
||||
$this->writeText(sprintf(" <info>%-${width}s</info> %s", $name, $description->getCommand($name)->getDescription()), $options);
|
||||
$this->writeText(sprintf(" <info>%-${width}s</info> %s", $name, $description->getCommand($name)->getDescription()), $options);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,7 +231,7 @@ class TextDescriptor extends Descriptor
|
|||
*/
|
||||
private function formatDefaultValue($default)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.4', '<')) {
|
||||
if (PHP_VERSION_ID < 50400) {
|
||||
return str_replace('\/', '/', json_encode($default));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Symfony\Component\Console\Input\InputOption;
|
|||
* XML descriptor.
|
||||
*
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class XmlDescriptor extends Descriptor
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,10 +12,51 @@
|
|||
namespace Symfony\Component\Console\Event;
|
||||
|
||||
/**
|
||||
* Allows to do things before the command is executed.
|
||||
* Allows to do things before the command is executed, like skipping the command or changing the input.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ConsoleCommandEvent extends ConsoleEvent
|
||||
{
|
||||
/**
|
||||
* The return code for skipped commands, this will also be passed into the terminate event
|
||||
*/
|
||||
const RETURN_CODE_DISABLED = 113;
|
||||
|
||||
/**
|
||||
* Indicates if the command should be run or skipped
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $commandShouldRun = true;
|
||||
|
||||
/**
|
||||
* Disables the command, so it won't be run
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function disableCommand()
|
||||
{
|
||||
return $this->commandShouldRun = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the command
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enableCommand()
|
||||
{
|
||||
return $this->commandShouldRun = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the command is runnable, false otherwise
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function commandShouldRun()
|
||||
{
|
||||
return $this->commandShouldRun;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ class ConsoleExceptionEvent extends ConsoleEvent
|
|||
/**
|
||||
* Gets the exit code.
|
||||
*
|
||||
* @return integer The command exit code
|
||||
* @return int The command exit code
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class ConsoleTerminateEvent extends ConsoleEvent
|
|||
/**
|
||||
* The exit code of the command.
|
||||
*
|
||||
* @var integer
|
||||
* @var int
|
||||
*/
|
||||
private $exitCode;
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ class ConsoleTerminateEvent extends ConsoleEvent
|
|||
/**
|
||||
* Sets the exit code.
|
||||
*
|
||||
* @param integer $exitCode The command exit code
|
||||
* @param int $exitCode The command exit code
|
||||
*/
|
||||
public function setExitCode($exitCode)
|
||||
{
|
||||
|
|
@ -49,7 +49,7 @@ class ConsoleTerminateEvent extends ConsoleEvent
|
|||
/**
|
||||
* Gets the exit code.
|
||||
*
|
||||
* @return integer The command exit code
|
||||
* @return int The command exit code
|
||||
*/
|
||||
public function getExitCode()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,20 +33,20 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
*/
|
||||
public static function escape($text)
|
||||
{
|
||||
return preg_replace('/([^\\\\]?)</is', '$1\\<', $text);
|
||||
return preg_replace('/([^\\\\]?)</', '$1\\<', $text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes console output formatter.
|
||||
*
|
||||
* @param Boolean $decorated Whether this formatter should actually decorate strings
|
||||
* @param bool $decorated Whether this formatter should actually decorate strings
|
||||
* @param OutputFormatterStyleInterface[] $styles Array of "name => FormatterStyle" instances
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function __construct($decorated = false, array $styles = array())
|
||||
{
|
||||
$this->decorated = (Boolean) $decorated;
|
||||
$this->decorated = (bool) $decorated;
|
||||
|
||||
$this->setStyle('error', new OutputFormatterStyle('white', 'red'));
|
||||
$this->setStyle('info', new OutputFormatterStyle('green'));
|
||||
|
|
@ -63,19 +63,19 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
/**
|
||||
* Sets the decorated flag.
|
||||
*
|
||||
* @param Boolean $decorated Whether to decorate the messages or not
|
||||
* @param bool $decorated Whether to decorate the messages or not
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
public function setDecorated($decorated)
|
||||
{
|
||||
$this->decorated = (Boolean) $decorated;
|
||||
$this->decorated = (bool) $decorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the decorated flag.
|
||||
*
|
||||
* @return Boolean true if the output will decorate messages, false otherwise
|
||||
* @return bool true if the output will decorate messages, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
@ -102,7 +102,7 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
@ -142,14 +142,19 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
*/
|
||||
public function format($message)
|
||||
{
|
||||
$message = (string) $message;
|
||||
$offset = 0;
|
||||
$output = '';
|
||||
$tagRegex = '[a-z][a-z0-9_=;-]*';
|
||||
preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#isx", $message, $matches, PREG_OFFSET_CAPTURE);
|
||||
preg_match_all("#<(($tagRegex) | /($tagRegex)?)>#ix", $message, $matches, PREG_OFFSET_CAPTURE);
|
||||
foreach ($matches[0] as $i => $match) {
|
||||
$pos = $match[1];
|
||||
$text = $match[0];
|
||||
|
||||
if (0 != $pos && '\\' == $message[$pos - 1]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// add the text up to the next tag
|
||||
$output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));
|
||||
$offset = $pos + strlen($text);
|
||||
|
|
@ -164,9 +169,6 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
if (!$open && !$tag) {
|
||||
// </>
|
||||
$this->styleStack->pop();
|
||||
} elseif ($pos && '\\' == $message[$pos - 1]) {
|
||||
// escaped tag
|
||||
$output .= $this->applyCurrentStyle($text);
|
||||
} elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {
|
||||
$output .= $this->applyCurrentStyle($text);
|
||||
} elseif ($open) {
|
||||
|
|
@ -194,7 +196,7 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
*
|
||||
* @param string $string
|
||||
*
|
||||
* @return OutputFormatterStyle|Boolean false if string is not format string
|
||||
* @return OutputFormatterStyle|bool false if string is not format string
|
||||
*/
|
||||
private function createStyleFromString($string)
|
||||
{
|
||||
|
|
@ -215,7 +217,11 @@ class OutputFormatter implements OutputFormatterInterface
|
|||
} elseif ('bg' == $match[0]) {
|
||||
$style->setBackground($match[1]);
|
||||
} else {
|
||||
$style->setOption($match[1]);
|
||||
try {
|
||||
$style->setOption($match[1]);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ interface OutputFormatterInterface
|
|||
/**
|
||||
* Sets the decorated flag.
|
||||
*
|
||||
* @param Boolean $decorated Whether to decorate the messages or not
|
||||
* @param bool $decorated Whether to decorate the messages or not
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
@ -32,7 +32,7 @@ interface OutputFormatterInterface
|
|||
/**
|
||||
* Gets the decorated flag.
|
||||
*
|
||||
* @return Boolean true if the output will decorate messages, false otherwise
|
||||
* @return bool true if the output will decorate messages, false otherwise
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
@ -53,7 +53,7 @@ interface OutputFormatterInterface
|
|||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return Boolean
|
||||
* @return bool
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -21,31 +21,33 @@ namespace Symfony\Component\Console\Formatter;
|
|||
class OutputFormatterStyle implements OutputFormatterStyleInterface
|
||||
{
|
||||
private static $availableForegroundColors = array(
|
||||
'black' => 30,
|
||||
'red' => 31,
|
||||
'green' => 32,
|
||||
'yellow' => 33,
|
||||
'blue' => 34,
|
||||
'magenta' => 35,
|
||||
'cyan' => 36,
|
||||
'white' => 37
|
||||
'black' => array('set' => 30, 'unset' => 39),
|
||||
'red' => array('set' => 31, 'unset' => 39),
|
||||
'green' => array('set' => 32, 'unset' => 39),
|
||||
'yellow' => array('set' => 33, 'unset' => 39),
|
||||
'blue' => array('set' => 34, 'unset' => 39),
|
||||
'magenta' => array('set' => 35, 'unset' => 39),
|
||||
'cyan' => array('set' => 36, 'unset' => 39),
|
||||
'white' => array('set' => 37, 'unset' => 39),
|
||||
'default' => array('set' => 39, 'unset' => 39),
|
||||
);
|
||||
private static $availableBackgroundColors = array(
|
||||
'black' => 40,
|
||||
'red' => 41,
|
||||
'green' => 42,
|
||||
'yellow' => 43,
|
||||
'blue' => 44,
|
||||
'magenta' => 45,
|
||||
'cyan' => 46,
|
||||
'white' => 47
|
||||
'black' => array('set' => 40, 'unset' => 49),
|
||||
'red' => array('set' => 41, 'unset' => 49),
|
||||
'green' => array('set' => 42, 'unset' => 49),
|
||||
'yellow' => array('set' => 43, 'unset' => 49),
|
||||
'blue' => array('set' => 44, 'unset' => 49),
|
||||
'magenta' => array('set' => 45, 'unset' => 49),
|
||||
'cyan' => array('set' => 46, 'unset' => 49),
|
||||
'white' => array('set' => 47, 'unset' => 49),
|
||||
'default' => array('set' => 49, 'unset' => 49),
|
||||
);
|
||||
private static $availableOptions = array(
|
||||
'bold' => 1,
|
||||
'underscore' => 4,
|
||||
'blink' => 5,
|
||||
'reverse' => 7,
|
||||
'conceal' => 8
|
||||
'bold' => array('set' => 1, 'unset' => 22),
|
||||
'underscore' => array('set' => 4, 'unset' => 24),
|
||||
'blink' => array('set' => 5, 'unset' => 25),
|
||||
'reverse' => array('set' => 7, 'unset' => 27),
|
||||
'conceal' => array('set' => 8, 'unset' => 28),
|
||||
);
|
||||
|
||||
private $foreground;
|
||||
|
|
@ -149,7 +151,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
|||
));
|
||||
}
|
||||
|
||||
if (false === array_search(static::$availableOptions[$option], $this->options)) {
|
||||
if (!in_array(static::$availableOptions[$option], $this->options)) {
|
||||
$this->options[] = static::$availableOptions[$option];
|
||||
}
|
||||
}
|
||||
|
|
@ -160,7 +162,6 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
|||
* @param string $option The option name
|
||||
*
|
||||
* @throws \InvalidArgumentException When the option name isn't defined
|
||||
*
|
||||
*/
|
||||
public function unsetOption($option)
|
||||
{
|
||||
|
|
@ -201,22 +202,28 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
|
|||
*/
|
||||
public function apply($text)
|
||||
{
|
||||
$codes = array();
|
||||
$setCodes = array();
|
||||
$unsetCodes = array();
|
||||
|
||||
if (null !== $this->foreground) {
|
||||
$codes[] = $this->foreground;
|
||||
$setCodes[] = $this->foreground['set'];
|
||||
$unsetCodes[] = $this->foreground['unset'];
|
||||
}
|
||||
if (null !== $this->background) {
|
||||
$codes[] = $this->background;
|
||||
$setCodes[] = $this->background['set'];
|
||||
$unsetCodes[] = $this->background['unset'];
|
||||
}
|
||||
if (count($this->options)) {
|
||||
$codes = array_merge($codes, $this->options);
|
||||
foreach ($this->options as $option) {
|
||||
$setCodes[] = $option['set'];
|
||||
$unsetCodes[] = $option['unset'];
|
||||
}
|
||||
}
|
||||
|
||||
if (0 === count($codes)) {
|
||||
if (0 === count($setCodes)) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
return sprintf("\033[%sm%s\033[0m", implode(';', $codes), $text);
|
||||
return sprintf("\033[%sm%s\033[%sm", implode(';', $setCodes), $text, implode(';', $unsetCodes));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class OutputFormatterStyleStack
|
|||
*
|
||||
* @return OutputFormatterStyleInterface
|
||||
*
|
||||
* @throws \InvalidArgumentException When style tags incorrectly nested
|
||||
* @throws \InvalidArgumentException When style tags incorrectly nested
|
||||
*/
|
||||
public function pop(OutputFormatterStyleInterface $style = null)
|
||||
{
|
||||
|
|
@ -96,7 +96,7 @@ class OutputFormatterStyleStack
|
|||
return $this->emptyStyle;
|
||||
}
|
||||
|
||||
return $this->styles[count($this->styles)-1];
|
||||
return $this->styles[count($this->styles) - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue