/app/Foundation/Paginator.php
https://github.com/jitamin/jitamin · PHP · 496 lines · 203 code · 65 blank · 228 comment · 10 complexity · 07201c0ce829b678f071d7cc89cb640e MD5 · raw file
- <?php
- /*
- * This file is part of Jitamin.
- *
- * Copyright (C) Jitamin Team
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Jitamin\Foundation;
- use PicoDb\Table;
- use Pimple\Container;
- /**
- * Paginator helper.
- */
- class Paginator
- {
- /**
- * Container instance.
- *
- * @var \Pimple\Container
- */
- private $container;
- /**
- * Total number of items.
- *
- * @var int
- */
- private $total = 0;
- /**
- * Page number.
- *
- * @var int
- */
- private $page = 1;
- /**
- * Offset.
- *
- * @var int
- */
- private $offset = 0;
- /**
- * Limit.
- *
- * @var int
- */
- private $limit = 0;
- /**
- * Sort by this column.
- *
- * @var string
- */
- private $order = '';
- /**
- * Sorting direction.
- *
- * @var string
- */
- private $direction = 'ASC';
- /**
- * Slice of items.
- *
- * @var array
- */
- private $items = [];
- /**
- * PicoDb Table instance.
- *
- * @var \Picodb\Table
- */
- private $query = null;
- /**
- * Controller name.
- *
- * @var string
- */
- private $controller = '';
- /**
- * Action name.
- *
- * @var string
- */
- private $action = '';
- /**
- * Url params.
- *
- * @var array
- */
- private $params = [];
- /**
- * Constructor.
- *
- * @param \Pimple\Container $container
- */
- public function __construct(Container $container)
- {
- $this->container = $container;
- }
- /**
- * Set a PicoDb query.
- *
- * @param \PicoDb\Table $query
- *
- * @return Paginator
- */
- public function setQuery(Table $query)
- {
- $this->query = $query;
- $this->total = $this->query->count();
- return $this;
- }
- /**
- * Execute a PicoDb query.
- *
- * @return array
- */
- public function executeQuery()
- {
- if ($this->query !== null) {
- return $this->query
- ->offset($this->offset)
- ->limit($this->limit)
- ->orderBy($this->order, $this->direction)
- ->findAll();
- }
- return [];
- }
- /**
- * Set url parameters.
- *
- * @param string $controller
- * @param string $action
- * @param array $params
- *
- * @return Paginator
- */
- public function setUrl($controller, $action, array $params = [])
- {
- $this->controller = $controller;
- $this->action = $action;
- $this->params = $params;
- return $this;
- }
- /**
- * Add manually items.
- *
- * @param array $items
- *
- * @return Paginator
- */
- public function setCollection(array $items)
- {
- $this->items = $items;
- return $this;
- }
- /**
- * Return the items.
- *
- * @return array
- */
- public function getCollection()
- {
- return $this->items ?: $this->executeQuery();
- }
- /**
- * Set the total number of items.
- *
- * @param int $total
- *
- * @return Paginator
- */
- public function setTotal($total)
- {
- $this->total = $total;
- return $this;
- }
- /**
- * Get the total number of items.
- *
- * @return int
- */
- public function getTotal()
- {
- return $this->total;
- }
- /**
- * Set the default page number.
- *
- * @param int $page
- *
- * @return Paginator
- */
- public function setPage($page)
- {
- $this->page = $page;
- return $this;
- }
- /**
- * Get the number of current page.
- *
- * @return int
- */
- public function getPage()
- {
- return $this->page;
- }
- /**
- * Get the total number of pages.
- *
- * @return int
- */
- public function getPageTotal()
- {
- return ceil($this->getTotal() / $this->getMax());
- }
- /**
- * Set the default column order.
- *
- * @param string $order
- *
- * @return Paginator
- */
- public function setOrder($order)
- {
- $this->order = $order;
- return $this;
- }
- /**
- * Set the default sorting direction.
- *
- * @param string $direction
- *
- * @return Paginator
- */
- public function setDirection($direction)
- {
- $this->direction = $direction;
- return $this;
- }
- /**
- * Set the maximum number of items per page.
- *
- * @param int $limit
- *
- * @return Paginator
- */
- public function setMax($limit)
- {
- $this->limit = $limit;
- return $this;
- }
- /**
- * Get the maximum number of items per page.
- *
- * @return int
- */
- public function getMax()
- {
- return $this->limit;
- }
- /**
- * Return true if the collection is empty.
- *
- * @return bool
- */
- public function isEmpty()
- {
- return $this->total === 0;
- }
- /**
- * Execute the offset calculation only if the $condition is true.
- *
- * @param bool $condition
- *
- * @return Paginator
- */
- public function calculateOnlyIf($condition)
- {
- if ($condition) {
- $this->calculate();
- }
- return $this;
- }
- /**
- * Calculate the offset value accoring to url params and the page number.
- *
- * @return Paginator
- */
- public function calculate()
- {
- $this->page = $this->container['request']->getIntegerParam('page', 1);
- $this->direction = $this->container['request']->getStringParam('direction', $this->direction);
- $this->order = $this->container['request']->getStringParam('order', $this->order);
- if ($this->page < 1) {
- $this->page = 1;
- }
- $this->offset = (int) (($this->page - 1) * $this->limit);
- return $this;
- }
- /**
- * Generation pagination links.
- *
- * @return string
- */
- public function toHtml()
- {
- $html = '';
- if (!$this->hasNothingtoShow()) {
- $html .= '<div class="pagination">';
- $html .= $this->generatPageShowing();
- $html .= $this->generatePreviousLink();
- $html .= $this->generateNextLink();
- $html .= '</div>';
- }
- return $html;
- }
- /**
- * Magic method to output pagination links.
- *
- * @return string
- */
- public function __toString()
- {
- return $this->toHtml();
- }
- /**
- * Column sorting.
- *
- * @param string $label Column title
- * @param string $column SQL column name
- *
- * @return string
- */
- public function order($label, $column)
- {
- $prefix = '';
- $direction = 'ASC';
- if ($this->order === $column) {
- $prefix = $this->direction === 'DESC' ? '▼ ' : '▲ ';
- $direction = $this->direction === 'DESC' ? 'ASC' : 'DESC';
- }
- return $prefix.$this->container['helper']->url->link(
- $label,
- $this->controller,
- $this->action,
- $this->getUrlParams($this->page, $column, $direction)
- );
- }
- /**
- * Get url params for link generation.
- *
- * @param int $page
- * @param string $order
- * @param string $direction
- *
- * @return string
- */
- protected function getUrlParams($page, $order, $direction)
- {
- $params = [
- 'page' => $page,
- 'order' => $order,
- 'direction' => $direction,
- ];
- return array_merge($this->params, $params);
- }
- /**
- * Generate the previous link.
- *
- * @return string
- */
- protected function generatePreviousLink()
- {
- $html = '<span class="pagination-previous">';
- if ($this->offset > 0) {
- $html .= $this->container['helper']->url->link(
- '« '.t('Previous'),
- $this->controller,
- $this->action,
- $this->getUrlParams($this->page - 1, $this->order, $this->direction),
- false,
- 'btn btn-info'
- );
- } else {
- $html .= '<span class="btn btn-default">« '.t('Previous').'</span>';
- }
- $html .= '</span>';
- return $html;
- }
- /**
- * Generate the next link.
- *
- * @return string
- */
- protected function generateNextLink()
- {
- $html = '<span class="pagination-next">';
- if (($this->total - $this->offset) > $this->limit) {
- $html .= $this->container['helper']->url->link(
- t('Next').' »',
- $this->controller,
- $this->action,
- $this->getUrlParams($this->page + 1, $this->order, $this->direction),
- false,
- 'btn btn-info'
- );
- } else {
- $html .= '<span class="btn btn-default">'.t('Next').' »</span>';
- }
- $html .= '</span>';
- return $html;
- }
- /**
- * Generate the page showing.
- *
- * @return string
- */
- protected function generatPageShowing()
- {
- return '<span class="pagination-showing">'.t('Showing %d-%d of %d', (($this->getPage() - 1) * $this->getMax() + 1), min($this->getTotal(), $this->getPage() * $this->getMax()), $this->getTotal()).'</span>';
- }
- /**
- * Return true if there is no pagination to show.
- *
- * @return bool
- */
- protected function hasNothingtoShow()
- {
- return $this->offset === 0 && ($this->total - $this->offset) <= $this->limit;
- }
- }