icingaweb2/library/Icinga/Web/Widget/Paginator.php

169 lines
4.4 KiB
PHP

<?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;
}
}