Rajout de doctrine/orm
[zf2.biz/galerie.git] / vendor / symfony / console / Symfony / Component / Console / Input / ArgvInput.php
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
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
28  * is the name of the running application.
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  *
34  * @author Fabien Potencier <fabien@symfony.com>
35  *
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
38  *
39  * @api
40  */
41 class ArgvInput extends Input
42 {
43     private $tokens;
44     private $parsed;
45
46     /**
47      * Constructor.
48      *
49      * @param array           $argv       An array of parameters from the CLI (in the argv format)
50      * @param InputDefinition $definition A InputDefinition instance
51      *
52      * @api
53      */
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
73     /**
74      * Processes command line arguments.
75      */
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]) {
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      */
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
116     /**
117      * Parses a short option set.
118      *
119      * @param string $name The current token
120      *
121      * @throws \RuntimeException When option given doesn't exist
122      */
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(), true);
138             }
139         }
140     }
141
142     /**
143      * Parses a long option.
144      *
145      * @param string $token The current token
146      */
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
158     /**
159      * Parses an argument.
160      *
161      * @param string $token The current token
162      *
163      * @throws \RuntimeException When too many arguments are given
164      */
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
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      */
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
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      */
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         if (null === $value && $option->acceptValue()) {
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) {
230             if ($option->isValueRequired()) {
231                 throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
232             }
233
234             $value = $option->isValueOptional() ? $option->getDefault() : true;
235         }
236
237         if ($option->isArray()) {
238             $this->options[$name][] = $value;
239         } else {
240             $this->options[$name] = $value;
241         }
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     /**
261      * Returns true if the raw parameters (not parsed) contain a value.
262      *
263      * This method is to be used to introspect the input parameters
264      * before they have been validated. It must be used carefully.
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     {
272         $values = (array) $values;
273
274         foreach ($this->tokens as $v) {
275             if (in_array($v, $values)) {
276                 return true;
277             }
278         }
279
280         return false;
281     }
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
287      * before they have been validated. It must be used carefully.
288      *
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
291      *
292      * @return mixed The option value
293      */
294     public function getParameterOption($values, $default = false)
295     {
296         $values = (array) $values;
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                     }
305
306                     return array_shift($tokens);
307                 }
308             }
309         }
310
311         return $default;
312     }
313 }