Passed
Push — master ( 1960ae...31e4ec )
by BENOIT
03:02
created

Pager::computeNbItems()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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