Extbase:
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / RangeIterator.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This class is a backport of the corresponding class of FLOW3.
9 * All credits go to the v5 team.
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27
28 /**
29 * A RangeIterator
30 *
31 * @package Extbase
32 * @version $Id: RangeIterator.php 1811 2009-01-28 12:04:49Z robert $
33 * @scope prototype
34 */
35 class Tx_Extbase_Persistence_RangeIterator implements Tx_Extbase_Persistence_RangeIteratorInterface {
36
37 /**
38 * @var array
39 */
40 protected $elements;
41
42 /**
43 * @var integer
44 */
45 protected $position = 0;
46
47 /**
48 * Constructs a new RangeIterator
49 *
50 * @param array $elements The elements to populate the iterator with
51 * @return void
52 */
53 public function __construct(array $elements = array()) {
54 $this->elements = $elements;
55 }
56
57 /**
58 * Append a new element to the end of the iteration
59 *
60 * @param mixed $element The element to append to the iteration
61 * @return void
62 */
63 public function append($element) {
64 $this->elements[] = $element;
65 }
66
67 /**
68 * Removes the last element returned by next()
69 *
70 * @return void
71 */
72 public function remove() {
73 $positionToRemove = $this->getPosition()-1;
74 array_splice($this->elements, $positionToRemove, 1);
75 // array_splice resets the array pointer, so we fix it together with the internal position
76 for ($skipped = 0; $skipped < --$this->position; $skipped++) next($this->elements);
77 }
78
79 /**
80 * Returns FALSE if there are more elements available.
81 *
82 * @return boolean
83 */
84 public function hasNext() {
85 return $this->getPosition() < $this->getSize();
86 }
87
88 /**
89 * Return the next (i.e. current) element in the iterator
90 *
91 * @return mixed The next element in the iteration
92 */
93 public function next() {
94 if ($this->hasNext()) {
95 $this->position++;
96 $element = current($this->elements);
97 next($this->elements);
98 return $element;
99 } else {
100 throw new OutOfBoundsException('Tried to go past the last element in the iterator.', 1187530869);
101 }
102 }
103
104 /**
105 * Skip a number of elements in the iterator.
106 *
107 * @param integer $skipNum the non-negative number of elements to skip
108 * @return void
109 * @throws OutOfBoundsException if skipped past the last element in the iterator.
110 */
111 public function skip($skipNum) {
112 $newPosition = $this->getPosition() + $skipNum;
113 if ($newPosition > $this->getSize()) {
114 throw new OutOfBoundsException('Skip operation past the last element in the iterator.', 1187530862);
115 } else {
116 $this->position = $newPosition;
117 for ($skipped = 0; $skipped < $skipNum; $skipped++) next($this->elements);
118 }
119 }
120
121 /**
122 * Returns the total number of of items available through this iterator.
123 *
124 * For example, for some node $n, $n->getNodes()->getSize() returns the number
125 * of child nodes of $n visible through the current Session.
126 *
127 * In some implementations precise information about the number of elements may
128 * not be available. In such cases this method must return -1. API clients will
129 * then be able to use RangeIterator->getNumberRemaining() to get an
130 * estimate on the number of elements.
131 *
132 * @return integer
133 */
134 public function getSize() {
135 return count($this->elements);
136 }
137
138 /**
139 * Returns the current position within the iterator. The number
140 * returned is the 0-based index of the next element in the iterator,
141 * i.e. the one that will be returned on the subsequent next() call.
142 *
143 * Note that this method does not check if there is a next element,
144 * i.e. an empty iterator will always return 0.
145 *
146 * @return integer The current position, 0-based
147 */
148 public function getPosition() {
149 return $this->position;
150 }
151
152 // non-JSR-283 methods below
153
154 /**
155 * Alias for hasNext(), valid() is required by SPL Iterator
156 *
157 * @return boolean
158 */
159 public function valid() {
160 return $this->hasNext();
161 }
162
163 /**
164 * Rewinds the element cursor, required by SPL Iterator
165 *
166 * @return void
167 */
168 public function rewind() {
169 $this->position = 0;
170 reset($this->elements);
171 }
172
173 /**
174 * Returns the current element, i.e. the element the last next() call returned
175 * Required by SPL Iterator
176 *
177 * @return mixed The current element
178 */
179 public function current() {
180 return current($this->elements);
181 }
182
183 /**
184 * Returns the key of the current element
185 * Required by SPL Iterator
186 *
187 * return integer The key of the current element
188 */
189 public function key() {
190 return $this->getPosition();
191 }
192 }
193 ?>