]> git.sur5r.net Git - bacula/bacula/blob - gui/baculum/framework/Collections/TPagedDataSource.php
baculum: New Baculum API and Baculum Web
[bacula/bacula] / gui / baculum / framework / Collections / TPagedDataSource.php
1 <?php
2 /**
3  * TPagedDataSource, TPagedListIterator, TPagedMapIterator classes
4  *
5  * @author Qiang Xue <qiang.xue@gmail.com>
6  * @link https://github.com/pradosoft/prado
7  * @copyright Copyright &copy; 2005-2016 The PRADO Group
8  * @license https://github.com/pradosoft/prado/blob/master/COPYRIGHT
9  * @package System.Collections
10  */
11
12 /**
13  * TPagedDataSource class
14  *
15  * TPagedDataSource implements an integer-indexed collection class with paging functionality.
16  *
17  * Data items in TPagedDataSource can be traversed using <b>foreach</b>
18  * PHP statement like the following,
19  * <code>
20  * foreach($pagedDataSource as $dataItem)
21  * </code>
22  * The data are fetched from {@link setDataSource DataSource}. Only the items
23  * within the specified page will be returned and traversed.
24  *
25  * @author Qiang Xue <qiang.xue@gmail.com>
26  * @package System.Collections
27  * @since 3.0
28  */
29 class TPagedDataSource extends TComponent implements IteratorAggregate,Countable
30 {
31         /**
32          * @var mixed original data source
33          */
34         private $_dataSource=null;
35         /**
36          * @var integer number of items in each page
37          */
38         private $_pageSize=10;
39         /**
40          * @var integer current page index
41          */
42         private $_currentPageIndex=0;
43         /**
44          * @var boolean whether to allow paging
45          */
46         private $_allowPaging=false;
47         /**
48          * @var boolean whether to allow custom paging
49          */
50         private $_allowCustomPaging=false;
51         /**
52          * @var integer user-assigned number of items in data source
53          */
54         private $_virtualCount=0;
55
56         /**
57          * @return mixed original data source. Defaults to null.
58          */
59         public function getDataSource()
60         {
61                 return $this->_dataSource;
62         }
63
64         /**
65          * @param mixed original data source
66          */
67         public function setDataSource($value)
68         {
69                 if(!($value instanceof TMap) && !($value instanceof TList))
70                 {
71                         if(is_array($value))
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');
77                 }
78                 $this->_dataSource=$value;
79         }
80
81         /**
82          * @return integer number of items in each page. Defaults to 10.
83          */
84         public function getPageSize()
85         {
86                 return $this->_pageSize;
87         }
88
89         /**
90          * @param integer number of items in each page
91          */
92         public function setPageSize($value)
93         {
94                 if(($value=TPropertyValue::ensureInteger($value))>0)
95                         $this->_pageSize=$value;
96                 else
97                         throw new TInvalidDataValueException('pageddatasource_pagesize_invalid');
98         }
99
100         /**
101          * @return integer current page index. Defaults to 0.
102          */
103         public function getCurrentPageIndex()
104         {
105                 return $this->_currentPageIndex;
106         }
107
108         /**
109          * @param integer current page index
110          */
111         public function setCurrentPageIndex($value)
112         {
113                 if(($value=TPropertyValue::ensureInteger($value))<0)
114                         $value=0;
115                 $this->_currentPageIndex=$value;
116         }
117
118         /**
119          * @return boolean whether to allow paging. Defaults to false.
120          */
121         public function getAllowPaging()
122         {
123                 return $this->_allowPaging;
124         }
125
126         /**
127          * @param boolean whether to allow paging
128          */
129         public function setAllowPaging($value)
130         {
131                 $this->_allowPaging=TPropertyValue::ensureBoolean($value);
132         }
133
134         /**
135          * @return boolean whether to allow custom paging. Defaults to false.
136          */
137         public function getAllowCustomPaging()
138         {
139                 return $this->_allowCustomPaging;
140         }
141
142         /**
143          * @param boolean whether to allow custom paging
144          */
145         public function setAllowCustomPaging($value)
146         {
147                 $this->_allowCustomPaging=TPropertyValue::ensureBoolean($value);
148         }
149
150         /**
151          * @return integer user-assigned number of items in data source Defaults to 0.
152          */
153         public function getVirtualItemCount()
154         {
155                 return $this->_virtualCount;
156         }
157
158         /**
159          * @param integer user-assigned number of items in data source
160          */
161         public function setVirtualItemCount($value)
162         {
163                 if(($value=TPropertyValue::ensureInteger($value))>=0)
164                         $this->_virtualCount=$value;
165                 else
166                         throw new TInvalidDataValueException('pageddatasource_virtualitemcount_invalid');
167         }
168
169         /**
170          * @return integer number of items in current page
171          */
172         public function getCount()
173         {
174                 if($this->_dataSource===null)
175                         return 0;
176                 if(!$this->_allowPaging)
177                         return $this->getDataSourceCount();
178                 if(!$this->_allowCustomPaging && $this->getIsLastPage())
179                         return $this->getDataSourceCount()-$this->getFirstIndexInPage();
180                 return $this->_pageSize;
181         }
182
183         /**
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.
187          */
188         public function count()
189         {
190                 return $this->getCount();
191         }
192
193         /**
194          * @return integer number of pages
195          */
196         public function getPageCount()
197         {
198                 if($this->_dataSource===null)
199                         return 0;
200                 $count=$this->getDataSourceCount();
201                 if(!$this->_allowPaging || $count<=0)
202                         return 1;
203                 return (int)(($count+$this->_pageSize-1)/$this->_pageSize);
204         }
205
206         /**
207          * @return boolean whether the current page is the first page Defaults to false.
208          */
209         public function getIsFirstPage()
210         {
211                 if($this->_allowPaging)
212                         return $this->_currentPageIndex===0;
213                 else
214                         return true;
215         }
216
217         /**
218          * @return boolean whether the current page is the last page
219          */
220         public function getIsLastPage()
221         {
222                 if($this->_allowPaging)
223                         return $this->_currentPageIndex===$this->getPageCount()-1;
224                 else
225                         return true;
226         }
227
228         /**
229          * @return integer the index of the item in data source, where the item is the first in
230          * current page
231          */
232         public function getFirstIndexInPage()
233         {
234                 if($this->_dataSource!==null && $this->_allowPaging && !$this->_allowCustomPaging)
235                         return $this->_currentPageIndex*$this->_pageSize;
236                 else
237                         return 0;
238         }
239
240         /**
241          * @return integer number of items in data source, if available
242          */
243         public function getDataSourceCount()
244         {
245                 if($this->_dataSource===null)
246                         return 0;
247                 else if($this->_allowCustomPaging)
248                         return $this->_virtualCount;
249                 else
250                         return $this->_dataSource->getCount();
251         }
252
253         /**
254          * @return Iterator iterator
255          */
256         public function getIterator()
257         {
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());
262                 else
263                         return null;
264         }
265 }
266
267
268
269 /**
270  * TPagedListIterator class
271  *
272  * TPagedListIterator implements Iterator interface.
273  *
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.
276  *
277  * @author Qiang Xue <qiang.xue@gmail.com>
278  * @package System.Collections
279  * @since 3.0
280  */
281 class TPagedListIterator implements Iterator
282 {
283         private $_list;
284         private $_startIndex;
285         private $_count;
286         private $_index;
287
288         /**
289          * Constructor.
290          * @param TList the data to be iterated through
291          * @param integer start index
292          * @param integer number of items to be iterated through
293          */
294         public function __construct(TList $list,$startIndex,$count)
295         {
296                 $this->_list=$list;
297                 $this->_index=0;
298                 $this->_startIndex=$startIndex;
299                 if($startIndex+$count>$list->getCount())
300                         $this->_count=$list->getCount()-$startIndex;
301                 else
302                         $this->_count=$count;
303         }
304
305         /**
306          * Rewinds internal array pointer.
307          * This method is required by the interface Iterator.
308          */
309         public function rewind()
310         {
311                 $this->_index=0;
312         }
313
314         /**
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
318          */
319         public function key()
320         {
321                 return $this->_index;
322         }
323
324         /**
325          * Returns the current array item.
326          * This method is required by the interface Iterator.
327          * @return mixed the current array item
328          */
329         public function current()
330         {
331                 return $this->_list->itemAt($this->_startIndex+$this->_index);
332         }
333
334         /**
335          * Moves the internal pointer to the next array item.
336          * This method is required by the interface Iterator.
337          */
338         public function next()
339         {
340                 $this->_index++;
341         }
342
343         /**
344          * Returns whether there is an item at current position.
345          * This method is required by the interface Iterator.
346          * @return boolean
347          */
348         public function valid()
349         {
350                 return $this->_index<$this->_count;
351         }
352 }
353
354 /**
355  * TPagedMapIterator class
356  *
357  * TPagedMapIterator implements Iterator interface.
358  *
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.
361  *
362  * @author Qiang Xue <qiang.xue@gmail.com>
363  * @package System.Collections
364  * @since 3.0
365  */
366 class TPagedMapIterator implements Iterator
367 {
368         private $_map;
369         private $_startIndex;
370         private $_count;
371         private $_index;
372         private $_iterator;
373
374         /**
375          * Constructor.
376          * @param array the data to be iterated through
377          */
378         public function __construct(TMap $map,$startIndex,$count)
379         {
380                 $this->_map=$map;
381                 $this->_index=0;
382                 $this->_startIndex=$startIndex;
383                 if($startIndex+$count>$map->getCount())
384                         $this->_count=$map->getCount()-$startIndex;
385                 else
386                         $this->_count=$count;
387                 $this->_iterator=$map->getIterator();
388         }
389
390         /**
391          * Rewinds internal array pointer.
392          * This method is required by the interface Iterator.
393          */
394         public function rewind()
395         {
396                 $this->_iterator->rewind();
397                 for($i=0;$i<$this->_startIndex;++$i)
398                         $this->_iterator->next();
399                 $this->_index=0;
400         }
401
402         /**
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
406          */
407         public function key()
408         {
409                 return $this->_iterator->key();
410         }
411
412         /**
413          * Returns the current array item.
414          * This method is required by the interface Iterator.
415          * @return mixed the current array item
416          */
417         public function current()
418         {
419                 return $this->_iterator->current();
420         }
421
422         /**
423          * Moves the internal pointer to the next array item.
424          * This method is required by the interface Iterator.
425          */
426         public function next()
427         {
428                 $this->_index++;
429                 $this->_iterator->next();
430         }
431
432         /**
433          * Returns whether there is an item at current position.
434          * This method is required by the interface Iterator.
435          * @return boolean
436          */
437         public function valid()
438         {
439                 return $this->_index<$this->_count;
440         }
441 }
442