Skip to content

Commit ab879a9

Browse files
serieznyisaimaz
authored andcommitted
Fix creating pager range (#245)
* fix creating page range (cherry picked from commit e261db6) * update default paginate template (cherry picked from commit 99436de) * make code more shortly and update view (cherry picked from commit 0b913bc) * again fix paginate view (cherry picked from commit 2179b86) * fix pagination if maxPage is even * update unit test for getPages * fix logic after error * calculate correction shortly * update code and add new test * add more data in test * fix code format * add new test * fix algoritm * remove throwing exception
1 parent eb1a026 commit ab879a9

File tree

5 files changed

+169
-58
lines changed

5 files changed

+169
-58
lines changed

Filter/ViewData/PagerAwareViewData.php

+29-36
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,17 @@ class PagerAwareViewData extends ViewData
5151
*
5252
* @param $totalItems
5353
* @param $currentPage
54-
* @param int $itemsPerPage
55-
* @param int $maxPages
54+
* @param int $itemsPerPage
55+
* @param int $maxPages
5656
*/
5757
public function setData($totalItems, $currentPage, $itemsPerPage = 12, $maxPages = 10)
5858
{
5959
$this->totalItems = $totalItems;
6060
$this->currentPage = $currentPage;
6161
$this->itemsPerPage = $itemsPerPage;
62-
63-
// if ($maxPages < 3) {
64-
// throw new \InvalidArgumentException('Max pages has to be more than 3.');
65-
// }
66-
$this->maxPages = $maxPages;
67-
6862
$this->numPages = (int) ceil($this->totalItems/$this->itemsPerPage);
63+
64+
$this->maxPages = $maxPages < 3 ? 3 : $maxPages;
6965
}
7066

7167
/**
@@ -166,43 +162,40 @@ public function isLastPage()
166162
return $this->currentPage == $this->getLastPage();
167163
}
168164

165+
/**
166+
* @return int
167+
*/
168+
private function calculateAdjacent()
169+
{
170+
$minus = $this->maxPages === 2 ? 0 : 1;
171+
172+
return (int) floor(($this->maxPages - $minus) / 2);
173+
}
174+
169175
/**
170176
* Generates a page list.
171177
*
172178
* @return array The page list.
173179
*/
174180
public function getPages()
175181
{
176-
$numAdjacents = (int) floor(($this->maxPages - 3) / 2);
177-
178-
if ($this->currentPage + $numAdjacents > $this->numPages) {
179-
$begin = $this->numPages - $this->maxPages + 2;
182+
// Reserve one position for first/last page
183+
$this->maxPages--;
184+
185+
$start = 1;
186+
$numAdjacents = $this->calculateAdjacent();
187+
188+
if ($this->currentPage - $numAdjacents < $start) {
189+
$begin = $start;
190+
$end = min($this->numPages, $this->maxPages);
191+
} elseif ($this->currentPage + $numAdjacents > $this->numPages) {
192+
$begin = max($start, $this->numPages - $this->maxPages + 1);
193+
$end = $this->numPages;
180194
} else {
181-
$begin = $this->currentPage - $numAdjacents;
182-
}
183-
if ($begin < 2) {
184-
$begin = 2;
195+
$begin = $this->currentPage - $numAdjacents + ($this->maxPages % 2);
196+
$end = $this->currentPage + $numAdjacents;
185197
}
186198

187-
$end = $begin + $this->maxPages - 2;
188-
// if ($end >= $this->numPages) $end = $this->numPages - 1;
189-
190-
// $tmpBegin = $this->maxPages - floor($this->maxPages / 2);
191-
// $tmpEnd = $tmpBegin + $this->maxPages - 1;
192-
//
193-
// if ($tmpBegin < 1) {
194-
// $tmpEnd += 1 - $tmpBegin;
195-
// $tmpBegin = 1;
196-
// }
197-
//
198-
// if ($tmpEnd > $this->getLastPage()) {
199-
// $tmpBegin -= $tmpEnd - $this->getLastPage();
200-
// $tmpEnd = $this->getLastPage();
201-
// }
202-
//
203-
// $begin = min($tmpBegin, 2);
204-
// $end = $tmpEnd;
205-
206-
return range($begin, $end, 1);
199+
return array_unique(array_merge([1], range($begin, $end, 1), [$this->numPages]));
207200
}
208201
}
+19-12
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,30 @@
11
<ul class="pagination">
2-
{% if pager.isFirstPage == false %}
3-
<li class="first"><a href="{{ ongr_paginate_path(route, pager.getFirstPage, parameters) }}">&laquo;</a></li>
4-
<li class="previous"><a href="{{ ongr_paginate_path(route, pager.getPreviousPage, parameters) }}">&lsaquo;</a></li>
5-
{% endif %}
6-
<li class="{% if 1 == pager.getCurrentPage %}active{% endif %}">
7-
<a href="{{ ongr_paginate_path(route, 1, parameters) }}">1</a>
8-
</li>
9-
{% if 1 < pager.getPages.0 - 1%}
10-
<li>
11-
<span>...</span>
2+
{% if pager.isFirstPage %}
3+
<li class="previous">&lsaquo;</li>
4+
{% else %}
5+
<li class="previous">
6+
<a href="{{ ongr_paginate_path(route, pager.getPreviousPage, parameters) }}">&lsaquo;</a>
127
</li>
138
{% endif %}
9+
10+
{% set previous = false %}
11+
1412
{% for page in pager.getPages %}
13+
{% if previous and page > previous + 1 %}
14+
<li>
15+
<span>...</span>
16+
</li>
17+
{% endif %}
18+
1519
<li class="{% if page == pager.getCurrentPage %}active{% endif %}">
1620
<a href="{{ ongr_paginate_path(route, page, parameters) }}">{{ page }}</a>
1721
</li>
22+
{% set previous = page %}
1823
{% endfor %}
19-
{% if pager.isLastPage == false %}
24+
25+
{% if pager.isLastPage %}
26+
<li class="next">&rsaquo;</li>
27+
{% else %}
2028
<li class="next"><a href="{{ ongr_paginate_path(route, pager.getNextPage, parameters) }}">&rsaquo;</a></li>
21-
<li class="last"><a href="{{ ongr_paginate_path(route, pager.getLastPage, parameters) }}">&raquo;</a></li>
2229
{% endif %}
2330
</ul>

Tests/Functional/Filter/Widget/Pager/PagerTest.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ protected function getDataArray()
5656
'manufacturer' => 'b',
5757
'stock' => 5,
5858
],
59+
[
60+
'_id' => 6,
61+
'color' => 'green',
62+
'manufacturer' => 'd',
63+
'stock' => 6,
64+
],
5965
],
6066
],
6167
];
@@ -75,7 +81,7 @@ public function testPager()
7581
$actual[] = $document->id;
7682
}
7783

78-
$this->assertEquals([5,4,3], $actual);
84+
$this->assertEquals([6,5,4], $actual);
7985
}
8086

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

95-
$this->assertEquals([2,1], $actual);
101+
$this->assertEquals([3,2,1], $actual);
96102
}
97103
}

Tests/Unit/Filter/ViewData/PagerAwareViewDataTest.php

+112-7
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,123 @@ public function testCheckPageNavigation()
6868
$this->assertEquals(1, $pagerData->getFirstPage());
6969
}
7070

71-
public function testGetPages()
71+
/**
72+
* @dataProvider getPagesDataProvider
73+
* @param int $totalItems
74+
* @param int $currentPage
75+
* @param int $itemsPerPage
76+
* @param int $maxPages
77+
* @param array $resultRange
78+
*/
79+
public function testGetPages($totalItems, $itemsPerPage, $currentPage, $maxPages, $resultRange)
7280
{
7381
$pagerData = new PagerAwareViewData();
7482
$pagerData->setState($this->createMock('ONGR\FilterManagerBundle\Filter\FilterState'));
75-
$pagerData->setData(100, 1, 12, 5);
7683

77-
$this->assertEquals(range(2, 5, 1), $pagerData->getPages());
84+
$pagerData->setData($totalItems, $currentPage, $itemsPerPage, $maxPages);
7885

79-
$pagerData->setData(100, 5, 12, 5);
80-
$this->assertEquals(range(4, 7, 1), $pagerData->getPages());
86+
$this->assertEquals(array_values($resultRange), array_values($pagerData->getPages()));
87+
}
8188

82-
$pagerData->setData(100, 9, 12, 5);
83-
$this->assertEquals(range(6, 9, 1), $pagerData->getPages());
89+
public function getPagesDataProvider()
90+
{
91+
return [
92+
// [1]
93+
[
94+
'totalItems' => 1,
95+
'itemsPerPage' => 10,
96+
'currentPage' => 1,
97+
'maxPages' => 5,
98+
'resultRange' => [1]
99+
],
100+
// 1 [2]
101+
[
102+
'totalItems' => 10,
103+
'itemsPerPage' => 5,
104+
'currentPage' => 2,
105+
'maxPages' => 5,
106+
'resultRange' => [1, 2]
107+
],
108+
// [1] 2 ... 5
109+
[
110+
'totalItems' => 25,
111+
'itemsPerPage' => 5,
112+
'currentPage' => 1,
113+
'maxPages' => 3,
114+
'resultRange' => [1, 2, 5]
115+
],
116+
// 1 ... 4 [5]
117+
[
118+
'totalItems' => 25,
119+
'itemsPerPage' => 5,
120+
'currentPage' => 5,
121+
'maxPages' => 3,
122+
'resultRange' => [1, 4, 5]
123+
],
124+
// [1] 2 3 4 5 6 7 8 ... 30
125+
[
126+
'totalItems' => 300,
127+
'itemsPerPage' => 10,
128+
'currentPage' => 1,
129+
'maxPages' => 9,
130+
'resultRange' => array_merge(range(1, 8, 1), [30])
131+
],
132+
// 1 ... 3 4 5 [6] 7 8 9 ... 30
133+
[
134+
'totalItems' => 300,
135+
'itemsPerPage' => 10,
136+
'currentPage' => 6,
137+
'maxPages' => 9,
138+
'resultRange' => array_merge([1], range(3, 9, 1), [30])
139+
],
140+
// 1 ... 12 13 14 [15] 16 17 18 ... 30
141+
[
142+
'totalItems' => 300,
143+
'itemsPerPage' => 10,
144+
'currentPage' => 15,
145+
'maxPages' => 9,
146+
'resultRange' => array_merge([1], range(12, 18, 1), [30])
147+
],
148+
// 1 ... 23 24 25 26 27 [28] 29 30
149+
[
150+
'totalItems' => 300,
151+
'itemsPerPage' => 10,
152+
'currentPage' => 28,
153+
'maxPages' => 9,
154+
'resultRange' => array_merge([1], range(23, 30, 1))
155+
],
156+
// [1] 2 3 4 5 6 7 ... 30
157+
[
158+
'totalItems' => 300,
159+
'itemsPerPage' => 10,
160+
'currentPage' => 1,
161+
'maxPages' => 8,
162+
'resultRange' => array_merge(range(1, 7, 1), [30])
163+
],
164+
// 1 ... 4 5 [6] 7 8 9 ... 30
165+
[
166+
'totalItems' => 300,
167+
'itemsPerPage' => 10,
168+
'currentPage' => 6,
169+
'maxPages' => 8,
170+
'resultRange' => array_merge([1], range(4, 9, 1), [30])
171+
],
172+
// 1 ... 13 14 [15] 16 17 18 ... 30
173+
[
174+
'totalItems' => 300,
175+
'itemsPerPage' => 10,
176+
'currentPage' => 15,
177+
'maxPages' => 8,
178+
'resultRange' => array_merge([1], range(13, 18, 1), [30])
179+
],
180+
// 1 ... 24 25 26 27 [28] 29 30
181+
[
182+
'totalItems' => 300,
183+
'itemsPerPage' => 10,
184+
'currentPage' => 28,
185+
'maxPages' => 8,
186+
'resultRange' => array_merge([1], range(24, 30, 1))
187+
],
188+
];
84189
}
85190
}

Tests/app/config/filters/pager.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ongr_filter_manager:
1212
document_field: ~
1313
options:
1414
count_per_page: 3
15-
max_pages: 2
15+
max_pages: 3
1616
pager_sort:
1717
type: sort
1818
request_field: 'sort'

0 commit comments

Comments
 (0)