/
CDataProviderIterator.php
161 lines (148 loc) · 4.35 KB
/
CDataProviderIterator.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<?php
/**
* CDataProviderIterator class file.
*
* @author Charles Pick <charles.pick@gmail.com>
* @link https://www.yiiframework.com/
* @copyright 2008-2013 Yii Software LLC
* @license https://www.yiiframework.com/license/
*/
/**
* CDataProviderIterator allows iteration over large data sets without holding the entire set in memory.
*
* CDataProviderIterator iterates over the results of a data provider, starting at the first page
* of results and ending at the last page. It is usually only suited for use with {@link CActiveDataProvider}.
*
* For example, the following code will iterate over all registered users (active record class User) without
* running out of memory, even if there are millions of users in the database.
* <pre>
* $dataProvider = new CActiveDataProvider("User");
* $iterator = new CDataProviderIterator($dataProvider);
* foreach($iterator as $user) {
* echo $user->name."\n";
* }
* </pre>
*
* @property CDataProvider $dataProvider the data provider to iterate over
* @property integer $totalItemCount the total number of items in the iterator
*
* @author Charles Pick <charles.pick@gmail.com>
* @author Carsten Brandt <mail@cebe.cc>
* @package system.web
* @since 1.1.13
*/
class CDataProviderIterator extends CComponent implements Iterator, Countable
{
private $_dataProvider;
private $_currentIndex=-1;
private $_currentPage=0;
private $_totalItemCount=-1;
private $_items;
/**
* Constructor.
* @param CDataProvider $dataProvider the data provider to iterate over
* @param integer $pageSize pageSize to use for iteration. This is the number of objects loaded into memory at the same time.
*/
public function __construct(CDataProvider $dataProvider, $pageSize=null)
{
$this->_dataProvider=$dataProvider;
$this->_totalItemCount=$dataProvider->getTotalItemCount();
if(($pagination=$this->_dataProvider->getPagination())===false)
$this->_dataProvider->setPagination($pagination=new CPagination());
if($pageSize!==null)
$pagination->setPageSize($pageSize);
}
/**
* Returns the data provider to iterate over
* @return CDataProvider the data provider to iterate over
*/
public function getDataProvider()
{
return $this->_dataProvider;
}
/**
* Gets the total number of items to iterate over
* @return integer the total number of items to iterate over
*/
public function getTotalItemCount()
{
return $this->_totalItemCount;
}
/**
* Loads a page of items
* @return array the items from the next page of results
*/
protected function loadPage()
{
$this->_dataProvider->getPagination()->setCurrentPage($this->_currentPage);
return $this->_items=$this->dataProvider->getData(true);
}
/**
* Gets the current item in the list.
* This method is required by the Iterator interface.
* @return mixed the current item in the list
*/
#[ReturnTypeWillChange]
public function current()
{
return $this->_items[$this->_currentIndex];
}
/**
* Gets the key of the current item.
* This method is required by the Iterator interface.
* @return integer the key of the current item
*/
#[ReturnTypeWillChange]
public function key()
{
$pageSize=$this->_dataProvider->getPagination()->getPageSize();
return $this->_currentPage*$pageSize+$this->_currentIndex;
}
/**
* Moves the pointer to the next item in the list.
* This method is required by the Iterator interface.
*/
#[ReturnTypeWillChange]
public function next()
{
$pageSize=$this->_dataProvider->getPagination()->getPageSize();
$this->_currentIndex++;
if($this->_currentIndex >= $pageSize)
{
$this->_currentPage++;
$this->_currentIndex=0;
$this->loadPage();
}
}
/**
* Rewinds the iterator to the start of the list.
* This method is required by the Iterator interface.
*/
#[ReturnTypeWillChange]
public function rewind()
{
$this->_currentIndex=0;
$this->_currentPage=0;
$this->loadPage();
}
/**
* Checks if the current position is valid or not.
* This method is required by the Iterator interface.
* @return boolean true if this index is valid
*/
#[ReturnTypeWillChange]
public function valid()
{
return $this->key() < $this->_totalItemCount;
}
/**
* Gets the total number of items in the dataProvider.
* This method is required by the Countable interface.
* @return integer the total number of items
*/
#[ReturnTypeWillChange]
public function count()
{
return $this->_totalItemCount;
}
}