-
Notifications
You must be signed in to change notification settings - Fork 16
/
limit-iterator.php
169 lines (147 loc) · 4.72 KB
/
limit-iterator.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
162
163
164
165
166
167
168
169
<?php
/**
* The main use case of a limit iterator is pagination. Below is an example
* Pagination class which takes an array (or object) iterator as an argument
* and allows pagination on the set.
*
* @author Corey Ballou
*/
class Paginator extends LimitIterator {
// stores the array iterator
protected $_it;
// stores the current page
protected $_currentPage;
// stores the max number of items to display per page
protected $_limit;
// stores the number of array items
protected $_count;
// stores the total pages in the resultset
protected $_totalPages;
/**
* Default constructor to load the iterator. Override the parent
* LimitIterator as we don't want to return
*
* @access public
* @param ArrayIterator $it
*/
public function __construct(ArrayIterator $it, $page = 1, $limit = 10)
{
$this->_it = $it;
$this->_count = $it->count();
$this->setCurrentPage($page);
$this->setItemsPerPage($limit);
}
/**
* Set the number of items to display per page.
*
* @access public
* @param int $count
*/
public function setItemsPerPage($count = 10)
{
$this->_itemsPerPage = (int) $count;
$this->_totalPages = ($this->_count > $this->_itemsPerPage) ? ceil($this->_count / $this->_itemsPerPage) : 1;
}
/**
* Set the current page (offset).
*
* @access public
* @param int $page
*/
public function setCurrentPage($page = 1)
{
$this->_currentPage = (int) $page;
}
/**
* Returns the current page.
*
* @access public
* @return int
*/
public function getCurrentPage()
{
return $this->_currentPage;
}
/**
* Determines if another page exists.
*
* @access public
* @return bool
*/
public function hasNextPage()
{
return $this->_currentPage < $this->_totalPages;
}
/**
* Determines if a previous page exists.
*
* @access public
* @return bool
*/
public function hasPreviousPage()
{
return $this->_currentPage > 1;
}
/**
* Returns (fake render) the items matching the specific requirements.
*
* @access public
* @param mixed $page
* @param mixed $limit
* @return mixed
*/
public function render($page = NULL, $limit = NULL)
{
if (!empty($page)) {
$this->setCurrentPage($page);
}
if (!empty($limit)) {
$this->setItemsPerPage($limit);
}
// quickly calculate the offset based on the page
if ($page > 0) $page -= 1;
$offset = $page * $this->_itemsPerPage;
// return the limit iterator
return new LimitIterator($this->_it, $offset, $this->_itemsPerPage);
}
}
// generate an example of page items to iterate over
$items = array(
array('id' => 1, 'name' => 'Item 1', 'desc' => 'Description', 'price' => 4.99),
array('id' => 2, 'name' => 'Item 2', 'desc' => 'Description', 'price' => 4.99),
array('id' => 3, 'name' => 'Item 3', 'desc' => 'Description', 'price' => 4.99),
array('id' => 4, 'name' => 'Item 4', 'desc' => 'Description', 'price' => 4.99),
array('id' => 5, 'name' => 'Item 5', 'desc' => 'Description', 'price' => 4.99),
array('id' => 6, 'name' => 'Item 6', 'desc' => 'Description', 'price' => 4.99),
array('id' => 7, 'name' => 'Item 7', 'desc' => 'Description', 'price' => 4.99),
array('id' => 8, 'name' => 'Item 8', 'desc' => 'Description', 'price' => 4.99),
array('id' => 9, 'name' => 'Item 9', 'desc' => 'Description', 'price' => 4.99),
array('id' => 10, 'name' => 'Item 10', 'desc' => 'Description', 'price' => 4.99),
array('id' => 11, 'name' => 'Item 11', 'desc' => 'Description', 'price' => 4.99),
array('id' => 12, 'name' => 'Item 12', 'desc' => 'Description', 'price' => 4.99),
array('id' => 13, 'name' => 'Item 13', 'desc' => 'Description', 'price' => 4.99),
array('id' => 14, 'name' => 'Item 14', 'desc' => 'Description', 'price' => 4.99),
array('id' => 15, 'name' => 'Item 15', 'desc' => 'Description', 'price' => 4.99),
array('id' => 16, 'name' => 'Item 16', 'desc' => 'Description', 'price' => 4.99),
array('id' => 17, 'name' => 'Item 17', 'desc' => 'Description', 'price' => 4.99),
array('id' => 18, 'name' => 'Item 18', 'desc' => 'Description', 'price' => 4.99),
array('id' => 19, 'name' => 'Item 19', 'desc' => 'Description', 'price' => 4.99),
array('id' => 20, 'name' => 'Item 20', 'desc' => 'Description', 'price' => 4.99),
array('id' => 21, 'name' => 'Item 21', 'desc' => 'Description', 'price' => 4.99)
);
// load the paginator
$Paginator = new Paginator(new ArrayIterator($items));
// displays the initial set (page 1, limit 10)
$results = $Paginator->render();
foreach ($results as $r) {
var_dump($r);
}
// check for another page
if ($Paginator->hasNextPage()) {
echo 'DISPLAYING THE NEXT SET OF RESULTS AS AN EXAMPLE' . PHP_EOL;
// displays the next page results as an example
$results = $Paginator->render($Paginator->getCurrentPage() + 1);
foreach ($results as $r) {
var_dump($r);
}
}