Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 314 lines (276 sloc) 9.436 kb
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
1 <?php
2
3 /*
4a83d99 @blue-eyes normalized license messages in PHP files
blue-eyes authored
4 * This file is part of the Symfony package.
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
5 *
b933805 @fabpot replaced symfony-project.org by symfony.com
fabpot authored
6 * (c) Fabien Potencier <fabien@symfony.com>
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
7 *
4a83d99 @blue-eyes normalized license messages in PHP files
blue-eyes authored
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
10 */
11
4a83d99 @blue-eyes normalized license messages in PHP files
blue-eyes authored
12 namespace Symfony\Component\Console\Input;
13
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
14 /**
15 * ArgvInput represents an input coming from the CLI arguments.
16 *
17 * Usage:
18 *
19 * $input = new ArgvInput();
20 *
21 * By default, the `$_SERVER['argv']` array is used for the input values.
22 *
23 * This can be overridden by explicitly passing the input values in the constructor:
24 *
25 * $input = new ArgvInput($_SERVER['argv']);
26 *
27 * If you pass it yourself, don't forget that the first element of the array
4d67b42 @javiereguiluz [Console][Input] Added missing PHPDoc and fixed some minor typos and gra...
javiereguiluz authored
28 * is the name of the running application.
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
29 *
30 * When passing an argument to the constructor, be sure that it respects
31 * the same rules as the argv one. It's almost always better to use the
32 * `StringInput` when you want to provide your own input.
33 *
b933805 @fabpot replaced symfony-project.org by symfony.com
fabpot authored
34 * @author Fabien Potencier <fabien@symfony.com>
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
35 *
d999b59 @fabpot [DoctrineBridge] fixed some CS
fabpot authored
36 * @see http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html
37 * @see http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
00b2567 @fabpot [Console] tagged the guaranteed BC API
fabpot authored
38 *
39 * @api
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
40 */
41 class ArgvInput extends Input
42 {
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
43 private $tokens;
44 private $parsed;
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
45
46 /**
47 * Constructor.
48 *
0e67dc7 @fabpot fixed phpdoc @param alignment
fabpot authored
49 * @param array $argv An array of parameters from the CLI (in the argv format)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
50 * @param InputDefinition $definition A InputDefinition instance
00b2567 @fabpot [Console] tagged the guaranteed BC API
fabpot authored
51 *
52 * @api
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
53 */
54 public function __construct(array $argv = null, InputDefinition $definition = null)
55 {
56 if (null === $argv) {
57 $argv = $_SERVER['argv'];
58 }
59
4d67b42 @javiereguiluz [Console][Input] Added missing PHPDoc and fixed some minor typos and gra...
javiereguiluz authored
60 // strip the application name
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
61 array_shift($argv);
62
63 $this->tokens = $argv;
64
65 parent::__construct($definition);
66 }
67
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
68 protected function setTokens(array $tokens)
69 {
70 $this->tokens = $tokens;
71 }
72
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
73 /**
74 * Processes command line arguments.
75 */
76 protected function parse()
77 {
76e259e @jmikola [Console] Stop parsing options after encountering "--" token
jmikola authored
78 $parseOptions = true;
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
79 $this->parsed = $this->tokens;
80 while (null !== $token = array_shift($this->parsed)) {
d093cc2 @ocubom [Console] avoid warning parsing empty string argument
ocubom authored
81 if ($parseOptions && '' == $token) {
82 $this->parseArgument($token);
83 } elseif ($parseOptions && '--' == $token) {
76e259e @jmikola [Console] Stop parsing options after encountering "--" token
jmikola authored
84 $parseOptions = false;
85 } elseif ($parseOptions && 0 === strpos($token, '--')) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
86 $this->parseLongOption($token);
76e259e @jmikola [Console] Stop parsing options after encountering "--" token
jmikola authored
87 } elseif ($parseOptions && '-' === $token[0]) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
88 $this->parseShortOption($token);
89 } else {
90 $this->parseArgument($token);
91 }
92 }
93 }
94
95 /**
96 * Parses a short option.
97 *
98 * @param string $token The current token.
99 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
100 private function parseShortOption($token)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
101 {
102 $name = substr($token, 1);
103
104 if (strlen($name) > 1) {
44cf179 @weaverryan [Command] Changing the InputOption::PARAMETER_* constants to InputOption...
weaverryan authored
105 if ($this->definition->hasShortcut($name[0]) && $this->definition->getOptionForShortcut($name[0])->acceptValue()) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
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
116 /**
117 * Parses a short option set.
118 *
4ec78d1 @pborreli [Phpdoc] Cleaning/fixing
pborreli authored
119 * @param string $name The current token
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
120 *
121 * @throws \RuntimeException When option given doesn't exist
122 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
123 private function parseShortOptionSet($name)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
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]);
44cf179 @weaverryan [Command] Changing the InputOption::PARAMETER_* constants to InputOption...
weaverryan authored
132 if ($option->acceptValue()) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
133 $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));
134
135 break;
136 } else {
137 $this->addLongOption($option->getName(), true);
138 }
139 }
140 }
141
142 /**
143 * Parses a long option.
144 *
145 * @param string $token The current token
146 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
147 private function parseLongOption($token)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
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
158 /**
159 * Parses an argument.
160 *
161 * @param string $token The current token
162 *
163 * @throws \RuntimeException When too many arguments are given
164 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
165 private function parseArgument($token)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
166 {
6be4927 Fixed array argument parsing in ArgvInput.
Degory Valentine authored
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;
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
178
6be4927 Fixed array argument parsing in ArgvInput.
Degory Valentine authored
179 // unexpected argument
180 } else {
499c965 added test to verify ArgvInput->parse() failure with array input definit...
Degory Valentine authored
181 throw new \RuntimeException('Too many arguments.');
6be4927 Fixed array argument parsing in ArgvInput.
Degory Valentine authored
182 }
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
183 }
184
185 /**
186 * Adds a short option value.
187 *
188 * @param string $shortcut The short option key
189 * @param mixed $value The value for the option
190 *
191 * @throws \RuntimeException When option given doesn't exist
192 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
193 private function addShortOption($shortcut, $value)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
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
202 /**
203 * Adds a long option value.
204 *
205 * @param string $name The long option key
206 * @param mixed $value The value for the option
207 *
208 * @throws \RuntimeException When option given doesn't exist
209 */
67dbf5e @fabpot moved most protected to private in the Console component
fabpot authored
210 private function addLongOption($name, $value)
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
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
44cf179 @weaverryan [Command] Changing the InputOption::PARAMETER_* constants to InputOption...
weaverryan authored
218 if (null === $value && $option->acceptValue()) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
219 // if option accepts an optional or mandatory argument
220 // let's see if there is one provided
221 $next = array_shift($this->parsed);
222 if ('-' !== $next[0]) {
223 $value = $next;
224 } else {
225 array_unshift($this->parsed, $next);
226 }
227 }
228
229 if (null === $value) {
44cf179 @weaverryan [Command] Changing the InputOption::PARAMETER_* constants to InputOption...
weaverryan authored
230 if ($option->isValueRequired()) {
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
231 throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
232 }
233
44cf179 @weaverryan [Command] Changing the InputOption::PARAMETER_* constants to InputOption...
weaverryan authored
234 $value = $option->isValueOptional() ? $option->getDefault() : true;
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
235 }
236
b0a0ac0 @Herzult Simplify conditional block
Herzult authored
237 if ($option->isArray()) {
5c604cd @Herzult [Command] Fix array option parsing
Herzult authored
238 $this->options[$name][] = $value;
239 } else {
240 $this->options[$name] = $value;
241 }
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
242 }
243
244 /**
245 * Returns the first argument from the raw parameters (not parsed).
246 *
247 * @return string The value of the first argument or null otherwise
248 */
249 public function getFirstArgument()
250 {
251 foreach ($this->tokens as $token) {
252 if ($token && '-' === $token[0]) {
253 continue;
254 }
255
256 return $token;
257 }
258 }
259
260 /**
4d67b42 @javiereguiluz [Console][Input] Added missing PHPDoc and fixed some minor typos and gra...
javiereguiluz authored
261 * Returns true if the raw parameters (not parsed) contain a value.
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
262 *
263 * This method is to be used to introspect the input parameters
4d67b42 @javiereguiluz [Console][Input] Added missing PHPDoc and fixed some minor typos and gra...
javiereguiluz authored
264 * before they have been validated. It must be used carefully.
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
265 *
266 * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
267 *
268 * @return Boolean true if the value is contained in the raw parameters
269 */
270 public function hasParameterOption($values)
271 {
27547b7 @vicb Make casting scalar to array consistent
vicb authored
272 $values = (array) $values;
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
273
274 foreach ($this->tokens as $v) {
275 if (in_array($v, $values)) {
276 return true;
277 }
278 }
279
280 return false;
281 }
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
282
283 /**
284 * Returns the value of a raw option (not parsed).
285 *
286 * This method is to be used to introspect the input parameters
4d67b42 @javiereguiluz [Console][Input] Added missing PHPDoc and fixed some minor typos and gra...
javiereguiluz authored
287 * before they have been validated. It must be used carefully.
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
288 *
0e67dc7 @fabpot fixed phpdoc @param alignment
fabpot authored
289 * @param string|array $values The value(s) to look for in the raw parameters (can be an array)
290 * @param mixed $default The default value to return if no result is found
d999b59 @fabpot [DoctrineBridge] fixed some CS
fabpot authored
291 *
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
292 * @return mixed The option value
293 */
678f116 @fabpot [Console] fixed typo
fabpot authored
294 public function getParameterOption($values, $default = false)
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
295 {
27547b7 @vicb Make casting scalar to array consistent
vicb authored
296 $values = (array) $values;
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
297
298 $tokens = $this->tokens;
299 while ($token = array_shift($tokens)) {
300 foreach ($values as $value) {
301 if (0 === strpos($token, $value)) {
302 if (false !== $pos = strpos($token, '=')) {
303 return substr($token, $pos + 1);
304 }
2622e1a @pborreli [Console] Removed useless else
pborreli authored
305
306 return array_shift($tokens);
d8b015d @fabpot added --debug/-d and --env/-d to console
fabpot authored
307 }
308 }
309 }
310
311 return $default;
312 }
68c191c @fabpot renamed Symfony\Components to Symfony\Component
fabpot authored
313 }
Something went wrong with that request. Please try again.