1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Ffcms\Core\Helper\HTML; |
4
|
|
|
|
5
|
|
|
use Ffcms\Core\Helper\Type\Any; |
6
|
|
|
use Ffcms\Core\Helper\Type\Arr; |
7
|
|
|
use Ffcms\Core\Helper\Type\Obj; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* Class SimplePagination. Build and display html pagination block |
11
|
|
|
* @package Ffcms\Core\Helper\HTML |
12
|
|
|
*/ |
13
|
|
|
class SimplePagination |
14
|
|
|
{ |
15
|
|
|
protected $url; |
16
|
|
|
protected $page; |
17
|
|
|
protected $step; |
18
|
|
|
protected $total; |
19
|
|
|
|
20
|
|
|
/** |
21
|
|
|
* SimplePagination constructor. Parse passed elements |
22
|
|
|
* @param array $elements |
23
|
|
|
*/ |
24
|
|
|
public function __construct(array $elements) |
25
|
|
|
{ |
26
|
|
|
$this->url = $elements['url']; |
27
|
|
|
$this->page = (int)$elements['page']; |
28
|
|
|
$this->step = (int)$elements['step'] > 0 ? (int)$elements['step'] : 5; |
29
|
|
|
$this->total = (int)$elements['total']; |
30
|
|
|
} |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* Display pagination html code. Must be initialized via (new SimplePagination([params]))->display(['class' => 'test']) |
34
|
|
|
* @param array|null $property |
35
|
|
|
* @return null|string |
36
|
|
|
*/ |
37
|
|
|
public function display(array $property = null): ?string |
38
|
|
|
{ |
39
|
|
|
// total items is less to pagination requirement |
40
|
|
|
if (($this->page * $this->step) + 1 > $this->total) { |
41
|
|
|
return null; |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
$lastPage = ceil($this->total / $this->step); // 6/5 ~ 2 = 0..2 |
|
|
|
|
45
|
|
|
|
46
|
|
|
if ($lastPage <= 1) { |
47
|
|
|
return null; |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
// prevent hack-boy's any try |
51
|
|
|
if ($this->page > $lastPage) { |
52
|
|
|
return null; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
$items = []; |
|
|
|
|
56
|
|
|
// more then 10 items in pagination |
57
|
|
|
if ($lastPage > 10) { |
58
|
|
|
if ($this->page < 4 || $lastPage - $this->page <= 4) { // list start, page in [0..4] |
|
|
|
|
59
|
|
|
// from start to 4 |
60
|
|
|
$items = $this->generateItems(0, 4); |
61
|
|
|
|
62
|
|
|
// add "..." button |
63
|
|
|
$items[] = [ |
64
|
|
|
'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled'] |
65
|
|
|
]; |
66
|
|
|
// add middle page |
67
|
|
|
$middlePage = ceil($lastPage / 2); |
68
|
|
|
$items[] = [ |
69
|
|
|
'type' => 'link', 'link' => $this->setUrlPage($middlePage), 'text' => $middlePage + 1 |
70
|
|
|
]; |
71
|
|
|
// add "..." button |
72
|
|
|
$items[] = [ |
73
|
|
|
'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled'] |
74
|
|
|
]; |
75
|
|
|
$items = Arr::merge($items, $this->generateItems($lastPage - 4, $lastPage)); |
76
|
|
|
} else { // meanwhile on middle |
77
|
|
|
// generate 1-2 pages |
78
|
|
|
$items = $this->generateItems(0, 2); |
79
|
|
|
|
80
|
|
|
// add "..." button |
81
|
|
|
$items[] = [ |
82
|
|
|
'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled'] |
83
|
|
|
]; |
84
|
|
|
|
85
|
|
|
// add middle variance -3..mid..+3 |
86
|
|
|
$items = Arr::merge($items, $this->generateItems($this->page - 3, $this->page + 3)); |
87
|
|
|
|
88
|
|
|
// add "..." button |
89
|
|
|
$items[] = [ |
90
|
|
|
'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled'] |
91
|
|
|
]; |
92
|
|
|
|
93
|
|
|
// add latest 2 items |
94
|
|
|
$items = Arr::merge($items, $this->generateItems($lastPage - 2, $lastPage)); |
95
|
|
|
} |
96
|
|
|
} else { // less then 10 items in pagination |
97
|
|
|
$items = $this->generateItems(0, $lastPage); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
return Listing::display([ |
101
|
|
|
'type' => 'ul', |
102
|
|
|
'property' => $property, |
103
|
|
|
'items' => $items |
104
|
|
|
]); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* Set GET param to property array |
109
|
|
|
* @param int|string $pageId |
110
|
|
|
* @return array |
111
|
|
|
*/ |
112
|
|
|
protected function setUrlPage($pageId) |
113
|
|
|
{ |
114
|
|
|
$url = $this->url; |
115
|
|
|
switch (count($url)) { // check nulls if not set |
116
|
|
|
case 1: // only controller/action is defined |
|
|
|
|
117
|
|
|
$url[1] = null; |
118
|
|
|
$url[2] = null; |
119
|
|
|
break; |
120
|
|
|
case 2: |
121
|
|
|
$url[2] = null; |
122
|
|
|
break; |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
// add page param if > 0 |
126
|
|
|
if ((int)$pageId > 0) { |
127
|
|
|
// merge with ?page if query is not empty |
128
|
|
|
$url[3] = (Any::isArray($url[3]) ? Arr::merge($url[3], ['page' => $pageId]) : ['page' => $pageId]); |
129
|
|
|
} |
130
|
|
|
|
131
|
|
|
return $url; |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* Generate item array to build pagination listing |
136
|
|
|
* @param int $start |
137
|
|
|
* @param int $end |
138
|
|
|
* @return array|null |
139
|
|
|
*/ |
140
|
|
|
protected function generateItems($start, $end) |
141
|
|
|
{ |
142
|
|
|
// prevent any shit's |
143
|
|
|
if ($end <= $start) { |
144
|
|
|
return null; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
$items = []; |
148
|
|
|
for ($i = $start; $i < $end; $i++) { |
149
|
|
|
$items[] = [ |
150
|
|
|
'type' => 'link', 'link' => $this->setUrlPage($i), 'text' => $i + 1 |
151
|
|
|
]; |
152
|
|
|
} |
153
|
|
|
return $items; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.