Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 311 and 401] [Versions 311 and 402] [Versions 311 and 403] [Versions 39 and 311]

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