Skip to content

Commit a02fed5

Browse files
Merge branch '6.4' into 7.2
* 6.4: [Console] Table counts wrong column width when using colspan and `setColumnMaxWidth()` [Console] Table counts wrong number of padding symbols in `renderCell()` method when cell contain unicode variant selector [Cache] Fix using a `ChainAdapter` as an adapter for a pool [Serializer] Fix collect_denormalization_errors flag in defaultContext [VarDumper] Avoid deprecated call in PgSqlCaster Fix command option mode (InputOption::VALUE_REQUIRED) [Uid] Improve entropy of the increment for UUIDv7
2 parents 74dc977 + 5d0df9f commit a02fed5

File tree

18 files changed

+177
-46
lines changed

18 files changed

+177
-46
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/TranslationDebugCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ protected function configure(): void
6969
->setDefinition([
7070
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
7171
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
72-
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'The messages domain'),
72+
new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'The messages domain'),
7373
new InputOption('only-missing', null, InputOption::VALUE_NONE, 'Display only missing messages'),
7474
new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Display only unused messages'),
7575
new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'),

src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ protected function configure(): void
7474
->setDefinition([
7575
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
7676
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
77-
new InputOption('prefix', null, InputOption::VALUE_OPTIONAL, 'Override the default prefix', '__'),
77+
new InputOption('prefix', null, InputOption::VALUE_REQUIRED, 'Override the default prefix', '__'),
7878
new InputOption('no-fill', null, InputOption::VALUE_NONE, 'Extract translation keys without filling in values'),
79-
new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf12'),
79+
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'Override the default output format', 'xlf12'),
8080
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
8181
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'),
8282
new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),
83-
new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to extract'),
83+
new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'Specify the domain to extract'),
8484
new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically'),
85-
new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
85+
new InputOption('as-tree', null, InputOption::VALUE_REQUIRED, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
8686
])
8787
->setHelp(<<<'EOF'
8888
The <info>%command.name%</info> command extracts translation strings from templates

src/Symfony/Component/Cache/DependencyInjection/CachePoolPass.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ public function process(ContainerBuilder $container): void
5555
continue;
5656
}
5757
$class = $adapter->getClass();
58+
$providers = $adapter->getArguments();
5859
while ($adapter instanceof ChildDefinition) {
5960
$adapter = $container->findDefinition($adapter->getParent());
6061
$class = $class ?: $adapter->getClass();
62+
$providers += $adapter->getArguments();
6163
if ($t = $adapter->getTag('cache.pool')) {
6264
$tags[0] += $t[0];
6365
}
@@ -87,7 +89,7 @@ public function process(ContainerBuilder $container): void
8789

8890
if (ChainAdapter::class === $class) {
8991
$adapters = [];
90-
foreach ($adapter->getArgument(0) as $provider => $adapter) {
92+
foreach ($providers['index_0'] ?? $providers[0] as $provider => $adapter) {
9193
if ($adapter instanceof ChildDefinition) {
9294
$chainedPool = $adapter;
9395
} else {

src/Symfony/Component/Cache/Tests/DependencyInjection/CachePoolPassTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ public function testChainAdapterPool()
209209
$container->register('cache.adapter.apcu', ApcuAdapter::class)
210210
->setArguments([null, 0, null])
211211
->addTag('cache.pool');
212-
$container->register('cache.chain', ChainAdapter::class)
212+
$container->register('cache.adapter.chain', ChainAdapter::class);
213+
$container->setDefinition('cache.chain', new ChildDefinition('cache.adapter.chain'))
213214
->addArgument(['cache.adapter.array', 'cache.adapter.apcu'])
214215
->addTag('cache.pool');
215216
$container->setDefinition('cache.app', new ChildDefinition('cache.chain'))
@@ -224,7 +225,7 @@ public function testChainAdapterPool()
224225
$this->assertSame('cache.chain', $appCachePool->getParent());
225226

226227
$chainCachePool = $container->getDefinition('cache.chain');
227-
$this->assertNotInstanceOf(ChildDefinition::class, $chainCachePool);
228+
$this->assertInstanceOf(ChildDefinition::class, $chainCachePool);
228229
$this->assertCount(2, $chainCachePool->getArgument(0));
229230
$this->assertInstanceOf(ChildDefinition::class, $chainCachePool->getArgument(0)[0]);
230231
$this->assertSame('cache.adapter.array', $chainCachePool->getArgument(0)[0]->getParent());

src/Symfony/Component/Console/Application.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1277,7 +1277,7 @@ private function splitStringByWidth(string $string, int $width): array
12771277

12781278
foreach (preg_split('//u', $m[0]) as $char) {
12791279
// test if $char could be appended to current line
1280-
if (mb_strwidth($line.$char, 'utf8') <= $width) {
1280+
if (Helper::width($line.$char) <= $width) {
12811281
$line .= $char;
12821282
continue;
12831283
}

src/Symfony/Component/Console/Helper/Helper.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@ public static function width(?string $string): int
4242
$string ??= '';
4343

4444
if (preg_match('//u', $string)) {
45-
return (new UnicodeString($string))->width(false);
45+
$string = preg_replace('/[\p{Cc}\x7F]++/u', '', $string, -1, $count);
46+
47+
return (new UnicodeString($string))->width(false) + $count;
4648
}
4749

4850
if (false === $encoding = mb_detect_encoding($string, null, true)) {

src/Symfony/Component/Console/Helper/Table.php

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -558,10 +558,7 @@ private function renderCell(array $row, int $column, string $cellFormat): string
558558
}
559559

560560
// str_pad won't work properly with multi-byte strings, we need to fix the padding
561-
if (false !== $encoding = mb_detect_encoding($cell, null, true)) {
562-
$width += \strlen($cell) - mb_strwidth($cell, $encoding);
563-
}
564-
561+
$width += \strlen($cell) - Helper::width($cell) - substr_count($cell, "\0");
565562
$style = $this->getColumnStyle($column);
566563

567564
if ($cell instanceof TableSeparator) {
@@ -626,8 +623,48 @@ private function buildTableRows(array $rows): TableRows
626623
foreach ($rows[$rowKey] as $column => $cell) {
627624
$colspan = $cell instanceof TableCell ? $cell->getColspan() : 1;
628625

629-
if (isset($this->columnMaxWidths[$column]) && Helper::width(Helper::removeDecoration($formatter, $cell)) > $this->columnMaxWidths[$column]) {
630-
$cell = $formatter->formatAndWrap($cell, $this->columnMaxWidths[$column] * $colspan);
626+
$minWrappedWidth = 0;
627+
$widthApplied = [];
628+
$lengthColumnBorder = $this->getColumnSeparatorWidth() + Helper::width($this->style->getCellRowContentFormat()) - 2;
629+
for ($i = $column; $i < ($column + $colspan); ++$i) {
630+
if (isset($this->columnMaxWidths[$i])) {
631+
$minWrappedWidth += $this->columnMaxWidths[$i];
632+
$widthApplied[] = ['type' => 'max', 'column' => $i];
633+
} elseif (($this->columnWidths[$i] ?? 0) > 0 && $colspan > 1) {
634+
$minWrappedWidth += $this->columnWidths[$i];
635+
$widthApplied[] = ['type' => 'min', 'column' => $i];
636+
}
637+
}
638+
if (1 === \count($widthApplied)) {
639+
if ($colspan > 1) {
640+
$minWrappedWidth *= $colspan; // previous logic
641+
}
642+
} elseif (\count($widthApplied) > 1) {
643+
$minWrappedWidth += (\count($widthApplied) - 1) * $lengthColumnBorder;
644+
}
645+
646+
$cellWidth = Helper::width(Helper::removeDecoration($formatter, $cell));
647+
if ($minWrappedWidth && $cellWidth > $minWrappedWidth) {
648+
$cell = $formatter->formatAndWrap($cell, $minWrappedWidth);
649+
}
650+
// update minimal columnWidths for spanned columns
651+
if ($colspan > 1 && $minWrappedWidth > 0) {
652+
$columnsMinWidthProcessed = [];
653+
$cellWidth = min($cellWidth, $minWrappedWidth);
654+
foreach ($widthApplied as $item) {
655+
if ('max' === $item['type'] && $cellWidth >= $this->columnMaxWidths[$item['column']]) {
656+
$minWidthColumn = $this->columnMaxWidths[$item['column']];
657+
$this->columnWidths[$item['column']] = $minWidthColumn;
658+
$columnsMinWidthProcessed[$item['column']] = true;
659+
$cellWidth -= $minWidthColumn + $lengthColumnBorder;
660+
}
661+
}
662+
for ($i = $column; $i < ($column + $colspan); ++$i) {
663+
if (isset($columnsMinWidthProcessed[$i])) {
664+
continue;
665+
}
666+
$this->columnWidths[$i] = $cellWidth + $lengthColumnBorder;
667+
}
631668
}
632669
if (!str_contains($cell ?? '', "\n")) {
633670
continue;

src/Symfony/Component/Console/Tests/Helper/TableTest.php

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1294,9 +1294,9 @@ public static function renderSetTitle()
12941294
'footer',
12951295
'default',
12961296
<<<'TABLE'
1297-
+---------------+---- Multiline
1297+
+---------------+--- Multiline
12981298
header
1299-
here -+------------------+
1299+
here +------------------+
13001300
| ISBN | Title | Author |
13011301
+---------------+--------------------------+------------------+
13021302
| 99921-58-10-7 | Divine Comedy | Dante Alighieri |
@@ -1576,17 +1576,17 @@ public function testWithColspanAndMaxWith()
15761576
$expected =
15771577
<<<TABLE
15781578
+-----------------+-----------------+-----------------+
1579-
| Lorem ipsum dolor sit amet, consectetur adipi |
1580-
| scing elit, sed do eiusmod tempor |
1579+
| Lorem ipsum dolor sit amet, consectetur adipiscing |
1580+
| elit, sed do eiusmod tempor |
15811581
+-----------------+-----------------+-----------------+
1582-
| Lorem ipsum dolor sit amet, consectetur |
1583-
| adipiscing elit, sed do eiusmod tempor |
1582+
| Lorem ipsum dolor sit amet, consectetur adipiscing |
1583+
| elit, sed do eiusmod tempor |
15841584
+-----------------+-----------------+-----------------+
1585-
| Lorem ipsum dolor sit amet, co | hello world |
1586-
| nsectetur | |
1585+
| Lorem ipsum dolor sit amet, conse | hello world |
1586+
| ctetur | |
15871587
+-----------------+-----------------+-----------------+
1588-
| hello world | Lorem ipsum dolor sit amet, co |
1589-
| | nsectetur adipiscing elit |
1588+
| hello world | Lorem ipsum dolor sit amet, conse |
1589+
| | ctetur adipiscing elit |
15901590
+-----------------+-----------------+-----------------+
15911591
| hello | world | Lorem ipsum |
15921592
| | | dolor sit amet, |
@@ -2078,4 +2078,36 @@ public function testGithubIssue52101HorizontalFalse()
20782078
$this->getOutputContent($output)
20792079
);
20802080
}
2081+
2082+
public function testGithubIssue60038WidthOfCellWithEmoji()
2083+
{
2084+
$table = (new Table($output = $this->getOutputStream()))
2085+
->setHeaderTitle('Test Title')
2086+
->setHeaders(['Title', 'Author'])
2087+
->setRows([
2088+
["🎭 💫 ☯"." Divine Comedy", "Dante Alighieri"],
2089+
// the snowflake (e2 9d 84 ef b8 8f) has a variant selector
2090+
["👑 ❄️ 🗡"." Game of Thrones", "George R.R. Martin"],
2091+
// the snowflake in text style (e2 9d 84 ef b8 8e) has a variant selector
2092+
["❄︎❄︎❄︎ snowflake in text style ❄︎❄︎❄︎", ""],
2093+
["And a very long line to show difference in previous lines", ""],
2094+
])
2095+
;
2096+
$table->render();
2097+
2098+
$this->assertSame(<<<TABLE
2099+
+---------------------------------- Test Title -------------+--------------------+
2100+
| Title | Author |
2101+
+-----------------------------------------------------------+--------------------+
2102+
| 🎭 💫 ☯ Divine Comedy | Dante Alighieri |
2103+
| 👑 ❄️ 🗡 Game of Thrones | George R.R. Martin |
2104+
| ❄︎❄︎❄︎ snowflake in text style ❄︎❄︎❄︎ | |
2105+
| And a very long line to show difference in previous lines | |
2106+
+-----------------------------------------------------------+--------------------+
2107+
2108+
TABLE
2109+
,
2110+
$this->getOutputContent($output)
2111+
);
2112+
}
20812113
}

src/Symfony/Component/Mailer/Command/MailerTestCommand.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ protected function configure(): void
3535
{
3636
$this
3737
->addArgument('to', InputArgument::REQUIRED, 'The recipient of the message')
38-
->addOption('from', null, InputOption::VALUE_OPTIONAL, 'The sender of the message', 'from@example.org')
39-
->addOption('subject', null, InputOption::VALUE_OPTIONAL, 'The subject of the message', 'Testing transport')
40-
->addOption('body', null, InputOption::VALUE_OPTIONAL, 'The body of the message', 'Testing body')
41-
->addOption('transport', null, InputOption::VALUE_OPTIONAL, 'The transport to be used')
38+
->addOption('from', null, InputOption::VALUE_REQUIRED, 'The sender of the message', 'from@example.org')
39+
->addOption('subject', null, InputOption::VALUE_REQUIRED, 'The subject of the message', 'Testing transport')
40+
->addOption('body', null, InputOption::VALUE_REQUIRED, 'The body of the message', 'Testing body')
41+
->addOption('transport', null, InputOption::VALUE_REQUIRED, 'The transport to be used')
4242
->setHelp(<<<'EOF'
4343
The <info>%command.name%</info> command tests a Mailer transport by sending a simple email message:
4444

src/Symfony/Component/Messenger/Command/FailedMessagesRemoveCommand.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ protected function configure(): void
3535
new InputArgument('id', InputArgument::OPTIONAL | InputArgument::IS_ARRAY, 'Specific message id(s) to remove'),
3636
new InputOption('all', null, InputOption::VALUE_NONE, 'Remove all failed messages from the transport'),
3737
new InputOption('force', null, InputOption::VALUE_NONE, 'Force the operation without confirmation'),
38-
new InputOption('transport', null, InputOption::VALUE_OPTIONAL, 'Use a specific failure transport', self::DEFAULT_TRANSPORT_OPTION),
38+
new InputOption('transport', null, InputOption::VALUE_REQUIRED, 'Use a specific failure transport', self::DEFAULT_TRANSPORT_OPTION),
3939
new InputOption('show-messages', null, InputOption::VALUE_NONE, 'Display messages before removing it (if multiple ids are given)'),
4040
])
4141
->setHelp(<<<'EOF'

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy