1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Symfony\Component\Console\Input;
13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40:
41: class ArgvInput extends Input
42: {
43: private $tokens;
44: private $parsed;
45:
46: 47: 48: 49: 50: 51: 52: 53:
54: public function __construct(array $argv = null, InputDefinition $definition = null)
55: {
56: if (null === $argv) {
57: $argv = $_SERVER['argv'];
58: }
59:
60:
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: 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: 97: 98: 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:
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: 118: 119: 120: 121: 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: 144: 145: 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: 160: 161: 162: 163: 164:
165: private function parseArgument($token)
166: {
167: $c = count($this->arguments);
168:
169:
170: if ($this->definition->hasArgument($c)) {
171: $arg = $this->definition->getArgument($c);
172: $this->arguments[$arg->getName()] = $arg->isArray()? array($token) : $token;
173:
174:
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:
180: } else {
181: throw new \RuntimeException('Too many arguments.');
182: }
183: }
184:
185: 186: 187: 188: 189: 190: 191: 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: 204: 205: 206: 207: 208: 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() && count($this->parsed)) {
219:
220:
221: $next = array_shift($this->parsed);
222: if (isset($next[0]) && '-' !== $next[0]) {
223: $value = $next;
224: } elseif (empty($next)) {
225: $value = '';
226: } else {
227: array_unshift($this->parsed, $next);
228: }
229: }
230:
231: if (null === $value) {
232: if ($option->isValueRequired()) {
233: throw new \RuntimeException(sprintf('The "--%s" option requires a value.', $name));
234: }
235:
236: $value = $option->isValueOptional() ? $option->getDefault() : true;
237: }
238:
239: if ($option->isArray()) {
240: $this->options[$name][] = $value;
241: } else {
242: $this->options[$name] = $value;
243: }
244: }
245:
246: 247: 248: 249: 250:
251: public function getFirstArgument()
252: {
253: foreach ($this->tokens as $token) {
254: if ($token && '-' === $token[0]) {
255: continue;
256: }
257:
258: return $token;
259: }
260: }
261:
262: 263: 264: 265: 266: 267: 268: 269: 270: 271:
272: public function hasParameterOption($values)
273: {
274: $values = (array) $values;
275:
276: foreach ($this->tokens as $v) {
277: if (in_array($v, $values)) {
278: return true;
279: }
280: }
281:
282: return false;
283: }
284:
285: 286: 287: 288: 289: 290: 291: 292: 293: 294: 295:
296: public function getParameterOption($values, $default = false)
297: {
298: $values = (array) $values;
299:
300: $tokens = $this->tokens;
301: while ($token = array_shift($tokens)) {
302: foreach ($values as $value) {
303: if (0 === strpos($token, $value)) {
304: if (false !== $pos = strpos($token, '=')) {
305: return substr($token, $pos + 1);
306: }
307:
308: return array_shift($tokens);
309: }
310: }
311: }
312:
313: return $default;
314: }
315: }
316: