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: * Name of the argument.
30: *
31: * @var string
32: */
33: protected $_name;
34:
35: /**
36: * Help string
37: *
38: * @var string
39: */
40: protected $_help;
41:
42: /**
43: * Is this option required?
44: *
45: * @var bool
46: */
47: protected $_required;
48:
49: /**
50: * An array of valid choices for this argument.
51: *
52: * @var string[]
53: */
54: protected $_choices;
55:
56: /**
57: * Make a new Input Argument
58: *
59: * @param string|array $name The long name of the option, or an array with all the properties.
60: * @param string $help The help text for this option
61: * @param bool $required Whether this argument is required. Missing required args will trigger exceptions
62: * @param string[] $choices Valid choices for this option.
63: */
64: public function __construct($name, $help = '', $required = false, $choices = [])
65: {
66: if (is_array($name) && isset($name['name'])) {
67: foreach ($name as $key => $value) {
68: $this->{'_' . $key} = $value;
69: }
70: } else {
71: $this->_name = $name;
72: $this->_help = $help;
73: $this->_required = $required;
74: $this->_choices = $choices;
75: }
76: }
77:
78: /**
79: * Get the value of the name attribute.
80: *
81: * @return string Value of this->_name.
82: */
83: public function name()
84: {
85: return $this->_name;
86: }
87:
88: /**
89: * Checks if this argument is equal to another argument.
90: *
91: * @param \Cake\Console\ConsoleInputArgument $argument ConsoleInputArgument to compare to.
92: * @return bool
93: */
94: public function isEqualTo(ConsoleInputArgument $argument)
95: {
96: return $this->usage() === $argument->usage();
97: }
98:
99: /**
100: * Generate the help for this argument.
101: *
102: * @param int $width The width to make the name of the option.
103: * @return string
104: */
105: public function help($width = 0)
106: {
107: $name = $this->_name;
108: if (strlen($name) < $width) {
109: $name = str_pad($name, $width, ' ');
110: }
111: $optional = '';
112: if (!$this->isRequired()) {
113: $optional = ' <comment>(optional)</comment>';
114: }
115: if ($this->_choices) {
116: $optional .= sprintf(' <comment>(choices: %s)</comment>', implode('|', $this->_choices));
117: }
118:
119: return sprintf('%s%s%s', $name, $this->_help, $optional);
120: }
121:
122: /**
123: * Get the usage value for this argument
124: *
125: * @return string
126: */
127: public function usage()
128: {
129: $name = $this->_name;
130: if ($this->_choices) {
131: $name = implode('|', $this->_choices);
132: }
133: $name = '<' . $name . '>';
134: if (!$this->isRequired()) {
135: $name = '[' . $name . ']';
136: }
137:
138: return $name;
139: }
140:
141: /**
142: * Check if this argument is a required argument
143: *
144: * @return bool
145: */
146: public function isRequired()
147: {
148: return (bool)$this->_required;
149: }
150:
151: /**
152: * Check that $value is a valid choice for this argument.
153: *
154: * @param string $value The choice to validate.
155: * @return true
156: * @throws \Cake\Console\Exception\ConsoleException
157: */
158: public function validChoice($value)
159: {
160: if (empty($this->_choices)) {
161: return true;
162: }
163: if (!in_array($value, $this->_choices, true)) {
164: throw new ConsoleException(
165: sprintf(
166: '"%s" is not a valid value for %s. Please use one of "%s"',
167: $value,
168: $this->_name,
169: implode(', ', $this->_choices)
170: )
171: );
172: }
173:
174: return true;
175: }
176:
177: /**
178: * Append this arguments XML representation to the passed in SimpleXml object.
179: *
180: * @param \SimpleXMLElement $parent The parent element.
181: * @return \SimpleXMLElement The parent with this argument appended.
182: */
183: public function xml(SimpleXMLElement $parent)
184: {
185: $option = $parent->addChild('argument');
186: $option->addAttribute('name', $this->_name);
187: $option->addAttribute('help', $this->_help);
188: $option->addAttribute('required', (int)$this->isRequired());
189: $choices = $option->addChild('choices');
190: foreach ($this->_choices as $valid) {
191: $choices->addChild('choice', $valid);
192: }
193:
194: return $parent;
195: }
196: }
197: