PHP Classes

File: vendor/jackbooted/forms/Paginator.php

Recommend this page to a friend!
  Classes of Brett Dutton   JackBooted PHP Framework   vendor/jackbooted/forms/Paginator.php   Download  
File: vendor/jackbooted/forms/Paginator.php
Role: Class source
Content type: text/plain
Description: Class source
Class: JackBooted PHP Framework
Web application framework using simplified MVC
Author: By
Last change:
Date: 8 years ago
Size: 14,414 bytes
 

Contents

Class file image Download
<?php namespace Jackbooted\Forms; use \Jackbooted\Html\Lists; use \Jackbooted\Html\Tag; use \Jackbooted\Util\Invocation; use \Jackbooted\DB\DB; /** * @copyright Confidential and copyright (c) 2016 Jackbooted Software. All rights reserved. * * Written by Brett Dutton of Jackbooted Software * brett at brettdutton dot com * * This software is written and distributed under the GNU General Public * License which means that its source code is freely-distributed and * available to the general public. */ /** */ class Paginator extends Navigator { const STARTING_PAGE = 'G'; const STARTING_ROW = 'R'; const TOTAL_ROWS = 'T'; const SQL_START = 'Q'; const ROWS_PER_PAGE = 'P'; const LOG_THRESHOLD = 'L'; const PAGE_VAR = '_PG'; const SUBMIT = 'S'; const PAGE_LINK_CLASS = 'PAGE_LINK_CLASS'; const PAGE_BUTTON_CLASS = 'PAGE_BUTTON_CLASS'; /** * @var integer Counts the number of times that this class is invoked so * that each invokation can have a unique id */ private static $pagination = [ self::STARTING_ROW => 0, self::STARTING_PAGE => 0, self::TOTAL_ROWS => 0, self::SQL_START => 0, self::ROWS_PER_PAGE => 10 ]; private static $itemsPerPageList = [ 5, 10, 20, 50, 100, 200 ]; /** * @static * @param $suffix * @return string */ public static function navVar ( $suffix ) { return self::PAGE_VAR . $suffix; } private $dispPageSize; /** * Create a Pagination Object. * @param array $props This is the properties that the Paginator will use to display. * <pre> * $props = array ( 'attribs' => 'array ( 'style' => 'display:none ), // Optional, * // Attributes that will be stamped on the div that is generated * // if not supplied will be empty array. * // Need to supply if the primary key is not simple column name * 'suffix' => 'V', // Optional, suffix for the action variable for paginator * // useful when there is a numbner on the screen * // if not supplied one will be generated based on the number of * // paginators that are generated * 'request_vars' => 'CEMID', // Optional, regexpression or individual name of any request * // vars that are to be copied to the response vars (chained vars) * 'display_pagesize' => true, // Optional defaults to true. If false the page sizes will not * // be displayed * 'rows' => 100, // Optional. Number of rows that the Paginator has to deal with * // Based on this number and the number of rows per page, the number of * // pages are calculated * ); * </pre> */ public function __construct ( $props=[] ) { $this->attribs = ( isset ( $props['attribs'] ) ) ? $props['attribs'] : []; $suffix = ( isset ( $props['suffix'] ) ) ? $props['suffix'] : Invocation::next(); $this->navVar = self::navVar ( $suffix ); $initPattern = ( isset ( $props['request_vars'] ) ) ? $props['request_vars'] : ''; $this->respVars = new Response ( $initPattern ); $this->dispPageSize = ( isset ( $props['display_pagesize'] ) ) ? $props['display_pagesize'] : true; // ensure that they have been set $requestPageVars = Request::get ( $this->navVar, [] ); foreach ( self::$pagination as $key => $val ) { $this->set ( $key, ( ( isset ( $requestPageVars[$key] ) ) ? $requestPageVars[$key] : $val ) ); } if ( isset ( $props['rows'] ) ) $this->setRows ( (int)$props['rows'] ); $this->styles[self::PAGE_LINK_CLASS] = 'jb-pagelink'; $this->styles[self::PAGE_BUTTON_CLASS] = 'jb-pagebuton'; if ( $this->getStart () > 0 && $this->getRows () < $this->getPageSize () ) { $this->setStart ( 0 ); } } /** * @param $rows * @return Navigator */ public function setRows ( $rows ) { return $this->set ( self::TOTAL_ROWS, $rows ); } /** * @return Response */ public function getRows ( ) { return $this->get ( self::TOTAL_ROWS ); } /** * @return Response */ public function getStart ( ) { return $this->get ( self::STARTING_ROW ); } /** * @param $start * @return Navigator */ public function setStart ( $start ) { if ( $start > 0 && $this->getRows () < $this->getPageSize () ) { $start = 0; } return $this->set ( self::STARTING_ROW, $start ); } /** * @return Response */ public function getPageSize ( ) { return $this->get ( self::ROWS_PER_PAGE ); } /** * @param $val * @return Navigator */ public function setPageSize ( $val ) { return $this->set ( self::ROWS_PER_PAGE, $val ); } /** * @param $key * @param $value * @return Paginator */ public function setStyle ( $key, $value ) { $this->styles[$key] = $value; $this->formVars[$key] = $value; return $this; } /** * @return string */ public function getLimits( $dbType=DB::MYSQL, $sql='' ) { $this->auditStartRow (); if ( $dbType == DB::MYSQL || $dbType == DB::SQLITE ) { return $sql . ' LIMIT ' . $this->getStart () . ',' . $this->getPageSize (); } else if ( $dbType == DB::ORACLE ) { $lowLim = $this->getStart (); $upLim = $this->getStart () + $this->getPageSize (); if ( $sql == '' ) $sql = '%s'; $qry = <<<SQL SELECT * FROM ( SELECT t__.*, ROWNUM AS r__ FROM ( $sql ) t__ ) WHERE r__ BETWEEN $lowLim AND $upLim-1 SQL; return $qry; } else { return ''; } } public function auditStartRow () { if ( $this->getStart () >= $this->getRows () ) { $this->setStart ( 0 ); $this->set ( self::STARTING_PAGE, 0 ); } return $this; } /** * @return string */ public function toHtml () { $this->auditStartRow (); $rowsPerPage = intval ( $this->getPageSize () ); $startingRow = intval ( $this->getStart () ); $startingPage = intval ( $this->get ( self::STARTING_PAGE ) ); $totalRows = intval ( $this->getRows () ); $saveStartingRow = intval ( $this->getStart () ); if ( $rowsPerPage <= 0 ) { $rowsPerPage = self::$pagination[self::ROWS_PER_PAGE]; } // Not enough rows for pagination if ( $totalRows <= $rowsPerPage ) { if ( $this->dispPageSize && $totalRows > 10 ) { return Tag::div ( $this->attribs ) . Tag::form ( [ 'method' => 'get' ] ) . $this->toHidden ( [ self::ROWS_PER_PAGE ] ) . '&nbsp;Max Rows:&nbsp;' . Lists::select ( $this->toFormName ( self::ROWS_PER_PAGE ), self::$itemsPerPageList, [ 'default' => $rowsPerPage, 'onChange' => 'submit();' ] ) . Tag::_form () . Tag::_div (); } else { return ''; } } if ( $startingPage > 0 ) { $startingRow = ( $startingPage - 1 ) * $rowsPerPage; $this->set ( self::STARTING_PAGE, 0 ); } if ( $startingRow >= $totalRows ) $startingRow = $totalRows - 1; $pageContainingStartRow = intval ( $startingRow / $rowsPerPage ); $this->set ( self::SQL_START, $rowsPerPage * $pageContainingStartRow ); // Get number of pages $numberOfPages = intval ( $totalRows / $rowsPerPage ); if ( ( $totalRows % $rowsPerPage ) != 0 ) { $numberOfPages ++; } $previousPage = ''; $nextPage = ''; $firstPage = ''; $lastPage = ''; $pageSizeHtml = ''; $html = [ [], [] ]; // This is the navigation from the current page forward for ( $currentPage=$pageContainingStartRow+1,$incr=1; $currentPage<$numberOfPages-1; $currentPage+=$incr ) { $startingRowForThisPage = $currentPage * $rowsPerPage; $currentPageDisplay = $currentPage + 1; $this->set ( self::STARTING_ROW, $startingRowForThisPage ); $html[1][] = Tag::hRef ( $this->toUrl ( ), number_format ( $currentPageDisplay ), [ 'title' => 'Go to Page ' . $currentPageDisplay, 'class' => $this->styles[self::PAGE_LINK_CLASS] ] ); $incr *= count ( $html[1] ); } // This is the navigation for next and last page if ( $pageContainingStartRow + 1 < $numberOfPages ) { $this->setStart ( $rowsPerPage * ( $numberOfPages - 1 ) ); $lastPage = Tag::button ( '>> ' . number_format ( $numberOfPages ), [ 'onclick' => "location.href='" . $this->toUrl() . "';return true;", 'title' => 'Go to Last Page - ' . $numberOfPages, 'class' => $this->styles[self::PAGE_BUTTON_CLASS] ] ); $this->setStart ( $rowsPerPage * ( $pageContainingStartRow + 1 ) ); $nextPage = Tag::button ( '>', [ 'onclick' => "location.href='" . $this->toUrl() . "';return true;", 'title' => 'Go to Next Page - ' . ( $pageContainingStartRow + 2 ), 'class' => $this->styles[self::PAGE_BUTTON_CLASS] ] ); } // Navigation for the current page nackwards for ( $currentPage=$pageContainingStartRow-1,$incr=1; $currentPage>0; $currentPage-=$incr ) { $startingRowForThisPage = $currentPage * $rowsPerPage; $currentPageDisplay = $currentPage + 1; $this->setStart ( $startingRowForThisPage ); $html[0][] = Tag::hRef ( $this->toUrl ( ), number_format ( $currentPageDisplay ), [ 'title' => 'Go to Page ' . $currentPageDisplay, 'class' => $this->styles[self::PAGE_LINK_CLASS] ] ); $incr *= count ( $html[0] ); } // Reverse the array so that it appears in correct order for pagination $html[0] = array_reverse ( $html[0] ); // Navigation for previous and first pages if ( $pageContainingStartRow != 0 ) { // Calculate navigation for first page $this->setStart ( 0 ); $firstPage = Tag::button ( '<< 1', [ 'onclick' => "location.href='" . $this->toUrl() . "';return true;", 'title' => 'Go to First Page - 1', 'class' => $this->styles[self::PAGE_BUTTON_CLASS] ] ); // Calculate navigation for previous page $this->setStart ( $rowsPerPage * ( $pageContainingStartRow - 1 ) ); $previousPage = Tag::button ( '< ', [ 'onclick' => "location.href='" . $this->toUrl() . "';return true;", 'title' => 'Go to Previous Page - ' . ( $pageContainingStartRow - 1 ), 'class' => $this->styles[self::PAGE_BUTTON_CLASS] ] ); } $this->setStart ( $saveStartingRow ); $curPage = (string)($pageContainingStartRow + 1); $exemptVars = [ self::STARTING_PAGE ]; // Create the drop down to set the number of rows displayed per page if ( $this->dispPageSize ) { $exemptVars[] = self::ROWS_PER_PAGE; $pageSizeHtml = '&nbsp;Rows:&nbsp;' . Lists::select ( $this->toFormName ( self::ROWS_PER_PAGE ), self::$itemsPerPageList, [ 'default' => $rowsPerPage, 'title' => 'This changes the number of rows to display', 'onChange' => 'submit();' ] ); } return Tag::div ( $this->attribs ) . Tag::form ( [ 'method' => 'get' ] ) . $this->toHidden ( $exemptVars ) . $firstPage . $previousPage . '&nbsp;' . join ( '&nbsp;&#183;&nbsp;', $html[0] ) . '&nbsp;' . Tag::text ( $this->toFormName ( self::STARTING_PAGE ), [ 'value' => $curPage, 'align' => 'middle', 'size' => 1 + max ( 1, strlen ( $curPage ) - 1 ), 'title' => 'Manually enter the page number that you want and press enter', 'style' => 'font-weight:bold;' ] ) . '&nbsp;' . join ( '&nbsp;&#183;&nbsp;', $html[1] ) . '&nbsp;' . $nextPage . $lastPage . $pageSizeHtml . Tag::_form () . Tag::_div (); } }