3 * TPagedDataSource, TPagedListIterator, TPagedMapIterator classes
5 * @author Qiang Xue <qiang.xue@gmail.com>
6 * @link https://github.com/pradosoft/prado
7 * @copyright Copyright © 2005-2016 The PRADO Group
8 * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
9 * @package System.Collections
13 * TPagedDataSource class
15 * TPagedDataSource implements an integer-indexed collection class with paging functionality.
17 * Data items in TPagedDataSource can be traversed using <b>foreach</b>
18 * PHP statement like the following,
20 * foreach($pagedDataSource as $dataItem)
22 * The data are fetched from {@link setDataSource DataSource}. Only the items
23 * within the specified page will be returned and traversed.
25 * @author Qiang Xue <qiang.xue@gmail.com>
26 * @package System.Collections
29 class TPagedDataSource extends TComponent implements IteratorAggregate,Countable
32 * @var mixed original data source
34 private $_dataSource=null;
36 * @var integer number of items in each page
38 private $_pageSize=10;
40 * @var integer current page index
42 private $_currentPageIndex=0;
44 * @var boolean whether to allow paging
46 private $_allowPaging=false;
48 * @var boolean whether to allow custom paging
50 private $_allowCustomPaging=false;
52 * @var integer user-assigned number of items in data source
54 private $_virtualCount=0;
57 * @return mixed original data source. Defaults to null.
59 public function getDataSource()
61 return $this->_dataSource;
65 * @param mixed original data source
67 public function setDataSource($value)
69 if(!($value instanceof TMap) && !($value instanceof TList))
72 $value=new TMap($value);
73 else if($value instanceof Traversable)
74 $value=new TList($value);
75 else if($value!==null)
76 throw new TInvalidDataTypeException('pageddatasource_datasource_invalid');
78 $this->_dataSource=$value;
82 * @return integer number of items in each page. Defaults to 10.
84 public function getPageSize()
86 return $this->_pageSize;
90 * @param integer number of items in each page
92 public function setPageSize($value)
94 if(($value=TPropertyValue::ensureInteger($value))>0)
95 $this->_pageSize=$value;
97 throw new TInvalidDataValueException('pageddatasource_pagesize_invalid');
101 * @return integer current page index. Defaults to 0.
103 public function getCurrentPageIndex()
105 return $this->_currentPageIndex;
109 * @param integer current page index
111 public function setCurrentPageIndex($value)
113 if(($value=TPropertyValue::ensureInteger($value))<0)
115 $this->_currentPageIndex=$value;
119 * @return boolean whether to allow paging. Defaults to false.
121 public function getAllowPaging()
123 return $this->_allowPaging;
127 * @param boolean whether to allow paging
129 public function setAllowPaging($value)
131 $this->_allowPaging=TPropertyValue::ensureBoolean($value);
135 * @return boolean whether to allow custom paging. Defaults to false.
137 public function getAllowCustomPaging()
139 return $this->_allowCustomPaging;
143 * @param boolean whether to allow custom paging
145 public function setAllowCustomPaging($value)
147 $this->_allowCustomPaging=TPropertyValue::ensureBoolean($value);
151 * @return integer user-assigned number of items in data source Defaults to 0.
153 public function getVirtualItemCount()
155 return $this->_virtualCount;
159 * @param integer user-assigned number of items in data source
161 public function setVirtualItemCount($value)
163 if(($value=TPropertyValue::ensureInteger($value))>=0)
164 $this->_virtualCount=$value;
166 throw new TInvalidDataValueException('pageddatasource_virtualitemcount_invalid');
170 * @return integer number of items in current page
172 public function getCount()
174 if($this->_dataSource===null)
176 if(!$this->_allowPaging)
177 return $this->getDataSourceCount();
178 if(!$this->_allowCustomPaging && $this->getIsLastPage())
179 return $this->getDataSourceCount()-$this->getFirstIndexInPage();
180 return $this->_pageSize;
184 * Returns the number of items in the current page.
185 * This method is required by Countable interface.
186 * @return integer number of items in the current page.
188 public function count()
190 return $this->getCount();
194 * @return integer number of pages
196 public function getPageCount()
198 if($this->_dataSource===null)
200 $count=$this->getDataSourceCount();
201 if(!$this->_allowPaging || $count<=0)
203 return (int)(($count+$this->_pageSize-1)/$this->_pageSize);
207 * @return boolean whether the current page is the first page Defaults to false.
209 public function getIsFirstPage()
211 if($this->_allowPaging)
212 return $this->_currentPageIndex===0;
218 * @return boolean whether the current page is the last page
220 public function getIsLastPage()
222 if($this->_allowPaging)
223 return $this->_currentPageIndex===$this->getPageCount()-1;
229 * @return integer the index of the item in data source, where the item is the first in
232 public function getFirstIndexInPage()
234 if($this->_dataSource!==null && $this->_allowPaging && !$this->_allowCustomPaging)
235 return $this->_currentPageIndex*$this->_pageSize;
241 * @return integer number of items in data source, if available
243 public function getDataSourceCount()
245 if($this->_dataSource===null)
247 else if($this->_allowCustomPaging)
248 return $this->_virtualCount;
250 return $this->_dataSource->getCount();
254 * @return Iterator iterator
256 public function getIterator()
258 if($this->_dataSource instanceof TList)
259 return new TPagedListIterator($this->_dataSource,$this->getFirstIndexInPage(),$this->getCount());
260 else if($this->_dataSource instanceof TMap)
261 return new TPagedMapIterator($this->_dataSource,$this->getFirstIndexInPage(),$this->getCount());
270 * TPagedListIterator class
272 * TPagedListIterator implements Iterator interface.
274 * TPagedListIterator is used by {@link TPagedDataSource}. It allows TPagedDataSource
275 * to return a new iterator for traversing the items in a {@link TList} object.
277 * @author Qiang Xue <qiang.xue@gmail.com>
278 * @package System.Collections
281 class TPagedListIterator implements Iterator
284 private $_startIndex;
290 * @param TList the data to be iterated through
291 * @param integer start index
292 * @param integer number of items to be iterated through
294 public function __construct(TList $list,$startIndex,$count)
298 $this->_startIndex=$startIndex;
299 if($startIndex+$count>$list->getCount())
300 $this->_count=$list->getCount()-$startIndex;
302 $this->_count=$count;
306 * Rewinds internal array pointer.
307 * This method is required by the interface Iterator.
309 public function rewind()
315 * Returns the key of the current array item.
316 * This method is required by the interface Iterator.
317 * @return integer the key of the current array item
319 public function key()
321 return $this->_index;
325 * Returns the current array item.
326 * This method is required by the interface Iterator.
327 * @return mixed the current array item
329 public function current()
331 return $this->_list->itemAt($this->_startIndex+$this->_index);
335 * Moves the internal pointer to the next array item.
336 * This method is required by the interface Iterator.
338 public function next()
344 * Returns whether there is an item at current position.
345 * This method is required by the interface Iterator.
348 public function valid()
350 return $this->_index<$this->_count;
355 * TPagedMapIterator class
357 * TPagedMapIterator implements Iterator interface.
359 * TPagedMapIterator is used by {@link TPagedDataSource}. It allows TPagedDataSource
360 * to return a new iterator for traversing the items in a {@link TMap} object.
362 * @author Qiang Xue <qiang.xue@gmail.com>
363 * @package System.Collections
366 class TPagedMapIterator implements Iterator
369 private $_startIndex;
376 * @param array the data to be iterated through
378 public function __construct(TMap $map,$startIndex,$count)
382 $this->_startIndex=$startIndex;
383 if($startIndex+$count>$map->getCount())
384 $this->_count=$map->getCount()-$startIndex;
386 $this->_count=$count;
387 $this->_iterator=$map->getIterator();
391 * Rewinds internal array pointer.
392 * This method is required by the interface Iterator.
394 public function rewind()
396 $this->_iterator->rewind();
397 for($i=0;$i<$this->_startIndex;++$i)
398 $this->_iterator->next();
403 * Returns the key of the current array item.
404 * This method is required by the interface Iterator.
405 * @return integer the key of the current array item
407 public function key()
409 return $this->_iterator->key();
413 * Returns the current array item.
414 * This method is required by the interface Iterator.
415 * @return mixed the current array item
417 public function current()
419 return $this->_iterator->current();
423 * Moves the internal pointer to the next array item.
424 * This method is required by the interface Iterator.
426 public function next()
429 $this->_iterator->next();
433 * Returns whether there is an item at current position.
434 * This method is required by the interface Iterator.
437 public function valid()
439 return $this->_index<$this->_count;