Completed
Pull Request — master (#578)
by Fabio
19:18 queued 07:13
created

TMap::offsetGet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
/**
3
 * TMap, TMapIterator classes
4
 *
5
 * @author Qiang Xue <[email protected]>
6
 * @link https://github.com/pradosoft/prado
7
 * @copyright Copyright &copy; 2005-2016 The PRADO Group
8
 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
9
 * @package System.Collections
10
 */
11
12
/**
13
 * TMap class
14
 *
15
 * TMap implements a collection that takes key-value pairs.
16
 *
17
 * You can access, add or remove an item with a key by using
18
 * {@link itemAt}, {@link add}, and {@link remove}.
19
 * To get the number of the items in the map, use {@link getCount}.
20
 * TMap can also be used like a regular array as follows,
21
 * <code>
22
 * $map[$key]=$value; // add a key-value pair
23
 * unset($map[$key]); // remove the value with the specified key
24
 * if(isset($map[$key])) // if the map contains the key
25
 * foreach($map as $key=>$value) // traverse the items in the map
26
 * $n=count($map);  // returns the number of items in the map
27
 * </code>
28
 *
29
 * @author Qiang Xue <[email protected]>
30
 * @package System.Collections
31
 * @since 3.0
32
 */
33
class TMap extends TComponent implements IteratorAggregate,ArrayAccess,Countable
0 ignored issues
show
Coding Style introduced by
Expected 1 space before "ArrayAccess"; 0 found
Loading history...
Coding Style introduced by
Expected 1 space before "Countable"; 0 found
Loading history...
34
{
35
	/**
36
	 * @var array internal data storage
37
	 */
38
	private $_d=array();
39
	/**
40
	 * @var boolean whether this list is read-only
41
	 */
42
	private $_r=false;
43
44
	/**
45
	 * Returns an array with the names of all variables of this object that should NOT be serialized
46
	 * because their value is the default one or useless to be cached for the next page loads.
47
	 * Reimplement in derived classes to add new variables, but remember to  also to call the parent
48
	 * implementation first.
49
	 */
50
	protected function _getZappableSleepProps(&$exprops)
51
	{
52
		parent::_getZappableSleepProps($exprops);
53
		if ($this->_d===array())
54
			$exprops[] = "\0TMap\0_d";
55
		if ($this->_r===false)
56
			$exprops[] = "\0TMap\0_r";
57
	}
58
59
	/**
60
	 * Constructor.
61
	 * Initializes the list with an array or an iterable object.
62
	 * @param array|Iterator the intial data. Default is null, meaning no initialization.
63
	 * @param boolean whether the list is read-only
64
	 * @throws TInvalidDataTypeException If data is not null and neither an array nor an iterator.
65
	 */
66
	public function __construct($data=null,$readOnly=false)
67
	{
68
		if($data!==null)
69
			$this->copyFrom($data);
70
		$this->setReadOnly($readOnly);
71
	}
72
73
	/**
74
	 * @return boolean whether this map is read-only or not. Defaults to false.
75
	 */
76
	public function getReadOnly()
77
	{
78
		return $this->_r;
79
	}
80
81
	/**
82
	 * @param boolean whether this list is read-only or not
83
	 */
84
	protected function setReadOnly($value)
85
	{
86
		$this->_r=TPropertyValue::ensureBoolean($value);
87
	}
88
89
	/**
90
	 * Returns an iterator for traversing the items in the list.
91
	 * This method is required by the interface IteratorAggregate.
92
	 * @return Iterator an iterator for traversing the items in the list.
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use ArrayIterator.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
93
	 */
94
	public function getIterator()
95
	{
96
		return new ArrayIterator( $this->_d );
97
	}
98
99
	/**
100
	 * Returns the number of items in the map.
101
	 * This method is required by Countable interface.
102
	 * @return integer number of items in the map.
103
	 */
104
	public function count()
105
	{
106
		return $this->getCount();
107
	}
108
109
	/**
110
	 * @return integer the number of items in the map
111
	 */
112
	public function getCount()
113
	{
114
		return count($this->_d);
115
	}
116
117
	/**
118
	 * @return array the key list
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<integer|string>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
119
	 */
120
	public function getKeys()
121
	{
122
		return array_keys($this->_d);
123
	}
124
125
	/**
126
	 * Returns the item with the specified key.
127
	 * This method is exactly the same as {@link offsetGet}.
128
	 * @param mixed the key
129
	 * @return mixed the element at the offset, null if no element is found at the offset
130
	 */
131
	public function itemAt($key)
132
	{
133
		return isset($this->_d[$key]) ? $this->_d[$key] : null;
134
	}
135
136
	/**
137
	 * Adds an item into the map.
138
	 * Note, if the specified key already exists, the old value will be overwritten.
139
	 * @param mixed key
140
	 * @param mixed value
141
	 * @throws TInvalidOperationException if the map is read-only
142
	 */
143
	public function add($key,$value)
144
	{
145
		if(!$this->_r)
146
			$this->_d[$key]=$value;
147
		else
148
			throw new TInvalidOperationException('map_readonly',get_class($this));
149
	}
150
151
	/**
152
	 * Removes an item from the map by its key.
153
	 * @param mixed the key of the item to be removed
154
	 * @return mixed the removed value, null if no such key exists.
155
	 * @throws TInvalidOperationException if the map is read-only
156
	 */
157
	public function remove($key)
158
	{
159
		if(!$this->_r)
160
		{
161
			if(isset($this->_d[$key]) || array_key_exists($key,$this->_d))
162
			{
163
				$value=$this->_d[$key];
164
				unset($this->_d[$key]);
165
				return $value;
166
			}
167
			else
168
				return null;
169
		}
170
		else
171
			throw new TInvalidOperationException('map_readonly',get_class($this));
172
	}
173
174
	/**
175
	 * Removes all items in the map.
176
	 */
177
	public function clear()
178
	{
179
		foreach(array_keys($this->_d) as $key)
180
			$this->remove($key);
181
	}
182
183
	/**
184
	 * @param mixed the key
185
	 * @return boolean whether the map contains an item with the specified key
186
	 */
187
	public function contains($key)
188
	{
189
		return isset($this->_d[$key]) || array_key_exists($key,$this->_d);
190
	}
191
192
	/**
193
	 * @return array the list of items in array
194
	 */
195
	public function toArray()
196
	{
197
		return $this->_d;
198
	}
199
200
	/**
201
	 * Copies iterable data into the map.
202
	 * Note, existing data in the map will be cleared first.
203
	 * @param mixed the data to be copied from, must be an array or object implementing Traversable
204
	 * @throws TInvalidDataTypeException If data is neither an array nor an iterator.
205
	 */
206
	public function copyFrom($data)
207
	{
208
		if(is_array($data) || $data instanceof Traversable)
209
		{
210
			if($this->getCount()>0)
211
				$this->clear();
212
			foreach($data as $key=>$value)
213
				$this->add($key,$value);
214
		}
215
		else if($data!==null)
216
			throw new TInvalidDataTypeException('map_data_not_iterable');
217
	}
218
219
	/**
220
	 * Merges iterable data into the map.
221
	 * Existing data in the map will be kept and overwritten if the keys are the same.
222
	 * @param mixed the data to be merged with, must be an array or object implementing Traversable
223
	 * @throws TInvalidDataTypeException If data is neither an array nor an iterator.
224
	 */
225
	public function mergeWith($data)
226
	{
227
		if(is_array($data) || $data instanceof Traversable)
228
		{
229
			foreach($data as $key=>$value)
230
				$this->add($key,$value);
231
		}
232
		else if($data!==null)
233
			throw new TInvalidDataTypeException('map_data_not_iterable');
234
	}
235
236
	/**
237
	 * Returns whether there is an element at the specified offset.
238
	 * This method is required by the interface ArrayAccess.
239
	 * @param mixed the offset to check on
240
	 * @return boolean
241
	 */
242
	public function offsetExists($offset)
243
	{
244
		return $this->contains($offset);
245
	}
246
247
	/**
248
	 * Returns the element at the specified offset.
249
	 * This method is required by the interface ArrayAccess.
250
	 * @param integer the offset to retrieve element.
251
	 * @return mixed the element at the offset, null if no element is found at the offset
252
	 */
253
	public function offsetGet($offset)
254
	{
255
		return $this->itemAt($offset);
256
	}
257
258
	/**
259
	 * Sets the element at the specified offset.
260
	 * This method is required by the interface ArrayAccess.
261
	 * @param integer the offset to set element
262
	 * @param mixed the element value
263
	 */
264
	public function offsetSet($offset,$item)
265
	{
266
		$this->add($offset,$item);
267
	}
268
269
	/**
270
	 * Unsets the element at the specified offset.
271
	 * This method is required by the interface ArrayAccess.
272
	 * @param mixed the offset to unset element
273
	 */
274
	public function offsetUnset($offset)
275
	{
276
		$this->remove($offset);
277
	}
278
}
279
280
/**
281
 * TMapIterator class
282
 *
283
 * TMapIterator implements Iterator interface.
284
 *
285
 * TMapIterator is used by TMap. It allows TMap to return a new iterator
286
 * for traversing the items in the map.
287
 *
288
 * @deprecated Issue 264 : ArrayIterator should be used instead
289
 * @author Qiang Xue <[email protected]>
290
 * @package System.Collections
291
 * @since 3.0
292
 */
293
class TMapIterator extends ArrayIterator
294
{
295
}
296