1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* ParameterCollection.php |
5
|
|
|
*/ |
6
|
|
|
|
7
|
|
|
namespace netfocusinc\argh; |
8
|
|
|
|
9
|
|
|
use netfocusinc\argh\Argument; |
10
|
|
|
use netfocusinc\argh\Parameter; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* Representation of a collection of Parameters |
14
|
|
|
* |
15
|
|
|
* A ParameterCollection maintains a list of the Parameters used to interpret command line arguments |
16
|
|
|
* In addition to maintaining the Parameter list, this class is also responsible for "merging" Arguments |
17
|
|
|
* with Parameters. This process involves using the Arguments (as parsed from the command line) to set |
18
|
|
|
* values of Parameters in the collection. |
19
|
|
|
* |
20
|
|
|
* @internal |
21
|
|
|
* |
22
|
|
|
* @author Benjamin Hough |
23
|
|
|
* |
24
|
|
|
* @since 1.0.0 |
25
|
|
|
*/ |
26
|
|
|
class ParameterCollection |
27
|
|
|
{ |
28
|
|
|
// |
29
|
|
|
// PRIVATE PROPERTIES |
30
|
|
|
// |
31
|
|
|
|
32
|
|
|
/** @var array An array of Parameters */ |
33
|
|
|
private $parameters; |
34
|
|
|
|
35
|
|
|
/** @var array A map from Parameter keys to their index in the $parameters array */ |
36
|
|
|
private $map; |
37
|
|
|
|
38
|
|
|
// |
39
|
|
|
// Magic Methods |
40
|
|
|
// |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* Magic function returns a string representation of this ParameterCollection |
44
|
|
|
* |
45
|
|
|
* @since 1.0.0 |
46
|
|
|
* |
47
|
|
|
* @return string |
48
|
|
|
*/ |
49
|
|
|
public function __toString() |
50
|
|
|
{ |
51
|
|
|
return $this->toString(); |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
// |
55
|
|
|
// PUBLIC METHODS |
56
|
|
|
// |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* ParameterCollection constructor |
60
|
|
|
* |
61
|
|
|
* Constructs a new ParameterCollection with an empty list of Parameters |
62
|
|
|
* and a "map" that can be used to reference Parameters in the collection by 'name' or 'tag' |
63
|
|
|
* |
64
|
|
|
* @since 1.0.0 |
65
|
|
|
*/ |
66
|
|
|
public function __construct() |
67
|
|
|
{ |
68
|
|
|
// Create a Parameter array |
69
|
|
|
$this->parameters = array(); |
70
|
|
|
|
71
|
|
|
// Create a 'map' array for quick lookup of Parameters by index |
72
|
|
|
$this->map = array(); |
73
|
|
|
} |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Returns TRUE when the specified $key matches the 'name' or 'flag' of a Parameter in the collection |
77
|
|
|
* |
78
|
|
|
* @since 1.0.0 |
79
|
|
|
* |
80
|
|
|
* @param string $key |
81
|
|
|
* |
82
|
|
|
* @return bool Returns TRUE when the specified $key matches a Parameter in the collection; FALSE otherwise. |
83
|
|
|
*/ |
84
|
|
|
public function exists(string $key): bool |
85
|
|
|
{ |
86
|
|
|
if( array_key_exists($key, $this->map) ) |
87
|
|
|
{ |
88
|
|
|
return true; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
return false; |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* Returns a boolean indicating if this collection contains a CommandParameter |
96
|
|
|
* |
97
|
|
|
* @since 1.0.0 |
98
|
|
|
* |
99
|
|
|
* @return bool Returns TRUE when the collection contains a CommandParameter |
100
|
|
|
*/ |
101
|
|
|
public function hasCommand(): bool |
102
|
|
|
{ |
103
|
|
|
foreach($this->parameters as $p) |
104
|
|
|
{ |
105
|
|
|
if( Parameter::ARGH_TYPE_COMMAND == $p->getParameterType() ) |
106
|
|
|
{ |
107
|
|
|
return true; |
108
|
|
|
} |
109
|
|
|
} |
110
|
|
|
return false; |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Returns a boolean indicating if this collection contains a VariableParameter |
115
|
|
|
* |
116
|
|
|
* @since 1.0.0 |
117
|
|
|
* |
118
|
|
|
* @return bool Returns TRUE when the collection contains a VariableParameter |
119
|
|
|
*/ |
120
|
|
|
public function hasVariable(): bool |
121
|
|
|
{ |
122
|
|
|
foreach($this->parameters as $p) |
123
|
|
|
{ |
124
|
|
|
if( Parameter::ARGH_TYPE_VARIABLE == $p->getParameterType() ) |
125
|
|
|
{ |
126
|
|
|
return true; |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
return false; |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Retrieves a Parameter in this collection by 'name' or 'flag' |
134
|
|
|
* |
135
|
|
|
* @since 1.0.0 |
136
|
|
|
* |
137
|
|
|
* @param string $key The 'name' or 'flag' of a Parameter |
138
|
|
|
* |
139
|
|
|
* @return Parameter |
140
|
|
|
* @throws ArghException When there is no Parameter in the collection matching the specified $key |
141
|
|
|
*/ |
142
|
|
|
public function get(string $key): Parameter |
143
|
|
|
{ |
144
|
|
|
if($this->exists($key)) |
145
|
|
|
{ |
146
|
|
|
$index = $this->map[$key]; |
147
|
|
|
|
148
|
|
|
return $this->parameters[$index]; |
149
|
|
|
} |
150
|
|
|
else |
151
|
|
|
{ |
152
|
|
|
throw new ArghException('Parameter \'' . $key . '\' not in collection'); |
153
|
|
|
} |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Returns an array of command strings |
158
|
|
|
* |
159
|
|
|
* If this collection contains any CommandParameters, |
160
|
|
|
* this method will return an array of the values defined by these commands. |
161
|
|
|
* |
162
|
|
|
* @since 1.0.0 |
163
|
|
|
* |
164
|
|
|
* @return array |
165
|
|
|
*/ |
166
|
|
|
public function getCommands(): array |
167
|
|
|
{ |
168
|
|
|
$commands = array(); |
169
|
|
|
|
170
|
|
|
foreach($this->parameters as $p) |
171
|
|
|
{ |
172
|
|
|
if( Parameter::ARGH_TYPE_COMMAND == $p->getParameterType() ) |
173
|
|
|
{ |
174
|
|
|
$commands[] = $p; |
175
|
|
|
} |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
return $commands; |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* Adds a Parameter to the array of Parameters maintained by this collection. |
183
|
|
|
* |
184
|
|
|
* @since 1.0.0 |
185
|
|
|
* |
186
|
|
|
* @param Parameter $param |
187
|
|
|
* |
188
|
|
|
* @throws ArghException If a Parameter with the same 'name' already exists |
189
|
|
|
*/ |
190
|
|
|
public function addParameter(Parameter $param) |
191
|
|
|
{ |
192
|
|
|
if( !$this->exists($param->getName()) ) |
193
|
|
|
{ |
194
|
|
|
// Add $param to $parameters array |
195
|
|
|
$this->parameters[] = $param; |
196
|
|
|
|
197
|
|
|
// Map the new parameter's 'name' to its corresponding index in the $parameters array |
198
|
|
|
$this->map[$param->getName()] = count($this->parameters)-1; |
199
|
|
|
|
200
|
|
|
// Map the new parameter's 'flag' to its corresponding index in the $parameters array |
201
|
|
|
if(!empty($param->getFlag())) $this->map[$param->getFlag()] = count($this->parameters)-1; |
202
|
|
|
} |
203
|
|
|
else |
204
|
|
|
{ |
205
|
|
|
throw(new ArghException(__CLASS__ . ': Parameter \'' . $param->getName() . '\' cannot be redefined.')); |
206
|
|
|
} |
207
|
|
|
} |
208
|
|
|
|
209
|
|
|
/** |
210
|
|
|
* Given an array of Arguments, this method sets the 'value' of Parameters in the collection |
211
|
|
|
* with the 'value' of its corresponding Argument. |
212
|
|
|
* |
213
|
|
|
* @since 1.0.0 |
214
|
|
|
* |
215
|
|
|
* @param array $arguments An array of Arguments |
216
|
|
|
* |
217
|
|
|
* @throws ArgumentException |
218
|
|
|
*/ |
219
|
|
|
public function mergeArguments(array $arguments): void |
220
|
|
|
{ |
221
|
|
|
|
222
|
|
|
foreach($arguments as $a) |
223
|
|
|
{ |
224
|
|
|
// Check for a Parameter with this Arguments key |
225
|
|
|
if( $this->exists($a->getKey()) ) |
226
|
|
|
{ |
227
|
|
|
// Enforce limitations of Parameters |
228
|
|
|
// 1. Do NOT allow value to be redefined |
229
|
|
|
// 2. ARGH_TYPE_VARIABLE (VariableParameter) can have values appended |
230
|
|
|
|
231
|
|
|
if( Parameter::ARGH_TYPE_VARIABLE == $this->parameters[$this->map[$a->getKey()]]->getParameterType() ) |
232
|
|
|
{ |
233
|
|
|
// Call VariableParameters::addValue() method |
234
|
|
|
$this->parameters[$this->map[$a->getKey()]]->addValue($a->getValue()); |
235
|
|
|
} |
236
|
|
|
else if( null !== $this->parameters[$this->map[$a->getKey()]]->getValue() ) |
237
|
|
|
{ |
238
|
|
|
// |
239
|
|
|
// Do NOT allow a Parameter's value to be redefined |
240
|
|
|
// |
241
|
|
|
|
242
|
|
|
throw(new ArghException(__CLASS__ . ': Parameter \'' . $a->getKey() . '\' value cannot be redefined.')); |
243
|
|
|
} |
244
|
|
|
else |
245
|
|
|
{ |
246
|
|
|
// Set Parameter value |
247
|
|
|
$this->parameters[$this->map[$a->getKey()]]->setValue($a->getValue()); |
248
|
|
|
} |
249
|
|
|
} |
250
|
|
|
else |
251
|
|
|
{ |
252
|
|
|
throw(new ArghException(__CLASS__ . ': Cannot merge Argument \'' . $a->getKey() . '\'. Parameter not defined.')); |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
} // END: foreach($arguments as $a) |
256
|
|
|
|
257
|
|
|
// Check for REQUIRED Parameters without any value |
258
|
|
|
foreach($this->parameters as $p) |
259
|
|
|
{ |
260
|
|
|
if( ($p->isRequired() ) && (null == $p->getValue()) ) |
261
|
|
|
{ |
262
|
|
|
throw(new ArghException(__CLASS__ . ': Missing required parameter \'' . $p->getName() . '\'.')); |
263
|
|
|
} |
264
|
|
|
} |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* Returns the array of Parameters in this collection. |
269
|
|
|
* |
270
|
|
|
* @since 1.0.0 |
271
|
|
|
* |
272
|
|
|
* @return array Array of Parameters in this collection. |
273
|
|
|
*/ |
274
|
|
|
public function all() |
275
|
|
|
{ |
276
|
|
|
return $this->parameters; |
277
|
|
|
} |
278
|
|
|
|
279
|
|
|
/** |
280
|
|
|
* Returns a string representation of this ParameterCollection. |
281
|
|
|
* |
282
|
|
|
* @since 1.0.0 |
283
|
|
|
* |
284
|
|
|
* @return string Returns |
285
|
|
|
*/ |
286
|
|
|
public function toString() |
287
|
|
|
{ |
288
|
|
|
return print_r($this->parameters, TRUE); |
289
|
|
|
} |
290
|
|
|
|
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
?> |
|
|
|
|
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.
A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.