These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php declare(strict_types = 1); |
||
2 | |||
3 | namespace ApiClients\Tools\Installer; |
||
4 | |||
5 | use InvalidArgumentException; |
||
6 | use Symfony\Component\Console\Command\Command; |
||
7 | use Symfony\Component\Console\Input\InputInterface; |
||
8 | use Symfony\Component\Console\Output\OutputInterface; |
||
9 | use Symfony\Component\Console\Style\SymfonyStyle; |
||
10 | use Symfony\Component\Console\Terminal; |
||
11 | use Throwable; |
||
12 | use function Composed\package; |
||
13 | use function igorw\get_in; |
||
14 | |||
15 | final class Install extends Command |
||
16 | { |
||
17 | const COMMAND = 'install'; |
||
18 | |||
19 | /** |
||
20 | * @var array |
||
21 | */ |
||
22 | private $yaml; |
||
23 | |||
24 | public function setYaml(array $yaml): Install |
||
25 | { |
||
26 | $this->yaml = $yaml; |
||
27 | |||
28 | return $this; |
||
29 | } |
||
30 | |||
31 | protected function execute(InputInterface $input, OutputInterface $output) |
||
32 | { |
||
33 | if ($this->yaml === null) { |
||
34 | throw new InvalidArgumentException('Missing configuration'); |
||
35 | } |
||
36 | |||
37 | $style = new SymfonyStyle($input, $output); |
||
38 | |||
39 | $style->newLine(2); |
||
40 | $this->asciiArt($style); |
||
41 | $style->newLine(2); |
||
42 | |||
43 | $style->title($this->yaml['text']['welcome']); |
||
44 | |||
45 | /** |
||
46 | * Launchpad, the retry goto point. |
||
47 | */ |
||
48 | retry: |
||
49 | $style->section('Please answer the following questions.'); |
||
50 | |||
51 | $replacements = []; |
||
52 | $table = []; |
||
53 | |||
54 | foreach ($this->yaml['questions'] as $identifier => $question) { |
||
55 | $replacements[$identifier] = $style->ask( |
||
56 | $question['question'], |
||
57 | get_in($question, ['default'], '') |
||
58 | ); |
||
59 | |||
60 | if (empty($replacements[$identifier]) || |
||
61 | (isset($question['validate']) && is_callable($question['validate'])) |
||
62 | ) { |
||
63 | while (!$this->validate($question['validate'], $replacements[$identifier]) || |
||
64 | empty($replacements[$identifier]) |
||
65 | ) { |
||
66 | $replacements[$identifier] = $style->ask( |
||
67 | 'Invalid response please try again, ' . $question['question'], |
||
68 | get_in($question, ['default'], '') |
||
69 | ); |
||
70 | } |
||
71 | } |
||
72 | |||
73 | $table[] = [ |
||
74 | $question['description'], |
||
75 | $replacements[$identifier], |
||
76 | ]; |
||
77 | } |
||
78 | |||
79 | $style->section('Summary:'); |
||
80 | $style->table( |
||
81 | [ |
||
82 | 'What', |
||
83 | 'Value', |
||
84 | ], |
||
85 | $table |
||
86 | ); |
||
87 | |||
88 | $installNow = $style->choice( |
||
89 | 'All settings correct?', |
||
90 | [ |
||
91 | 'y' => 'Yes', |
||
92 | 'n' => 'Change settings', |
||
93 | 'q' => 'Cancel installation', |
||
94 | ], |
||
95 | 'Yes' |
||
96 | ); |
||
97 | |||
98 | switch (strtolower($installNow)) { |
||
99 | case 'y': |
||
100 | { |
||
101 | $style->text('Creating your middleware package now.'); |
||
102 | /** @var callable $operation */ |
||
103 | foreach ($this->yaml['operations'] as $operation) { |
||
104 | $operation()->operate($replacements, $this->yaml['env'] ?? [], $style); |
||
105 | } |
||
106 | $style->section('Package creation has been successfully.'); |
||
107 | $style->text('Next up we\'re running composer update twice to ensure all traces of this installer are gone.'); |
||
108 | $style->text('(The first time to update composer.lock, and the second time to update the autoloader.)'); |
||
109 | $style->text('After which your new package is ready to be developed.'); |
||
110 | $style->success('Installer done.'); |
||
111 | break; |
||
112 | } |
||
113 | |||
114 | case 'n': |
||
115 | { |
||
116 | /** |
||
117 | * Retry, goto launchpad. |
||
118 | */ |
||
119 | goto retry; |
||
120 | break; |
||
0 ignored issues
–
show
|
|||
121 | } |
||
122 | |||
123 | case 'q': |
||
124 | { |
||
125 | $style->error('Installation canceled.'); |
||
126 | |||
127 | return 9; |
||
128 | } |
||
129 | } |
||
130 | |||
131 | return 0; |
||
132 | } |
||
133 | |||
134 | private function validate(callable $validator, $input): bool |
||
135 | { |
||
136 | try { |
||
137 | return $validator($input); |
||
138 | } catch (Throwable $t) { |
||
139 | return false; |
||
140 | } |
||
141 | } |
||
142 | |||
143 | private function asciiArt(SymfonyStyle $style) |
||
144 | { |
||
145 | if (!isset($this->yaml['text']['ascii_art_file'])) { |
||
146 | return; |
||
147 | } |
||
148 | |||
149 | if (isset($this->yaml['text']['ascii_art_package'])) { |
||
150 | $path = package($this->yaml['text']['ascii_art_package'])->getPath() . DIRECTORY_SEPARATOR; |
||
151 | } |
||
152 | |||
153 | $files = $this->yaml['text']['ascii_art_file']; |
||
154 | if (!is_array($files)) { |
||
155 | $files = [$files]; |
||
156 | } |
||
157 | |||
158 | $sortedFiles = []; |
||
159 | foreach ($files as $file) { |
||
160 | $artWidth = 0; |
||
161 | $contents = file($path . $file); |
||
0 ignored issues
–
show
The variable
$path does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
Loading history...
|
|||
162 | foreach ($contents as $line) { |
||
163 | $line = strip_tags($line); |
||
164 | $lineLength = mb_strlen($line); |
||
165 | if ($lineLength > $artWidth) { |
||
166 | $artWidth = $lineLength; |
||
167 | } |
||
168 | } |
||
169 | $sortedFiles[$artWidth] = $path . $file; |
||
170 | } |
||
171 | |||
172 | $width = (new Terminal())->getWidth(); |
||
173 | $sortedFiles = array_filter($sortedFiles, function ($artWidth) use ($width) { |
||
174 | return $width >= $artWidth; |
||
175 | }, ARRAY_FILTER_USE_KEY); |
||
176 | |||
177 | krsort($sortedFiles); |
||
178 | $file = current($sortedFiles); |
||
179 | |||
180 | foreach (file($file) as $line) { |
||
181 | $style->write($line); |
||
182 | } |
||
183 | } |
||
184 | } |
||
185 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.