I have an OutputInterface
and I use it to write a bunch of tables onto them via the Table helper. The information has nested context, so I want the output to be indented by 4 spaces.
I thought that something like this should be possible:
new Table($output);
$output->writeln('0. run');
$someTable->render();
$output->increaseIndentLevel(); // pseudocode
$output->writeln('1. run');
$someTable->render();
to create the expected output:
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 |
+---------------+-----------------------+------------------+
I searched for ways to implement this. I noticed that the OutputInterface
provides a OutputFormatterStyle
, yet this seems to only be able to change the colors of the text and some options can be set that have nothing to do with prepending or appending content to a write operation.
I could extend an OutputInterface
, e.g. ConsoleOutput
, yet I also would like to have the ability to add this functionality to any OutputInterfaces
(e.g. BufferedOutput
) as well, without having to create a manual version of each one.
And my last try was to inject a my own OutputFormatter
to the 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;
}
}
and using it like this from a command:
/**
* @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;
}
Yet this yields in the problem that not only the table is rendered via indentation, but also its content fields:
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 |
+-------------------------------+---------------------------------------+----------------------------------+
How can I get indentation to work using the symfony2 components of and OutputInterface
and a Table
helper?