Skip to content

Commit ac6611a

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

File tree

6 files changed

+601
-498
lines changed

6 files changed

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

src/Symfony/Component/Console/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
---
66

77
* Add `TesterTrait::assertCommandIsSuccessful()` to test command
8+
* `SymfonyStyle` is final since Symfony 5.4
89

910
5.3
1011
---

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)