2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Console\Question ;
2016-04-20 09:56:34 -07:00
use Symfony\Component\Console\Exception\InvalidArgumentException ;
2015-08-17 17:00:26 -07:00
/**
* Represents a choice question .
*
* @ author Fabien Potencier < fabien @ symfony . com >
*/
class ChoiceQuestion extends Question
{
private $choices ;
private $multiselect = false ;
private $prompt = ' > ' ;
private $errorMessage = 'Value "%s" is invalid' ;
/**
* Constructor .
*
* @ param string $question The question to ask to the user
* @ param array $choices The list of available choices
* @ param mixed $default The default answer to return
*/
public function __construct ( $question , array $choices , $default = null )
{
parent :: __construct ( $question , $default );
$this -> choices = $choices ;
$this -> setValidator ( $this -> getDefaultValidator ());
$this -> setAutocompleterValues ( $choices );
}
/**
* Returns available choices .
*
* @ return array
*/
public function getChoices ()
{
return $this -> choices ;
}
/**
* Sets multiselect option .
*
* When multiselect is set to true , multiple choices can be answered .
*
* @ param bool $multiselect
*
2017-02-02 16:28:38 -08:00
* @ return $this
2015-08-17 17:00:26 -07:00
*/
public function setMultiselect ( $multiselect )
{
$this -> multiselect = $multiselect ;
$this -> setValidator ( $this -> getDefaultValidator ());
return $this ;
}
2017-02-02 16:28:38 -08:00
/**
* Returns whether the choices are multiselect .
*
* @ return bool
*/
public function isMultiselect ()
{
return $this -> multiselect ;
}
2015-08-17 17:00:26 -07:00
/**
* Gets the prompt for choices .
*
* @ return string
*/
public function getPrompt ()
{
return $this -> prompt ;
}
/**
* Sets the prompt for choices .
*
* @ param string $prompt
*
2017-02-02 16:28:38 -08:00
* @ return $this
2015-08-17 17:00:26 -07:00
*/
public function setPrompt ( $prompt )
{
$this -> prompt = $prompt ;
return $this ;
}
/**
* Sets the error message for invalid values .
*
* The error message has a string placeholder ( % s ) for the invalid value .
*
* @ param string $errorMessage
*
2017-02-02 16:28:38 -08:00
* @ return $this
2015-08-17 17:00:26 -07:00
*/
public function setErrorMessage ( $errorMessage )
{
$this -> errorMessage = $errorMessage ;
$this -> setValidator ( $this -> getDefaultValidator ());
return $this ;
}
/**
* Returns the default answer validator .
*
* @ return callable
*/
private function getDefaultValidator ()
{
$choices = $this -> choices ;
$errorMessage = $this -> errorMessage ;
$multiselect = $this -> multiselect ;
$isAssoc = $this -> isAssoc ( $choices );
return function ( $selected ) use ( $choices , $errorMessage , $multiselect , $isAssoc ) {
// Collapse all spaces.
$selectedChoices = str_replace ( ' ' , '' , $selected );
if ( $multiselect ) {
// Check for a separated comma values
if ( ! preg_match ( '/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/' , $selectedChoices , $matches )) {
2016-04-20 09:56:34 -07:00
throw new InvalidArgumentException ( sprintf ( $errorMessage , $selected ));
2015-08-17 17:00:26 -07:00
}
$selectedChoices = explode ( ',' , $selectedChoices );
} else {
$selectedChoices = array ( $selected );
}
$multiselectChoices = array ();
foreach ( $selectedChoices as $value ) {
$results = array ();
foreach ( $choices as $key => $choice ) {
if ( $choice === $value ) {
$results [] = $key ;
}
}
if ( count ( $results ) > 1 ) {
2016-04-20 09:56:34 -07:00
throw new InvalidArgumentException ( sprintf ( 'The provided answer is ambiguous. Value should be one of %s.' , implode ( ' or ' , $results )));
2015-08-17 17:00:26 -07:00
}
$result = array_search ( $value , $choices );
if ( ! $isAssoc ) {
if ( false !== $result ) {
$result = $choices [ $result ];
} elseif ( isset ( $choices [ $value ])) {
$result = $choices [ $value ];
}
} elseif ( false === $result && isset ( $choices [ $value ])) {
$result = $value ;
}
if ( false === $result ) {
2016-04-20 09:56:34 -07:00
throw new InvalidArgumentException ( sprintf ( $errorMessage , $value ));
2015-08-17 17:00:26 -07:00
}
2015-08-27 12:03:05 -07:00
2015-09-04 13:20:09 -07:00
$multiselectChoices [] = ( string ) $result ;
2015-08-17 17:00:26 -07:00
}
if ( $multiselect ) {
return $multiselectChoices ;
}
return current ( $multiselectChoices );
};
}
}