initial version of pagination library.
This commit is contained in:
parent
2b132512e8
commit
abd269aa78
|
@ -1,8 +1,8 @@
|
|||
<?php namespace System\DB;
|
||||
|
||||
use System\DB;
|
||||
use System\Config;
|
||||
use System\Str;
|
||||
use System\Config;
|
||||
|
||||
class Query {
|
||||
|
||||
|
@ -447,6 +447,25 @@ private function aggregate($aggregator, $column)
|
|||
return $this->first()->aggregate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get paginated query results.
|
||||
*
|
||||
* @param int $per_page
|
||||
* @return Paginator
|
||||
*/
|
||||
public function paginate($per_page)
|
||||
{
|
||||
$total = $this->count();
|
||||
|
||||
// Reset the SELECT clause so we can execute another query to get the results.
|
||||
$this->select = null;
|
||||
|
||||
// Get the current page from the Paginator. The Paginator class will validate the page number.
|
||||
$page = \System\Paginator::page(ceil($total / $per_page));
|
||||
|
||||
return new \System\Paginator($this->skip(($page - 1) * $per_page)->take($per_page)->get(), $total, $per_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute an INSERT statement.
|
||||
*
|
||||
|
|
|
@ -35,6 +35,18 @@ public static function style($url, $media = 'all')
|
|||
return '<link href="'.static::entities(URL::to_asset($url)).'" rel="stylesheet" type="text/css" media="'.$media.'">'.PHP_EOL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an HTML span tag.
|
||||
*
|
||||
* @param string $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public static function span($value, $attributes = array())
|
||||
{
|
||||
return '<span'.static::attributes($attributes).'>'.static::entities($value).'</span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a HTML link.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
<?php namespace System;
|
||||
|
||||
class Paginator {
|
||||
|
||||
/**
|
||||
* The results for the current page.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $results;
|
||||
|
||||
/**
|
||||
* The total number of results.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $total;
|
||||
|
||||
/**
|
||||
* The current page.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $page;
|
||||
|
||||
/**
|
||||
* The number of items per page.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $per_page;
|
||||
|
||||
/**
|
||||
* The last page number.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $last_page;
|
||||
|
||||
/**
|
||||
* Create a new Paginator instance.
|
||||
*
|
||||
* @param array $results
|
||||
* @param int $total
|
||||
* @param int $per_page
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($results, $total, $per_page)
|
||||
{
|
||||
$this->per_page = $per_page;
|
||||
$this->results = $results;
|
||||
$this->total = $total;
|
||||
|
||||
// Validate and set the current page. If the given page is greater than the last page, the
|
||||
// current page will be set to the last page. If the given page is not an integer or is less
|
||||
// than 1, the current page will be set to 1.
|
||||
$this->page = static::page($this->last_page());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current page from the request query string.
|
||||
*
|
||||
* @param int $last_page
|
||||
* @return int
|
||||
*/
|
||||
public static function page($last_page)
|
||||
{
|
||||
$page = Input::get('page', 1);
|
||||
|
||||
if (is_numeric($page) and $page > $last_page)
|
||||
{
|
||||
return $last_page;
|
||||
}
|
||||
|
||||
return (filter_var($page, FILTER_VALIDATE_INT) === false or $page < 1) ? 1 : $page;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the HTML pagination links.
|
||||
*
|
||||
* @param int $adjacent
|
||||
* @return string
|
||||
*/
|
||||
public function links($adjacent = 3)
|
||||
{
|
||||
if ($this->last_page() > 1)
|
||||
{
|
||||
return '<div class="pagination">'.$this->previous().$this->numbers($adjacent).$this->next();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the HTML numeric page links.
|
||||
*
|
||||
* @param int $adjacent
|
||||
* @return string
|
||||
*/
|
||||
public function numbers($adjacent = 3)
|
||||
{
|
||||
// If there are not enough pages to make it worth sliding, we will show all of the pages.
|
||||
//
|
||||
// We add "7" for the constant elements in a slider: the first and last two links, the
|
||||
// current page, and the two "..." strings.
|
||||
return ($this->last_page() < 7 + ($adjacent * 2)) ? $this->range(1, $this->last_page()) : $this->slider($adjacent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build sliding list of HTML numeric page links.
|
||||
*
|
||||
* @param int $adjacent
|
||||
* @return string
|
||||
*/
|
||||
protected function slider($adjacent)
|
||||
{
|
||||
$pagination = '';
|
||||
|
||||
if ($this->page <= $adjacent * 2)
|
||||
{
|
||||
// Buffer the current page with four pages to the right. Any more pages will interfere with hiding.
|
||||
$pagination .= $this->range(1, 4 + ($adjacent * 2)).$this->ending();
|
||||
}
|
||||
elseif ($this->page >= $this->last_page() - ($adjacent * 2))
|
||||
{
|
||||
// Buffer with at least two pages to the left of the current page.
|
||||
$pagination .= $this->beginning().$this->range($this->last_page() - 2 - ($adjacent * 2), $this->last_page());
|
||||
}
|
||||
else
|
||||
{
|
||||
$pagination .= $this->beginning().$this->range($this->page - $adjacent, $this->page + $adjacent).$this->ending();
|
||||
}
|
||||
|
||||
return $pagination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the "previous" HTML link.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function previous($value = '« Previous')
|
||||
{
|
||||
if ($this->page > 1)
|
||||
{
|
||||
return HTML::link(Request::uri().'?page='.($this->page - 1), $value, array('class' => 'prev_page')).' ';
|
||||
}
|
||||
|
||||
return HTML::span($value, array('class' => 'disabled prev_page')).' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the "next" HTML link.
|
||||
*
|
||||
* @param string $value
|
||||
* @return string
|
||||
*/
|
||||
public function next($value = 'Next »')
|
||||
{
|
||||
if ($this->page < $this->last_page())
|
||||
{
|
||||
return HTML::link(Request::uri().'?page='.($this->page + 1), $value, array('class' => 'next_page'));
|
||||
}
|
||||
|
||||
return HTML::span($value, array('class' => 'disabled next_page'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the first two page links for a sliding page range.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function beginning()
|
||||
{
|
||||
return $this->range(1, 2).' ... ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the last two page links for a sliding page range.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function ending()
|
||||
{
|
||||
return ' ... '.$this->range($this->last_page() - 1, $this->last_page());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the last page based on the last page and the items per page.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function last_page()
|
||||
{
|
||||
return ceil($this->total / $this->per_page);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a range of page links.
|
||||
*
|
||||
* For the current page, an HTML span element will be generated instead of a link.
|
||||
*
|
||||
* @param int $start
|
||||
* @param int $end
|
||||
* @return string
|
||||
*/
|
||||
protected function range($start, $end)
|
||||
{
|
||||
$pages = '';
|
||||
|
||||
for ($i = $start; $i <= $end; $i++)
|
||||
{
|
||||
$pages .= ($this->page == $i) ? HTML::span($i, array('class' => 'current')).' ' : HTML::link(Request::uri().'?page='.$i, $i).' ';
|
||||
}
|
||||
|
||||
return $pages;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue