Skip to content

Commit 991fa8c

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

File tree

4 files changed

+598
-494
lines changed

4 files changed

+598
-494
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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+
* @author Vadim Zharkov <hushker@gmail.com>
22+
*/
23+
class MessageBlock
24+
{
25+
private const MAX_LINE_LENGTH = 120;
26+
27+
public static function createBlock(
28+
iterable $messages,
29+
OutputFormatterInterface $formatter,
30+
string $type = null,
31+
string $style = null,
32+
string $prefix = ' ',
33+
bool $padding = false,
34+
bool $escape = false,
35+
int $lineLength = null,
36+
bool $isDecorated = false
37+
): array {
38+
$lineLength = $lineLength ?: self::getTerminalLineLength();
39+
$indentLength = 0;
40+
$prefixLength = Helper::width(Helper::removeDecoration($formatter, $prefix));
41+
$lines = [];
42+
43+
if (null !== $type) {
44+
$type = sprintf('[%s] ', $type);
45+
$indentLength = \strlen($type);
46+
$lineIndentation = str_repeat(' ', $indentLength);
47+
}
48+
49+
// wrap and add newlines for each element
50+
foreach ($messages as $key => $message) {
51+
if ($escape) {
52+
$message = OutputFormatter::escape($message);
53+
}
54+
55+
$decorationLength = Helper::width($message) - Helper::width(
56+
Helper::removeDecoration($formatter, $message)
57+
);
58+
$messageLineLength = min(
59+
$lineLength - $prefixLength - $indentLength + $decorationLength,
60+
$lineLength
61+
);
62+
$messageLines = explode(\PHP_EOL, wordwrap($message, $messageLineLength, \PHP_EOL, true));
63+
foreach ($messageLines as $messageLine) {
64+
$lines[] = $messageLine;
65+
}
66+
67+
if (\count($messages) > 1 && $key < \count($messages) - 1) {
68+
$lines[] = '';
69+
}
70+
}
71+
72+
$firstLineIndex = 0;
73+
if ($padding && $isDecorated) {
74+
$firstLineIndex = 1;
75+
array_unshift($lines, '');
76+
$lines[] = '';
77+
}
78+
79+
foreach ($lines as $i => &$line) {
80+
if (null !== $type) {
81+
$line = $firstLineIndex === $i ? $type.$line : $lineIndentation.$line;
82+
}
83+
84+
$line = $prefix.$line;
85+
$line .= str_repeat(
86+
' ',
87+
max(
88+
$lineLength - Helper::width(
89+
Helper::removeDecoration($formatter, $line)
90+
),
91+
0
92+
)
93+
);
94+
95+
if ($style) {
96+
$line = sprintf('<%s>%s</>', $style, $line);
97+
}
98+
}
99+
100+
return $lines;
101+
}
102+
103+
private static function getTerminalLineLength(): int
104+
{
105+
$width = (new Terminal())->getWidth() ?: self::MAX_LINE_LENGTH;
106+
107+
return $width - (int)(\DIRECTORY_SEPARATOR === '\\');
108+
}
109+
}

0 commit comments

Comments
 (0)