ParameterCollection   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 263
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 48
dl 0
loc 263
rs 10
c 0
b 0
f 0
wmc 28

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __toString() 0 3 1
A get() 0 11 2
A all() 0 3 1
A getCommands() 0 13 3
A toString() 0 3 1
A hasVariable() 0 10 3
A exists() 0 8 2
A hasCommand() 0 10 3
B mergeArguments() 0 44 8
A __construct() 0 7 1
A addParameter() 0 16 3
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
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

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.

Loading history...