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'