Skip to content

Commit

Permalink
Introduce widget Paginator
Browse files Browse the repository at this point in the history
This does not support custom scrolling styles as of now. Custom view
scripts are supported though. In case Paginator::getPages() does not
suffice, feel free to improve this.
  • Loading branch information
Johannes Meyer committed May 19, 2015
1 parent 4cedfce commit bd7c7f9
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 6 deletions.
10 changes: 4 additions & 6 deletions library/Icinga/Web/Controller.php
Expand Up @@ -3,12 +3,11 @@

namespace Icinga\Web;

use Zend_Paginator;
use Icinga\Data\Sortable;
use Icinga\Data\QueryInterface;
use Icinga\Web\Paginator\Adapter\QueryAdapter;
use Icinga\Web\Controller\ModuleActionController;
use Icinga\Web\Widget\Limiter;
use Icinga\Web\Widget\Paginator;
use Icinga\Web\Widget\SortBox;

/**
Expand Down Expand Up @@ -115,12 +114,11 @@ protected function setupPaginationControl(QueryInterface $query, $itemsPerPage =
$request = $this->getRequest();
$limit = $request->getParam('limit', $itemsPerPage);
$page = $request->getParam('page', $pageNumber);
$query->limit($limit, $page * $limit);
$query->limit($limit, $page > 0 ? ($page - 1) * $limit : 0);

if (! $this->view->compact) {
$paginator = new Zend_Paginator(new QueryAdapter($query));
$paginator->setItemCountPerPage($limit);
$paginator->setCurrentPageNumber($page);
$paginator = new Paginator();
$paginator->setQuery($query);
$this->view->paginator = $paginator;
}

Expand Down
168 changes: 168 additions & 0 deletions library/Icinga/Web/Widget/Paginator.php
@@ -0,0 +1,168 @@
<?php
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */

namespace Icinga\Web\Widget;

use Icinga\Data\QueryInterface;
use Icinga\Exception\ProgrammingError;

/**
* Paginator
*/
class Paginator extends AbstractWidget
{
/**
* The query the paginator widget is created for
*
* @var QueryInterface
*/
protected $query;

/**
* The view script in use
*
* @var string|array
*/
protected $viewScript = array('mixedPagination.phtml', 'default');

/**
* Set the query to create the paginator widget for
*
* @param QueryInterface $query
*
* @return $this
*/
public function setQuery(QueryInterface $query)
{
$this->query = $query;
return $this;
}

/**
* Set the view script to use
*
* @param string|array $script
*
* @return $this
*/
public function setViewScript($script)
{
$this->viewScript = $script;
return $this;
}

/**
* Render this paginator
*/
public function render()
{
if ($this->query === null) {
throw new ProgrammingError('Need a query to create the paginator widget for');
}

$itemCountPerPage = $this->query->getLimit();
if (! $itemCountPerPage) {
return ''; // No pagination required
}

$totalItemCount = count($this->query);
$pageCount = (int) ceil($totalItemCount / $itemCountPerPage);
$currentPage = $this->query->hasOffset() ? ($this->query->getOffset() / $itemCountPerPage) + 1 : 1;
$pagesInRange = $this->getPages($pageCount, $currentPage);
$variables = array(
'totalItemCount' => $totalItemCount,
'pageCount' => $pageCount,
'itemCountPerPage' => $itemCountPerPage,
'first' => 1,
'current' => $currentPage,
'last' => $pageCount,
'pagesInRange' => $pagesInRange,
'firstPageInRange' => min($pagesInRange),
'lastPageInRange' => max($pagesInRange)
);

if ($currentPage > 1) {
$variables['previous'] = $currentPage - 1;
}

if ($currentPage < $pageCount) {
$variables['next'] = $currentPage + 1;
}

if (is_array($this->viewScript)) {
if ($this->viewScript[1] !== null) {
return $this->view()->partial($this->viewScript[0], $this->viewScript[1], $variables);
}

return $this->view()->partial($this->viewScript[0], $variables);
}

return $this->view()->partial($this->viewScript, $variables);
}

/**
* Returns an array of "local" pages given the page count and current page number
*
* @return array
*/
protected function getPages($pageCount, $currentPage)
{
$range = array();

if ($pageCount < 10) {
// Show all pages if we have less than 10
for ($i = 1; $i < 10; $i++) {
if ($i > $pageCount) {
break;
}

$range[$i] = $i;
}
} else {
// More than 10 pages:
foreach (array(1, 2) as $i) {
$range[$i] = $i;
}

if ($currentPage < 6 ) {
// We are on page 1-5 from
for ($i = 1; $i <= 7; $i++) {
$range[$i] = $i;
}
} else {
// Current page > 5
$range[] = '...';

if (($pageCount - $currentPage) < 5) {
// Less than 5 pages left
$start = 5 - ($pageCount - $currentPage);
} else {
$start = 1;
}

for ($i = $currentPage - $start; $i < ($currentPage + (4 - $start)); $i++) {
if ($i > $pageCount) {
break;
}

$range[$i] = $i;
}
}

if ($currentPage < ($pageCount - 2)) {
$range[] = '...';
}

foreach (array($pageCount - 1, $pageCount) as $i) {
$range[$i] = $i;
}

}

if (empty($range)) {
$range[] = 1;
}

return $range;
}
}

0 comments on commit bd7c7f9

Please sign in to comment.