adodb-pager.inc.php 7.9 KB

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