From 7c1c14cf64b59f211b9d505112797cb855e5b604 Mon Sep 17 00:00:00 2001 From: Frederic Guillot Date: Sun, 18 Jan 2015 17:59:41 -0500 Subject: Pagination refactoring --- app/Core/Helper.php | 68 +------- app/Core/Paginator.php | 461 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 462 insertions(+), 67 deletions(-) create mode 100644 app/Core/Paginator.php (limited to 'app/Core') diff --git a/app/Core/Helper.php b/app/Core/Helper.php index 146cb2f8..dbe5a271 100644 --- a/app/Core/Helper.php +++ b/app/Core/Helper.php @@ -462,73 +462,7 @@ class Helper $values += $params; - return '?'.http_build_query($values, ''); - } - - /** - * Pagination links - * - * @param array $pagination Pagination information - * @return string - */ - public function paginate(array $pagination) - { - extract($pagination); - - if ($pagination['offset'] === 0 && ($total - $pagination['offset']) <= $limit) { - return ''; - } - - $html = ''; - - return $html; - } - - /** - * Column sorting (work with pagination) - * - * @param string $label Column title - * @param string $column SQL column name - * @param array $pagination Pagination information - * @return string - */ - public function order($label, $column, array $pagination) - { - extract($pagination); - - $prefix = ''; - - if ($order === $column) { - $prefix = $direction === 'DESC' ? '▼ ' : '▲ '; - $direction = $direction === 'DESC' ? 'ASC' : 'DESC'; - } - - $order = $column; - - return $prefix.$this->a($label, $controller, $action, $params + compact('offset', 'order', 'direction')); + return '?'.http_build_query($values); } /** diff --git a/app/Core/Paginator.php b/app/Core/Paginator.php new file mode 100644 index 00000000..7d7ce7ce --- /dev/null +++ b/app/Core/Paginator.php @@ -0,0 +1,461 @@ +container = $container; + } + + /** + * Set a PicoDb query + * + * @access public + * @param \PicoDb\Table + * @return Paginator + */ + public function setQuery(Table $query) + { + $this->query = $query; + $this->total = $this->query->count(); + return $this; + } + + /** + * Execute a PicoDb query + * + * @access public + * @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 array(); + } + + /** + * Set url parameters + * + * @access public + * @param string $controller + * @param string $action + * @param array $params + * @return Paginator + */ + public function setUrl($controller, $action, array $params = array()) + { + $this->controller = $controller; + $this->action = $action; + $this->params = $params; + return $this; + } + + /** + * Add manually items + * + * @access public + * @param array $items + * @return Paginator + */ + public function setCollection(array $items) + { + $this->items = $items; + return $this; + } + + /** + * Return the items + * + * @access public + * @return array + */ + public function getCollection() + { + return $this->items ?: $this->executeQuery(); + } + + /** + * Set the total number of items + * + * @access public + * @param integer $total + * @return Paginator + */ + public function setTotal($total) + { + $this->total = $total; + return $this; + } + + /** + * Get the total number of items + * + * @access public + * @return integer + */ + public function getTotal() + { + return $this->total; + } + + /** + * Set the default page number + * + * @access public + * @param integer $page + * @return Paginator + */ + public function setPage($page) + { + $this->page = $page; + return $this; + } + + /** + * Set the default column order + * + * @access public + * @param string $order + * @return Paginator + */ + public function setOrder($order) + { + $this->order = $order; + return $this; + } + + /** + * Set the default sorting direction + * + * @access public + * @param string $direction + * @return Paginator + */ + public function setDirection($direction) + { + $this->direction = $direction; + return $this; + } + + /** + * Set the maximum number of items per page + * + * @access public + * @param integer $limit + * @return Paginator + */ + public function setMax($limit) + { + $this->limit = $limit; + return $this; + } + + /** + * Return true if the collection is empty + * + * @access public + * @return boolean + */ + public function isEmpty() + { + return $this->total === 0; + } + + /** + * Execute the offset calculation only if the $condition is true + * + * @access public + * @param boolean $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 + * + * @access public + * @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 = ($this->page - 1) * $this->limit; + + return $this; + } + + /** + * Get url params for link generation + * + * @access public + * @param integer $page + * @param string $order + * @param string $direction + * @return string + */ + public function getUrlParams($page, $order, $direction) + { + $params = array( + 'page' => $page, + 'order' => $order, + 'direction' => $direction, + ); + + return array_merge($this->params, $params); + } + + /** + * Generate the previous link + * + * @access public + * @return string + */ + public function generatePreviousLink() + { + $html = ''; + + if ($this->offset > 0) { + $html .= $this->container['helper']->a( + '← '.t('Previous'), + $this->controller, + $this->action, + $this->getUrlParams($this->page - 1, $this->order, $this->direction) + ); + } + else { + $html .= '← '.t('Previous'); + } + + $html .= ''; + + return $html; + } + + /** + * Generate the next link + * + * @access public + * @return string + */ + public function generateNextLink() + { + $html = ''; + + if (($this->total - $this->offset) > $this->limit) { + $html .= $this->container['helper']->a( + t('Next').' →', + $this->controller, + $this->action, + $this->getUrlParams($this->page + 1, $this->order, $this->direction) + ); + } + else { + $html .= t('Next').' →'; + } + + $html .= ''; + + return $html; + } + + /** + * Return true if there is no pagination to show + * + * @access public + * @return boolean + */ + public function hasNothingtoShow() + { + return $this->offset === 0 && ($this->total - $this->offset) <= $this->limit; + } + + /** + * Generation pagination links + * + * @access public + * @return string + */ + public function toHtml() + { + $html = ''; + + if (! $this->hasNothingtoShow()) { + $html .= ''; + } + + return $html; + } + + /** + * Magic method to output pagination links + * + * @access public + * @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']->a( + $label, + $this->controller, + $this->action, + $this->getUrlParams($this->page, $column, $direction) + ); + } +} -- cgit v1.2.3