Completed
Branch master (a2d832)
by Timo
02:40
created

Paginator::_getLastPageUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 4
cts 5
cp 0.8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
crap 2.032
1
<?php
2
3
namespace hamburgscleanest\DataTables\Models\DataComponents;
4
5
use hamburgscleanest\DataTables\Helpers\UrlHelper;
6
use hamburgscleanest\DataTables\Models\DataComponent;
7
use Illuminate\Database\Eloquent\Builder;
8
9
/**
10
 * Class Paginator
11
 * @package hamburgscleanest\DataTables\Models\DataComponents
12
 */
13
class Paginator extends DataComponent {
14
15
    /** @var int */
16
    private $_perPage;
17
18
    /** @var int */
19
    private $_currentPage;
20
21
    /** @var string */
22
    private $_firstPageSymbol = 'first';
23
24
    /** @var string */
25
    private $_previousPageSymbol = '←';
26
27
    /** @var string */
28
    private $_nextPageSymbol = '→';
29
30
    /** @var string */
31
    private $_lastPageSymbol = 'last';
32
33
    /** @var int */
34
    private $_surroundingPages = 2;
35
36
37
    /**
38
     * Paginator constructor.
39
     * @param int $perPage
40
     */
41 1
    public function __construct(int $perPage = 15)
42
    {
43 1
        $this->_perPage = $perPage;
44 1
    }
45
46 1
    protected function _afterInit()
47
    {
48 1
        $this->_currentPage = + $this->_request->get('page', 1);
49 1
    }
50
51
    /**
52
     * How many entries per page?
53
     *
54
     * @param int $perPage
55
     * @return $this
56
     */
57
    public function entriesPerPage($perPage = 15)
58
    {
59
        $this->_perPage = $perPage;
60
61
        return $this;
62
    }
63
64
    /**
65
     * How many surrounding pages should be shown?
66
     *
67
     * @param int $count
68
     * @return $this
69
     */
70
    public function surroundingPages($count = 2)
71
    {
72
        $this->_surroundingPages = $count;
73
74
        return $this;
75
    }
76
77
    /**
78
     * @return Builder
79
     */
80
    public function shapeData(): Builder
81
    {
82
        if ($this->_perPage === 0)
83
        {
84
            return $this->_queryBuilder;
85
        }
86
87
        return $this->_queryBuilder->limit($this->_perPage)->offset(($this->_currentPage - 1) * $this->_perPage);
88
    }
89
90
    /**
91
     * @return int
92
     */
93 1
    public function pageCount(): int
94
    {
95 1
        if ($this->_perPage === 0)
96
        {
97
            return 1;
98
        }
99
100 1
        $queryCount = $this->getQueryCount();
101 1
        if ($queryCount < $this->_perPage)
102
        {
103
            return 1;
104
        }
105
106 1
        return (int) \floor($queryCount / $this->_perPage);
107
    }
108
109
    /**
110
     * @return null|string
111
     * @throws \RuntimeException
112
     */
113 1
    private function _getFirstPageUrl()
114
    {
115 1
        if ($this->_currentPage <= $this->_surroundingPages + 1)
116
        {
117 1
            return null;
118
        }
119
120
        return $this->_buildPageUrl(1);
121
    }
122
123
    /**
124
     * @return null|string
125
     * @throws \RuntimeException
126
     */
127 1
    private function _getPreviousPageUrl()
128
    {
129 1
        $previousPage = $this->_currentPage - 1;
130 1
        if ($previousPage < 1)
131
        {
132 1
            return null;
133
        }
134
135
        return $this->_buildPageUrl($previousPage);
136
    }
137
138
    /**
139
     * @return null|string
140
     * @throws \RuntimeException
141
     */
142 1
    private function _getNextPageUrl()
143
    {
144 1
        if ($this->_currentPage >= $this->pageCount())
145
        {
146
            return null;
147
        }
148
149 1
        return $this->_buildPageUrl($this->_currentPage + 1);
150
    }
151
152
    /**
153
     * @return null|string
154
     * @throws \RuntimeException
155
     */
156 1
    private function _getLastPageUrl()
157
    {
158 1
        $lastPage = $this->pageCount();
159 1
        if ($this->_currentPage + $this->_surroundingPages >= $lastPage)
160
        {
161
            return null;
162
        }
163
164 1
        return $this->_buildPageUrl($lastPage);
165
    }
166
167
    /**
168
     * Generate URL to jump to {$pageNumber}.
169
     *
170
     * @param int $pageNumber
171
     * @return string
172
     *
173
     * @throws \RuntimeException
174
     */
175 1
    private function _buildPageUrl(int $pageNumber): string
176
    {
177 1
        $parameters = UrlHelper::parameterizeQuery($this->_request->getQueryString());
178 1
        $parameters['page'] = $pageNumber;
179
180 1
        return $this->_request->url() . '?' . \http_build_query($parameters);
181
    }
182
183
    /**
184
     * Renders a list item with a page link.
185
     *
186
     * @param string $pagenumber
187
     * @param string $url
188
     * @param string|null $symbol
189
     *
190
     * @return string
191
     */
192 1
    private function _renderListItem(string $pagenumber, ? string $url, ? string $symbol = null) : string
193
    {
194 1
        if ($url === null)
195
        {
196 1
            return '';
197
        }
198
199 1
        if ($symbol === null)
200
        {
201 1
            $symbol = $pagenumber;
202
        }
203
204 1
        $class = '';
205 1
        if (+$pagenumber === $this->_currentPage)
206
        {
207 1
            $class = ' class="active"';
208
        }
209
210 1
        return '<li' . $class . '><a href="' . $url . '">' . $symbol . '</a></li>';
211
    }
212
213
    /**
214
     * Renders a list of pages.
215
     *
216
     * @return string
217
     * @throws \RuntimeException
218
     */
219 1
    private function _renderPageList(): string
220
    {
221 1
        $start = $this->_currentPage - $this->_surroundingPages;
222 1
        if ($start < 1)
223
        {
224 1
            $start = 1;
225
        }
226
227 1
        $pageCount = $this->pageCount();
228 1
        $end = $this->_currentPage + $this->_surroundingPages;
229 1
        if ($end > $pageCount)
230
        {
231
            $end = $pageCount;
232
        }
233
234 1
        $pageList = '';
235 1
        for ($i = $start; $i <= $end; $i++)
236
        {
237 1
            $pageList .= $this->_renderListItem($i, $this->_buildPageUrl($i));
238
        }
239
240 1
        return $pageList;
241
    }
242
243
    /**
244
     * Render the page links.
245
     *
246
     * @return string
247
     * @throws \RuntimeException
248
     */
249 1
    public function render(): string
250
    {
251 1
        if ($this->_perPage === 0)
252
        {
253
            return '';
254
        }
255
256
        return '<ul class="pagination">' .
257 1
                $this->_renderListItem($this->_currentPage - 1, $this->_getFirstPageUrl(), $this->_firstPageSymbol) .
258 1
                $this->_renderListItem($this->_currentPage - 1, $this->_getPreviousPageUrl(), $this->_previousPageSymbol) .
259 1
                $this->_renderPageList() .
260 1
                $this->_renderListItem($this->_currentPage + 1, $this->_getNextPageUrl(), $this->_nextPageSymbol) .
261 1
                $this->_renderListItem($this->_currentPage + 1, $this->_getLastPageUrl(), $this->_lastPageSymbol) .
262 1
                '</ul>';
263
    }
264
}