Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]

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