TYPO3  7.6
ArgvInput.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Symfony package.
5  *
6  * (c) Fabien Potencier <fabien@symfony.com>
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 Symfony\Component\Console\Input;
13 
41 class ArgvInput extends Input
42 {
43  private $tokens;
44  private $parsed;
45 
54  public function __construct(array $argv = null, InputDefinition $definition = null)
55  {
56  if (null === $argv) {
57  $argv = $_SERVER['argv'];
58  }
59 
60  // strip the application name
61  array_shift($argv);
62 
63  $this->tokens = $argv;
64 
65  parent::__construct($definition);
66  }
67 
68  protected function setTokens(array $tokens)
69  {
70  $this->tokens = $tokens;
71  }
72 
76  protected function parse()
77  {
78  $parseOptions = true;
79  $this->parsed = $this->tokens;
80  while (null !== $token = array_shift($this->parsed)) {
81  if ($parseOptions && '' == $token) {
82  $this->parseArgument($token);
83  } elseif ($parseOptions && '--' == $token) {
84  $parseOptions = false;
85  } elseif ($parseOptions && 0 === strpos($token, '--')) {
86  $this->parseLongOption($token);
87  } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {
88  $this->parseShortOption($token);
89  } else {
90  $this->parseArgument($token);
91  }
92  }
93  }
94 
100  private function parseShortOption($token)
101  {
102  $name = substr($token, 1);
103 
104  if (strlen($name) > 1) {
105  if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
106  // an option with a value (with no space)
107  $this->addShortOption($name[0], substr($name, 1));
108  } else {
109  $this->parseShortOptionSet($name);
110  }
111  } else {
112  $this->addShortOption($name, null);
113  }
114  }
115 
123  private function parseShortOptionSet($name)
124  {
125  $len = strlen($name);
126  for ($i = 0; $i < $len; ++$i) {
127  if (!$this->definition->hasShortcut($name[$i])) {
128  throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $name[$i]));
129  }
130 
131  $option = $this->definition->getOptionForShortcut($name[$i]);
132  if ($option->acceptValue()) {
133  $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
134 
135  break;
136  } else {
137  $this->addLongOption($option->getName(), null);
138  }
139  }
140  }
141 
147  private function parseLongOption($token)
148  {
149  $name = substr($token, 2);
150 
151  if (false !== $pos = strpos($name, '=')) {
152  $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));
153  } else {
154  $this->addLongOption($name, null);
155  }
156  }
157 
165  private function parseArgument($token)
166  {
167  $c = count($this->arguments);
168 
169  // if input is expecting another argument, add it
170  if ($this->definition->hasArgument($c)) {
171  $arg = $this->definition->getArgument($c);
172  $this->arguments[$arg->getName()] = $arg->isArray() ? array($token) : $token;
173 
174  // if last argument isArray(), append token to last argument
175  } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {
176  $arg = $this->definition->getArgument($c - 1);
177  $this->arguments[$arg->getName()][] = $token;
178 
179  // unexpected argument
180  } else {
181  throw new \RuntimeException('Too many arguments.');
182  }
183  }
184 
193  private function addShortOption($shortcut, $value)
194  {
195  if (!$this->definition->hasShortcut($shortcut)) {
196  throw new \RuntimeException(sprintf('The "-%s" option does not exist.', $shortcut));
197  }
198 
199  $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);
200  }
201 
210  private function addLongOption($name, $value)
211  {
212  if (!$this->definition->hasOption($name)) {
213  throw new \RuntimeException(sprintf('The "--%s" option does not exist.', $name));
214  }
215 
216  $option = $this->definition->getOption($name);
217 
218  // Convert empty values to null
219  if (!isset($value[0])) {
220  $value = null;
221  }
222 
223  if (null !== $value && !$option->acceptValue()) {
224  throw new \RuntimeException(sprintf('The "--%s" option does not accept a value.', $name));
225  }
226 
227  if (null === $value && $option->acceptValue() && count($this->parsed)) {
228  // if option accepts an optional or mandatory argument
229  // let's see if there is one provided
230  $next = array_shift($this->parsed);
231  if (isset($next[0]) && '-' !== $next[0]) {
232  $value = $next;
233  } elseif (empty($next)) {
234  $value = '';
235  } else {
236  array_unshift($this->parsed, $next);
237  }
238  }
239 
240  if (null === $value) {
241  if ($option->isValueRequired()) {
242  throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
243  }
244 
245  if (!$option->isArray()) {
246  $value = $option->isValueOptional() ? $option->getDefault() : true;
247  }
248  }
249 
250  if ($option->isArray()) {
251  $this->options[$name][] = $value;
252  } else {
253  $this->options[$name] = $value;
254  }
255  }
256 
262  public function getFirstArgument()
263  {
264  foreach ($this->tokens as $token) {
265  if ($token && '-' === $token[0]) {
266  continue;
267  }
268 
269  return $token;
270  }
271  }
272 
283  public function hasParameterOption($values)
284  {
285  $values = (array) $values;
286 
287  foreach ($this->tokens as $token) {
288  foreach ($values as $value) {
289  if ($token === $value || 0 === strpos($token, $value.'=')) {
290  return true;
291  }
292  }
293  }
294 
295  return false;
296  }
297 
309  public function getParameterOption($values, $default = false)
310  {
311  $values = (array) $values;
313 
314  while (0 < count($tokens)) {
315  $token = array_shift($tokens);
316 
317  foreach ($values as $value) {
318  if ($token === $value || 0 === strpos($token, $value.'=')) {
319  if (false !== $pos = strpos($token, '=')) {
320  return substr($token, $pos + 1);
321  }
322 
323  return array_shift($tokens);
324  }
325  }
326  }
327 
328  return $default;
329  }
330 
336  public function __toString()
337  {
338  $self = $this;
339  $tokens = array_map(function ($token) use ($self) {
340  if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {
341  return $match[1].$self->escapeToken($match[2]);
342  }
343 
344  if ($token && $token[0] !== '-') {
345  return $self->escapeToken($token);
346  }
347 
348  return $token;
349  }, $this->tokens);
350 
351  return implode(' ', $tokens);
352  }
353 }