Skip to content

Commit 6a870f1

Browse files
committed
bug symfony#17314 Fix max width for multibyte keys in choice question (mheki)
This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes symfony#17314). Discussion ---------- Fix max width for multibyte keys in choice question Fixes wrong key max width for ChoiceQuestion in multibyte strings Before: ![before](https://cloud.githubusercontent.com/assets/2435655/12203385/977e88c0-b626-11e5-9425-d497f84a9ab3.png) After: ![after](https://cloud.githubusercontent.com/assets/2435655/12203390/9d9a0b4e-b626-11e5-8d4e-ba9290820778.png) To replicate you can use this code as an example: ``` namespace AppBundle\Command; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ChoiceQuestion; class QuesionCommand extends Command { protected function configure() { $this->setName('app:question'); $this->setDescription('Command for testing PR'); } protected function execute(InputInterface $input, OutputInterface $output) { $helper = $this->getHelper('question'); $question = new ChoiceQuestion('Choose something:', [ 'foo' => 'foo', 'żółw' => 'bar', 'łabądź' => 'baz', 'известно' => 'lorem', 'газета' => 'ipsum', ], 0); $colour = $helper->ask($input, $output, $question); $output->writeln('you have chosen: ' . $colour); } } ``` | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#15368 | License | MIT | Doc PR | - Commits ------- 5d2463b Fix max width for multibyte keys in choice question
2 parents 3c6d1a9 + 5d2463b commit 6a870f1

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,11 +162,12 @@ protected function writePrompt(OutputInterface $output, Question $question)
162162
$message = $question->getQuestion();
163163

164164
if ($question instanceof ChoiceQuestion) {
165-
$width = max(array_map('strlen', array_keys($question->getChoices())));
165+
$maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
166166

167167
$messages = (array) $question->getQuestion();
168168
foreach ($question->getChoices() as $key => $value) {
169-
$messages[] = sprintf(" [<info>%-${width}s</info>] %s", $key, $value);
169+
$width = $maxWidth - $this->strlen($key);
170+
$messages[] = ' [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
170171
}
171172

172173
$output->writeln($messages);

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Console\Tests\Helper;
1313

14+
use Symfony\Component\Console\Formatter\OutputFormatter;
1415
use Symfony\Component\Console\Helper\QuestionHelper;
1516
use Symfony\Component\Console\Helper\HelperSet;
1617
use Symfony\Component\Console\Helper\FormatterHelper;
@@ -350,6 +351,34 @@ public function testNoInteraction()
350351
$this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
351352
}
352353

354+
public function testChoiceOutputFormattingQuestionForUtf8Keys()
355+
{
356+
$question = 'Lorem ipsum?';
357+
$possibleChoices = array(
358+
'foo' => 'foo',
359+
'żółw' => 'bar',
360+
'łabądź' => 'baz',
361+
);
362+
$outputShown = array(
363+
$question,
364+
' [<info>foo </info>] foo',
365+
' [<info>żółw </info>] bar',
366+
' [<info>łabądź</info>] baz',
367+
);
368+
$output = $this->getMock('\Symfony\Component\Console\Output\OutputInterface');
369+
$output->method('getFormatter')->willReturn(new OutputFormatter());
370+
371+
$dialog = new QuestionHelper();
372+
$dialog->setInputStream($this->getInputStream("\n"));
373+
$helperSet = new HelperSet(array(new FormatterHelper()));
374+
$dialog->setHelperSet($helperSet);
375+
376+
$output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
377+
378+
$question = new ChoiceQuestion($question, $possibleChoices, 'foo');
379+
$dialog->ask($this->createInputInterfaceMock(), $output, $question);
380+
}
381+
353382
protected function getInputStream($input)
354383
{
355384
$stream = fopen('php://memory', 'r+', false);

0 commit comments

Comments
 (0)