Как сделать отступ в операциях записи с использованием symfony2-компоновок OutputInterface и помощника Table?

у меня есть 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 помощник?

3

Решение

Это делает работу

Выходной декоратор

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
3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]