Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix creating pager range #245

Merged
merged 15 commits into from
May 3, 2018
65 changes: 29 additions & 36 deletions Filter/ViewData/PagerAwareViewData.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Author

@serieznyi serieznyi Jan 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@saimaz I replace throwing exception on default minimum value because I afraid that my changes crash somebody app.

}

/**
Expand Down Expand Up @@ -166,43 +162,40 @@ 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.
*
* @return array The page list.
*/
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]));
}
}
31 changes: 19 additions & 12 deletions Resources/views/Pager/paginate.html.twig
Original file line number Diff line number Diff line change
@@ -1,23 +1,30 @@
<ul class="pagination">
{% if pager.isFirstPage == false %}
<li class="first"><a href="{{ ongr_paginate_path(route, pager.getFirstPage, parameters) }}">&laquo;</a></li>
<li class="previous"><a href="{{ ongr_paginate_path(route, pager.getPreviousPage, parameters) }}">&lsaquo;</a></li>
{% endif %}
<li class="{% if 1 == pager.getCurrentPage %}active{% endif %}">
<a href="{{ ongr_paginate_path(route, 1, parameters) }}">1</a>
</li>
{% if 1 < pager.getPages.0 - 1%}
<li>
<span>...</span>
{% if pager.isFirstPage %}
<li class="previous">&lsaquo;</li>
{% else %}
<li class="previous">
<a href="{{ ongr_paginate_path(route, pager.getPreviousPage, parameters) }}">&lsaquo;</a>
</li>
{% endif %}

{% set previous = false %}

{% for page in pager.getPages %}
{% if previous and page > previous + 1 %}
<li>
<span>...</span>
</li>
{% endif %}

<li class="{% if page == pager.getCurrentPage %}active{% endif %}">
<a href="{{ ongr_paginate_path(route, page, parameters) }}">{{ page }}</a>
</li>
{% set previous = page %}
{% endfor %}
{% if pager.isLastPage == false %}

{% if pager.isLastPage %}
<li class="next">&rsaquo;</li>
{% else %}
<li class="next"><a href="{{ ongr_paginate_path(route, pager.getNextPage, parameters) }}">&rsaquo;</a></li>
<li class="last"><a href="{{ ongr_paginate_path(route, pager.getLastPage, parameters) }}">&raquo;</a></li>
{% endif %}
</ul>
10 changes: 8 additions & 2 deletions Tests/Functional/Filter/Widget/Pager/PagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ protected function getDataArray()
'manufacturer' => 'b',
'stock' => 5,
],
[
'_id' => 6,
'color' => 'green',
'manufacturer' => 'd',
'stock' => 6,
],
],
],
];
Expand All @@ -75,7 +81,7 @@ public function testPager()
$actual[] = $document->id;
}

$this->assertEquals([5,4,3], $actual);
$this->assertEquals([6,5,4], $actual);
}

/**
Expand All @@ -92,6 +98,6 @@ public function testPagerOnSecondPage()
$actual[] = $document->id;
}

$this->assertEquals([2,1], $actual);
$this->assertEquals([3,2,1], $actual);
}
}
119 changes: 112 additions & 7 deletions Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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))
],
];
}
}
2 changes: 1 addition & 1 deletion Tests/app/config/filters/pager.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down