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