Passed
Pull Request — master (#154)
by
unknown
03:24 queued 31s
created

BasePaginator::data()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 0

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 0
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 2
rs 10
1
<?php
2
3
namespace Quantum\Libraries\Database;
4
5
class BasePaginator implements PaginatorInterface
6
{
7
	/**
8
	 * @var string
9
	 */
10
	protected const PAGINATION_CLASS = 'pagination';
11
12
	/**
13
	 * @var string
14
	 */
15
	protected const PAGINATION_CLASS_ACTIVE = 'active';
16
17
	/**
18
	 * @var string
19
	 */
20
	protected const PER_PAGE = 'per_page';
21
22
	/**
23
	 * @var string
24
	 */
25
	protected const PAGE = 'page';
26
27
	/**
28
	 * @var int
29
	 */
30
	protected const FIRST_PAGE_NUMBER = 1;
31
32
	/**
33
	 * @var int
34
	 */
35
	protected $total;
36
37
	/**
38
	 * @var string
39
	 */
40
	protected $baseUrl;
41
42
	/**
43
	 * @var int
44
	 */
45
	protected $perPage;
46
47
	/**
48
	 * @var int
49
	 */
50
	protected $page;
51
52
	/**
53
	 * @return int
54
	 */
55
	public function currentPageNumber(): int
56
	{
57
		return $this->page;
58
	}
59
60
	/**
61
	 * @param bool $withBaseUrl
62
	 * @return string|null
63
	 */
64
	public function currentPageLink(bool $withBaseUrl = false): ?string
65
	{
66
		return $this->getPageLink($this->page, $withBaseUrl);
67
	}
68
69
	/**
70
	 * @return int|null
71
	 */
72
	public function previousPageNumber(): ?int
73
	{
74
		$previous = null;
75
		if ($this->page > 1) {
76
			$previous = $this->page - 1;
77
		} elseif ($this->page == 1) {
78
			$previous = $this->page;
79
		}
80
81
		return $previous;
82
	}
83
84
	/**
85
	 * @param bool $withBaseUrl
86
	 * @return string|null
87
	 */
88
	public function previousPageLink(bool $withBaseUrl = false): ?string
89
	{
90
		return $this->getPageLink($this->previousPageNumber(), $withBaseUrl);
91
	}
92
93
	/**
94
	 * @return int|null
95
	 */
96
	public function nextPageNumber(): ?int
97
	{
98
		$next = null;
99
		if ($this->page < $this->lastPageNumber()) {
100
			$next = $this->page + 1;
101
		} elseif ($this->page == $this->lastPageNumber()) {
102
			$next = $this->page;
103
		}
104
		return $next;
105
	}
106
107
	/**
108
	 * @param bool $withBaseUrl
109
	 * @return string|null
110
	 */
111
	public function nextPageLink(bool $withBaseUrl = false): ?string
112
	{
113
		return $this->getPageLink($this->nextPageNumber(), $withBaseUrl);
114
	}
115
116
	/**
117
	 * @param bool $withBaseUrl
118
	 * @return string|null
119
	 */
120
	public function firstPageLink(bool $withBaseUrl = false): ?string
121
	{
122
		return $this->getPageLink(self::FIRST_PAGE_NUMBER, $withBaseUrl);
123
	}
124
125
	/**
126
	 * @return int
127
	 */
128
	public function lastPageNumber(): int
129
	{
130
		return (int)ceil($this->total() / $this->perPage);
131
	}
132
133
	/**
134
	 * @param bool $withBaseUrl
135
	 * @return string|null
136
	 */
137
	public function lastPageLink(bool $withBaseUrl = false): ?string
138
	{
139
		return $this->getPageLink($this->lastPageNumber(), $withBaseUrl);
140
	}
141
142
	/**
143
	 * @return int
144
	 */
145
	public function perPage(): int
146
	{
147
		return $this->perPage;
148
	}
149
150
	/**
151
	 * @return int
152
	 */
153
	public function total(): int
154
	{
155
		return $this->total;
156
	}
157
158
	/**
159
	 * @param bool $withBaseUrl
160
	 * @return array
161
	 */
162
	public function links(bool $withBaseUrl = false): array
163
	{
164
		$links = [];
165
		for ($i = 1; $i <= $this->lastPageNumber(); $i++) {
166
			$links[] = $this->getPageLink($i, $withBaseUrl);
167
		}
168
169
		return $links;
170
	}
171
172
	/**
173
	 * @param bool $withBaseUrl
174
	 * @return string
175
	 */
176
	protected function getUri(bool $withBaseUrl = false): string
177
	{
178
		$routeUrl = preg_replace('/([?&](page|per_page)=\d+)/', '', route_uri());
179
		$routeUrl = preg_replace('/&/', '?', $routeUrl, 1);
180
		$url = $routeUrl;
181
182
		if ($withBaseUrl) {
183
			$url = $this->baseUrl . $routeUrl;
184
		}
185
186
		$delimiter = strpos($url, '?') ? '&' : '?';
187
		return $url . $delimiter;
188
	}
189
190
	protected function getPageLink($pageNumber, $withBaseUrl = false): ?string
191
	{
192
		if (!empty($pageNumber)){
193
			return $this->getUri($withBaseUrl) . self::PER_PAGE .'=' . $this->perPage . '&'. self::PAGE .'=' . $pageNumber;
194
		}
195
		return null;
196
	}
197
198
	/**
199
	 * @param bool $withBaseUrl
200
	 * @param $pageItemsCount
201
	 * @return string|null
202
	 */
203
	public function getPagination(bool $withBaseUrl = false, $pageItemsCount = null): ?string
204
	{
205
		if (!is_null($pageItemsCount) && $pageItemsCount < 3) {
206
			$pageItemsCount = 3;
207
		}
208
209
		$currentPage = $this->currentPageNumber();
210
		$totalPages = $this->lastPageNumber();
211
212
		if ($totalPages <= 1) {
213
			return null;
214
		}
215
216
		$pagination = '<ul class="'. self::PAGINATION_CLASS .'">';
217
218
		if ($currentPage > 1) {
219
			$pagination .= $this->getPreviousPageItem($this->previousPageLink());
0 ignored issues
show
Bug introduced by
It seems like $this->previousPageLink() can also be of type null; however, parameter $previousPageLink of Quantum\Libraries\Databa...::getPreviousPageItem() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

219
			$pagination .= $this->getPreviousPageItem(/** @scrutinizer ignore-type */ $this->previousPageLink());
Loading history...
220
		}
221
222
		if ($pageItemsCount) {
223
			$pagination = $this->getPageItems($pagination, $currentPage, $totalPages, $pageItemsCount, $withBaseUrl);
224
		}
225
226
		if ($currentPage < $totalPages) {
227
			$pagination .= $this->getNextPageItem($this->nextPageLink());
0 ignored issues
show
Bug introduced by
It seems like $this->nextPageLink() can also be of type null; however, parameter $nextPageLink of Quantum\Libraries\Databa...ator::getNextPageItem() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

227
			$pagination .= $this->getNextPageItem(/** @scrutinizer ignore-type */ $this->nextPageLink());
Loading history...
228
		}
229
230
		$pagination .= '</ul>';
231
232
		return $pagination;
233
	}
234
235
	/**
236
	 * @param $pagination
237
	 * @param $currentPage
238
	 * @param $totalPages
239
	 * @param $pageItemsCount
240
	 * @param $withBaseUrl
241
	 * @return mixed|string
242
	 */
243
	protected function getPageItems($pagination, $currentPage, $totalPages, $pageItemsCount, $withBaseUrl = false)
244
	{
245
		$startPage = max(1, $currentPage - ceil(($pageItemsCount - 3) / 2));
246
		$endPage = min($totalPages, $startPage + $pageItemsCount - 3);
247
		$startPage = max(1, $endPage - $pageItemsCount + 3);
248
249
		if ($startPage > 1) {
250
			$pagination .= '<li><a href="' . $this->firstPageLink() . '">1</a></li>';
251
			if ($startPage > 2) {
252
				$pagination .= '<li><span>...</span></li>';
253
			}
254
		}
255
256
		$links = $this->links($withBaseUrl);
257
		for ($i = $startPage; $i <= $endPage; $i++) {
258
			$active = $i == $currentPage ? 'class="'. self::PAGINATION_CLASS_ACTIVE .'"' : '';
259
			$pagination .= '<li ' . $active . '><a href="' . $links[$i - 1] . '">' . $i . '</a></li>';
260
		}
261
262
		if ($endPage < $totalPages) {
263
			if ($endPage < $totalPages - 1) {
264
				$pagination .= '<li><span>...</span></li>';
265
			}
266
267
			$pagination .= '<li><a href="' . $links[$totalPages - 1] . '">' . $totalPages . '</a></li>';
268
		}
269
		return $pagination;
270
	}
271
272
	/**
273
	 * @param string $nextPageLink
274
	 * @return string
275
	 */
276
	protected function getNextPageItem(string $nextPageLink): string
277
	{
278
		return '<li><a href="' . $nextPageLink . '">Next &raquo;</a></li>';
279
	}
280
281
	/**
282
	 * @param string $previousPageLink
283
	 * @return string
284
	 */
285
	protected function getPreviousPageItem(string $previousPageLink): string
286
	{
287
		return '<li><a href="' . $previousPageLink . '">&laquo; Previous</a></li>';
288
	}
289
290
	public function firstItem()
291
	{
292
		// TODO: Implement firstItem() method.
293
	}
294
295
	public function lastItem()
296
	{
297
		// TODO: Implement lastItem() method.
298
	}
299
300
	public function data()
301
	{
302
		// TODO: Implement data() method.
303
	}
304
}