1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Collections;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21:
22: class KeyNotFoundException extends \RuntimeException
23: {
24: }
25:
26:
27:
28: 29: 30: 31: 32:
33: class Hashtable extends Collection implements IMap
34: {
35:
36: private $throwKeyNotFound = FALSE;
37:
38:
39:
40: 41: 42: 43: 44: 45: 46:
47: public function add($key, $item)
48: {
49:
50: if (!is_scalar($key)) {
51: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
52: }
53:
54: if (parent::offsetExists($key)) {
55: throw new \InvalidStateException('An element with the same key already exists.');
56: }
57:
58: $this->beforeAdd($item);
59: parent::offsetSet($key, $item);
60: return TRUE;
61: }
62:
63:
64:
65: 66: 67:
68: public function append($item)
69: {
70: throw new \NotSupportedException;
71: }
72:
73:
74:
75: 76: 77: 78:
79: public function getKeys()
80: {
81: return array_keys($this->getArrayCopy());
82: }
83:
84:
85:
86: 87: 88: 89: 90: 91:
92: public function search($item)
93: {
94: return array_search($item, $this->getArrayCopy(), TRUE);
95: }
96:
97:
98:
99: 100: 101: 102: 103: 104:
105: public function import($arr)
106: {
107: $this->updating();
108:
109: if (!(is_array($arr) || $arr instanceof \Traversable)) {
110: throw new \InvalidArgumentException("Argument must be traversable.");
111: }
112:
113: if ($this->getItemType() === NULL) {
114: $this->setArray((array) $arr);
115:
116: } else {
117: $this->clear();
118: foreach ($arr as $key => $item) {
119: $this->offsetSet($key, $item);
120: }
121: }
122: }
123:
124:
125:
126: 127: 128: 129: 130: 131: 132:
133: public function get($key, $default = NULL)
134: {
135: if (!is_scalar($key)) {
136: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
137: }
138:
139: if (parent::offsetExists($key)) {
140: return parent::offsetGet($key);
141:
142: } else {
143: return $default;
144: }
145: }
146:
147:
148:
149: 150: 151: 152:
153: public function throwKeyNotFound($val = TRUE)
154: {
155: $this->throwKeyNotFound = (bool) $val;
156: }
157:
158:
159:
160:
161:
162:
163:
164: 165: 166: 167: 168: 169: 170:
171: public function offsetSet($key, $item)
172: {
173: if (!is_scalar($key)) {
174: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
175: }
176:
177: $this->beforeAdd($item);
178: parent::offsetSet($key, $item);
179: }
180:
181:
182:
183: 184: 185: 186: 187: 188:
189: public function offsetGet($key)
190: {
191: if (!is_scalar($key)) {
192: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
193: }
194:
195: if (parent::offsetExists($key)) {
196: return parent::offsetGet($key);
197:
198: } elseif ($this->throwKeyNotFound) {
199: throw new KeyNotFoundException;
200:
201: } else {
202: return NULL;
203: }
204: }
205:
206:
207:
208: 209: 210: 211: 212: 213:
214: public function offsetExists($key)
215: {
216: if (!is_scalar($key)) {
217: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
218: }
219:
220: return parent::offsetExists($key);
221: }
222:
223:
224:
225: 226: 227: 228: 229: 230:
231: public function offsetUnset($key)
232: {
233: $this->updating();
234:
235: if (!is_scalar($key)) {
236: throw new \InvalidArgumentException("Key must be either a string or an integer, " . gettype($key) ." given.");
237: }
238:
239: if (parent::offsetExists($key)) {
240: parent::offsetUnset($key);
241: }
242: }
243:
244: }
245: