Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ArgvInput.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Console\Input;
013
014 use Symfony\Component\Console\Exception\RuntimeException;
015
016 /**
017 * ArgvInput represents an input coming from the CLI arguments.
018 *
019 * Usage:
020 *
021 * $input = new ArgvInput();
022 *
023 * By default, the `$_SERVER['argv']` array is used for the input values.
024 *
025 * This can be overridden by explicitly passing the input values in the constructor:
026 *
027 * $input = new ArgvInput($_SERVER['argv']);
028 *
029 * If you pass it yourself, don't forget that the first element of the array
030 * is the name of the running application.
031 *
032 * When passing an argument to the constructor, be sure that it respects
033 * the same rules as the argv one. It's almost always better to use the
034 * `StringInput` when you want to provide your own input.
035 *
036 * @author Fabien Potencier <fabien@symfony.com>
037 *
038 * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
039 * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
040 */
041 class ArgvInput extends Input
042 {
043 private $tokens;
044 private $parsed;
045
046 /**
047 * @param array|null $argv An array of parameters from the CLI (in the argv format)
048 * @param InputDefinition|null $definition A InputDefinition instance
049 */
050 public function __construct(array $argv = null, InputDefinition $definition = null)
051 {
052 $argv = null !== $argv ? $argv : (isset($_SERVER['argv']) ? $_SERVER['argv'] : []);
053
054 // strip the application name
055 array_shift($argv);
056
057 $this->tokens = $argv;
058
059 parent::__construct($definition);
060 }
061
062 protected function setTokens(array $tokens)
063 {
064 $this->tokens = $tokens;
065 }
066
067 /**
068 * {@inheritdoc}
069 */
070 protected function parse()
071 {
072 $parseOptions = true;
073 $this->parsed = $this->tokens;
074 while (null !== $token = array_shift($this->parsed)) {
075 if ($parseOptions && '' == $token) {
076 $this->parseArgument($token);
077 } elseif ($parseOptions && '--' == $token) {
078 $parseOptions = false;
079 } elseif ($parseOptions && 0 === strpos($token, '--')) {
080 $this->parseLongOption($token);
081 } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
082 $this->parseShortOption($token);
083 } else {
084 $this->parseArgument($token);
085 }
086 }
087 }
088
089 /**
090 * Parses a short option.
091 *
092 * @param string $token The current token
093 */
094 private function parseShortOption($token)
095 {
096 $name = substr($token, 1);
097
098 if (\strlen($name) > 1) {
099 if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
100 // an option with a value (with no space)
101 $this->addShortOption($name[0], substr($name, 1));
102 } else {
103 $this->parseShortOptionSet($name);
104 }
105 } else {
106 $this->addShortOption($name, null);
107 }
108 }
109
110 /**
111 * Parses a short option set.
112 *
113 * @param string $name The current token
114 *
115 * @throws RuntimeException When option given doesn't exist
116 */
117 private function parseShortOptionSet($name)
118 {
119 $len = \strlen($name);
120 for ($i = 0; $i < $len; ++$i) {
121 if (!$this->definition->hasShortcut($name[$i])) {
122 $encoding = mb_detect_encoding($name, null, true);
123 throw new RuntimeException(sprintf('The "-%s" option does not exist.', false === $encoding ? $name[$i] : mb_substr($name, $i, 1, $encoding)));
124 }
125
126 $option = $this->definition->getOptionForShortcut($name[$i]);
127 if ($option->acceptValue()) {
128 $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
129
130 break;
131 } else {
132 $this->addLongOption($option->getName(), null);
133 }
134 }
135 }
136
137 /**
138 * Parses a long option.
139 *
140 * @param string $token The current token
141 */
142 private function parseLongOption($token)
143 {
144 $name = substr($token, 2);
145
146 if (false !== $pos = strpos($name, '=')) {
147 if (0 === \strlen($value = substr($name, $pos + 1))) {
148 // if no value after "=" then substr() returns "" since php7 only, false before
149 // see https://php.net/migration70.incompatible.php#119151
150 if (\PHP_VERSION_ID < 70000 && false === $value) {
151 $value = '';
152 }
153 array_unshift($this->parsed, $value);
154 }
155 $this->addLongOption(substr($name, 0, $pos), $value);
156 } else {
157 $this->addLongOption($name, null);
158 }
159 }
160
161 /**
162 * Parses an argument.
163 *
164 * @param string $token The current token
165 *
166 * @throws RuntimeException When too many arguments are given
167 */
168 private function parseArgument($token)
169 {
170 $c = \count($this->arguments);
171
172 // if input is expecting another argument, add it
173 if ($this->definition->hasArgument($c)) {
174 $arg = $this->definition->getArgument($c);
175 $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;
176
177 // if last argument isArray(), append token to last argument
178 } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
179 $arg = $this->definition->getArgument($c - 1);
180 $this->arguments[$arg->getName()][] = $token;
181
182 // unexpected argument
183 } else {
184 $all = $this->definition->getArguments();
185 if (\count($all)) {
186 throw new RuntimeException(sprintf('Too many arguments, expected arguments "%s".', implode('" "', array_keys($all))));
187 }
188
189 throw new RuntimeException(sprintf('No arguments expected, got "%s".', $token));
190 }
191 }
192
193 /**
194 * Adds a short option value.
195 *
196 * @param string $shortcut The short option key
197 * @param mixed $value The value for the option
198 *
199 * @throws RuntimeException When option given doesn't exist
200 */
201 private function addShortOption($shortcut, $value)
202 {
203 if (!$this->definition->hasShortcut($shortcut)) {
204 throw new RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
205 }
206
207 $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
208 }
209
210 /**
211 * Adds a long option value.
212 *
213 * @param string $name The long option key
214 * @param mixed $value The value for the option
215 *
216 * @throws RuntimeException When option given doesn't exist
217 */
218 private function addLongOption($name, $value)
219 {
220 if (!$this->definition->hasOption($name)) {
221 throw new RuntimeException(sprintf('The "--%s" option does not exist.', $name));
222 }
223
224 $option = $this->definition->getOption($name);
225
226 if (null !== $value && !$option->acceptValue()) {
227 throw new RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
228 }
229
230 if (\in_array($value, ['', null], true) && $option->acceptValue() && \count($this->parsed)) {
231 // if option accepts an optional or mandatory argument
232 // let's see if there is one provided
233 $next = array_shift($this->parsed);
234 if ((isset($next[0]) && '-' !== $next[0]) || \in_array($next, ['', null], true)) {
235 $value = $next;
236 } else {
237 array_unshift($this->parsed, $next);
238 }
239 }
240
241 if (null === $value) {
242 if ($option->isValueRequired()) {
243 throw new RuntimeException(sprintf('The "--%s" option requires a value.', $name));
244 }
245
246 if (!$option->isArray() && !$option->isValueOptional()) {
247 $value = true;
248 }
249 }
250
251 if ($option->isArray()) {
252 $this->options[$name][] = $value;
253 } else {
254 $this->options[$name] = $value;
255 }
256 }
257
258 /**
259 * {@inheritdoc}
260 */
261 public function getFirstArgument()
262 {
263 $isOption = false;
264 foreach ($this->tokens as $i => $token) {
265 if ($token && '-' === $token[0]) {
266 if (false !== strpos($token, '=') || !isset($this->tokens[$i + 1])) {
267 continue;
268 }
269
270 // If it's a long option, consider that everything after "--" is the option name.
271 // Otherwise, use the last char (if it's a short option set, only the last one can take a value with space separator)
272 $name = '-' === $token[1] ? substr($token, 2) : substr($token, -1);
273 if (!isset($this->options[$name]) && !$this->definition->hasShortcut($name)) {
274 // noop
275 } elseif ((isset($this->options[$name]) || isset($this->options[$name = $this->definition->shortcutToName($name)])) && $this->tokens[$i + 1] === $this->options[$name]) {
276 $isOption = true;
277 }
278
279 continue;
280 }
281
282 if ($isOption) {
283 $isOption = false;
284 continue;
285 }
286
287 return $token;
288 }
289
290 return null;
291 }
292
293 /**
294 * {@inheritdoc}
295 */
296 public function hasParameterOption($values, $onlyParams = false)
297 {
298 $values = (array) $values;
299
300 foreach ($this->tokens as $token) {
301 if ($onlyParams && '--' === $token) {
302 return false;
303 }
304 foreach ($values as $value) {
305 // Options with values:
306 // For long options, test for '--option=' at beginning
307 // For short options, test for '-o' at beginning
308 $leading = 0 === strpos($value, '--') ? $value.'=' : $value;
309 if ($token === $value || '' !== $leading && 0 === strpos($token, $leading)) {
310 return true;
311 }
312 }
313 }
314
315 return false;
316 }
317
318 /**
319 * {@inheritdoc}
320 */
321 public function getParameterOption($values, $default = false, $onlyParams = false)
322 {
323 $values = (array) $values;
324 $tokens = $this->tokens;
325
326 while (0 < \count($tokens)) {
327 $token = array_shift($tokens);
328 if ($onlyParams && '--' === $token) {
329 return $default;
330 }
331
332 foreach ($values as $value) {
333 if ($token === $value) {
334 return array_shift($tokens);
335 }
336 // Options with values:
337 // For long options, test for '--option=' at beginning
338 // For short options, test for '-o' at beginning
339 $leading = 0 === strpos($value, '--') ? $value.'=' : $value;
340 if ('' !== $leading && 0 === strpos($token, $leading)) {
341 return substr($token, \strlen($leading));
342 }
343 }
344 }
345
346 return $default;
347 }
348
349 /**
350 * Returns a stringified representation of the args passed to the command.
351 *
352 * @return string
353 */
354 public function __toString()
355 {
356 $tokens = array_map(function ($token) {
357 if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
358 return $match[1].$this->escapeToken($match[2]);
359 }
360
361 if ($token && '-' !== $token[0]) {
362 return $this->escapeToken($token);
363 }
364
365 return $token;
366 }, $this->tokens);
367
368 return implode(' ', $tokens);
369 }
370 }
371