Pager::getOffset()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
1
<?php
2
3
namespace BenTools\Pager\Model;
4
5
use BenTools\Pager\Contract\PageInterface;
6
use BenTools\Pager\Contract\PagerInterface;
7
use BenTools\Pager\Contract\PageUrlBuilderInterface;
8
use BenTools\Pager\Model\Factory\PageParameterUrlBuilder;
9
use function BenTools\UriFactory\Helper\current_location;
10
11
final class Pager implements PagerInterface
12
{
13
    /**
14
     * @var int
15
     */
16
    private $perPage;
17
18
    /**
19
     * @var int
20
     */
21
    private $currentPageNumber;
22
23
    /**
24
     * @var int
25
     */
26
    private $numFound;
27
28
    /**
29
     * @var PageUrlBuilderInterface
30
     */
31
    private $urlBuilder;
32
33
    /**
34
     * Pager constructor.
35
     * @param int|null                     $perPage
36
     * @param int|null                     $currentPageNumber
37
     * @param int|null                     $numFound
38
     * @param PageUrlBuilderInterface|null $urlBuilder
39
     */
40
    public function __construct(int $perPage = null, int $currentPageNumber = null, int $numFound = null, PageUrlBuilderInterface $urlBuilder = null)
41
    {
42
        $this->perPage = $perPage ?? 0;
43
        $this->currentPageNumber = $currentPageNumber ?? 1;
44
        $this->numFound = $numFound ?? 0;
45
        $this->urlBuilder = $urlBuilder;
46
    }
47
48
    /**
49
     * @inheritDoc
50
     */
51
    public function count(): int
52
    {
53
        if (0 === $this->getPerPage()) {
54
            return 1;
55
        }
56
        return max(1, (int) ceil($this->getNumFound() / $this->getPerPage()));
57
    }
58
59
    /**
60
     * @inheritDoc
61
     */
62
    public function getIterator(): iterable
63
    {
64
        for ($nbPages = count($this), $pageNumber = 1; $pageNumber <= $nbPages; $pageNumber++) {
65
            yield $this->getPage($pageNumber);
66
        }
67
    }
68
69
    /**
70
     * @inheritdoc
71
     */
72
    public function asArray(): array
73
    {
74
        return iterator_to_array($this);
75
    }
76
77
    /**
78
     * @inheritdoc
79
     */
80
    public function getPage(int $pageNumber): PageInterface
81
    {
82
        $nbPages = count($this);
83
        return new Page($pageNumber, $this->computeNbItems($pageNumber, $nbPages));
84
    }
85
86
    /**
87
     * @inheritdoc
88
     */
89
    public function setCurrentPageNumber(int $currentPageNumber): PagerInterface
90
    {
91
        $this->currentPageNumber = max(0, $currentPageNumber);
92
        return $this;
93
    }
94
95
    /**
96
     * @inheritDoc
97
     */
98
    public function getCurrentPageNumber(): int
99
    {
100
        return $this->currentPageNumber;
101
    }
102
103
    /**
104
     * @inheritDoc
105
     */
106
    public function getNumFound(): int
107
    {
108
        return $this->numFound;
109
    }
110
111
    /**
112
     * @param int $numFound
113
     * @return Pager
114
     */
115
    public function setNumFound(int $numFound): PagerInterface
116
    {
117
        $this->numFound = max(0, $numFound);
118
        return $this;
119
    }
120
121
    /**
122
     * @inheritDoc
123
     */
124
    public function getPerPage(): int
125
    {
126
        return $this->perPage;
127
    }
128
129
    /**
130
     * @param int $perPage
131
     * @return Pager
132
     */
133
    public function setPerPage(int $perPage): PagerInterface
134
    {
135
        $this->perPage = max(0, $perPage);
136
        return $this;
137
    }
138
139
    /**
140
     * @inheritDoc
141
     */
142
    public function getOffset(): int
143
    {
144
        return ($this->getCurrentPageNumber() - 1) * $this->getPerPage();
145
    }
146
147
    /**
148
     * @inheritDoc
149
     */
150
    public function getCurrentPage(): PageInterface
151
    {
152
        return $this->getPage($this->getCurrentPageNumber());
153
    }
154
155
    /**
156
     * @inheritDoc
157
     */
158
    public function isCurrentPage(PageInterface $page): bool
159
    {
160
        return $page->getPageNumber() === $this->getCurrentPageNumber();
161
    }
162
163
    /**
164
     * @inheritDoc
165
     */
166
    public function getPreviousPage(): ?PageInterface
167
    {
168
        if (1 === $this->getCurrentPageNumber()) {
169
            return null;
170
        }
171
        return $this->getPage($this->getCurrentPageNumber() - 1);
172
    }
173
174
    /**
175
     * @inheritDoc
176
     */
177
    public function isPreviousPage(PageInterface $page): bool
178
    {
179
        return (-1 + $this->getCurrentPageNumber()) === $page->getPageNumber();
180
    }
181
182
    /**
183
     * @inheritDoc
184
     */
185
    public function getNextPage(): ?PageInterface
186
    {
187
        $nbPages = count($this);
188
        if ($nbPages === $this->getCurrentPageNumber()) {
189
            return null;
190
        }
191
        return $this->getPage($this->getCurrentPageNumber() + 1);
192
    }
193
194
    /**
195
     * @inheritDoc
196
     */
197
    public function isNextPage(PageInterface $page): bool
198
    {
199
        return (1 + $this->getCurrentPageNumber()) === $page->getPageNumber();
200
    }
201
202
    /**
203
     * @inheritDoc
204
     */
205
    public function getFirstPage(): PageInterface
206
    {
207
        return $this->getPage(1);
208
    }
209
210
    /**
211
     * @inheritDoc
212
     */
213
    public function isFirstPage(PageInterface $page): bool
214
    {
215
        return 1 === $page->getPageNumber();
216
    }
217
218
    /**
219
     * @inheritDoc
220
     */
221
    public function getLastPage(): PageInterface
222
    {
223
        return $this->getPage(count($this));
224
    }
225
226
    /**
227
     * @inheritDoc
228
     */
229
    public function isLastPage(PageInterface $page): bool
230
    {
231
        return count($this) === $page->getPageNumber();
232
    }
233
234
    /**
235
     * @inheritDoc
236
     */
237
    public function getPageOffset(PageInterface $page): int
238
    {
239
        return ($page->getPageNumber() - 1) * $this->getPerPage();
240
    }
241
242
    /**
243
     * @param PageUrlBuilderInterface|null $urlBuilder
244
     */
245
    public function setUrlBuilder(?PageUrlBuilderInterface $urlBuilder): void
246
    {
247
        $this->urlBuilder = $urlBuilder;
248
    }
249
250
    /**
251
     * @param PageInterface $page
252
     * @return string
253
     */
254
    public function getUrl(PageInterface $page): string
255
    {
256
        if (null === $this->urlBuilder) {
257
            $this->urlBuilder = new PageParameterUrlBuilder((string) current_location(), $this->perPage);
258
        }
259
        return $this->urlBuilder->buildUrl($this, $page);
260
    }
261
262
    /**
263
     * @param int $pageNumber
264
     * @param int $nbPages
265
     * @return int
266
     */
267
    private function computeNbItems(int $pageNumber, int $nbPages): int
268
    {
269
        if ($pageNumber > $nbPages) {
270
            return 0;
271
        }
272
273
        if ($pageNumber === $nbPages) {
274
            return ($this->getPerPage() - (($pageNumber * $this->getPerPage()) - $this->getNumFound()));
275
        }
276
277
        return $this->getPerPage();
278
    }
279
}
280