1
+ <?php
2
+ /**
3
+ * Pagination class
4
+ * Making pagination of records easy(ier)
5
+ * @author Michael Peacock
6
+ * @url www.michaelpeacock.co.uk
7
+ */
8
+ class Pagination {
9
+
10
+ /**
11
+ * MySQLi Connection
12
+ */
13
+ private $ db ;
14
+
15
+ /**
16
+ * The query we will be paginating
17
+ */
18
+ private $ query = "" ;
19
+
20
+ /**
21
+ * The processed query which will be executed
22
+ */
23
+ private $ executedQuery = "" ;
24
+
25
+ /**
26
+ * The results from the query
27
+ */
28
+ private $ results ;
29
+
30
+ /**
31
+ * The maximum number of results to display per page
32
+ */
33
+ private $ limit = 25 ;
34
+
35
+ /**
36
+ * The results offset - i.e. page we are on (-1)
37
+ */
38
+ private $ offset = 0 ;
39
+
40
+ /**
41
+ * The number of rows there were in the query passed
42
+ */
43
+ private $ numRows ;
44
+
45
+ /**
46
+ * The number of rows on the current page (main use if on last page, may not have as many as limit on the page)
47
+ */
48
+ private $ numRowsPage ;
49
+
50
+ /**
51
+ * Number of pages of results there are
52
+ */
53
+ private $ numPages ;
54
+
55
+ /**
56
+ * Is this the first page of results?
57
+ */
58
+ private $ isFirst ;
59
+
60
+ /**
61
+ * Is this the last page of results?
62
+ */
63
+ private $ isLast ;
64
+
65
+ /**
66
+ * The current page we are on
67
+ */
68
+ private $ currentPage ;
69
+
70
+ /**
71
+ * Our constructor
72
+ * @param mysqli $mysqli_link
73
+ * @return void
74
+ */
75
+ function __construct ( $ mysqli_link )
76
+ {
77
+ $ this ->db = $ mysqli_link ;
78
+ }
79
+
80
+ /**
81
+ * Process the query, and set the paginated properties
82
+ * @return bool (true if there are some rows on the page, false if there are not)
83
+ */
84
+ public function generatePagination ()
85
+ {
86
+ $ temp_query = $ this ->query ;
87
+
88
+ // its more efficient to query one row (if possible) and include a count, as opposed to querying all of them
89
+ if ( preg_match ( '#SELECT DISTINCT((.+?)),#si ' , $ temp_query ) > 0 )
90
+ {
91
+ // this is a distinct query, we really have to query them all :-(
92
+ $ q = mysqli_query ( $ this ->db , $ temp_query );
93
+ $ nums = mysqli_num_rows ( $ q );
94
+ $ this ->numRows = $ nums ;
95
+ }
96
+ else
97
+ {
98
+ // normal query, let's strip out everything before the "primary" FROM
99
+ $ q = mysqli_query ( $ this ->db , "SELECT COUNT(*) AS nums " . $ this ->excludePrimarySelects ( $ temp_query ) . " LIMIT 1 " );
100
+ if ( mysqli_num_rows ( $ q ) == 1 )
101
+ {
102
+ // how many rows?
103
+ $ row = mysqli_fetch_array ( $ q , MYSQLI_ASSOC );
104
+ $ this ->numRows = $ row ['nums ' ];
105
+ }
106
+ else
107
+ {
108
+ // query didn't work...0 rows
109
+ $ this ->numRows = 0 ;
110
+ }
111
+ }
112
+
113
+ // limit!
114
+ $ this ->executedQuery = $ temp_query . " LIMIT " . ( $ this ->offset * $ this ->limit ) . ", " . $ this ->limit ;
115
+
116
+ $ q = mysqli_query ( $ this ->db , $ this ->executedQuery );
117
+ while ( $ row = mysqli_fetch_array ( $ q , MYSQLI_ASSOC ) )
118
+ {
119
+ $ this ->results [] = $ row ;
120
+ }
121
+
122
+ // be nice...do some calculations
123
+
124
+ // num pages
125
+ $ this ->numPages = ceil ($ this ->numRows / $ this ->limit );
126
+ // is first
127
+ $ this ->isFirst = ( $ this ->offset == 0 ) ? true : false ;
128
+ // is last
129
+ $ this ->isLast = ( ( $ this ->offset + 1 ) == $ this ->numPages ) ? true : false ;
130
+ // current page
131
+ $ this ->currentPage = ( $ this ->numPages == 0 ) ? 0 : $ this ->offset +1 ;
132
+ $ this ->numRowsPage = mysqli_num_rows ( $ q );
133
+
134
+ return ( $ this ->numRowsPage == 0 ) ? false : true ;
135
+
136
+ }
137
+
138
+ //===========================================================================//
139
+ // HELPER METHODS //
140
+ //===========================================================================//
141
+
142
+ /**
143
+ * Exclude the primary selects from the SQL query
144
+ * @param String $sql the SQL query
145
+ * @return String the query starting with FROM
146
+ */
147
+ private function excludePrimarySelects ( $ sql )
148
+ {
149
+ $ word = "from " ;
150
+ $ wordLength = strlen ( $ word );
151
+ $ left = 0 ;
152
+ $ right = 0 ;
153
+ $ within = 0 ;
154
+ $ precedingSQLStatement = "" ;
155
+ for ( $ i = 0 ; $ i < ( strlen ( $ sql ) ); $ i ++ )
156
+ {
157
+ $ left = ( $ sql [ $ i ] == "( " ) ? $ left +1 : $ left ;
158
+ $ right = ( $ sql [ $ i ] == ") " ) ? $ right +1 : $ right ;
159
+ if ( $ left === $ right )
160
+ {
161
+ if ( $ within < $ wordLength && strcasecmp ( $ sql [ $ i ], $ word [ $ within ] ) == 0 )
162
+ {
163
+ $ within ++;
164
+ }
165
+ elseif ( $ within <> $ wordLength )
166
+ {
167
+ $ within = 0 ;
168
+ }
169
+ }
170
+ elseif ( $ within <> $ wordLength )
171
+ {
172
+ $ within = 0 ;
173
+ }
174
+
175
+ if ( $ within < $ wordLength )
176
+ {
177
+ $ precedingSQLStatement .= $ sql [ $ i ];
178
+ }
179
+ elseif ( $ within == $ wordLength )
180
+ {
181
+ $ precedingSQLStatement .= $ sql [ $ i ];
182
+ break ;
183
+ }
184
+ }
185
+
186
+ return str_replace ( $ precedingSQLStatement , " FROM " , $ sql );
187
+ }
188
+
189
+
190
+ //===========================================================================//
191
+ // GETTER AND SETTER METHODS //
192
+ //===========================================================================//
193
+
194
+ /**
195
+ * Set the query to be paginated
196
+ * @param String $sql the query
197
+ * @return void
198
+ */
199
+ public function setQuery ( $ sql )
200
+ {
201
+ $ this ->query = $ sql ;
202
+ }
203
+
204
+ /**
205
+ * Set the limit of how many results should be displayed per page
206
+ * @param int $limit the limit
207
+ * @return void
208
+ */
209
+ public function setLimit ( $ limit )
210
+ {
211
+ $ this ->limit = $ limit ;
212
+ }
213
+
214
+ /**
215
+ * Set the offset - i.e. if offset is 1, then we show the next page of results
216
+ * @param int $offset the offset
217
+ * @return void
218
+ */
219
+ public function setOffset ( $ offset )
220
+ {
221
+ $ this ->offset = $ offset ;
222
+ }
223
+
224
+ /**
225
+ * Get the result set
226
+ * @return array
227
+ */
228
+ public function getResults ()
229
+ {
230
+ return $ this ->results ;
231
+ }
232
+
233
+ /**
234
+ * Get the number of pages of results there are
235
+ * @return int
236
+ */
237
+ public function getNumPages ()
238
+ {
239
+ return $ this ->numPages ;
240
+ }
241
+
242
+ /**
243
+ * Is this page the first page of results?
244
+ * @return bool
245
+ */
246
+ public function isFirst ()
247
+ {
248
+ return $ this ->isFirst ;
249
+ }
250
+
251
+ /**
252
+ * Is this page the last page of results?
253
+ * @return bool
254
+ */
255
+ public function isLast ()
256
+ {
257
+ return $ this ->isLast ;
258
+ }
259
+
260
+ /**
261
+ * Get the current page within the paginated results we are viewing
262
+ * @return int
263
+ */
264
+ public function getCurrentPage ()
265
+ {
266
+ return $ this ->currentPage ;
267
+ }
268
+
269
+ /**
270
+ * Get the number of rows there are on the current page
271
+ * @return int
272
+ */
273
+ public function getNumRowsPage ()
274
+ {
275
+ return $ this ->numRowsPage ;
276
+ }
277
+
278
+ }
279
+ ?>
0 commit comments