123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- <?php namespace Laravel;
- class Paginator {
- /**
- * The results for the current page.
- *
- * @var array
- */
- public $results;
- /**
- * The current page.
- *
- * @var int
- */
- protected $page;
- /**
- * The last page available for the result set.
- *
- * @var int
- */
- protected $last;
- /**
- * The total number of results.
- *
- * @var int
- */
- protected $total;
- /**
- * The number of items per page.
- *
- * @var int
- */
- protected $per_page;
- /**
- * The values that should be appended to the end of the link query strings.
- *
- * @var array
- */
- protected $appends;
- /**
- * The compiled appendage that will be appended to the links.
- *
- * This consists of a sprintf format with a page place-holder and query string.
- *
- * @var string
- */
- protected $appendage;
- /**
- * The pagination elements that will be generated.
- *
- * @var array
- */
- protected $elements = array('first', 'previous', 'status', 'next', 'last');
- /**
- * Create a new Paginator instance.
- *
- * @param array $results
- * @param int $last
- * @param int $page
- * @param int $total
- * @param int $per_page
- * @return void
- */
- protected function __construct($results, $page, $total, $per_page, $last)
- {
- $this->page = $page;
- $this->last = $last;
- $this->total = $total;
- $this->results = $results;
- $this->per_page = $per_page;
- }
- /**
- * Create a new Paginator instance.
- *
- * @param array $results
- * @param int $total
- * @param int $per_page
- * @return Paginator
- */
- public static function make($results, $total, $per_page)
- {
- $page = static::page($total, $per_page);
- $last_page = ceil($total / $per_page);
- return new static($results, $page, $total, $per_page, $last_page);
- }
- /**
- * Get the current page from the request query string.
- *
- * @param int $total
- * @param int $per_page
- * @return int
- */
- public static function page($total, $per_page)
- {
- $page = Input::get('page', 1);
- // The page will be validated and adjusted if it is less than one or greater
- // than the last page. For example, if the current page is not an integer or
- // less than one, one will be returned. If the current page is greater than
- // the last page, the last page will be returned.
- if (is_numeric($page) and $page > $last = ceil($total / $per_page))
- {
- return ($last > 0) ? $last : 1;
- }
- return ($page < 1 or filter_var($page, FILTER_VALIDATE_INT) === false) ? 1 : $page;
- }
- /**
- * Create the HTML pagination links.
- *
- * @return string
- */
- public function links()
- {
- if ($this->last <= 1) return '';
- // Each pagination element is created by an element method. This allows
- // us to keep this class clean and simple, because pagination code can
- // become a mess. We would rather keep it simple and beautiful.
- foreach ($this->elements as $element)
- {
- $elements[] = $this->$element(Lang::line("pagination.{$element}")->get());
- }
- return '<div class="pagination">'.implode(' ', $elements).'</div>'.PHP_EOL;
- }
- /**
- * Get the "status" pagination element.
- *
- * @param string $text
- * @return string
- */
- protected function status($text)
- {
- return str_replace(array(':current', ':last'), array($this->page, $this->last), $text);
- }
- /**
- * Create the "first" pagination element.
- *
- * @param string $text
- * @return string
- */
- protected function first($text)
- {
- return $this->backwards(__FUNCTION__, $text, 1);
- }
- /**
- * Create the "previous" pagination element.
- *
- * @param string $text
- * @return string
- */
- protected function previous($text)
- {
- return $this->backwards(__FUNCTION__, $text, $this->page - 1);
- }
- /**
- * Create the "next" pagination element.
- *
- * @param string $text
- * @return string
- */
- protected function next($text)
- {
- return $this->forwards(__FUNCTION__, $text, $this->page + 1);
- }
- /**
- * Create the "last" pagination element.
- *
- * @param string $text
- * @return string
- */
- protected function last($text)
- {
- return $this->forwards(__FUNCTION__, $text, $this->last);
- }
- /**
- * Create a "backwards" paginatino element.
- *
- * This function handles the creation of the first and previous elements.
- *
- * @param string $element
- * @param string $text
- * @param int $last
- * @return string
- */
- protected function backwards($element, $text, $last)
- {
- $disabler = function($page) { return $page <= 1; };
- return $this->element($element, $text, $last, $disabler);
- }
- /**
- * Create a "forwards" paginatino element.
- *
- * This function handles the creation of the next and last elements.
- *
- * @param string $element
- * @param string $text
- * @param int $last
- * @return string
- */
- protected function forwards($element, $text, $last)
- {
- $disabler = function($page, $last) { return $page >= $last; };
- return $this->element($element, $text, $last, $disabler);
- }
- /**
- * Create a chronological pagination element.
- *
- * @param string $element
- * @param string $text
- * @param int $page
- * @param Closure $disabler
- * @return string
- */
- protected function element($element, $text, $page, $disabler)
- {
- $class = "{$element}_page";
- if ($disabler($this->page, $this->last))
- {
- return HTML::span($text, array('class' => "disabled {$class}"));
- }
- else
- {
- // We will assume the page links should use HTTPS if the current request
- // is also using HTTPS. Since pagination links automatically point to
- // the current URI, this makes pretty good sense.
- list($uri, $secure) = array(Request::uri(), Request::secure());
- $appendage = $this->appendage($element, $page);
- return HTML::link($uri.$appendage, $text, array('class' => $class), $secure);
- }
- }
- /**
- * Create the pagination link "appendage" for an element.
- *
- * @param string $element
- * @param int $page
- * @return string
- */
- protected function appendage($element, $page)
- {
- if (is_null($this->appendage))
- {
- $this->appendage = '?page=%s'.http_build_query((array) $this->appends);
- }
- return sprintf($this->appendage, $page);
- }
- /**
- * Set the items that should be appended to the link query strings.
- *
- * This provides a convenient method of maintaining sort or passing other information
- * to the route handling pagination.
- *
- * @param array $values
- * @return Paginator
- */
- public function appends($values)
- {
- $this->appends = $values;
- return $this;
- }
- /**
- * Set the elements that should be included when creating the pagination links.
- *
- * The available elements are "first", "previous", "status", "next", and "last".
- *
- * @param array $elements
- * @return string
- */
- public function elements($elements)
- {
- $this->elements = $elements;
- return $this;
- }
- }
|