feature #26863 [Console] Support iterable in SymfonyStyle::write/writeln (ogizanagi)

This PR was merged into the 4.1-dev branch.

Discussion
----------

[Console] Support iterable in SymfonyStyle::write/writeln

| Q             | A
| ------------- | ---
| Branch?       | master <!-- see below -->
| Bug fix?      | no
| New feature?  | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | N/A   <!-- #-prefixed issue number(s), if any -->
| License       | MIT
| Doc PR        | N/A

Relates to https://github.com/symfony/symfony/pull/26847.

This would enable iterables benefits even when using `SymfonyStyle` output.

Commits
-------

d66827e [Console] Support iterable in SymfonyStyle::write/writeln
This commit is contained in:
Robin Chalas 2018-04-09 09:47:20 +02:00
commit 5736321ea7
3 changed files with 82 additions and 12 deletions

View File

@ -306,11 +306,14 @@ class SymfonyStyle extends OutputStyle
*/
public function writeln($messages, $type = self::OUTPUT_NORMAL)
{
if ($messages instanceof \Traversable) {
$messages = iterator_to_array($messages, false);
if (!is_iterable($messages)) {
$messages = array($messages);
}
foreach ($messages as $message) {
parent::writeln($message, $type);
$this->writeBuffer($message, true, $type);
}
parent::writeln($messages, $type);
$this->bufferedOutput->writeln($this->reduceBuffer($messages), $type);
}
/**
@ -318,11 +321,14 @@ class SymfonyStyle extends OutputStyle
*/
public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)
{
if ($messages instanceof \Traversable) {
$messages = iterator_to_array($messages, false);
if (!is_iterable($messages)) {
$messages = array($messages);
}
foreach ($messages as $message) {
parent::write($message, $newline, $type);
$this->writeBuffer($message, $newline, $type);
}
parent::write($messages, $newline, $type);
$this->bufferedOutput->write($this->reduceBuffer($messages), $newline, $type);
}
/**
@ -375,13 +381,11 @@ class SymfonyStyle extends OutputStyle
}
}
private function reduceBuffer($messages): array
private function writeBuffer(string $message, bool $newLine, int $type): void
{
// We need to know if the two last chars are PHP_EOL
// Preserve the last 4 chars inserted (PHP_EOL on windows is two chars) in the history buffer
return array_map(function ($value) {
return substr($value, -4);
}, array_merge(array($this->bufferedOutput->fetch()), (array) $messages));
$this->bufferedOutput->write(substr($message, -4), $newLine, $type);
}
private function createBlock(iterable $messages, string $type = null, string $style = null, string $prefix = ' ', bool $padding = false, bool $escape = false)

View File

@ -0,0 +1,34 @@
<?php
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
//Ensure has single blank line after any text and a title
return function (InputInterface $input, OutputInterface $output) {
$output = new SymfonyStyle($input, $output);
$output->write('Lorem ipsum dolor sit amet');
$output->title('First title');
$output->writeln('Lorem ipsum dolor sit amet');
$output->title('Second title');
$output->write('Lorem ipsum dolor sit amet');
$output->write('');
$output->title('Third title');
//Ensure edge case by appending empty strings to history:
$output->write('Lorem ipsum dolor sit amet');
$output->write(new \ArrayIterator(array('', '', '')));
$output->title('Fourth title');
//Ensure have manual control over number of blank lines:
$output->writeln('Lorem ipsum dolor sit amet');
$output->writeln(new \ArrayIterator(array('', ''))); //Should append an extra blank line
$output->title('Fifth title');
$output->writeln('Lorem ipsum dolor sit amet');
$output->newLine(2); //Should append an extra blank line
$output->title('Fifth title');
};

View File

@ -0,0 +1,32 @@
Lorem ipsum dolor sit amet
First title
===========
Lorem ipsum dolor sit amet
Second title
============
Lorem ipsum dolor sit amet
Third title
===========
Lorem ipsum dolor sit amet
Fourth title
============
Lorem ipsum dolor sit amet
Fifth title
===========
Lorem ipsum dolor sit amet
Fifth title
===========