tl;dr: I want to change an output formatter style across my entire Console application without having to modify every command. How can I make a single set of changes that take effect globally?
I want to globally change the error output formatter style in my Symfony 4 Console application. As per the documentation, it's easy to do so in an ad hoc fashion per command, e.g.:
public function execute(InputInterface $input, OutputInterface $output): int {
$output->getFormatter()->setStyle('error', new OutputFormatterStyle('red'));
}
But I don't want to add needless boilerplate to all my commands--especially not with a new operator. For maintainability and testability, I prefer to override and inject my dependencies via the service container. I tried to do this by overriding the output formatter:
MyOutputFormatter.php
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
class MyOutputFormatter extends OutputFormatter {
public function __construct($decorated = FALSE, array $styles = []) {
// I've tried it this way:
$styles['error'] = new OutputFormatterStyle('red');
parent::__construct($decorated, $styles);
// I've tried it this way:
$this->setStyle('error', new OutputFormatterStyle('red'));
// And I've tried it this way:
$this->getStyle('error')->setForeground('red');
$this->getStyle('error')->setBackground();
}
}
services.yml:
Symfony\Component\Console\Formatter\OutputFormatterInterface:
alias: My\Console\Formatter\OutputFormatter
MyCommand.php
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class MyCommand extends Command {
public function execute(InputInterface $input, OutputInterface $output) {
$output->writeln("<error>I'm an error.</error>");
}
}
But I must be doing something wrong, because although my class definitely gets injected and interpreted, whether I try to override an existing style or create a new one, it has no effect: I expect my custom style to be used (red foreground with no background), the default style is used instead (white foreground with a red background).
Can someone correct my misunderstanding or suggest a better way? Thanks!!