Permalink
Browse files

[Console] added select() method for DialogHelper

  • Loading branch information...
1 parent 4dc0777 commit 219da600ff68c8d1909581f3ef24ca9c86efb3c0 @nfx nfx committed with fabpot Sep 2, 2012
Showing with 76 additions and 0 deletions.
  1. +1 −0 CHANGELOG.md
  2. +53 −0 Helper/DialogHelper.php
  3. +22 −0 Tests/Helper/DialogHelperTest.php
View
1 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
-----
View
53 Helper/DialogHelper.php
@@ -25,6 +25,59 @@ class DialogHelper extends Helper
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(" <info>%-${width}s</info> %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.
*
* @param OutputInterface $output An Output instance
View
22 Tests/Helper/DialogHelperTest.php
@@ -18,6 +18,28 @@
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();

0 comments on commit 219da60

Please sign in to comment.