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