annotate vendor/chi-teck/drupal-code-generator/src/Helper/InputHandler.php @ 5:12f9dff5fda9 tip

Update to Drupal core 8.7.1
author Chris Cannam
date Thu, 09 May 2019 15:34:47 +0100
parents a9cd425dd02b
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace DrupalCodeGenerator\Helper;
Chris@0 4
Chris@0 5 use DrupalCodeGenerator\Utils;
Chris@0 6 use Symfony\Component\Console\Exception\InvalidOptionException;
Chris@0 7 use Symfony\Component\Console\Helper\Helper;
Chris@0 8 use Symfony\Component\Console\Input\InputInterface;
Chris@0 9 use Symfony\Component\Console\Output\OutputInterface;
Chris@0 10 use Symfony\Component\Console\Question\ChoiceQuestion;
Chris@0 11 use Symfony\Component\Console\Question\ConfirmationQuestion;
Chris@0 12 use Symfony\Component\Console\Question\Question;
Chris@0 13
Chris@0 14 /**
Chris@0 15 * Generator input handler.
Chris@0 16 */
Chris@0 17 class InputHandler extends Helper {
Chris@0 18
Chris@0 19 use QuestionSettersTrait;
Chris@0 20
Chris@0 21 /**
Chris@0 22 * {@inheritdoc}
Chris@0 23 */
Chris@0 24 public function getName() {
Chris@0 25 return 'dcg_input_handler';
Chris@0 26 }
Chris@0 27
Chris@5 28 protected $askedQuestions = [];
Chris@5 29
Chris@0 30 /**
Chris@0 31 * Interacts with the user and returns variables for templates.
Chris@0 32 *
Chris@0 33 * @param \Symfony\Component\Console\Input\InputInterface $input
Chris@0 34 * Input instance.
Chris@0 35 * @param \Symfony\Component\Console\Output\OutputInterface $output
Chris@0 36 * Output instance.
Chris@0 37 * @param \Symfony\Component\Console\Question\Question[] $questions
Chris@0 38 * List of questions that the user should answer.
Chris@0 39 * @param array $vars
Chris@0 40 * Array of predefined template variables.
Chris@0 41 *
Chris@0 42 * @return array
Chris@0 43 * Template variables.
Chris@0 44 */
Chris@0 45 public function collectVars(InputInterface $input, OutputInterface $output, array $questions, array $vars = []) {
Chris@0 46
Chris@0 47 // A user can pass answers through the command line option.
Chris@0 48 $answers = NULL;
Chris@0 49 if ($answers_raw = $input->getOption('answers')) {
Chris@0 50 $answers = json_decode($answers_raw, TRUE);
Chris@0 51 if (!is_array($answers)) {
Chris@0 52 throw new InvalidOptionException('Answers should be encoded in JSON format.');
Chris@0 53 }
Chris@0 54 }
Chris@0 55
Chris@0 56 /** @var \Symfony\Component\Console\Helper\QuestionHelper $question_helper */
Chris@0 57 $question_helper = $this->getHelperSet()->get('question');
Chris@0 58
Chris@0 59 /** @var \DrupalCodeGenerator\Command\GeneratorInterface $command */
Chris@0 60 $command = $this->getHelperSet()->getCommand();
Chris@0 61 $directory = $command->getDirectory();
Chris@0 62
Chris@0 63 foreach ($questions as $name => $question) {
Chris@5 64
Chris@5 65 if (in_array($name, $this->askedQuestions)) {
Chris@5 66 continue;
Chris@5 67 }
Chris@5 68 $this->askedQuestions[] = $name;
Chris@5 69
Chris@0 70 /** @var \Symfony\Component\Console\Question\Question $question */
Chris@0 71 $default_value = $question->getDefault();
Chris@0 72
Chris@0 73 // Make some assumptions based on question name.
Chris@0 74 if ($default_value === NULL) {
Chris@0 75 switch ($name) {
Chris@0 76 case 'name':
Chris@0 77 $root_directory = basename(Utils::getExtensionRoot($directory) ?: $directory);
Chris@0 78 $default_value = Utils::machine2human($root_directory);
Chris@0 79 break;
Chris@0 80
Chris@0 81 case 'machine_name':
Chris@0 82 $default_value = function (array $vars) use ($directory) {
Chris@0 83 return Utils::human2machine(isset($vars['name']) ? $vars['name'] : basename($directory));
Chris@0 84 };
Chris@0 85 break;
Chris@0 86 }
Chris@0 87 }
Chris@0 88
Chris@0 89 // Turn the callback into a value acceptable for Symfony question helper.
Chris@0 90 if (is_callable($default_value)) {
Chris@0 91 // Do not treat simple strings as callable because they may match PHP
Chris@0 92 // builtin functions.
Chris@0 93 if (!is_string($default_value) || strpos('::', $default_value) !== FALSE) {
Chris@0 94 $default_value = call_user_func($default_value, $vars);
Chris@0 95 }
Chris@0 96 }
Chris@0 97 // Default value may have tokens.
Chris@0 98 $default_value = Utils::tokenReplace($default_value, $vars);
Chris@0 99 $this->setQuestionDefault($question, $default_value);
Chris@0 100
Chris@0 101 if ($answers) {
Chris@0 102 if (array_key_exists($name, $answers)) {
Chris@0 103 $answer = $answers[$name];
Chris@4 104 // Validate provided answer.
Chris@4 105 if ($validator = $question->getValidator()) {
Chris@4 106 $validator($answer);
Chris@4 107 }
Chris@0 108 // Turn 'yes/no' string into boolean.
Chris@0 109 if ($question instanceof ConfirmationQuestion && !is_bool($answer)) {
Chris@0 110 $answer = strcasecmp($answer, 'yes') == 0;
Chris@0 111 }
Chris@0 112 }
Chris@0 113 else {
Chris@0 114 $answer = $default_value;
Chris@0 115 }
Chris@0 116 }
Chris@0 117 else {
Chris@0 118 $this->formatQuestionText($question);
Chris@0 119 $answer = $question_helper->ask($input, $output, $question);
Chris@0 120 }
Chris@0 121
Chris@0 122 $vars[$name] = $answer;
Chris@0 123 }
Chris@0 124
Chris@0 125 return $vars;
Chris@0 126 }
Chris@0 127
Chris@0 128 /**
Chris@0 129 * Formats question text.
Chris@0 130 *
Chris@0 131 * @param \Symfony\Component\Console\Question\Question $question
Chris@0 132 * The question.
Chris@0 133 */
Chris@0 134 protected function formatQuestionText(Question $question) {
Chris@0 135 $question_text = $question->getQuestion();
Chris@0 136 $default_value = $question->getDefault();
Chris@0 137
Chris@0 138 $question_text = "\n <info>$question_text</info>";
Chris@0 139 if (is_bool($default_value)) {
Chris@0 140 $default_value = $default_value ? 'Yes' : 'No';
Chris@0 141 }
Chris@0 142 if ($default_value) {
Chris@0 143 $question_text .= " [<comment>$default_value</comment>]";
Chris@0 144 }
Chris@0 145 $question_text .= ":";
Chris@0 146 if ($question instanceof ChoiceQuestion) {
Chris@0 147 $question->setPrompt(' ➤➤➤ ');
Chris@0 148 }
Chris@0 149 else {
Chris@0 150 $question_text .= "\n ➤ ";
Chris@0 151 }
Chris@0 152
Chris@0 153 $this->setQuestionText($question, $question_text);
Chris@0 154 }
Chris@0 155
Chris@0 156 /**
Chris@0 157 * Normalizes questions.
Chris@0 158 *
Chris@0 159 * @param \Symfony\Component\Console\Question\Question[] $questions
Chris@0 160 * Questions to normalize.
Chris@0 161 *
Chris@0 162 * @return \Symfony\Component\Console\Question\Question[]
Chris@0 163 * Normalized questions
Chris@0 164 *
Chris@0 165 * @deprecated
Chris@0 166 * Use Symfony\Component\Console\Question\Question to define questions.
Chris@0 167 *
Chris@0 168 * @codeCoverageIgnore
Chris@0 169 */
Chris@0 170 protected function normalizeQuestions(array $questions) {
Chris@0 171 return array_map(function ($question) {
Chris@0 172 // Support array syntax.
Chris@0 173 if (is_array($question)) {
Chris@0 174 if (count($question) > 2) {
Chris@0 175 throw new \OutOfBoundsException('The question array is too long.');
Chris@0 176 }
Chris@0 177 list($question_text, $default_value) = array_pad($question, 2, NULL);
Chris@0 178 $question = new Question($question_text, $default_value);
Chris@0 179 }
Chris@0 180 return $question;
Chris@0 181 }, $questions);
Chris@0 182 }
Chris@0 183
Chris@0 184 }