bug #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 #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 | https://github.com/symfony/symfony/issues/15368
| License | MIT
| Doc PR | -
Commits
-------
5d2463b
Fix max width for multibyte keys in choice question
This commit is contained in:
commit
6a870f12ae
@ -162,11 +162,12 @@ class QuestionHelper extends Helper
|
|||||||
$message = $question->getQuestion();
|
$message = $question->getQuestion();
|
||||||
|
|
||||||
if ($question instanceof ChoiceQuestion) {
|
if ($question instanceof ChoiceQuestion) {
|
||||||
$width = max(array_map('strlen', array_keys($question->getChoices())));
|
$maxWidth = max(array_map(array($this, 'strlen'), array_keys($question->getChoices())));
|
||||||
|
|
||||||
$messages = (array) $question->getQuestion();
|
$messages = (array) $question->getQuestion();
|
||||||
foreach ($question->getChoices() as $key => $value) {
|
foreach ($question->getChoices() as $key => $value) {
|
||||||
$messages[] = sprintf(" [<info>%-${width}s</info>] %s", $key, $value);
|
$width = $maxWidth - $this->strlen($key);
|
||||||
|
$messages[] = ' [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
|
||||||
}
|
}
|
||||||
|
|
||||||
$output->writeln($messages);
|
$output->writeln($messages);
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Console\Tests\Helper;
|
namespace Symfony\Component\Console\Tests\Helper;
|
||||||
|
|
||||||
|
use Symfony\Component\Console\Formatter\OutputFormatter;
|
||||||
use Symfony\Component\Console\Helper\QuestionHelper;
|
use Symfony\Component\Console\Helper\QuestionHelper;
|
||||||
use Symfony\Component\Console\Helper\HelperSet;
|
use Symfony\Component\Console\Helper\HelperSet;
|
||||||
use Symfony\Component\Console\Helper\FormatterHelper;
|
use Symfony\Component\Console\Helper\FormatterHelper;
|
||||||
@ -350,6 +351,34 @@ class QuestionHelperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
|
$this->assertEquals('not yet', $dialog->ask($this->createInputInterfaceMock(false), $this->createOutputInterface(), $question));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testChoiceOutputFormattingQuestionForUtf8Keys()
|
||||||
|
{
|
||||||
|
$question = 'Lorem ipsum?';
|
||||||
|
$possibleChoices = array(
|
||||||
|
'foo' => 'foo',
|
||||||
|
'żółw' => 'bar',
|
||||||
|
'łabądź' => 'baz',
|
||||||
|
);
|
||||||
|
$outputShown = array(
|
||||||
|
$question,
|
||||||
|
' [<info>foo </info>] foo',
|
||||||
|
' [<info>żółw </info>] bar',
|
||||||
|
' [<info>łabądź</info>] baz',
|
||||||
|
);
|
||||||
|
$output = $this->getMock('\Symfony\Component\Console\Output\OutputInterface');
|
||||||
|
$output->method('getFormatter')->willReturn(new OutputFormatter());
|
||||||
|
|
||||||
|
$dialog = new QuestionHelper();
|
||||||
|
$dialog->setInputStream($this->getInputStream("\n"));
|
||||||
|
$helperSet = new HelperSet(array(new FormatterHelper()));
|
||||||
|
$dialog->setHelperSet($helperSet);
|
||||||
|
|
||||||
|
$output->expects($this->once())->method('writeln')->with($this->equalTo($outputShown));
|
||||||
|
|
||||||
|
$question = new ChoiceQuestion($question, $possibleChoices, 'foo');
|
||||||
|
$dialog->ask($this->createInputInterfaceMock(), $output, $question);
|
||||||
|
}
|
||||||
|
|
||||||
protected function getInputStream($input)
|
protected function getInputStream($input)
|
||||||
{
|
{
|
||||||
$stream = fopen('php://memory', 'r+', false);
|
$stream = fopen('php://memory', 'r+', false);
|
||||||
|
Reference in New Issue
Block a user