1<?php 2 3/* 4 v4.992 10 Nov 2009 (c) 2000-2009 John Lim (jlim#natsoft.com). All rights reserved. 5 Released under both BSD license and Lesser GPL library license. 6 Whenever there is any discrepancy between the two licenses, 7 the BSD license will take precedence. 8 Set tabs to 4 for best viewing. 9 10 This class provides recordset pagination with 11 First/Prev/Next/Last links. 12 13 Feel free to modify this class for your own use as 14 it is very basic. To learn how to use it, see the 15 example in adodb/tests/testpaging.php. 16 17 "Pablo Costa" <pablo@cbsp.com.br> implemented Render_PageLinks(). 18 19 Please note, this class is entirely unsupported, 20 and no free support requests except for bug reports 21 will be entertained by the author. 22 23*/ 24class ADODB_Pager { 25 var $id; // unique id for pager (defaults to 'adodb') 26 var $db; // ADODB connection object 27 var $sql; // sql used 28 var $rs; // recordset generated 29 var $curr_page; // current page number before Render() called, calculated in constructor 30 var $rows; // number of rows per page 31 var $linksPerPage=10; // number of links per page in navigation bar 32 var $showPageLinks; 33 34 var $gridAttributes = 'width=100% border=1 bgcolor=white'; 35 36 // Localize text strings here 37 var $first = '<code>|<</code>'; 38 var $prev = '<code><<</code>'; 39 var $next = '<code>>></code>'; 40 var $last = '<code>>|</code>'; 41 var $moreLinks = '...'; 42 var $startLinks = '...'; 43 var $gridHeader = false; 44 var $htmlSpecialChars = true; 45 var $page = 'Page'; 46 var $linkSelectedColor = 'red'; 47 var $cache = 0; #secs to cache with CachePageExecute() 48 49 //---------------------------------------------- 50 // constructor 51 // 52 // $db adodb connection object 53 // $sql sql statement 54 // $id optional id to identify which pager, 55 // if you have multiple on 1 page. 56 // $id should be only be [a-z0-9]* 57 // 58 function ADODB_Pager(&$db,$sql,$id = 'adodb', $showPageLinks = false) 59 { 60 global $PHP_SELF; 61 62 $curr_page = $id.'_curr_page'; 63 $PHP_SELF = htmlspecialchars($_SERVER['PHP_SELF']); // htmlspecialchars() to prevent XSS attacks 64 65 $this->sql = $sql; 66 $this->id = $id; 67 $this->db = $db; 68 $this->showPageLinks = $showPageLinks; 69 70 $next_page = $id.'_next_page'; 71 72 if (isset($_GET[$next_page])) { 73 $_SESSION[$curr_page] = (integer) $_GET[$next_page]; 74 } 75 if (empty($_SESSION[$curr_page])) $_SESSION[$curr_page] = 1; ## at first page 76 77 $this->curr_page = $_SESSION[$curr_page]; 78 79 } 80 81 //--------------------------- 82 // Display link to first page 83 function Render_First($anchor=true) 84 { 85 global $PHP_SELF; 86 if ($anchor) { 87 ?> 88 <a href="<?php echo $PHP_SELF,'?',$this->id;?>_next_page=1"><?php echo $this->first;?></a> 89 <?php 90 } else { 91 print "$this->first "; 92 } 93 } 94 95 //-------------------------- 96 // Display link to next page 97 function render_next($anchor=true) 98 { 99 global $PHP_SELF; 100 101 if ($anchor) { 102 ?> 103 <a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() + 1 ?>"><?php echo $this->next;?></a> 104 <?php 105 } else { 106 print "$this->next "; 107 } 108 } 109 110 //------------------ 111 // Link to last page 112 // 113 // for better performance with large recordsets, you can set 114 // $this->db->pageExecuteCountRows = false, which disables 115 // last page counting. 116 function render_last($anchor=true) 117 { 118 global $PHP_SELF; 119 120 if (!$this->db->pageExecuteCountRows) return; 121 122 if ($anchor) { 123 ?> 124 <a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->LastPageNo() ?>"><?php echo $this->last;?></a> 125 <?php 126 } else { 127 print "$this->last "; 128 } 129 } 130 131 //--------------------------------------------------- 132 // original code by "Pablo Costa" <pablo@cbsp.com.br> 133 function render_pagelinks() 134 { 135 global $PHP_SELF; 136 $pages = $this->rs->LastPageNo(); 137 $linksperpage = $this->linksPerPage ? $this->linksPerPage : $pages; 138 for($i=1; $i <= $pages; $i+=$linksperpage) 139 { 140 if($this->rs->AbsolutePage() >= $i) 141 { 142 $start = $i; 143 } 144 } 145 $numbers = ''; 146 $end = $start+$linksperpage-1; 147 $link = $this->id . "_next_page"; 148 if($end > $pages) $end = $pages; 149 150 151 if ($this->startLinks && $start > 1) { 152 $pos = $start - 1; 153 $numbers .= "<a href=$PHP_SELF?$link=$pos>$this->startLinks</a> "; 154 } 155 156 for($i=$start; $i <= $end; $i++) { 157 if ($this->rs->AbsolutePage() == $i) 158 $numbers .= "<font color=$this->linkSelectedColor><b>$i</b></font> "; 159 else 160 $numbers .= "<a href=$PHP_SELF?$link=$i>$i</a> "; 161 162 } 163 if ($this->moreLinks && $end < $pages) 164 $numbers .= "<a href=$PHP_SELF?$link=$i>$this->moreLinks</a> "; 165 print $numbers . ' '; 166 } 167 // Link to previous page 168 function render_prev($anchor=true) 169 { 170 global $PHP_SELF; 171 if ($anchor) { 172 ?> 173 <a href="<?php echo $PHP_SELF,'?',$this->id,'_next_page=',$this->rs->AbsolutePage() - 1 ?>"><?php echo $this->prev;?></a> 174 <?php 175 } else { 176 print "$this->prev "; 177 } 178 } 179 180 //-------------------------------------------------------- 181 // Simply rendering of grid. You should override this for 182 // better control over the format of the grid 183 // 184 // We use output buffering to keep code clean and readable. 185 function RenderGrid() 186 { 187 global $gSQLBlockRows; // used by rs2html to indicate how many rows to display 188 include_once(ADODB_DIR.'/tohtml.inc.php'); 189 ob_start(); 190 $gSQLBlockRows = $this->rows; 191 rs2html($this->rs,$this->gridAttributes,$this->gridHeader,$this->htmlSpecialChars); 192 $s = ob_get_contents(); 193 ob_end_clean(); 194 return $s; 195 } 196 197 //------------------------------------------------------- 198 // Navigation bar 199 // 200 // we use output buffering to keep the code easy to read. 201 function RenderNav() 202 { 203 ob_start(); 204 if (!$this->rs->AtFirstPage()) { 205 $this->Render_First(); 206 $this->Render_Prev(); 207 } else { 208 $this->Render_First(false); 209 $this->Render_Prev(false); 210 } 211 if ($this->showPageLinks){ 212 $this->Render_PageLinks(); 213 } 214 if (!$this->rs->AtLastPage()) { 215 $this->Render_Next(); 216 $this->Render_Last(); 217 } else { 218 $this->Render_Next(false); 219 $this->Render_Last(false); 220 } 221 $s = ob_get_contents(); 222 ob_end_clean(); 223 return $s; 224 } 225 226 //------------------- 227 // This is the footer 228 function RenderPageCount() 229 { 230 if (!$this->db->pageExecuteCountRows) return ''; 231 $lastPage = $this->rs->LastPageNo(); 232 if ($lastPage == -1) $lastPage = 1; // check for empty rs. 233 if ($this->curr_page > $lastPage) $this->curr_page = 1; 234 return "<font size=-1>$this->page ".$this->curr_page."/".$lastPage."</font>"; 235 } 236 237 //----------------------------------- 238 // Call this class to draw everything. 239 function Render($rows=10) 240 { 241 global $ADODB_COUNTRECS; 242 243 $this->rows = $rows; 244 245 if ($this->db->dataProvider == 'informix') $this->db->cursorType = IFX_SCROLL; 246 247 $savec = $ADODB_COUNTRECS; 248 if ($this->db->pageExecuteCountRows) $ADODB_COUNTRECS = true; 249 if ($this->cache) 250 $rs = &$this->db->CachePageExecute($this->cache,$this->sql,$rows,$this->curr_page); 251 else 252 $rs = &$this->db->PageExecute($this->sql,$rows,$this->curr_page); 253 $ADODB_COUNTRECS = $savec; 254 255 $this->rs = &$rs; 256 if (!$rs) { 257 print "<h3>Query failed: $this->sql</h3>"; 258 return; 259 } 260 261 if (!$rs->EOF && (!$rs->AtFirstPage() || !$rs->AtLastPage())) 262 $header = $this->RenderNav(); 263 else 264 $header = " "; 265 266 $grid = $this->RenderGrid(); 267 $footer = $this->RenderPageCount(); 268 269 $this->RenderLayout($header,$grid,$footer); 270 271 $rs->Close(); 272 $this->rs = false; 273 } 274 275 //------------------------------------------------------ 276 // override this to control overall layout and formating 277 function RenderLayout($header,$grid,$footer,$attributes='border=1 bgcolor=beige') 278 { 279 echo "<table ".$attributes."><tr><td>", 280 $header, 281 "</td></tr><tr><td>", 282 $grid, 283 "</td></tr><tr><td>", 284 $footer, 285 "</td></tr></table>"; 286 } 287} 288 289 290?>