This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the webmozart/console package. |
||
5 | * |
||
6 | * (c) Bernhard Schussek <[email protected]> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace Webmozart\Console\UI\Help; |
||
13 | |||
14 | use Webmozart\Console\Api\Args\Format\ArgsFormat; |
||
15 | use Webmozart\Console\Api\Args\Format\Argument; |
||
16 | use Webmozart\Console\Api\Args\Format\Option; |
||
17 | use Webmozart\Console\Api\IO\IO; |
||
18 | use Webmozart\Console\UI\Component; |
||
19 | use Webmozart\Console\UI\Component\EmptyLine; |
||
20 | use Webmozart\Console\UI\Component\LabeledParagraph; |
||
21 | use Webmozart\Console\UI\Component\Paragraph; |
||
22 | use Webmozart\Console\UI\Layout\BlockLayout; |
||
23 | |||
24 | /** |
||
25 | * Base class for rendering help pages. |
||
26 | * |
||
27 | * @since 1.0 |
||
28 | * |
||
29 | * @author Bernhard Schussek <[email protected]> |
||
30 | */ |
||
31 | abstract class AbstractHelp implements Component |
||
32 | { |
||
33 | /** |
||
34 | * Renders the usage. |
||
35 | * |
||
36 | * @param IO $io The I/O. |
||
37 | * @param int $indentation The number of spaces to indent. |
||
38 | */ |
||
39 | 46 | public function render(IO $io, $indentation = 0) |
|
40 | { |
||
41 | 46 | $layout = new BlockLayout(); |
|
42 | |||
43 | 46 | $this->renderHelp($layout); |
|
44 | |||
45 | 46 | $layout->render($io, $indentation); |
|
46 | 46 | } |
|
47 | |||
48 | /** |
||
49 | * Renders the usage. |
||
50 | * |
||
51 | * Overwrite this class in your sub-classes to implement the actual |
||
52 | * rendering. |
||
53 | * |
||
54 | * @param BlockLayout $layout The layout. |
||
55 | */ |
||
56 | abstract protected function renderHelp(BlockLayout $layout); |
||
0 ignored issues
–
show
|
|||
57 | |||
58 | /** |
||
59 | * Renders a list of arguments. |
||
60 | * |
||
61 | * @param BlockLayout $layout The layout. |
||
62 | * @param Argument[] $arguments The arguments to render. |
||
63 | */ |
||
64 | 23 | View Code Duplication | protected function renderArguments(BlockLayout $layout, array $arguments) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
65 | { |
||
66 | 23 | $layout->add(new Paragraph('<b>ARGUMENTS</b>')); |
|
67 | 23 | $layout->beginBlock(); |
|
68 | |||
69 | 23 | foreach ($arguments as $argument) { |
|
70 | 23 | $this->renderArgument($layout, $argument); |
|
71 | } |
||
72 | |||
73 | 23 | $layout->endBlock(); |
|
74 | 23 | $layout->add(new EmptyLine()); |
|
75 | 23 | } |
|
76 | |||
77 | /** |
||
78 | * Renders an argument. |
||
79 | * |
||
80 | * @param BlockLayout $layout The layout. |
||
81 | * @param Argument $argument The argument to render. |
||
82 | */ |
||
83 | 25 | protected function renderArgument(BlockLayout $layout, Argument $argument) |
|
84 | { |
||
85 | 25 | $description = $argument->getDescription(); |
|
86 | 25 | $name = '<c1><'.$argument->getName().'></c1>'; |
|
87 | 25 | $defaultValue = $argument->getDefaultValue(); |
|
88 | |||
89 | 25 | View Code Duplication | if (null !== $defaultValue && (!is_array($defaultValue) || count($defaultValue))) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
90 | $description .= sprintf(' <b>(default: %s)</b>', $this->formatValue($defaultValue)); |
||
91 | } |
||
92 | |||
93 | 25 | $layout->add(new LabeledParagraph($name, $description)); |
|
94 | 25 | } |
|
95 | |||
96 | /** |
||
97 | * Renders a list of options. |
||
98 | * |
||
99 | * @param BlockLayout $layout The layout. |
||
100 | * @param Option[] $options The options to render. |
||
101 | */ |
||
102 | 9 | View Code Duplication | protected function renderOptions(BlockLayout $layout, array $options) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
103 | { |
||
104 | 9 | $layout->add(new Paragraph('<b>OPTIONS</b>')); |
|
105 | 9 | $layout->beginBlock(); |
|
106 | |||
107 | 9 | foreach ($options as $option) { |
|
108 | 9 | $this->renderOption($layout, $option); |
|
109 | } |
||
110 | |||
111 | 9 | $layout->endBlock(); |
|
112 | 9 | $layout->add(new EmptyLine()); |
|
113 | 9 | } |
|
114 | |||
115 | /** |
||
116 | * Renders a list of global options. |
||
117 | * |
||
118 | * @param BlockLayout $layout The layout. |
||
119 | * @param Option[] $options The global options to render. |
||
120 | */ |
||
121 | 28 | View Code Duplication | protected function renderGlobalOptions(BlockLayout $layout, array $options) |
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
122 | { |
||
123 | 28 | $layout->add(new Paragraph('<b>GLOBAL OPTIONS</b>')); |
|
124 | 28 | $layout->beginBlock(); |
|
125 | |||
126 | 28 | foreach ($options as $option) { |
|
127 | 28 | $this->renderOption($layout, $option); |
|
128 | } |
||
129 | |||
130 | 28 | $layout->endBlock(); |
|
131 | 28 | $layout->add(new EmptyLine()); |
|
132 | 28 | } |
|
133 | |||
134 | /** |
||
135 | * Renders an option. |
||
136 | * |
||
137 | * @param BlockLayout $layout The layout. |
||
138 | * @param Option $option The option to render. |
||
139 | */ |
||
140 | 34 | protected function renderOption(BlockLayout $layout, Option $option) |
|
141 | { |
||
142 | 34 | $description = $option->getDescription(); |
|
143 | 34 | $defaultValue = $option->getDefaultValue(); |
|
144 | |||
145 | 34 | if ($option->isLongNamePreferred()) { |
|
146 | 32 | $preferredName = '--'.$option->getLongName(); |
|
147 | 32 | $alternativeName = $option->getShortName() ? '-'.$option->getShortName() : null; |
|
148 | } else { |
||
149 | 26 | $preferredName = '-'.$option->getShortName(); |
|
150 | 26 | $alternativeName = '--'.$option->getLongName(); |
|
151 | } |
||
152 | |||
153 | 34 | $name = '<c1>'.$preferredName.'</c1>'; |
|
154 | |||
155 | 34 | if ($alternativeName) { |
|
0 ignored issues
–
show
The expression
$alternativeName of type string|null is loosely compared to true ; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.
In PHP, under loose comparison (like For '' == false // true
'' == null // true
'ab' == false // false
'ab' == null // false
// It is often better to use strict comparison
'' === false // false
'' === null // false
![]() |
|||
156 | 28 | $name .= sprintf(' (%s)', $alternativeName); |
|
157 | } |
||
158 | |||
159 | 34 | View Code Duplication | if ($option->acceptsValue() && null !== $defaultValue && (!is_array($defaultValue) || count($defaultValue))) { |
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
160 | 1 | $description .= sprintf(' <b>(default: %s)</b>', $this->formatValue($defaultValue)); |
|
161 | } |
||
162 | |||
163 | 34 | if ($option->isMultiValued()) { |
|
164 | $description .= ' <b>(multiple values allowed)</b>'; |
||
165 | } |
||
166 | |||
167 | 34 | $layout->add(new LabeledParagraph($name, $description)); |
|
168 | 34 | } |
|
169 | |||
170 | /** |
||
171 | * Renders the synopsis of a console command. |
||
172 | * |
||
173 | * @param BlockLayout $layout The layout. |
||
174 | * @param ArgsFormat $argsFormat The console arguments to render. |
||
175 | * @param string $appName The name of the application binary. |
||
176 | * @param string $prefix The prefix to insert. |
||
177 | * @param bool $lastOptional Set to `true` if the last command of the |
||
178 | * console arguments is optional. This |
||
179 | * command will be enclosed in brackets in |
||
180 | * the output. |
||
181 | */ |
||
182 | 46 | protected function renderSynopsis(BlockLayout $layout, ArgsFormat $argsFormat, $appName, $prefix = '', $lastOptional = false) |
|
183 | { |
||
184 | 46 | $nameParts = array(); |
|
185 | 46 | $argumentParts = array(); |
|
186 | |||
187 | 46 | $nameParts[] = '<u>'.($appName ?: 'console').'</u>'; |
|
188 | |||
189 | 46 | foreach ($argsFormat->getCommandNames() as $commandName) { |
|
190 | 27 | $nameParts[] = '<u>'.$commandName->toString().'</u>'; |
|
191 | } |
||
192 | |||
193 | 46 | foreach ($argsFormat->getCommandOptions() as $commandOption) { |
|
194 | 4 | $nameParts[] = $commandOption->isLongNamePreferred() |
|
195 | 4 | ? '--'.$commandOption->getLongName() |
|
196 | 4 | : '-'.$commandOption->getShortName(); |
|
197 | } |
||
198 | |||
199 | 46 | if ($lastOptional) { |
|
200 | 2 | $lastIndex = count($nameParts) - 1; |
|
201 | 2 | $nameParts[$lastIndex] = '['.$nameParts[$lastIndex].']'; |
|
202 | } |
||
203 | |||
204 | 46 | foreach ($argsFormat->getOptions(false) as $option) { |
|
205 | // \xC2\xA0 is a non-breaking space |
||
206 | 23 | if ($option->isValueRequired()) { |
|
207 | 1 | $format = "%s\xC2\xA0<%s>"; |
|
208 | 22 | } elseif ($option->isValueOptional()) { |
|
209 | 16 | $format = "%s\xC2\xA0[<%s>]"; |
|
210 | } else { |
||
211 | 17 | $format = '%s'; |
|
212 | } |
||
213 | |||
214 | 23 | $optionName = $option->isLongNamePreferred() |
|
215 | 21 | ? '--'.$option->getLongName() |
|
216 | 23 | : '-'.$option->getShortName(); |
|
217 | |||
218 | 23 | $argumentParts[] = sprintf('['.$format.']', $optionName, $option->getValueName()); |
|
219 | } |
||
220 | |||
221 | 46 | foreach ($argsFormat->getArguments() as $argument) { |
|
222 | 27 | $argName = $argument->getName(); |
|
223 | |||
224 | 27 | $argumentParts[] = sprintf( |
|
225 | 27 | $argument->isRequired() ? '<%s>' : '[<%s>]', |
|
226 | 27 | $argName.($argument->isMultiValued() ? '1' : '') |
|
227 | ); |
||
228 | |||
229 | 27 | if ($argument->isMultiValued()) { |
|
230 | 27 | $argumentParts[] = sprintf('... [<%sN>]', $argName); |
|
231 | } |
||
232 | } |
||
233 | |||
234 | 46 | $argsOpts = implode(' ', $argumentParts); |
|
235 | 46 | $name = implode(' ', $nameParts); |
|
236 | |||
237 | 46 | $layout->add(new LabeledParagraph($prefix.$name, $argsOpts, 1, false)); |
|
238 | 46 | } |
|
239 | |||
240 | /** |
||
241 | * Formats the default value of an argument or an option. |
||
242 | * |
||
243 | * @param mixed $value The default value to format. |
||
244 | * |
||
245 | * @return string The formatted value. |
||
246 | */ |
||
247 | 1 | protected function formatValue($value) |
|
248 | { |
||
249 | 1 | if (PHP_VERSION_ID < 50400) { |
|
250 | return str_replace('\/', '/', json_encode($value)); |
||
251 | } |
||
252 | |||
253 | 1 | return json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); |
|
254 | } |
||
255 | } |
||
256 |
For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a
@return
doc comment to communicate to implementors of these methods what they are expected to return.