1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Iterators;
9:
10: use Nette;
11:
12:
13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29:
30: class CachingIterator extends \CachingIterator implements \Countable
31: {
32:
33: private $counter = 0;
34:
35:
36: public function __construct($iterator)
37: {
38: if (is_array($iterator) || $iterator instanceof \stdClass) {
39: $iterator = new \ArrayIterator($iterator);
40:
41: } elseif ($iterator instanceof \Traversable) {
42: if ($iterator instanceof \IteratorAggregate) {
43: $iterator = $iterator->getIterator();
44:
45: } elseif (!$iterator instanceof \Iterator) {
46: $iterator = new \IteratorIterator($iterator);
47: }
48:
49: } else {
50: throw new Nette\InvalidArgumentException("Invalid argument passed to foreach resp. " . __CLASS__ . "; array or Traversable expected, " . (is_object($iterator) ? get_class($iterator) : gettype($iterator)) ." given.");
51: }
52:
53: parent::__construct($iterator, 0);
54: }
55:
56:
57: 58: 59: 60: 61:
62: public function isFirst($width = NULL)
63: {
64: return $this->counter === 1 || ($width && $this->counter !== 0 && (($this->counter - 1) % $width) === 0);
65: }
66:
67:
68: 69: 70: 71: 72:
73: public function isLast($width = NULL)
74: {
75: return !$this->hasNext() || ($width && ($this->counter % $width) === 0);
76: }
77:
78:
79: 80: 81: 82:
83: public function isEmpty()
84: {
85: return $this->counter === 0;
86: }
87:
88:
89: 90: 91: 92:
93: public function isOdd()
94: {
95: return $this->counter % 2 === 1;
96: }
97:
98:
99: 100: 101: 102:
103: public function isEven()
104: {
105: return $this->counter % 2 === 0;
106: }
107:
108:
109: 110: 111: 112:
113: public function getCounter()
114: {
115: return $this->counter;
116: }
117:
118:
119: 120: 121: 122:
123: public function count()
124: {
125: $inner = $this->getInnerIterator();
126: if ($inner instanceof \Countable) {
127: return $inner->count();
128:
129: } else {
130: throw new Nette\NotSupportedException('Iterator is not countable.');
131: }
132: }
133:
134:
135: 136: 137: 138:
139: public function next()
140: {
141: parent::next();
142: if (parent::valid()) {
143: $this->counter++;
144: }
145: }
146:
147:
148: 149: 150: 151:
152: public function rewind()
153: {
154: parent::rewind();
155: $this->counter = parent::valid() ? 1 : 0;
156: }
157:
158:
159: 160: 161: 162:
163: public function getNextKey()
164: {
165: return $this->getInnerIterator()->key();
166: }
167:
168:
169: 170: 171: 172:
173: public function getNextValue()
174: {
175: return $this->getInnerIterator()->current();
176: }
177:
178:
179:
180:
181:
182: 183: 184: 185: 186: 187: 188:
189: public function __call($name, $args)
190: {
191: return Nette\ObjectMixin::call($this, $name, $args);
192: }
193:
194:
195: 196: 197: 198: 199: 200:
201: public function &__get($name)
202: {
203: return Nette\ObjectMixin::get($this, $name);
204: }
205:
206:
207: 208: 209: 210: 211: 212: 213:
214: public function __set($name, $value)
215: {
216: Nette\ObjectMixin::set($this, $name, $value);
217: }
218:
219:
220: 221: 222: 223: 224:
225: public function __isset($name)
226: {
227: return Nette\ObjectMixin::has($this, $name);
228: }
229:
230:
231: 232: 233: 234: 235: 236:
237: public function __unset($name)
238: {
239: Nette\ObjectMixin::remove($this, $name);
240: }
241:
242:
243: }
244: