From 692b0f41ae3efe13462d1f03b0155842e02a3a91 Mon Sep 17 00:00:00 2001 From: Serge Smertin Date: Sun, 2 Sep 2012 22:35:58 +0300 Subject: [PATCH] [Console] added select() method for DialogHelper --- src/Symfony/Component/Console/CHANGELOG.md | 1 + .../Component/Console/Helper/DialogHelper.php | 53 +++++++++++++++++++ .../Console/Tests/Helper/DialogHelperTest.php | 22 ++++++++ 3 files changed, 76 insertions(+) diff --git a/src/Symfony/Component/Console/CHANGELOG.md b/src/Symfony/Component/Console/CHANGELOG.md index a5f1722bae..ee0459e13d 100644 --- a/src/Symfony/Component/Console/CHANGELOG.md +++ b/src/Symfony/Component/Console/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * added support for colorization on Windows via ConEmu * add a method to Dialog Helper to ask for a question and hide the response + * added support for interactive selections in console (DialogHelper::select()) 2.1.0 ----- diff --git a/src/Symfony/Component/Console/Helper/DialogHelper.php b/src/Symfony/Component/Console/Helper/DialogHelper.php index 232343454e..5fcef88d5f 100644 --- a/src/Symfony/Component/Console/Helper/DialogHelper.php +++ b/src/Symfony/Component/Console/Helper/DialogHelper.php @@ -24,6 +24,59 @@ class DialogHelper extends Helper private static $shell; private static $stty; + /** + * Asks to select array value to the user. + * + * @param OutputInterface $output An Output instance + * @param string|array $question The question to ask + * @param array $choices List of choices to pick from + * @param Boolean $default The default answer if the user enters nothing + * @param array $options Display options: + * 'attempts' - Max number of times to ask before giving up (false by default, + * which means infinite) + * 'error_template' - Message which will be shown if invalid value from choice + * list would be picked. Defaults to "Value '%s' is not in provided + * in choice list" + * 'return' - What should be returned from choice list - 'key' or 'value' + * + * @return mixed + */ + public function select(OutputInterface $output, $question, $choices, $default = null, array $options = array()) + { + $options = array_merge(array( + 'attempts' => false, + 'error_template' => "Value '%s' is not in provided in choice list", + 'return' => 'key' + ), $options); + + $width = max(array_map('strlen', array_keys($choices))) + 2; + + $messages = (array) $question; + foreach ($choices as $key => $value) { + $messages[] = sprintf(" %-${width}s %s", $key, $value); + } + + $output->writeln($messages); + + $result = $this->askAndValidate($output, '> ', function($picked) use ($choices, $options) { + if (empty($choices[$picked])) { + throw new \InvalidArgumentException(sprintf($options['error_template'], $picked)); + } + + return $picked; + }, $options['attempts'], $default); + + switch($options['return']) { + case 'key': + return $result; + case 'value': + return $choices[$result]; + default: + $tpl = 'Invalid return type specified: "%s". Should be either "key" or "value".'; + throw new \InvalidArgumentException(sprintf($tpl . '', $options['return'])); + } + } + /** * Asks a question to the user. * diff --git a/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php b/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php index 658ab69b4c..1354b50139 100644 --- a/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php +++ b/src/Symfony/Component/Console/Tests/Helper/DialogHelperTest.php @@ -18,6 +18,28 @@ use Symfony\Component\Console\Output\StreamOutput; class DialogHelperTest extends \PHPUnit_Framework_TestCase { + public function testSelect() + { + $dialog = new DialogHelper(); + + $helperSet = new HelperSet(array(new FormatterHelper())); + $dialog->setHelperSet($helperSet); + + $heroes = array('Superman', 'Batman', 'Putin'); + + $dialog->setInputStream($this->getInputStream("\n1\n")); + $this->assertEquals('2', $dialog->select($this->getOutputStream(), 'What superhero rocks?', $heroes, '2')); + $this->assertEquals('1', $dialog->select($this->getOutputStream(), 'What superhero rocks?', $heroes)); + + $dialog->setInputStream($this->getInputStream("\n1\n")); + $this->assertEquals('Putin', $dialog->select($this->getOutputStream(), 'What superhero rocks?', $heroes, '2', array( + 'return' => 'value' + ))); + $this->assertEquals('Batman', $dialog->select($this->getOutputStream(), 'What superhero rocks?', $heroes, null, array( + 'return' => 'value' + ))); + } + public function testAsk() { $dialog = new DialogHelper();