├── .gitignore ├── LICENSE ├── Pagination.class.php ├── README.md ├── render.inc.php └── themes └── light.css /.gitignore: -------------------------------------------------------------------------------- 1 | .svn 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2016 Oliver Nassar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pagination.class.php: -------------------------------------------------------------------------------- 1 | 16 | * @todo add setter parameter type and range checks w/ exceptions 17 | * @example 18 | * 19 | * // source inclusion 20 | * require_once APP . '/vendors/PHP-Pagination/Pagination.class.php'; 21 | * 22 | * // determine page (based on <_GET>) 23 | * $page = isset($_GET['page']) ? ((int) $_GET['page']) : 1; 24 | * 25 | * // instantiate with page and records as constructor parameters 26 | * $pagination = (new Pagination($page, 200)); 27 | * $markup = $pagination->parse(); 28 | * 29 | * @example 30 | * 31 | * // source inclusion 32 | * require_once APP . '/vendors/PHP-Pagination/Pagination.class.php'; 33 | * 34 | * // determine page (based on <_GET>) 35 | * $page = isset($_GET['page']) ? ((int) $_GET['page']) : 1; 36 | * 37 | * // instantiate; set current page; set number of records 38 | * $pagination = (new Pagination()); 39 | * $pagination->setCurrent($page); 40 | * $pagination->setTotal(200); 41 | * 42 | * // grab rendered/parsed pagination markup 43 | * $markup = $pagination->parse(); 44 | * 45 | */ 46 | class Pagination 47 | { 48 | /** 49 | * _variables 50 | * 51 | * Sets default variables for the rendering of the pagination markup. 52 | * 53 | * @var array 54 | * @access protected 55 | */ 56 | protected $_variables = array( 57 | 'classes' => array('clearfix', 'pagination'), 58 | 'crumbs' => 5, 59 | 'rpp' => 10, 60 | 'hash' => null, 61 | 'key' => 'page', 62 | 'target' => '', 63 | 'next' => 'Next »', 64 | 'previous' => '« Previous', 65 | 'alwaysShowPagination' => false, 66 | 'clean' => false 67 | ); 68 | 69 | /** 70 | * __construct 71 | * 72 | * @access public 73 | * @param null|int $current (default: null) 74 | * @param null|int $total (default: null) 75 | * @return void 76 | */ 77 | public function __construct(?int $current = null, ?int $total = null) 78 | { 79 | // current instantiation setting 80 | if (is_null($current) === false) { 81 | $this->setCurrent($current); 82 | } 83 | 84 | // total instantiation setting 85 | if (is_null($total) === false) { 86 | $this->setTotal($total); 87 | } 88 | 89 | // Pass along get (for link generation) 90 | $this->_variables['get'] = $_GET; 91 | } 92 | 93 | /** 94 | * _check 95 | * 96 | * Checks the current (page) and total (records) parameters to ensure 97 | * they've been set. Throws an exception otherwise. 98 | * 99 | * @access protected 100 | * @return void 101 | */ 102 | protected function _check(): void 103 | { 104 | if (isset($this->_variables['current']) === false) { 105 | throw new Exception('Pagination::current must be set.'); 106 | } elseif (isset($this->_variables['total']) === false) { 107 | throw new Exception('Pagination::total must be set.'); 108 | } 109 | } 110 | 111 | /** 112 | * addClasses 113 | * 114 | * Sets the classes to be added to the pagination div node. 115 | * Useful with Twitter Bootstrap (eg. pagination-centered, etc.) 116 | * 117 | * @see http://twitter.github.com/bootstrap/components.html#pagination 118 | * @access public 119 | * @param mixed $classes 120 | * @return void 121 | */ 122 | public function addClasses($classes): void 123 | { 124 | $this->_variables['classes'] = array_merge( 125 | $this->_variables['classes'], 126 | (array) $classes 127 | ); 128 | } 129 | 130 | /** 131 | * alwaysShowPagination 132 | * 133 | * Tells the rendering engine to show the pagination links even if there 134 | * aren't any pages to paginate through. 135 | * 136 | * @access public 137 | * @return void 138 | */ 139 | public function alwaysShowPagination(): void 140 | { 141 | $this->_variables['alwaysShowPagination'] = true; 142 | } 143 | 144 | /** 145 | * getCanonicalUrl 146 | * 147 | * @access public 148 | * @return string 149 | */ 150 | public function getCanonicalUrl() 151 | { 152 | $target = $this->_variables['target']; 153 | if (empty($target) === true) { 154 | $target = $_SERVER['PHP_SELF']; 155 | } 156 | $page = (int) $this->_variables['current']; 157 | if ($page !== 1) { 158 | return 'http://' . ($_SERVER['HTTP_HOST']) . ($target) . $this->getPageParam(); 159 | } 160 | return 'http://' . ($_SERVER['HTTP_HOST']) . ($target); 161 | } 162 | 163 | /** 164 | * getPageParam 165 | * 166 | * @access public 167 | * @param bool|int $page (default: false) 168 | * @return string 169 | */ 170 | public function getPageParam($page = false) 171 | { 172 | if ($page === false) { 173 | $page = (int) $this->_variables['current']; 174 | } 175 | $key = $this->_variables['key']; 176 | return '?' . ($key) . '=' . ((int) $page); 177 | } 178 | 179 | /** 180 | * getPageUrl 181 | * 182 | * @access public 183 | * @param bool|int $page (default: false) 184 | * @return string 185 | */ 186 | public function getPageUrl($page = false) 187 | { 188 | $target = $this->_variables['target']; 189 | if (empty($target) === true) { 190 | $target = $_SERVER['PHP_SELF']; 191 | } 192 | return 'http://' . ($_SERVER['HTTP_HOST']) . ($target) . ($this->getPageParam($page)); 193 | } 194 | 195 | /** 196 | * getRelPrevNextLinkTags 197 | * 198 | * @see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=1663744 199 | * @see http://googlewebmastercentral.blogspot.ca/2011/09/pagination-with-relnext-and-relprev.html 200 | * @see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=139394 201 | * @access public 202 | * @return array 203 | */ 204 | public function getRelPrevNextLinkTags() 205 | { 206 | // generate path 207 | $target = $this->_variables['target']; 208 | if (empty($target) === true) { 209 | $target = $_SERVER['PHP_SELF']; 210 | } 211 | $key = $this->_variables['key']; 212 | $params = $this->_variables['get']; 213 | $params[$key] = 'pgnmbr'; 214 | $href = ($target) . '?' . http_build_query($params); 215 | $href = preg_replace( 216 | array('/=$/', '/=&/'), 217 | array('', '&'), 218 | $href 219 | ); 220 | $href = 'http://' . ($_SERVER['HTTP_HOST']) . $href; 221 | 222 | // Pages 223 | $currentPage = (int) $this->_variables['current']; 224 | $numberOfPages = ( 225 | (int) ceil( 226 | $this->_variables['total'] / 227 | $this->_variables['rpp'] 228 | ) 229 | ); 230 | 231 | // On first page 232 | if ($currentPage === 1) { 233 | 234 | // There is a page after this one 235 | if ($numberOfPages > 1) { 236 | $href = str_replace('pgnmbr', 2, $href); 237 | return array( 238 | '' 239 | ); 240 | } 241 | return array(); 242 | } 243 | 244 | // Store em 245 | $prevNextTags = array( 246 | '' 247 | ); 248 | 249 | // There is a page after this one 250 | if ($numberOfPages > $currentPage) { 251 | array_push( 252 | $prevNextTags, 253 | '' 254 | ); 255 | } 256 | return $prevNextTags; 257 | } 258 | 259 | /** 260 | * parse 261 | * 262 | * Parses the pagination markup based on the parameters set and the 263 | * logic found in the render.inc.php file. 264 | * 265 | * @access public 266 | * @return string 267 | */ 268 | public function parse(): string 269 | { 270 | // ensure required parameters were set 271 | $this->_check(); 272 | 273 | // bring variables forward 274 | foreach ($this->_variables as $_name => $_value) { 275 | $$_name = $_value; 276 | } 277 | 278 | // buffer handling 279 | ob_start(); 280 | include 'render.inc.php'; 281 | $_response = ob_get_contents(); 282 | ob_end_clean(); 283 | return $_response; 284 | } 285 | 286 | /** 287 | * setClasses 288 | * 289 | * @see http://twitter.github.com/bootstrap/components.html#pagination 290 | * @access public 291 | * @param mixed $classes 292 | * @return void 293 | */ 294 | public function setClasses($classes): void 295 | { 296 | $this->_variables['classes'] = (array) $classes; 297 | } 298 | 299 | /** 300 | * setClean 301 | * 302 | * Sets the pagination to exclude page numbers, and only output 303 | * previous/next markup. The counter-method of this is self::setFull. 304 | * 305 | * @access public 306 | * @return void 307 | */ 308 | public function setClean(): void 309 | { 310 | $this->_variables['clean'] = true; 311 | } 312 | 313 | /** 314 | * setCrumbs 315 | * 316 | * Sets the maximum number of 'crumbs' (eg. numerical page items) 317 | * available. 318 | * 319 | * @access public 320 | * @param int $crumbs 321 | * @return void 322 | */ 323 | public function setCrumbs(int $crumbs): void 324 | { 325 | $this->_variables['crumbs'] = $crumbs; 326 | } 327 | 328 | /** 329 | * setCurrent 330 | * 331 | * Sets the current page being viewed. 332 | * 333 | * @access public 334 | * @param int $current 335 | * @return void 336 | */ 337 | public function setCurrent(int $current): void 338 | { 339 | $this->_variables['current'] = (int) $current; 340 | } 341 | 342 | /** 343 | * setFull 344 | * 345 | * See self::setClean for documentation. 346 | * 347 | * @access public 348 | * @return void 349 | */ 350 | public function setFull(): void 351 | { 352 | $this->_variables['clean'] = false; 353 | } 354 | 355 | /** 356 | * setHash 357 | * 358 | * @access public 359 | * @param string $hash 360 | * @return void 361 | */ 362 | public function setHash(string $hash): void 363 | { 364 | $this->_variables['hash'] = $hash; 365 | } 366 | 367 | /** 368 | * setKey 369 | * 370 | * Sets the key of the <_GET> array that contains, and ought to contain, 371 | * paging information (eg. which page is being viewed). 372 | * 373 | * @access public 374 | * @param string $key 375 | * @return void 376 | */ 377 | public function setKey(string $key): void 378 | { 379 | $this->_variables['key'] = $key; 380 | } 381 | 382 | /** 383 | * setNext 384 | * 385 | * Sets the copy of the next anchor. 386 | * 387 | * @access public 388 | * @param string $str 389 | * @return void 390 | */ 391 | public function setNext(string $str): void 392 | { 393 | $this->_variables['next'] = $str; 394 | } 395 | 396 | /** 397 | * setPrevious 398 | * 399 | * Sets the copy of the previous anchor. 400 | * 401 | * @access public 402 | * @param string $str 403 | * @return void 404 | */ 405 | public function setPrevious(string $str): void 406 | { 407 | $this->_variables['previous'] = $str; 408 | } 409 | 410 | /** 411 | * setRPP 412 | * 413 | * Sets the number of records per page (used for determining total 414 | * number of pages). 415 | * 416 | * @access public 417 | * @param int $rpp 418 | * @return void 419 | */ 420 | public function setRPP(int $rpp): void 421 | { 422 | $this->_variables['rpp'] = (int)$rpp; 423 | } 424 | 425 | /** 426 | * setTarget 427 | * 428 | * Sets the leading path for anchors. 429 | * 430 | * @access public 431 | * @param string $target 432 | * @return void 433 | */ 434 | public function setTarget(string $target): void 435 | { 436 | $this->_variables['target'] = $target; 437 | } 438 | 439 | /** 440 | * setTotal 441 | * 442 | * Sets the total number of records available for pagination. 443 | * 444 | * @access public 445 | * @param int $total 446 | * @return void 447 | */ 448 | public function setTotal(int $total): void 449 | { 450 | $this->_variables['total'] = (int)$total; 451 | } 452 | } 453 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHP Pagination 2 | === 3 | 4 | PHP-Pagination contains an instantiable class, along with a *view* which renders 5 | the pagination markup. 6 | 7 | The purpose of this library is to provide a simple API to render pagination 8 | markup, without having to worry about including common files and set too many 9 | settings. With this class, you simply pass in your parameters and make a call to 10 | the instance's `parse` method. 11 | 12 | ### Pagination Instantiation and Rendering 13 | 14 | ``` php 15 | // source inclusion 16 | require_once APP . '/vendors/PHP-Pagination/Pagination.class.php'; 17 | 18 | // set the page number (based on a URL param; cast as an int; ensure min page number) 19 | $page = $_GET['page'] ?? 1; 20 | $page = (int) $page; 21 | $page = min($page, 1); 22 | 23 | // instantiate; set current page; set number of records per page; number of records in total 24 | $pagination = new Pagination(); 25 | $pagination->setCurrent($page); 26 | $pagination->setRPP(24); 27 | $pagination->setTotal(200); 28 | 29 | // grab rendered pagination markup 30 | $markup = $pagination->parse(); 31 | ``` 32 | -------------------------------------------------------------------------------- /render.inc.php: -------------------------------------------------------------------------------- 1 | $pages) { 9 | return; 10 | } 11 | 12 | // if there are pages to be shown 13 | if ($pages > 1 || $alwaysShowPagination === true) { 14 | ?> 15 | 139 |