Pagination Class

<?php

  /**
   * Squiloople Framework
   *
   * LICENSE: Feel free to use and redistribute this code.
   *
   * @author Michael Rushton <michael@squiloople.com>
   * @link http://squiloople.com/
   * @package Squiloople
   * @version 1.0
   * @copyright © 2012 Michael Rushton
   */

  /**
   * Paginator
   *
   * Create the pagination
   */
  final class Paginator
  {

    /**
     * The URL
     *
     * @access private
     * @var string $_url
     */
    private $_url;

    /**
     * The total number of results
     *
     * @access private
     * @var integer $_total
     */
    private $_total;

    /**
     * The page number
     *
     * @access private
     * @var integer $_page
     */
    private $_page;

    /**
     * The limit
     *
     * @access private
     * @var integer $_limit
     */
    private $_limit;

    /**
     * The total number of pages
     *
     * @access private
     * @var integer $_pages
     */
    private $_pages;

    /**
     * The offset
     *
     * @access private
     * @var integer $_offset
     */
    private $_offset;

    /**
     * Set the initial conditions
     *
     * @access public
     * @param string $url
     * @param integer $total
     * @param integer $page
     * @param integer $limit
     */
    public function __construct($url, $total, $page, $limit)
    {

      // Set the URL
      $this->_setURL($url);

      // Set the total
      $this->_setTotal($total);

      // Set the page
      $this->_setPage($page);

      // Set the limit
      $this->_setLimit($limit);

      // Set the total number of pages
      $this->_setTotalPages();

      // Set the offset
      $this->_setOffset();

    }

    /**
     * Set the URL
     *
     * @access private
     * @param string $url
     */
    private function _setURL($url)
    {
      $this->_url = (string) $url;
    }

    /**
     * Set the total number of results
     *
     * @access private
     * @param integer $total
     */
    private function _setTotal($total)
    {

      // Set the total to 0 if less than 0
      if (($this->_total = (int) $total) < 0)
      {
        $this->_total = 0;
      }

    }

    /**
     * Get the total
     *
     * @access public
     * @return integer
     */
    public function getTotal()
    {
      return $this->_total;
    }

    /**
     * Set the page
     *
     * @access private
     * @param integer $page
     */
    private function _setPage($page)
    {

      // Set the page to 1 if less than 1
      if (($this->_page = (int) $page) < 1)
      {
        $this->_page = 1;
      }

    }

    /**
     * Get the page
     *
     * @access public
     * @return integer
     */
    public function getPage()
    {
      return $this->_page;
    }

    /**
     * Set the limit
     *
     * @access private
     * @param integer $limit
     */
    private function _setLimit($limit)
    {

      // Set the limit to 10 if less than 1
      if (($this->_limit = (int) $limit) < 1)
      {
        $this->_limit = 10;
      }

    }

    /**
     * Get the limit
     *
     * @access public
     * @return integer
     */
    public function getLimit()
    {
      return $this->_limit;
    }

    /**
     * Set the offset
     *
     * @access private
     */
    private function _setOffset()
    {
      $this->_offset = $this->_limit * ($this->_page - 1);
    }

    /**
     * Get the offset
     *
     * @access public
     * @return integer
     */
    public function getOffset()
    {
      return $this->_offset;
    }

    /**
     * Set the total number of pages
     *
     * @access private
     */
    private function _setTotalPages()
    {

      // Set the page to the last if later than the last
      if ($this->_page > $this->_pages = 0 != $this->_total ? ceil($this->_total / $this->_limit) : 1)
      {
        $this->_page = $this->_pages;
      }

    }

    /**
     * Get the total number of pages
     *
     * @access public
     * @return integer
     */
    public function getTotalPages()
    {
      return $this->_pages;
    }

    /**
     * Get the limit options
     *
     * @access public
     * @param array $options
     * @param string $name
     * @return string
     */
    public function getLimitOptions(array $options = array(10, 25, 50, 100), $name = 'squiloople-pagination-limit')
    {

      // Include the limit if not already included
      if (!in_array($this->_limit, $options))
      {
        array_push($options, $this->_limit);
      }

      // Sort the array
      sort($options);

      // Open the drop-down
      $select[] = '<select name="' . $name . '">';

      // Iterate over each option and add
      foreach (array_unique($options) as $option)
      {
        $select[] = '<option value="' . $option . '" ' . ($this->_limit == $option ? 'selected' : '') . '>' . $option . '</option>';
      }

      // Close the drop-down
      $select[] = '</select>';

      // Return the limit options
      return '<div class="squiloople-pagination-limit"><span>Results Per Page:</span> ' . implode(PHP_EOL, $select) . '</div>';

    }

    /**
     * Get the information
     *
     * @access public
     * @return string
     */
    public function getInformation()
    {

      // Get the first result
      $first = 0 != $this->_total ? $this->_offset + 1 : 0;

      // Get the last result
      if ($this->_total < $last = $this->_limit * $this->_page)
      {
        $last = $this->_total;
      }

      // Return the result information
      return '<div class="squiloople-pagination-information">Results ' . number_format($first) . ' - ' . number_format($last) . ' of ' . number_format($this->_total) . '</div>';

    }

    /**
     * Get the first page link
     *
     * @access private
     * @return string
     */
    private function _getFirstPageLink()
    {
      return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=1&limit=' . $this->_limit . '" title="First page">«</a></li>';
    }

    /**
     * Get the previous page link
     *
     * @access private
     * @return string
     */
    private function _getPreviousPageLink()
    {
      return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . ($this->_page - 1) . '&limit=' . $this->_limit . '" title="Previous page">‹</a></li>';
    }

    /**
     * Get the next page link
     *
     * @access private
     * @return string
     */
    private function _getNextPageLink()
    {
      return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . ($this->_page + 1) . '&limit=' . $this->_limit . '" title="Next page">›</a></li>';
    }

    /**
     * Get the last page link
     *
     * @access private
     * @return string
     */
    private function _getLastPageLink()
    {
      return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . $this->_pages . '&limit=' . $this->_limit . '" title="Last page">»</a></li>';
    }

    /**
     * Get the page link
     *
     * @access private
     * @param integer $page
     * @return string
     */
    private function _getPageLink($page)
    {

      // Return an empty link if we're on the last page
      if ($page == $this->_page)
      {
        return '<li class="squiloople-pagination-inactive">' . number_format($page) . '</li>';
      }

      // Return the link
      return '<li class="squiloople-pagination-active"><a href="' . $this->_url . '?page=' . $page . '&limit=' . $this->_limit . '" title="Page ' . number_format($page) . '">' . number_format($page) . '</a></li>';

    }

    /**
     * Get the pagination
     *
     * @access public
     * @return string
     */
    public function getPagination()
    {

      // If we only have one page then return an empty string
      if (1 == $this->_pages)
      {
        return '';
      }

      // If we are not on the first page
      if (1 != $this->_page)
      {

        // Add the first page link
        $pages[] = $this->_getFirstPageLink();

        // Add the previous page link
        $pages[] = $this->_getPreviousPageLink();

        // Add an empty page link
        $pages[] = '<li class="squiloople-pagination-inactive"> </li>';

      }

      // Iterate over available pages
      for ($i = 1; $i <= $this->_pages; ++$i)
      {

        // Determine what is to be added
        switch (TRUE)
        {

          // If there are 7 or fewer pages
          case ($this->_pages <= 7):

          // If the page is the first, the one before the current, the current, the one after the current, or the last
          case (in_array($i, array(1, $this->_page - 1, $this->_page, $this->_page + 1, $this->_pages))):

          // If the page is at most the fifth and the current is at most the fourth
          case ($i <= 5 && $this->_page < 5):

          // If the page is at least the fifth-to-last and the current is at least the fourth-to-last
          case ($i >= $this->_pages - 4 && $this->_page > $this->_pages - 4):

            // Add the page link
            $pages[] = $this->_getPageLink($i);

            // Break
            break;

          // If the page is the second or the second-to-last
          case (in_array($i, array(2, $this->_pages - 1))):

            // Add the ellipsis
            $pages[] = '<li class="squiloople-pagination-inactive">…</li>';

            // Break
            break;

        }

      }

      // If we are not on the last page
      if ($this->_pages != $this->_page)
      {

        // Add an empty page link
        $pages[] = '<li class="squiloople-pagination-inactive"> </li>';

        // Add the next page link
        $pages[] = $this->_getNextPageLink();

        // Add the last page link
        $pages[] = $this->_getLastPageLink();

      }

      // Return the pagination
      return '<ul class="squiloople-pagination">' . implode(PHP_EOL, $pages) . '</ul>';

    }

  }

Download ZIP

To instantiate a Paginator object simply use the new keyword and pass as the first parameter the URL, the second parameter the total number of results, the third parameter the current page, and the fourth parameter the result limit.

$paginator = new Paginator('results.php', $total, $page, $limit);

The total number of results can be retrieved by using the getTotal() method. This method does not accept any parameters.

$total = $paginator->getTotal();

The current page can be retrieved using the getPage() method. This method does not accept any parameters.

$page = $paginator->getPage();

The result limit can be retrieved using the getLimit() method. This method does not accept any parameters.

$limit = $paginator->getLimit();

The offset (for database queries) can be retrieved using the getOffset() method. This method does not accept any parameters.

$offset = $paginator->getOffset();

The total number of pages can be retrieved using the getTotalPages() method. This method does not accept any parameters.

$pages = $paginator->getTotalPages();

To return the pagination information in the form “Results x – y of z”, call the getInformation() method. This method does not accept any parameters.

echo $paginator->getInformation();

To return a select drop-down of the limit options, call the getLimitOptions() method passing as the first parameter an array of the options and as an optional second parameter the name for the drop-down. The array is automatically sorted, duplicates are removed, and the current limit is included if not already. The default name is squiloople-pagination-limit.

echo $paginator->getLimitOptions(array(10, 25, 50, 100));

To return the pagination as an unordered list, call the getPagination() method. This method does not accept any parameters.

echo $paginator->getPagination();

The page links are in the format [url]?page=[page]&limit=[limit]. The class for the ul tag is squiloople-pagination, the class for active li tags is squiloople-pagination-active, and the class for inactive li tags is squiloople-pagination-inactive.

Inactive li tags are for the current page, the first and previous page link if on the first page, the next and last page link if on the last page, and the ellipsis links which denote two or more undefined pages. Active pages are defined pages which are not inactive. Defined pages are the first page, the current page, the pages directly before and after the current page, and the last page. If the current page is one of the first 4 pages then the first 5 pages will be defined. If the current page is one of the last 4 pages then the last 5 pages will be defined. If the total number of pages is less than or equal to 7 then every page will be defined.

The pagination information is contained within a div tag with the class squiloople-pagination-information. The limit options are contained within a div tag with the class squiloople-pagination-limit and the Results per page: label is contained within a classless span tag.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>