<?php /** * CodeIgniter * * An open source application development framework for PHP * * This content is released under the MIT License (MIT) * * Copyright (c) 2014-2019 British Columbia Institute of Technology * Copyright (c) 2019-2020 CodeIgniter Foundation * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * @package CodeIgniter * @author CodeIgniter Dev Team * @copyright 2019-2020 CodeIgniter Foundation * @license https://opensource.org/licenses/MIT MIT License * @link https://codeigniter.com * @since Version 4.0.0 * @filesource */ namespace CodeIgniter\Pager; /** * Class PagerRenderer * * This class is passed to the view that describes the pagination, * and is used to get the link information and provide utility * methods needed to work with pagination. * * @package CodeIgniter\Pager */ class PagerRenderer { /** * First page number. * * @var integer */ protected $first; /** * Last page number. * * @var integer */ protected $last; /** * Current page number. * * @var integer */ protected $current; /** * Total number of pages? unused? * * @var integer */ protected $total; /** * Page count? * * @var integer */ protected $pageCount; /** * URI base for pagination links * * @var integer */ protected $uri; /** * Segment number used for pagination. * * @var integer */ protected $segment; /** * Name of $_GET parameter * * @var integer */ protected $pageSelector; //-------------------------------------------------------------------- /** * Constructor. * * @param array $details */ public function __construct(array $details) { $this->first = 1; $this->last = $details['pageCount']; $this->current = $details['currentPage']; $this->total = $details['total']; $this->uri = $details['uri']; $this->pageCount = $details['pageCount']; $this->segment = $details['segment'] ?? 0; $this->pageSelector = $details['pageSelector'] ?? 'page'; } //-------------------------------------------------------------------- /** * Sets the total number of links that should appear on either * side of the current page. Adjusts the first and last counts * to reflect it. * * @param integer|null $count * * @return PagerRenderer */ public function setSurroundCount(int $count = null) { $this->updatePages($count); return $this; } //-------------------------------------------------------------------- /** * Checks to see if there is a "previous" page before our "first" page. * * @return boolean */ public function hasPrevious(): bool { return $this->first > 1; } //-------------------------------------------------------------------- /** * Returns a URL to the "previous" page. The previous page is NOT the * page before the current page, but is the page just before the * "first" page. * * You MUST call hasPrevious() first, or this value may be invalid. * * @return string|null */ public function getPrevious() { if (! $this->hasPrevious()) { return null; } $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->first - 1); } else { $uri->setSegment($this->segment, $this->first - 1); } return (string) $uri; } //-------------------------------------------------------------------- /** * Checks to see if there is a "next" page after our "last" page. * * @return boolean */ public function hasNext(): bool { return $this->pageCount > $this->last; } //-------------------------------------------------------------------- /** * Returns a URL to the "next" page. The next page is NOT, the * page after the current page, but is the page that follows the * "last" page. * * You MUST call hasNext() first, or this value may be invalid. * * @return string|null */ public function getNext() { if (! $this->hasNext()) { return null; } $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->last + 1); } else { $uri->setSegment($this->segment, $this->last + 1); } return (string) $uri; } //-------------------------------------------------------------------- /** * Returns the URI of the first page. * * @return string */ public function getFirst(): string { $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, 1); } else { $uri->setSegment($this->segment, 1); } return (string) $uri; } //-------------------------------------------------------------------- /** * Returns the URI of the last page. * * @return string */ public function getLast(): string { $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->pageCount); } else { $uri->setSegment($this->segment, $this->pageCount); } return (string) $uri; } //-------------------------------------------------------------------- /** * Returns the URI of the current page. * * @return string */ public function getCurrent(): string { $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->current); } else { $uri->setSegment($this->segment, $this->current); } return (string) $uri; } //-------------------------------------------------------------------- /** * Returns an array of links that should be displayed. Each link * is represented by another array containing of the URI the link * should go to, the title (number) of the link, and a boolean * value representing whether this link is active or not. * * @return array */ public function links(): array { $links = []; $uri = clone $this->uri; for ($i = $this->first; $i <= $this->last; $i ++) { $links[] = [ 'uri' => (string) ($this->segment === 0 ? $uri->addQuery($this->pageSelector, $i) : $uri->setSegment($this->segment, $i)), 'title' => (int) $i, 'active' => ($i === $this->current), ]; } return $links; } //-------------------------------------------------------------------- /** * Updates the first and last pages based on $surroundCount, * which is the number of links surrounding the active page * to show. * * @param integer|null $count The new "surroundCount" */ protected function updatePages(int $count = null) { if (is_null($count)) { return; } $this->first = $this->current - $count > 0 ? (int) ($this->current - $count) : 1; $this->last = $this->current + $count <= $this->pageCount ? (int) ($this->current + $count) : (int) $this->pageCount; } //-------------------------------------------------------------------- /** * Checks to see if there is a "previous" page before our "first" page. * * @return boolean */ public function hasPreviousPage(): bool { return $this->current > 1; } //-------------------------------------------------------------------- /** * Returns a URL to the "previous" page. * * You MUST call hasPreviousPage() first, or this value may be invalid. * * @return string|null */ public function getPreviousPage() { if (!$this->hasPreviousPage()) { return null; } $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->current - 1); } else { $uri->setSegment($this->segment, $this->current - 1); } return (string) $uri; } //-------------------------------------------------------------------- /** * Checks to see if there is a "next" page after our "last" page. * * @return boolean */ public function hasNextPage(): bool { return $this->current < $this->last; } //-------------------------------------------------------------------- /** * Returns a URL to the "next" page. * * You MUST call hasNextPage() first, or this value may be invalid. * * @return string|null */ public function getNextPage() { if (!$this->hasNextPage()) { return null; } $uri = clone $this->uri; if ($this->segment === 0) { $uri->addQuery($this->pageSelector, $this->current + 1); } else { $uri->setSegment($this->segment, $this->current + 1); } return (string) $uri; } }