Choice.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | ThinkPHP [ WE CAN DO IT JUST THINK ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
  8. // +----------------------------------------------------------------------
  9. // | Author: yunwuxin <448901948@qq.com>
  10. // +----------------------------------------------------------------------
  11. namespace think\console\output\question;
  12. use think\console\output\Question;
  13. class Choice extends Question
  14. {
  15. private $choices;
  16. private $multiselect = false;
  17. private $prompt = ' > ';
  18. private $errorMessage = 'Value "%s" is invalid';
  19. /**
  20. * 构造方法
  21. * @param string $question 问题
  22. * @param array $choices 选项
  23. * @param mixed $default 默认答案
  24. */
  25. public function __construct($question, array $choices, $default = null)
  26. {
  27. parent::__construct($question, $default);
  28. $this->choices = $choices;
  29. $this->setValidator($this->getDefaultValidator());
  30. $this->setAutocompleterValues($choices);
  31. }
  32. /**
  33. * 可选项
  34. * @return array
  35. */
  36. public function getChoices()
  37. {
  38. return $this->choices;
  39. }
  40. /**
  41. * 设置可否多选
  42. * @param bool $multiselect
  43. * @return self
  44. */
  45. public function setMultiselect($multiselect)
  46. {
  47. $this->multiselect = $multiselect;
  48. $this->setValidator($this->getDefaultValidator());
  49. return $this;
  50. }
  51. public function isMultiselect()
  52. {
  53. return $this->multiselect;
  54. }
  55. /**
  56. * 获取提示
  57. * @return string
  58. */
  59. public function getPrompt()
  60. {
  61. return $this->prompt;
  62. }
  63. /**
  64. * 设置提示
  65. * @param string $prompt
  66. * @return self
  67. */
  68. public function setPrompt($prompt)
  69. {
  70. $this->prompt = $prompt;
  71. return $this;
  72. }
  73. /**
  74. * 设置错误提示信息
  75. * @param string $errorMessage
  76. * @return self
  77. */
  78. public function setErrorMessage($errorMessage)
  79. {
  80. $this->errorMessage = $errorMessage;
  81. $this->setValidator($this->getDefaultValidator());
  82. return $this;
  83. }
  84. /**
  85. * 获取默认的验证方法
  86. * @return callable
  87. */
  88. private function getDefaultValidator()
  89. {
  90. $choices = $this->choices;
  91. $errorMessage = $this->errorMessage;
  92. $multiselect = $this->multiselect;
  93. $isAssoc = $this->isAssoc($choices);
  94. return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {
  95. // Collapse all spaces.
  96. $selectedChoices = str_replace(' ', '', $selected);
  97. if ($multiselect) {
  98. // Check for a separated comma values
  99. if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {
  100. throw new \InvalidArgumentException(sprintf($errorMessage, $selected));
  101. }
  102. $selectedChoices = explode(',', $selectedChoices);
  103. } else {
  104. $selectedChoices = [$selected];
  105. }
  106. $multiselectChoices = [];
  107. foreach ($selectedChoices as $value) {
  108. $results = [];
  109. foreach ($choices as $key => $choice) {
  110. if ($choice === $value) {
  111. $results[] = $key;
  112. }
  113. }
  114. if (count($results) > 1) {
  115. throw new \InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
  116. }
  117. $result = array_search($value, $choices);
  118. if (!$isAssoc) {
  119. if (!empty($result)) {
  120. $result = $choices[$result];
  121. } elseif (isset($choices[$value])) {
  122. $result = $choices[$value];
  123. }
  124. } elseif (empty($result) && array_key_exists($value, $choices)) {
  125. $result = $value;
  126. }
  127. if (empty($result)) {
  128. throw new \InvalidArgumentException(sprintf($errorMessage, $value));
  129. }
  130. array_push($multiselectChoices, $result);
  131. }
  132. if ($multiselect) {
  133. return $multiselectChoices;
  134. }
  135. return current($multiselectChoices);
  136. };
  137. }
  138. }