123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- <?php
- namespace think\console\output\question;
- use think\console\output\Question;
- class Choice extends Question
- {
- private $choices;
- private $multiselect = false;
- private $prompt = ' > ';
- private $errorMessage = 'Value "%s" is invalid';
-
- public function __construct($question, array $choices, $default = null)
- {
- parent::__construct($question, $default);
- $this->choices = $choices;
- $this->setValidator($this->getDefaultValidator());
- $this->setAutocompleterValues($choices);
- }
-
- public function getChoices()
- {
- return $this->choices;
- }
-
- public function setMultiselect($multiselect)
- {
- $this->multiselect = $multiselect;
- $this->setValidator($this->getDefaultValidator());
- return $this;
- }
- public function isMultiselect()
- {
- return $this->multiselect;
- }
-
- public function getPrompt()
- {
- return $this->prompt;
- }
-
- public function setPrompt($prompt)
- {
- $this->prompt = $prompt;
- return $this;
- }
-
- public function setErrorMessage($errorMessage)
- {
- $this->errorMessage = $errorMessage;
- $this->setValidator($this->getDefaultValidator());
- return $this;
- }
-
- private function getDefaultValidator()
- {
- $choices = $this->choices;
- $errorMessage = $this->errorMessage;
- $multiselect = $this->multiselect;
- $isAssoc = $this->isAssoc($choices);
- return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
-
- $selectedChoices = str_replace(' ', '', $selected);
- if ($multiselect) {
-
- if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
- throw new \InvalidArgumentException(sprintf($errorMessage, $selected));
- }
- $selectedChoices = explode(',', $selectedChoices);
- } else {
- $selectedChoices = [$selected];
- }
- $multiselectChoices = [];
- foreach ($selectedChoices as $value) {
- $results = [];
- foreach ($choices as $key => $choice) {
- if ($choice === $value) {
- $results[] = $key;
- }
- }
- if (count($results) > 1) {
- throw new \InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
- }
- $result = array_search($value, $choices);
- if (!$isAssoc) {
- if (!empty($result)) {
- $result = $choices[$result];
- } elseif (isset($choices[$value])) {
- $result = $choices[$value];
- }
- } elseif (empty($result) && array_key_exists($value, $choices)) {
- $result = $value;
- }
- if (empty($result)) {
- throw new \InvalidArgumentException(sprintf($errorMessage, $value));
- }
- array_push($multiselectChoices, $result);
- }
- if ($multiselect) {
- return $multiselectChoices;
- }
- return current($multiselectChoices);
- };
- }
- }
|