Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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