diff --git a/Filter/ViewData/PagerAwareViewData.php b/Filter/ViewData/PagerAwareViewData.php
index d658a19c..be7e805b 100644
--- a/Filter/ViewData/PagerAwareViewData.php
+++ b/Filter/ViewData/PagerAwareViewData.php
@@ -51,21 +51,17 @@ class PagerAwareViewData extends ViewData
*
* @param $totalItems
* @param $currentPage
- * @param int $itemsPerPage
- * @param int $maxPages
+ * @param int $itemsPerPage
+ * @param int $maxPages
*/
public function setData($totalItems, $currentPage, $itemsPerPage = 12, $maxPages = 10)
{
$this->totalItems = $totalItems;
$this->currentPage = $currentPage;
$this->itemsPerPage = $itemsPerPage;
-
-// if ($maxPages < 3) {
-// throw new \InvalidArgumentException('Max pages has to be more than 3.');
-// }
- $this->maxPages = $maxPages;
-
$this->numPages = (int) ceil($this->totalItems/$this->itemsPerPage);
+
+ $this->maxPages = $maxPages < 3 ? 3 : $maxPages;
}
/**
@@ -166,6 +162,16 @@ public function isLastPage()
return $this->currentPage == $this->getLastPage();
}
+ /**
+ * @return int
+ */
+ private function calculateAdjacent()
+ {
+ $minus = $this->maxPages === 2 ? 0 : 1;
+
+ return (int) floor(($this->maxPages - $minus) / 2);
+ }
+
/**
* Generates a page list.
*
@@ -173,36 +179,23 @@ public function isLastPage()
*/
public function getPages()
{
- $numAdjacents = (int) floor(($this->maxPages - 3) / 2);
-
- if ($this->currentPage + $numAdjacents > $this->numPages) {
- $begin = $this->numPages - $this->maxPages + 2;
+ // Reserve one position for first/last page
+ $this->maxPages--;
+
+ $start = 1;
+ $numAdjacents = $this->calculateAdjacent();
+
+ if ($this->currentPage - $numAdjacents < $start) {
+ $begin = $start;
+ $end = min($this->numPages, $this->maxPages);
+ } elseif ($this->currentPage + $numAdjacents > $this->numPages) {
+ $begin = max($start, $this->numPages - $this->maxPages + 1);
+ $end = $this->numPages;
} else {
- $begin = $this->currentPage - $numAdjacents;
- }
- if ($begin < 2) {
- $begin = 2;
+ $begin = $this->currentPage - $numAdjacents + ($this->maxPages % 2);
+ $end = $this->currentPage + $numAdjacents;
}
- $end = $begin + $this->maxPages - 2;
-// if ($end >= $this->numPages) $end = $this->numPages - 1;
-
-// $tmpBegin = $this->maxPages - floor($this->maxPages / 2);
-// $tmpEnd = $tmpBegin + $this->maxPages - 1;
-//
-// if ($tmpBegin < 1) {
-// $tmpEnd += 1 - $tmpBegin;
-// $tmpBegin = 1;
-// }
-//
-// if ($tmpEnd > $this->getLastPage()) {
-// $tmpBegin -= $tmpEnd - $this->getLastPage();
-// $tmpEnd = $this->getLastPage();
-// }
-//
-// $begin = min($tmpBegin, 2);
-// $end = $tmpEnd;
-
- return range($begin, $end, 1);
+ return array_unique(array_merge([1], range($begin, $end, 1), [$this->numPages]));
}
}
diff --git a/Resources/views/Pager/paginate.html.twig b/Resources/views/Pager/paginate.html.twig
index 175a852e..2d716b6d 100644
--- a/Resources/views/Pager/paginate.html.twig
+++ b/Resources/views/Pager/paginate.html.twig
@@ -1,23 +1,30 @@
diff --git a/Tests/Functional/Filter/Widget/Pager/PagerTest.php b/Tests/Functional/Filter/Widget/Pager/PagerTest.php
index c5b39b6d..0dbad776 100644
--- a/Tests/Functional/Filter/Widget/Pager/PagerTest.php
+++ b/Tests/Functional/Filter/Widget/Pager/PagerTest.php
@@ -56,6 +56,12 @@ protected function getDataArray()
'manufacturer' => 'b',
'stock' => 5,
],
+ [
+ '_id' => 6,
+ 'color' => 'green',
+ 'manufacturer' => 'd',
+ 'stock' => 6,
+ ],
],
],
];
@@ -75,7 +81,7 @@ public function testPager()
$actual[] = $document->id;
}
- $this->assertEquals([5,4,3], $actual);
+ $this->assertEquals([6,5,4], $actual);
}
/**
@@ -92,6 +98,6 @@ public function testPagerOnSecondPage()
$actual[] = $document->id;
}
- $this->assertEquals([2,1], $actual);
+ $this->assertEquals([3,2,1], $actual);
}
}
diff --git a/Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php b/Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php
index 4b8fc39d..82e9e1f2 100644
--- a/Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php
+++ b/Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php
@@ -68,18 +68,123 @@ public function testCheckPageNavigation()
$this->assertEquals(1, $pagerData->getFirstPage());
}
- public function testGetPages()
+ /**
+ * @dataProvider getPagesDataProvider
+ * @param int $totalItems
+ * @param int $currentPage
+ * @param int $itemsPerPage
+ * @param int $maxPages
+ * @param array $resultRange
+ */
+ public function testGetPages($totalItems, $itemsPerPage, $currentPage, $maxPages, $resultRange)
{
$pagerData = new PagerAwareViewData();
$pagerData->setState($this->createMock('ONGR\FilterManagerBundle\Filter\FilterState'));
- $pagerData->setData(100, 1, 12, 5);
- $this->assertEquals(range(2, 5, 1), $pagerData->getPages());
+ $pagerData->setData($totalItems, $currentPage, $itemsPerPage, $maxPages);
- $pagerData->setData(100, 5, 12, 5);
- $this->assertEquals(range(4, 7, 1), $pagerData->getPages());
+ $this->assertEquals(array_values($resultRange), array_values($pagerData->getPages()));
+ }
- $pagerData->setData(100, 9, 12, 5);
- $this->assertEquals(range(6, 9, 1), $pagerData->getPages());
+ public function getPagesDataProvider()
+ {
+ return [
+ // [1]
+ [
+ 'totalItems' => 1,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 1,
+ 'maxPages' => 5,
+ 'resultRange' => [1]
+ ],
+ // 1 [2]
+ [
+ 'totalItems' => 10,
+ 'itemsPerPage' => 5,
+ 'currentPage' => 2,
+ 'maxPages' => 5,
+ 'resultRange' => [1, 2]
+ ],
+ // [1] 2 ... 5
+ [
+ 'totalItems' => 25,
+ 'itemsPerPage' => 5,
+ 'currentPage' => 1,
+ 'maxPages' => 3,
+ 'resultRange' => [1, 2, 5]
+ ],
+ // 1 ... 4 [5]
+ [
+ 'totalItems' => 25,
+ 'itemsPerPage' => 5,
+ 'currentPage' => 5,
+ 'maxPages' => 3,
+ 'resultRange' => [1, 4, 5]
+ ],
+ // [1] 2 3 4 5 6 7 8 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 1,
+ 'maxPages' => 9,
+ 'resultRange' => array_merge(range(1, 8, 1), [30])
+ ],
+ // 1 ... 3 4 5 [6] 7 8 9 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 6,
+ 'maxPages' => 9,
+ 'resultRange' => array_merge([1], range(3, 9, 1), [30])
+ ],
+ // 1 ... 12 13 14 [15] 16 17 18 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 15,
+ 'maxPages' => 9,
+ 'resultRange' => array_merge([1], range(12, 18, 1), [30])
+ ],
+ // 1 ... 23 24 25 26 27 [28] 29 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 28,
+ 'maxPages' => 9,
+ 'resultRange' => array_merge([1], range(23, 30, 1))
+ ],
+ // [1] 2 3 4 5 6 7 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 1,
+ 'maxPages' => 8,
+ 'resultRange' => array_merge(range(1, 7, 1), [30])
+ ],
+ // 1 ... 4 5 [6] 7 8 9 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 6,
+ 'maxPages' => 8,
+ 'resultRange' => array_merge([1], range(4, 9, 1), [30])
+ ],
+ // 1 ... 13 14 [15] 16 17 18 ... 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 15,
+ 'maxPages' => 8,
+ 'resultRange' => array_merge([1], range(13, 18, 1), [30])
+ ],
+ // 1 ... 24 25 26 27 [28] 29 30
+ [
+ 'totalItems' => 300,
+ 'itemsPerPage' => 10,
+ 'currentPage' => 28,
+ 'maxPages' => 8,
+ 'resultRange' => array_merge([1], range(24, 30, 1))
+ ],
+ ];
}
}
diff --git a/Tests/app/config/filters/pager.yml b/Tests/app/config/filters/pager.yml
index 2d7acf32..5aa5e130 100644
--- a/Tests/app/config/filters/pager.yml
+++ b/Tests/app/config/filters/pager.yml
@@ -12,7 +12,7 @@ ongr_filter_manager:
document_field: ~
options:
count_per_page: 3
- max_pages: 2
+ max_pages: 3
pager_sort:
type: sort
request_field: 'sort'