Skip to content

Commit 83c91c6

Browse files
committed
[Console] Extract customizable BaseOutputStyle and reusable MessageBlock
1 parent 01613b1 commit 83c91c6

File tree

5 files changed

+601
-498
lines changed

5 files changed

+601
-498
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Console\Block;
13+
14+
use Symfony\Component\Console\Formatter\OutputFormatter;
15+
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
16+
use Symfony\Component\Console\Helper\Helper;
17+
use Symfony\Component\Console\Terminal;
18+
19+
/**
20+
* Class MessageBlock.
21+
*
22+
* @author Vadim Zharkov <hushker@gmail.com>
23+
*/
24+
class MessageBlock
25+
{
26+
private const MAX_LINE_LENGTH = 120;
27+
28+
public static function createBlock(
29+
array $messages,
30+
OutputFormatterInterface $formatter,
31+
string $type = null,
32+
string $style = null,
33+
string $prefix = ' ',
34+
bool $padding = false,
35+
bool $escape = false,
36+
int $lineLength = null,
37+
bool $isDecorated = false
38+
): array {
39+
$lineLength = $lineLength ?: self::getTerminalLineLength();
40+
$indentLength = 0;
41+
$prefixLength = Helper::width(Helper::removeDecoration($formatter, $prefix));
42+
$lines = [];
43+
44+
if (null !== $type) {
45+
$type = sprintf('[%s] ', $type);
46+
$indentLength = \strlen($type);
47+
$lineIndentation = str_repeat(' ', $indentLength);
48+
}
49+
50+
// wrap and add newlines for each element
51+
foreach ($messages as $key => $message) {
52+
if ($escape) {
53+
$message = OutputFormatter::escape($message);
54+
}
55+
56+
$decorationLength = Helper::width($message) - Helper::width(
57+
Helper::removeDecoration($formatter, $message)
58+
);
59+
$messageLineLength = min(
60+
$lineLength - $prefixLength - $indentLength + $decorationLength,
61+
$lineLength
62+
);
63+
$messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
64+
foreach ($messageLines as $messageLine) {
65+
$lines[] = $messageLine;
66+
}
67+
68+
if (\count($messages) > 1 && $key < \count($messages) - 1) {
69+
$lines[] = '';
70+
}
71+
}
72+
73+
$firstLineIndex = 0;
74+
if ($padding && $isDecorated) {
75+
$firstLineIndex = 1;
76+
array_unshift($lines, '');
77+
$lines[] = '';
78+
}
79+
80+
foreach ($lines as $i => &$line) {
81+
if (null !== $type) {
82+
$line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
83+
}
84+
85+
$line = $prefix.$line;
86+
$line .= str_repeat(
87+
' ',
88+
max(
89+
$lineLength - Helper::width(
90+
Helper::removeDecoration($formatter, $line)
91+
),
92+
0
93+
)
94+
);
95+
96+
if ($style) {
97+
$line = sprintf('<%s>%s</>', $style, $line);
98+
}
99+
}
100+
101+
return $lines;
102+
}
103+
104+
private static function getTerminalLineLength(): int
105+
{
106+
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
107+
108+
return $width - (int) (\DIRECTORY_SEPARATOR === '\\');
109+
}
110+
}

src/Symfony/Component/Console/Output/OutputInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function write($messages, bool $newline = false, int $options = 0);
4545
* @param string|iterable $messages The message as an iterable of strings or a single string
4646
* @param int $options A bitmask of options (one of the OUTPUT or VERBOSITY constants), 0 is considered the same as self::OUTPUT_NORMAL | self::VERBOSITY_NORMAL
4747
*/
48-
public function writeln($messages, int $options = 0);
48+
public function writeln($messages, int $options = self::OUTPUT_NORMAL);
4949

5050
/**
5151
* Sets the verbosity of the output.

0 commit comments

Comments
 (0)