1: <?php
2: /**
3: * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4: * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5: *
6: * Licensed under The MIT License
7: * For full copyright and license information, please see the LICENSE.txt
8: * Redistributions of files must retain the above copyright notice.
9: *
10: * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11: * @link https://cakephp.org CakePHP(tm) Project
12: * @since 2.0.0
13: * @license https://opensource.org/licenses/mit-license.php MIT License
14: */
15: namespace Cake\Console;
16:
17: use Cake\Console\Exception\ConsoleException;
18: use SimpleXMLElement;
19:
20: /**
21: * An object to represent a single argument used in the command line.
22: * ConsoleOptionParser creates these when you use addArgument()
23: *
24: * @see \Cake\Console\ConsoleOptionParser::addArgument()
25: */
26: class ConsoleInputArgument
27: {
28:
29: /**
30: * Name of the argument.
31: *
32: * @var string
33: */
34: protected $_name;
35:
36: /**
37: * Help string
38: *
39: * @var string
40: */
41: protected $_help;
42:
43: /**
44: * Is this option required?
45: *
46: * @var bool
47: */
48: protected $_required;
49:
50: /**
51: * An array of valid choices for this argument.
52: *
53: * @var array
54: */
55: protected $_choices;
56:
57: /**
58: * Make a new Input Argument
59: *
60: * @param string|array $name The long name of the option, or an array with all the properties.
61: * @param string $help The help text for this option
62: * @param bool $required Whether this argument is required. Missing required args will trigger exceptions
63: * @param array $choices Valid choices for this option.
64: */
65: public function __construct($name, $help = '', $required = false, $choices = [])
66: {
67: if (is_array($name) && isset($name['name'])) {
68: foreach ($name as $key => $value) {
69: $this->{'_' . $key} = $value;
70: }
71: } else {
72: $this->_name = $name;
73: $this->_help = $help;
74: $this->_required = $required;
75: $this->_choices = $choices;
76: }
77: }
78:
79: /**
80: * Get the value of the name attribute.
81: *
82: * @return string Value of this->_name.
83: */
84: public function name()
85: {
86: return $this->_name;
87: }
88:
89: /**
90: * Checks if this argument is equal to another argument.
91: *
92: * @param \Cake\Console\ConsoleInputArgument $argument ConsoleInputArgument to compare to.
93: * @return bool
94: */
95: public function isEqualTo(ConsoleInputArgument $argument)
96: {
97: return $this->usage() === $argument->usage();
98: }
99:
100: /**
101: * Generate the help for this argument.
102: *
103: * @param int $width The width to make the name of the option.
104: * @return string
105: */
106: public function help($width = 0)
107: {
108: $name = $this->_name;
109: if (strlen($name) < $width) {
110: $name = str_pad($name, $width, ' ');
111: }
112: $optional = '';
113: if (!$this->isRequired()) {
114: $optional = ' <comment>(optional)</comment>';
115: }
116: if ($this->_choices) {
117: $optional .= sprintf(' <comment>(choices: %s)</comment>', implode('|', $this->_choices));
118: }
119:
120: return sprintf('%s%s%s', $name, $this->_help, $optional);
121: }
122:
123: /**
124: * Get the usage value for this argument
125: *
126: * @return string
127: */
128: public function usage()
129: {
130: $name = $this->_name;
131: if ($this->_choices) {
132: $name = implode('|', $this->_choices);
133: }
134: $name = '<' . $name . '>';
135: if (!$this->isRequired()) {
136: $name = '[' . $name . ']';
137: }
138:
139: return $name;
140: }
141:
142: /**
143: * Check if this argument is a required argument
144: *
145: * @return bool
146: */
147: public function isRequired()
148: {
149: return (bool)$this->_required;
150: }
151:
152: /**
153: * Check that $value is a valid choice for this argument.
154: *
155: * @param string $value The choice to validate.
156: * @return bool
157: * @throws \Cake\Console\Exception\ConsoleException
158: */
159: public function validChoice($value)
160: {
161: if (empty($this->_choices)) {
162: return true;
163: }
164: if (!in_array($value, $this->_choices)) {
165: throw new ConsoleException(
166: sprintf(
167: '"%s" is not a valid value for %s. Please use one of "%s"',
168: $value,
169: $this->_name,
170: implode(', ', $this->_choices)
171: )
172: );
173: }
174:
175: return true;
176: }
177:
178: /**
179: * Append this arguments XML representation to the passed in SimpleXml object.
180: *
181: * @param \SimpleXMLElement $parent The parent element.
182: * @return \SimpleXMLElement The parent with this argument appended.
183: */
184: public function xml(SimpleXMLElement $parent)
185: {
186: $option = $parent->addChild('argument');
187: $option->addAttribute('name', $this->_name);
188: $option->addAttribute('help', $this->_help);
189: $option->addAttribute('required', (int)$this->isRequired());
190: $choices = $option->addChild('choices');
191: foreach ($this->_choices as $valid) {
192: $choices->addChild('choice', $valid);
193: }
194:
195: return $parent;
196: }
197: }
198: