mirror of
https://gitlab.com/signalytic/client-external/streamline/streamline-emr.git
synced 2026-09-13 03:31:31 +00:00
Import latest app updates from streamline
An updated set of source files and initialization was provided by streamline to address issues observed during initial testing. These files have been updated in order to generate a new set of app images.
This commit is contained in:
@@ -1,106 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Julien Boudry <julien@condorcet.vote>
|
||||
*/
|
||||
enum AnsiColorMode
|
||||
{
|
||||
/*
|
||||
* Classical 4-bit Ansi colors, including 8 classical colors and 8 bright color. Output syntax is "ESC[${foreGroundColorcode};${backGroundColorcode}m"
|
||||
* Must be compatible with all terminals and it's the minimal version supported.
|
||||
*/
|
||||
case Ansi4;
|
||||
|
||||
/*
|
||||
* 8-bit Ansi colors (240 different colors + 16 duplicate color codes, ensuring backward compatibility).
|
||||
* Output syntax is: "ESC[38;5;${foreGroundColorcode};48;5;${backGroundColorcode}m"
|
||||
* Should be compatible with most terminals.
|
||||
*/
|
||||
case Ansi8;
|
||||
|
||||
/*
|
||||
* 24-bit Ansi colors (RGB).
|
||||
* Output syntax is: "ESC[38;2;${foreGroundColorcodeRed};${foreGroundColorcodeGreen};${foreGroundColorcodeBlue};48;2;${backGroundColorcodeRed};${backGroundColorcodeGreen};${backGroundColorcodeBlue}m"
|
||||
* May be compatible with many modern terminals.
|
||||
*/
|
||||
case Ansi24;
|
||||
|
||||
/**
|
||||
* Converts an RGB hexadecimal color to the corresponding Ansi code.
|
||||
*/
|
||||
public function convertFromHexToAnsiColorCode(string $hexColor): string
|
||||
{
|
||||
$hexColor = str_replace('#', '', $hexColor);
|
||||
|
||||
if (3 === \strlen($hexColor)) {
|
||||
$hexColor = $hexColor[0].$hexColor[0].$hexColor[1].$hexColor[1].$hexColor[2].$hexColor[2];
|
||||
}
|
||||
|
||||
if (6 !== \strlen($hexColor)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid "#%s" color.', $hexColor));
|
||||
}
|
||||
|
||||
$color = hexdec($hexColor);
|
||||
|
||||
$r = ($color >> 16) & 255;
|
||||
$g = ($color >> 8) & 255;
|
||||
$b = $color & 255;
|
||||
|
||||
return match ($this) {
|
||||
self::Ansi4 => (string) $this->convertFromRGB($r, $g, $b),
|
||||
self::Ansi8 => '8;5;'.((string) $this->convertFromRGB($r, $g, $b)),
|
||||
self::Ansi24 => sprintf('8;2;%d;%d;%d', $r, $g, $b)
|
||||
};
|
||||
}
|
||||
|
||||
private function convertFromRGB(int $r, int $g, int $b): int
|
||||
{
|
||||
return match ($this) {
|
||||
self::Ansi4 => $this->degradeHexColorToAnsi4($r, $g, $b),
|
||||
self::Ansi8 => $this->degradeHexColorToAnsi8($r, $g, $b),
|
||||
default => throw new InvalidArgumentException("RGB cannot be converted to {$this->name}.")
|
||||
};
|
||||
}
|
||||
|
||||
private function degradeHexColorToAnsi4(int $r, int $g, int $b): int
|
||||
{
|
||||
return round($b / 255) << 2 | (round($g / 255) << 1) | round($r / 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inspired from https://github.com/ajalt/colormath/blob/e464e0da1b014976736cf97250063248fc77b8e7/colormath/src/commonMain/kotlin/com/github/ajalt/colormath/model/Ansi256.kt code (MIT license).
|
||||
*/
|
||||
private function degradeHexColorToAnsi8(int $r, int $g, int $b): int
|
||||
{
|
||||
if ($r === $g && $g === $b) {
|
||||
if ($r < 8) {
|
||||
return 16;
|
||||
}
|
||||
|
||||
if ($r > 248) {
|
||||
return 231;
|
||||
}
|
||||
|
||||
return (int) round(($r - 8) / 247 * 24) + 232;
|
||||
} else {
|
||||
return 16 +
|
||||
(36 * (int) round($r / 255 * 5)) +
|
||||
(6 * (int) round($g / 255 * 5)) +
|
||||
(int) round($b / 255 * 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
/**
|
||||
* @author Jean-François Simon <contact@jfsimon.fr>
|
||||
*/
|
||||
class BufferedOutput extends Output
|
||||
{
|
||||
private string $buffer = '';
|
||||
|
||||
/**
|
||||
* Empties buffer and returns its content.
|
||||
*/
|
||||
public function fetch(): string
|
||||
{
|
||||
$content = $this->buffer;
|
||||
$this->buffer = '';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= \PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* ConsoleOutput is the default class for all CLI output. It uses STDOUT and STDERR.
|
||||
*
|
||||
* This class is a convenient wrapper around `StreamOutput` for both STDOUT and STDERR.
|
||||
*
|
||||
* $output = new ConsoleOutput();
|
||||
*
|
||||
* This is equivalent to:
|
||||
*
|
||||
* $output = new StreamOutput(fopen('php://stdout', 'w'));
|
||||
* $stdErr = new StreamOutput(fopen('php://stderr', 'w'));
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class ConsoleOutput extends StreamOutput implements ConsoleOutputInterface
|
||||
{
|
||||
private OutputInterface $stderr;
|
||||
private array $consoleSectionOutputs = [];
|
||||
|
||||
/**
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
*/
|
||||
public function __construct(int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
parent::__construct($this->openOutputStream(), $verbosity, $decorated, $formatter);
|
||||
|
||||
if (null === $formatter) {
|
||||
// for BC reasons, stdErr has it own Formatter only when user don't inject a specific formatter.
|
||||
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$actualDecorated = $this->isDecorated();
|
||||
$this->stderr = new StreamOutput($this->openErrorStream(), $verbosity, $decorated, $this->getFormatter());
|
||||
|
||||
if (null === $decorated) {
|
||||
$this->setDecorated($actualDecorated && $this->stderr->isDecorated());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new output section.
|
||||
*/
|
||||
public function section(): ConsoleSectionOutput
|
||||
{
|
||||
return new ConsoleSectionOutput($this->getStream(), $this->consoleSectionOutputs, $this->getVerbosity(), $this->isDecorated(), $this->getFormatter());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
parent::setDecorated($decorated);
|
||||
$this->stderr->setDecorated($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
parent::setFormatter($formatter);
|
||||
$this->stderr->setFormatter($formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
parent::setVerbosity($level);
|
||||
$this->stderr->setVerbosity($level);
|
||||
}
|
||||
|
||||
public function getErrorOutput(): OutputInterface
|
||||
{
|
||||
return $this->stderr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setErrorOutput(OutputInterface $error)
|
||||
{
|
||||
$this->stderr = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current environment supports writing console output to
|
||||
* STDOUT.
|
||||
*/
|
||||
protected function hasStdoutSupport(): bool
|
||||
{
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if current environment supports writing console output to
|
||||
* STDERR.
|
||||
*/
|
||||
protected function hasStderrSupport(): bool
|
||||
{
|
||||
return false === $this->isRunningOS400();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current executing environment is IBM iSeries (OS400), which
|
||||
* doesn't properly convert character-encodings between ASCII to EBCDIC.
|
||||
*/
|
||||
private function isRunningOS400(): bool
|
||||
{
|
||||
$checks = [
|
||||
\function_exists('php_uname') ? php_uname('s') : '',
|
||||
getenv('OSTYPE'),
|
||||
\PHP_OS,
|
||||
];
|
||||
|
||||
return false !== stripos(implode(';', $checks), 'OS400');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
private function openOutputStream()
|
||||
{
|
||||
if (!$this->hasStdoutSupport()) {
|
||||
return fopen('php://output', 'w');
|
||||
}
|
||||
|
||||
// Use STDOUT when possible to prevent from opening too many file descriptors
|
||||
return \defined('STDOUT') ? \STDOUT : (@fopen('php://stdout', 'w') ?: fopen('php://output', 'w'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return resource
|
||||
*/
|
||||
private function openErrorStream()
|
||||
{
|
||||
if (!$this->hasStderrSupport()) {
|
||||
return fopen('php://output', 'w');
|
||||
}
|
||||
|
||||
// Use STDERR when possible to prevent from opening too many file descriptors
|
||||
return \defined('STDERR') ? \STDERR : (@fopen('php://stderr', 'w') ?: fopen('php://output', 'w'));
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
/**
|
||||
* ConsoleOutputInterface is the interface implemented by ConsoleOutput class.
|
||||
* This adds information about stderr and section output stream.
|
||||
*
|
||||
* @author Dariusz Górecki <darek.krk@gmail.com>
|
||||
*/
|
||||
interface ConsoleOutputInterface extends OutputInterface
|
||||
{
|
||||
/**
|
||||
* Gets the OutputInterface for errors.
|
||||
*/
|
||||
public function getErrorOutput(): OutputInterface;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setErrorOutput(OutputInterface $error);
|
||||
|
||||
public function section(): ConsoleSectionOutput;
|
||||
}
|
||||
-244
@@ -1,244 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
use Symfony\Component\Console\Helper\Helper;
|
||||
use Symfony\Component\Console\Terminal;
|
||||
|
||||
/**
|
||||
* @author Pierre du Plessis <pdples@gmail.com>
|
||||
* @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
|
||||
*/
|
||||
class ConsoleSectionOutput extends StreamOutput
|
||||
{
|
||||
private array $content = [];
|
||||
private int $lines = 0;
|
||||
private array $sections;
|
||||
private Terminal $terminal;
|
||||
private int $maxHeight = 0;
|
||||
|
||||
/**
|
||||
* @param resource $stream
|
||||
* @param ConsoleSectionOutput[] $sections
|
||||
*/
|
||||
public function __construct($stream, array &$sections, int $verbosity, bool $decorated, OutputFormatterInterface $formatter)
|
||||
{
|
||||
parent::__construct($stream, $verbosity, $decorated, $formatter);
|
||||
array_unshift($sections, $this);
|
||||
$this->sections = &$sections;
|
||||
$this->terminal = new Terminal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a maximum number of lines for this section.
|
||||
*
|
||||
* When more lines are added, the section will automatically scroll to the
|
||||
* end (i.e. remove the first lines to comply with the max height).
|
||||
*/
|
||||
public function setMaxHeight(int $maxHeight): void
|
||||
{
|
||||
// when changing max height, clear output of current section and redraw again with the new height
|
||||
$previousMaxHeight = $this->maxHeight;
|
||||
$this->maxHeight = $maxHeight;
|
||||
$existingContent = $this->popStreamContentUntilCurrentSection($previousMaxHeight ? min($previousMaxHeight, $this->lines) : $this->lines);
|
||||
|
||||
parent::doWrite($this->getVisibleContent(), false);
|
||||
parent::doWrite($existingContent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears previous output for this section.
|
||||
*
|
||||
* @param int $lines Number of lines to clear. If null, then the entire output of this section is cleared
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function clear(?int $lines = null)
|
||||
{
|
||||
if (empty($this->content) || !$this->isDecorated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($lines) {
|
||||
array_splice($this->content, -$lines);
|
||||
} else {
|
||||
$lines = $this->lines;
|
||||
$this->content = [];
|
||||
}
|
||||
|
||||
$this->lines -= $lines;
|
||||
|
||||
parent::doWrite($this->popStreamContentUntilCurrentSection($this->maxHeight ? min($this->maxHeight, $lines) : $lines), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites the previous output with a new message.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function overwrite(string|iterable $message)
|
||||
{
|
||||
$this->clear();
|
||||
$this->writeln($message);
|
||||
}
|
||||
|
||||
public function getContent(): string
|
||||
{
|
||||
return implode('', $this->content);
|
||||
}
|
||||
|
||||
public function getVisibleContent(): string
|
||||
{
|
||||
if (0 === $this->maxHeight) {
|
||||
return $this->getContent();
|
||||
}
|
||||
|
||||
return implode('', \array_slice($this->content, -$this->maxHeight));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function addContent(string $input, bool $newline = true): int
|
||||
{
|
||||
$width = $this->terminal->getWidth();
|
||||
$lines = explode(\PHP_EOL, $input);
|
||||
$linesAdded = 0;
|
||||
$count = \count($lines) - 1;
|
||||
foreach ($lines as $i => $lineContent) {
|
||||
// re-add the line break (that has been removed in the above `explode()` for
|
||||
// - every line that is not the last line
|
||||
// - if $newline is required, also add it to the last line
|
||||
if ($i < $count || $newline) {
|
||||
$lineContent .= \PHP_EOL;
|
||||
}
|
||||
|
||||
// skip line if there is no text (or newline for that matter)
|
||||
if ('' === $lineContent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For the first line, check if the previous line (last entry of `$this->content`)
|
||||
// needs to be continued (i.e. does not end with a line break).
|
||||
if (0 === $i
|
||||
&& (false !== $lastLine = end($this->content))
|
||||
&& !str_ends_with($lastLine, \PHP_EOL)
|
||||
) {
|
||||
// deduct the line count of the previous line
|
||||
$this->lines -= (int) ceil($this->getDisplayLength($lastLine) / $width) ?: 1;
|
||||
// concatenate previous and new line
|
||||
$lineContent = $lastLine.$lineContent;
|
||||
// replace last entry of `$this->content` with the new expanded line
|
||||
array_splice($this->content, -1, 1, $lineContent);
|
||||
} else {
|
||||
// otherwise just add the new content
|
||||
$this->content[] = $lineContent;
|
||||
}
|
||||
|
||||
$linesAdded += (int) ceil($this->getDisplayLength($lineContent) / $width) ?: 1;
|
||||
}
|
||||
|
||||
$this->lines += $linesAdded;
|
||||
|
||||
return $linesAdded;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function addNewLineOfInputSubmit(): void
|
||||
{
|
||||
$this->content[] = \PHP_EOL;
|
||||
++$this->lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
// Simulate newline behavior for consistent output formatting, avoiding extra logic
|
||||
if (!$newline && str_ends_with($message, \PHP_EOL)) {
|
||||
$message = substr($message, 0, -\strlen(\PHP_EOL));
|
||||
$newline = true;
|
||||
}
|
||||
|
||||
if (!$this->isDecorated()) {
|
||||
parent::doWrite($message, $newline);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the previous line (last entry of `$this->content`) needs to be continued
|
||||
// (i.e. does not end with a line break). In which case, it needs to be erased first.
|
||||
$linesToClear = $deleteLastLine = ($lastLine = end($this->content) ?: '') && !str_ends_with($lastLine, \PHP_EOL) ? 1 : 0;
|
||||
|
||||
$linesAdded = $this->addContent($message, $newline);
|
||||
|
||||
if ($lineOverflow = $this->maxHeight > 0 && $this->lines > $this->maxHeight) {
|
||||
// on overflow, clear the whole section and redraw again (to remove the first lines)
|
||||
$linesToClear = $this->maxHeight;
|
||||
}
|
||||
|
||||
$erasedContent = $this->popStreamContentUntilCurrentSection($linesToClear);
|
||||
|
||||
if ($lineOverflow) {
|
||||
// redraw existing lines of the section
|
||||
$previousLinesOfSection = \array_slice($this->content, $this->lines - $this->maxHeight, $this->maxHeight - $linesAdded);
|
||||
parent::doWrite(implode('', $previousLinesOfSection), false);
|
||||
}
|
||||
|
||||
// if the last line was removed, re-print its content together with the new content.
|
||||
// otherwise, just print the new content.
|
||||
parent::doWrite($deleteLastLine ? $lastLine.$message : $message, true);
|
||||
parent::doWrite($erasedContent, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* At initial stage, cursor is at the end of stream output. This method makes cursor crawl upwards until it hits
|
||||
* current section. Then it erases content it crawled through. Optionally, it erases part of current section too.
|
||||
*/
|
||||
private function popStreamContentUntilCurrentSection(int $numberOfLinesToClearFromCurrentSection = 0): string
|
||||
{
|
||||
$numberOfLinesToClear = $numberOfLinesToClearFromCurrentSection;
|
||||
$erasedContent = [];
|
||||
|
||||
foreach ($this->sections as $section) {
|
||||
if ($section === $this) {
|
||||
break;
|
||||
}
|
||||
|
||||
$numberOfLinesToClear += $section->maxHeight ? min($section->lines, $section->maxHeight) : $section->lines;
|
||||
if ('' !== $sectionContent = $section->getVisibleContent()) {
|
||||
if (!str_ends_with($sectionContent, \PHP_EOL)) {
|
||||
$sectionContent .= \PHP_EOL;
|
||||
}
|
||||
$erasedContent[] = $sectionContent;
|
||||
}
|
||||
}
|
||||
|
||||
if ($numberOfLinesToClear > 0) {
|
||||
// move cursor up n lines
|
||||
parent::doWrite(sprintf("\x1b[%dA", $numberOfLinesToClear), false);
|
||||
// erase to end of screen
|
||||
parent::doWrite("\x1b[0J", false);
|
||||
}
|
||||
|
||||
return implode('', array_reverse($erasedContent));
|
||||
}
|
||||
|
||||
private function getDisplayLength(string $text): int
|
||||
{
|
||||
return Helper::width(Helper::removeDecoration($this->getFormatter(), str_replace("\t", ' ', $text)));
|
||||
}
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Formatter\NullOutputFormatter;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* NullOutput suppresses all output.
|
||||
*
|
||||
* $output = new NullOutput();
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Tobias Schultze <http://tobion.de>
|
||||
*/
|
||||
class NullOutput implements OutputInterface
|
||||
{
|
||||
private NullOutputFormatter $formatter;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function getFormatter(): OutputFormatterInterface
|
||||
{
|
||||
// to comply with the interface we must return a OutputFormatterInterface
|
||||
return $this->formatter ??= new NullOutputFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function isDecorated(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
return self::VERBOSITY_QUIET;
|
||||
}
|
||||
|
||||
public function isQuiet(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function isVerbose(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isVeryVerbose(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function isDebug(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* Base class for output classes.
|
||||
*
|
||||
* There are five levels of verbosity:
|
||||
*
|
||||
* * normal: no option passed (normal output)
|
||||
* * verbose: -v (more output)
|
||||
* * very verbose: -vv (highly extended output)
|
||||
* * debug: -vvv (all debug output)
|
||||
* * quiet: -q (no output)
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
abstract class Output implements OutputInterface
|
||||
{
|
||||
private int $verbosity;
|
||||
private OutputFormatterInterface $formatter;
|
||||
|
||||
/**
|
||||
* @param int|null $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool $decorated Whether to decorate messages
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
*/
|
||||
public function __construct(?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
$this->verbosity = $verbosity ?? self::VERBOSITY_NORMAL;
|
||||
$this->formatter = $formatter ?? new OutputFormatter();
|
||||
$this->formatter->setDecorated($decorated);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
public function getFormatter(): OutputFormatterInterface
|
||||
{
|
||||
return $this->formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated)
|
||||
{
|
||||
$this->formatter->setDecorated($decorated);
|
||||
}
|
||||
|
||||
public function isDecorated(): bool
|
||||
{
|
||||
return $this->formatter->isDecorated();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level)
|
||||
{
|
||||
$this->verbosity = $level;
|
||||
}
|
||||
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
return $this->verbosity;
|
||||
}
|
||||
|
||||
public function isQuiet(): bool
|
||||
{
|
||||
return self::VERBOSITY_QUIET === $this->verbosity;
|
||||
}
|
||||
|
||||
public function isVerbose(): bool
|
||||
{
|
||||
return self::VERBOSITY_VERBOSE <= $this->verbosity;
|
||||
}
|
||||
|
||||
public function isVeryVerbose(): bool
|
||||
{
|
||||
return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;
|
||||
}
|
||||
|
||||
public function isDebug(): bool
|
||||
{
|
||||
return self::VERBOSITY_DEBUG <= $this->verbosity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
$this->write($messages, true, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = self::OUTPUT_NORMAL)
|
||||
{
|
||||
if (!is_iterable($messages)) {
|
||||
$messages = [$messages];
|
||||
}
|
||||
|
||||
$types = self::OUTPUT_NORMAL | self::OUTPUT_RAW | self::OUTPUT_PLAIN;
|
||||
$type = $types & $options ?: self::OUTPUT_NORMAL;
|
||||
|
||||
$verbosities = self::VERBOSITY_QUIET | self::VERBOSITY_NORMAL | self::VERBOSITY_VERBOSE | self::VERBOSITY_VERY_VERBOSE | self::VERBOSITY_DEBUG;
|
||||
$verbosity = $verbosities & $options ?: self::VERBOSITY_NORMAL;
|
||||
|
||||
if ($verbosity > $this->getVerbosity()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($messages as $message) {
|
||||
switch ($type) {
|
||||
case OutputInterface::OUTPUT_NORMAL:
|
||||
$message = $this->formatter->format($message);
|
||||
break;
|
||||
case OutputInterface::OUTPUT_RAW:
|
||||
break;
|
||||
case OutputInterface::OUTPUT_PLAIN:
|
||||
$message = strip_tags($this->formatter->format($message));
|
||||
break;
|
||||
}
|
||||
|
||||
$this->doWrite($message ?? '', $newline);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a message to the output.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract protected function doWrite(string $message, bool $newline);
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* OutputInterface is the interface implemented by all Output classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
interface OutputInterface
|
||||
{
|
||||
public const VERBOSITY_QUIET = 16;
|
||||
public const VERBOSITY_NORMAL = 32;
|
||||
public const VERBOSITY_VERBOSE = 64;
|
||||
public const VERBOSITY_VERY_VERBOSE = 128;
|
||||
public const VERBOSITY_DEBUG = 256;
|
||||
|
||||
public const OUTPUT_NORMAL = 1;
|
||||
public const OUTPUT_RAW = 2;
|
||||
public const OUTPUT_PLAIN = 4;
|
||||
|
||||
/**
|
||||
* Writes a message to the output.
|
||||
*
|
||||
* @param bool $newline Whether to add a newline
|
||||
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants),
|
||||
* 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function write(string|iterable $messages, bool $newline = false, int $options = 0);
|
||||
|
||||
/**
|
||||
* Writes a message to the output and adds a newline at the end.
|
||||
*
|
||||
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants),
|
||||
* 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function writeln(string|iterable $messages, int $options = 0);
|
||||
|
||||
/**
|
||||
* Sets the verbosity of the output.
|
||||
*
|
||||
* @param self::VERBOSITY_* $level
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setVerbosity(int $level);
|
||||
|
||||
/**
|
||||
* Gets the current verbosity of the output.
|
||||
*
|
||||
* @return self::VERBOSITY_*
|
||||
*/
|
||||
public function getVerbosity(): int;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is quiet (-q).
|
||||
*/
|
||||
public function isQuiet(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is verbose (-v).
|
||||
*/
|
||||
public function isVerbose(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is very verbose (-vv).
|
||||
*/
|
||||
public function isVeryVerbose(): bool;
|
||||
|
||||
/**
|
||||
* Returns whether verbosity is debug (-vvv).
|
||||
*/
|
||||
public function isDebug(): bool;
|
||||
|
||||
/**
|
||||
* Sets the decorated flag.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDecorated(bool $decorated);
|
||||
|
||||
/**
|
||||
* Gets the decorated flag.
|
||||
*/
|
||||
public function isDecorated(): bool;
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setFormatter(OutputFormatterInterface $formatter);
|
||||
|
||||
/**
|
||||
* Returns current output formatter instance.
|
||||
*/
|
||||
public function getFormatter(): OutputFormatterInterface;
|
||||
}
|
||||
@@ -1,125 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* StreamOutput writes the output to a given stream.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* $output = new StreamOutput(fopen('php://stdout', 'w'));
|
||||
*
|
||||
* As `StreamOutput` can use any stream, you can also use a file:
|
||||
*
|
||||
* $output = new StreamOutput(fopen('/path/to/output.log', 'a', false));
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class StreamOutput extends Output
|
||||
{
|
||||
/** @var resource */
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
* @param resource $stream A stream resource
|
||||
* @param int $verbosity The verbosity level (one of the VERBOSITY constants in OutputInterface)
|
||||
* @param bool|null $decorated Whether to decorate messages (null for auto-guessing)
|
||||
* @param OutputFormatterInterface|null $formatter Output formatter instance (null to use default OutputFormatter)
|
||||
*
|
||||
* @throws InvalidArgumentException When first argument is not a real stream
|
||||
*/
|
||||
public function __construct($stream, int $verbosity = self::VERBOSITY_NORMAL, ?bool $decorated = null, ?OutputFormatterInterface $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();
|
||||
|
||||
parent::__construct($verbosity, $decorated, $formatter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the stream attached to this StreamOutput instance.
|
||||
*
|
||||
* @return resource
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
if ($newline) {
|
||||
$message .= \PHP_EOL;
|
||||
}
|
||||
|
||||
@fwrite($this->stream, $message);
|
||||
|
||||
fflush($this->stream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the stream supports colorization.
|
||||
*
|
||||
* Colorization is disabled if not supported by the stream:
|
||||
*
|
||||
* This is tricky on Windows, because Cygwin, Msys2 etc emulate pseudo
|
||||
* terminals via named pipes, so we can only check the environment.
|
||||
*
|
||||
* Reference: Composer\XdebugHandler\Process::supportsColor
|
||||
* https://github.com/composer/xdebug-handler
|
||||
*
|
||||
* @return bool true if the stream supports colorization, false otherwise
|
||||
*/
|
||||
protected function hasColorSupport(): bool
|
||||
{
|
||||
// Follow https://no-color.org/
|
||||
if (isset($_SERVER['NO_COLOR']) || false !== getenv('NO_COLOR')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Detect msysgit/mingw and assume this is a tty because detection
|
||||
// does not work correctly, see https://github.com/composer/composer/issues/9690
|
||||
if (!@stream_isatty($this->stream) && !\in_array(strtoupper((string) getenv('MSYSTEM')), ['MINGW32', 'MINGW64'], true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ('\\' === \DIRECTORY_SEPARATOR && @sapi_windows_vt100_support($this->stream)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('Hyper' === getenv('TERM_PROGRAM')
|
||||
|| false !== getenv('COLORTERM')
|
||||
|| false !== getenv('ANSICON')
|
||||
|| 'ON' === getenv('ConEmuANSI')
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ('dumb' === $term = (string) getenv('TERM')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// See https://github.com/chalk/supports-color/blob/d4f413efaf8da045c5ab440ed418ef02dbb28bf1/index.js#L157
|
||||
return preg_match('/^((screen|xterm|vt100|vt220|putty|rxvt|ansi|cygwin|linux).*)|(.*-256(color)?(-bce)?)$/', $term);
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Console\Output;
|
||||
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
|
||||
|
||||
/**
|
||||
* A BufferedOutput that keeps only the last N chars.
|
||||
*
|
||||
* @author Jérémy Derussé <jeremy@derusse.com>
|
||||
*/
|
||||
class TrimmedBufferOutput extends Output
|
||||
{
|
||||
private int $maxLength;
|
||||
private string $buffer = '';
|
||||
|
||||
public function __construct(int $maxLength, ?int $verbosity = self::VERBOSITY_NORMAL, bool $decorated = false, ?OutputFormatterInterface $formatter = null)
|
||||
{
|
||||
if ($maxLength <= 0) {
|
||||
throw new InvalidArgumentException(sprintf('"%s()" expects a strictly positive maxLength. Got %d.', __METHOD__, $maxLength));
|
||||
}
|
||||
|
||||
parent::__construct($verbosity, $decorated, $formatter);
|
||||
$this->maxLength = $maxLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Empties buffer and returns its content.
|
||||
*/
|
||||
public function fetch(): string
|
||||
{
|
||||
$content = $this->buffer;
|
||||
$this->buffer = '';
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
protected function doWrite(string $message, bool $newline)
|
||||
{
|
||||
$this->buffer .= $message;
|
||||
|
||||
if ($newline) {
|
||||
$this->buffer .= \PHP_EOL;
|
||||
}
|
||||
|
||||
$this->buffer = substr($this->buffer, 0 - $this->maxLength);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user