у меня есть OutputInterface
и я использую его, чтобы написать кучу таблиц на них через Таблица помощник. Информация имеет вложенный контекст, поэтому я хочу, чтобы выходные данные были с отступом в 4 пробела.
Я думал, что что-то вроде этого должно быть возможно
new Table($output);
$output->writeln('0. run');
$someTable->render();
$output->increaseIndentLevel(); // pseudocode
$output->writeln('1. run');
$someTable->render();
создать ожидаемый результат:
0. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
1. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
Я искал способы реализовать это. Я заметил, что OutputInterface
обеспечивает OutputFormatterStyle
Тем не менее, кажется, что это может только изменить цвета текста, и могут быть установлены некоторые параметры, которые не имеют ничего общего с добавлением или добавлением содержимого в операцию записи.
Я мог бы продлить OutputInterface
например, ConsoleOutput
Тем не менее, я также хотел бы иметь возможность добавить эту функцию в любой OutputInterfaces
(например. BufferedOutput
) также без необходимости создания ручной версии каждого из них.
И моей последней попыткой было ввести мой собственный OutputFormatter
к OutputInterface
:
<?php
namespace Hive\App;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyleInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
* IndentedOutputFormatter
**/
class IndentedOutputFormatter extends OutputFormatter
{
const INDENT_AMOUNT = 4;
private $indentLevel = 0;
/**
* Formats a message according to the given styles.
* @param string $message The message to style
* @return string The styled message
* @api
*/
public function format($message)
{
$message = parent::format($message);
if ($this->indentLevel === 0) {
return $message;
}
$amount = self::INDENT_AMOUNT * $this->indentLevel;
$prependBy = str_repeat(' ', $amount);
$message = $prependBy . $message;
return $message;
}
/**
*
*/
public function increaseLevel()
{
$this->indentLevel = $this->indentLevel + 1;
}
/**
*
*/
public function decreaseLevel()
{
$this->indentLevel = $this->indentLevel - 1;
}
}
и используя это так из команды:
/**
* @param InputInterface $input
* @param OutputInterface $output
* @return int
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$headers = [
'ISBN',
'Title',
'Author',
];
$rows = [
[
'99921-58-10-7',
'Divine Comedy',
'Dante Alighieri',
],
[
'9971-5-0210-0',
'A Tale of Two Cities',
'Charles Dickens',
],
[
'960-425-059-0',
'The Lord of the Rings',
'J. R. R. Tolkien',
],
];
$formatter = new IndentedOutputFormatter();
$output->setFormatter($formatter);
$table = new Table($output);
$table->setHeaders($headers);
$table->setRows($rows);
foreach (range(0, 3) as $currentRun) {
$output->writeln("$currentRun. run");
$formatter->increaseLevel();
$table->render();
}
return 0;
}
Тем не менее, это приводит к проблеме, заключающейся в том, что не только таблица визуализируется с помощью отступов, но и поля ее содержимого:
0. run
+-------------------+---------------------------+----------------------+
| ISBN | Title | Author |
+-------------------+---------------------------+----------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+-------------------+---------------------------+----------------------+
1. run
+-----------------------+-------------------------------+--------------------------+
| ISBN | Title | Author |
+-----------------------+-------------------------------+--------------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+-----------------------+-------------------------------+--------------------------+
2. run
+---------------------------+-----------------------------------+------------------------------+
| ISBN | Title | Author |
+---------------------------+-----------------------------------+------------------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------------------+-----------------------------------+------------------------------+
3. run
+-------------------------------+---------------------------------------+----------------------------------+
| ISBN | Title | Author |
+-------------------------------+---------------------------------------+----------------------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+-------------------------------+---------------------------------------+----------------------------------+
Как заставить работать отступ с использованием компонентов symfony2 и OutputInterface
и Table
помощник?
Это делает работу
Выходной декоратор
use Symfony\Component\Console\Output\Output;
class IndentedOutput extends Output
{
const INDENT_AMOUNT = 4;
private $output;
private $indentLevel = 0;
private $resetLine = false;
public function setOutput(OutputInterface $output)
{
$this->output = $output;
}
public function increaseLevel()
{
$this->indentLevel += 1;
}
public function decreaseLevel()
{
$this->indentLevel -= 1;
}
public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
$prependBy = str_repeat(' ', self::INDENT_AMOUNT * $this->indentLevel);
if ($newline) {
$this->resetLine = true;
$messages = $prependBy.$messages;
}
if ($this->resetLine && !$newline) {
$messages = $prependBy.$messages;
$this->resetLine = false;
}
$this->output->write($messages, $newline, $type);
}
public function doWrite($message, $newline)
{
$this->output->doWrite($message, $newline);
}
}
Тестовое задание
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Output\BufferedOutput;
$headers = [
'ISBN',
'Title',
'Author',
];
$rows = [[
'99921-58-10-7',
'Divine Comedy',
'Dante Alighieri',
],[
'9971-5-0210-0',
'A Tale of Two Cities',
'Charles Dickens',
],[
'960-425-059-0',
'The Lord of the Rings',
'J. R. R. Tolkien',
]];
$app = new Application();
$app
->register('foo')
->setCode(function(InputInterface $input, OutputInterface $output) use ($headers, $rows) {
$buffered = new BufferedOutput;
$indented = new IndentedOutput;
$indented->setOutput($buffered);
$table = new Table($indented);
$table->setHeaders($headers);
$table->setRows($rows);
foreach (range(0, 3) as $currentRun) {
$indented->writeln("$currentRun. run");
$table->render();
$indented->increaseLevel();
}
$indented->decreaseLevel();
$indented->decreaseLevel();
$indented->decreaseLevel();
$indented->decreaseLevel();
$indented->write('hello world');
$output->write($buffered->fetch());
});
$app->run();
Выход:
0. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
1. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
2. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
3. run
+---------------+-----------------------+------------------+
| ISBN | Title | Author |
+---------------+-----------------------+------------------+
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
| 9971-5-0210-0 | A Tale of Two Cities | Charles Dickens |
| 960-425-059-0 | The Lord of the Rings | J. R. R. Tolkien |
+---------------+-----------------------+------------------+
hello world
Других решений пока нет …