From eb5b12ff4631884ba56ef75fc6a924e1c3b2ef43 Mon Sep 17 00:00:00 2001 From: geoffrey Date: Mon, 11 Jan 2010 12:24:08 +0100 Subject: [PATCH] [Console] implemented helpers and moved formatter and ask* methods to their own helpers --- .../Components/Console/Command/Command.php | 48 ++++++- .../Console/Helper/FormatterHelper.php | 9 ++ .../Components/Console/Helper/Helper.php | 8 +- .../Console/Helper/HelperInterface.php | 22 ++-- .../Components/Console/Helper/HelperSet.php | 9 +- .../Console/Helper/InteractHelper.php | 119 ++++++++++++++++++ 6 files changed, 190 insertions(+), 25 deletions(-) create mode 100644 src/Symfony/Components/Console/Helper/InteractHelper.php diff --git a/src/Symfony/Components/Console/Command/Command.php b/src/Symfony/Components/Console/Command/Command.php index 013b239cbf..7fb727b090 100644 --- a/src/Symfony/Components/Console/Command/Command.php +++ b/src/Symfony/Components/Console/Command/Command.php @@ -8,6 +8,9 @@ use Symfony\Components\Console\Input\InputArgument; use Symfony\Components\Console\Input\InputInterface; use Symfony\Components\Console\Output\OutputInterface; use Symfony\Components\Console\Application; +use Symfony\Components\Console\Helper\HelperSet; +use Symfony\Components\Console\Helper\FormatterHelper; +use Symfony\Components\Console\Helper\InteractHelper; /* * This file is part of the symfony framework. @@ -42,15 +45,26 @@ class Command /** * Constructor. * - * @param string $name The name of the command + * @param string $name + * @param HelperSet $helperSet A helper set instance */ - public function __construct($name = null) + public function __construct($name = null, HelperSet $helperSet = null) { $this->definition = new InputDefinition(); $this->ignoreValidationErrors = false; $this->applicationDefinitionMerged = false; $this->aliases = array(); + if (null === $helperSet) + { + $helperSet = new HelperSet(array( + new FormatterHelper(), + new InteractHelper(), + )); + } + + $this->setHelperSet($helperSet); + if (null !== $name) { $this->setName($name); @@ -389,17 +403,39 @@ class Command } /** - * Gets a helper instance by name. + * Set a helper set to be used with the command. * - * @param string $name The helper name + * @param HelperSet $helperSet The helper set + */ + public function setHelperSet(HelperSet $helperSet) + { + $this->helperSet = $helperSet; + + $helperSet->setCommand($this); + } + + /** + * Get the helper set associated with the command + * + * @return HelperSet + */ + public function getHelperSet() + { + return $this->helperSet; + } + + /** + * Gets a helper value. + * + * @param string $name The helper name * * @return mixed The helper value * * @throws \InvalidArgumentException if the helper is not defined */ - protected function getHelper($name) + public function __get($name) { - return $this->application->getHelperSet()->get($name); + return $this->helperSet->get($name); } /** diff --git a/src/Symfony/Components/Console/Helper/FormatterHelper.php b/src/Symfony/Components/Console/Helper/FormatterHelper.php index 6eedca733a..9dc7591c65 100644 --- a/src/Symfony/Components/Console/Helper/FormatterHelper.php +++ b/src/Symfony/Components/Console/Helper/FormatterHelper.php @@ -20,6 +20,14 @@ namespace Symfony\Components\Console\Helper; */ class FormatterHelper extends Helper { + /** + * Returns the helper's canonical name + */ + public function getName() + { + return 'formatter'; + } + /** * Formats a message within a section. * @@ -87,3 +95,4 @@ class FormatterHelper extends Helper return 'formatter'; } } + diff --git a/src/Symfony/Components/Console/Helper/Helper.php b/src/Symfony/Components/Console/Helper/Helper.php index f083b47abe..642e7a67c7 100644 --- a/src/Symfony/Components/Console/Helper/Helper.php +++ b/src/Symfony/Components/Console/Helper/Helper.php @@ -3,19 +3,19 @@ namespace Symfony\Components\Console\Helper; /* - * This file is part of the symfony framework. + * This file is part of the symfony package. * * (c) Fabien Potencier * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ /** * Helper is the base class for all helper classes. * * @package symfony - * @subpackage console + * @subpackage templating * @author Fabien Potencier */ abstract class Helper implements HelperInterface diff --git a/src/Symfony/Components/Console/Helper/HelperInterface.php b/src/Symfony/Components/Console/Helper/HelperInterface.php index f3de9aa65e..a3474fc610 100644 --- a/src/Symfony/Components/Console/Helper/HelperInterface.php +++ b/src/Symfony/Components/Console/Helper/HelperInterface.php @@ -3,23 +3,30 @@ namespace Symfony\Components\Console\Helper; /* - * This file is part of the symfony framework. + * This file is part of the symfony package. * * (c) Fabien Potencier * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ /** * HelperInterface is the interface all helpers must implement. * * @package symfony - * @subpackage console + * @subpackage templating * @author Fabien Potencier */ interface HelperInterface { + /** + * Returns the canonical name of this helper. + * + * @return string The canonical name + */ + function getName(); + /** * Sets the helper set associated with this helper. * @@ -33,11 +40,4 @@ interface HelperInterface * @return HelperSet A HelperSet instance */ function getHelperSet(); - - /** - * Returns the canonical name of this helper. - * - * @return string The canonical name - */ - function getName(); } diff --git a/src/Symfony/Components/Console/Helper/HelperSet.php b/src/Symfony/Components/Console/Helper/HelperSet.php index 67d764f52e..b71e9bd1b7 100644 --- a/src/Symfony/Components/Console/Helper/HelperSet.php +++ b/src/Symfony/Components/Console/Helper/HelperSet.php @@ -5,19 +5,19 @@ namespace Symfony\Components\Console\Helper; use Symfony\Components\Console\Command\Command; /* - * This file is part of the symfony framework. + * This file is part of the symfony package. * * (c) Fabien Potencier * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ /** * HelperSet represents a set of helpers to be used with a command. * * @package symfony - * @subpackage console + * @subpackage templating * @author Fabien Potencier */ class HelperSet @@ -102,3 +102,4 @@ class HelperSet return $this->command; } } + diff --git a/src/Symfony/Components/Console/Helper/InteractHelper.php b/src/Symfony/Components/Console/Helper/InteractHelper.php new file mode 100644 index 0000000000..0054ab08d3 --- /dev/null +++ b/src/Symfony/Components/Console/Helper/InteractHelper.php @@ -0,0 +1,119 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +/** + * The Interact class provides helpers to interact with the user. + * + * @package symfony + * @subpackage cli + * @author Fabien Potencier + */ +class InteractHelper extends Helper +{ + /** + * Returns the helper's canonical name + */ + public function getName() + { + return 'interact'; + } + + /** + * Asks a question to the user. + * + * @param OutputInterface $output + * @param string|array $question The question to ask + * @param string $default The default answer if none is given by the user + * + * @param string The user answer + */ + public function ask(OutputInterface $output, $question, $default = null) + { + // @codeCoverageIgnoreStart + $output->write($question); + + $ret = trim(fgets(STDIN)); + + return $ret ? $ret : $default; + // @codeCoverageIgnoreEnd + } + + /** + * Asks a confirmation to the user. + * + * The question will be asked until the user answer by nothing, yes, or no. + * + * @param OutputInterface $output + * @param string|array $question The question to ask + * @param Boolean $default The default answer if the user enters nothing + * + * @param Boolean true if the user has confirmed, false otherwise + */ + public function askConfirmation(OutputInterface $output, $question, $default = true) + { + // @codeCoverageIgnoreStart + $answer = 'z'; + while ($answer && !in_array(strtolower($answer[0]), array('y', 'n'))) + { + $answer = $this->ask($output, $question); + } + + if (false === $default) + { + return $answer && 'y' == strtolower($answer[0]); + } + else + { + return !$answer || 'y' == strtolower($answer[0]); + } + // @codeCoverageIgnoreEnd + } + + /** + * Asks for a value and validates the response. + * + * @param OutputInterface $output + * @param string|array $question + * @param Closure $validator + * @param integer $attempts Max number of times to ask before giving up (false by default, which means infinite) + * + * @return mixed + */ + public function askAndValidate(OutputInterface $output, $question, \Closure $validator, $attempts = false) + { + // @codeCoverageIgnoreStart + $error = null; + while (false === $attempts || $attempts--) + { + if (null !== $error) + { + $output->write($this->getHelperSet()->get('formatter')->formatBlock($error->getMessage(), 'error')); + } + + $value = $this->ask($output, $question, null); + + try + { + return $validator($value); + } + catch (\Exception $error) + { + } + } + + throw $error; + // @codeCoverageIgnoreEnd + } +}