<?php
/**
* @class pager
* @brief (x)HTML Pager
*
* This class implements a pager helper to browse any type of results.
*
* @package Clearbricks
* @subpackage Pager
*
* @copyright Olivier Meunier & Association Dotclear
* @copyright GPL-2.0-only
*/
class pager
{
protected $env;
protected $nb_elements;
protected $nb_per_page;
protected $nb_pages_per_group;
protected $nb_pages;
protected $nb_groups;
protected $env_group;
protected $index_group_start;
protected $index_group_end;
protected $page_url = null;
public $index_start; ///< integer Start index
public $index_end; ///< integer End index
public $base_url = null; ///< string Base URL
public $var_page = 'page'; ///< string GET param name for current page
public $html_cur_page = '<strong>%s</strong>'; ///< string Current page HTML
public $html_link_sep = '-'; ///< string Link separator
public $html_prev = '«prev.'; ///< string Previous HTML code
public $html_next = 'next»'; ///< string Next HTML code
public $html_prev_grp = '...'; ///< string Next group HTML code
public $html_next_grp = '...'; ///< string Previous group HTML code
/**
* Constructor
*
* @param integer $env Current page index
* @param integer $nb_elements Total number of elements
* @param integer $nb_per_page Number of items per page
* @param integer $nb_pages_per_group Number of pages per group
*/
public function __construct($env, $nb_elements, $nb_per_page = 10, $nb_pages_per_group = 10)
{
$this->env = abs((int) $env);
$this->nb_elements = abs((int) $nb_elements);
$this->nb_per_page = abs((int) $nb_per_page);
$this->nb_pages_per_group = abs((int) $nb_pages_per_group);
# Pages count
$this->nb_pages = ceil($this->nb_elements / $this->nb_per_page);
# Fix env value
if ($this->env > $this->nb_pages || $this->env < 1) {
$this->env = 1;
}
# Groups count
$this->nb_groups = (int) ceil($this->nb_pages / $this->nb_pages_per_group);
# Page first element index
$this->index_start = ($this->env - 1) * $this->nb_per_page;
# Page last element index
$this->index_end = $this->index_start + $this->nb_per_page - 1;
if ($this->index_end >= $this->nb_elements) {
$this->index_end = $this->nb_elements - 1;
}
# Current group
$this->env_group = (int) ceil($this->env / $this->nb_pages_per_group);
# Group first page index
$this->index_group_start = ($this->env_group - 1) * $this->nb_pages_per_group + 1;
# Group last page index
$this->index_group_end = $this->index_group_start + $this->nb_pages_per_group - 1;
if ($this->index_group_end > $this->nb_pages) {
$this->index_group_end = $this->nb_pages;
}
}
/**
* Pager Links
*
* Returns pager links
*
* @return string
*/
public function getLinks()
{
$htmlLinks = '';
$htmlPrev = '';
$htmlNext = '';
$htmlPrevGrp = '';
$htmlNextGrp = '';
$this->setURL();
for ($i = $this->index_group_start; $i <= $this->index_group_end; $i++) {
if ($i == $this->env) {
$htmlLinks .= sprintf($this->html_cur_page, $i);
} else {
$htmlLinks .= '<a href="' . sprintf($this->page_url, $i) . '">' . $i . '</a>';
}
if ($i != $this->index_group_end) {
$htmlLinks .= $this->html_link_sep;
}
}
# Previous page
if ($this->env != 1) {
$htmlPrev = '<a href="' . sprintf($this->page_url, $this->env - 1) . '">' .
$htmlPrev .= $this->html_prev . '</a> ';
}
# Next page
if ($this->env != $this->nb_pages) {
$htmlNext = ' <a href="' . sprintf($this->page_url, $this->env + 1) . '">';
$htmlNext .= $this->html_next . '</a>';
}
# Previous group
if ($this->env_group != 1) {
$htmlPrevGrp = ' <a href="' . sprintf($this->page_url, $this->index_group_start - $this->nb_pages_per_group) . '">';
$htmlPrevGrp .= $this->html_prev_grp . '</a> ';
}
# Next group
if ($this->env_group != $this->nb_groups) {
$htmlNextGrp = ' <a href="' . sprintf($this->page_url, $this->index_group_end + 1) . '">';
$htmlNextGrp .= $this->html_next_grp . '</a> ';
}
$res = $htmlPrev .
$htmlPrevGrp .
$htmlLinks .
$htmlNextGrp .
$htmlNext;
return $this->nb_elements > 0 ? $res : '';
}
protected function setURL()
{
if ($this->base_url !== null) {
$this->page_url = $this->base_url;
return;
}
$url = (string) $_SERVER['REQUEST_URI'];
# Removing session information
if (session_id()) {
$url = preg_replace('/' . preg_quote(session_name() . '=' . session_id(), '/') . '([&]?)/', '', $url);
$url = preg_replace('/&$/', '', $url);
}
# Escape page_url for sprintf
$url = preg_replace('/%/', '%%', $url);
# Changing page ref
if (preg_match('/[?&]' . $this->var_page . '=[0-9]+/', $url)) {
$url = preg_replace('/([?&]' . $this->var_page . '=)[0-9]+/', '$1%1$d', $url);
} elseif (preg_match('/[?]/', $url)) {
$url .= '&' . $this->var_page . '=%1$d';
} else {
$url .= '?' . $this->var_page . '=%1$d';
}
$this->page_url = html::escapeHTML($url);
}
public function debug()
{
return
'Elements per page ........... ' . $this->nb_per_page . "\n" .
'Pages per group.............. ' . $this->nb_pages_per_group . "\n" .
'Elements count .............. ' . $this->nb_elements . "\n" .
'Pages ....................... ' . $this->nb_pages . "\n" .
'Groups ...................... ' . $this->nb_groups . "\n\n" .
'Current page .................' . $this->env . "\n" .
'Start index ................. ' . $this->index_start . "\n" .
'End index ................... ' . $this->index_end . "\n" .
'Current group ............... ' . $this->env_group . "\n" .
'Group first page index ...... ' . $this->index_group_start . "\n" .
'Group last page index ....... ' . $this->index_group_end;
}
}