Passed
Push — master ( 9e1161...5545f1 )
by Kirill
03:21
created

Paginator::getOffset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Pagination;
13
14
/**
15
 * Simple predictable paginator.
16
 */
17
final class Paginator implements PaginatorInterface, \Countable
18
{
19
    /** @var int */
20
    private $pageNumber = 1;
21
22
    /** @var int */
23
    private $countPages = 1;
24
25
    /** @var int */
26
    private $limit = 25;
27
28
    /** @var int */
29
    private $count = 0;
30
31
    /** @var string|null */
32
    private $parameter = null;
33
34
    /**
35
     * @param int         $limit
36
     * @param int         $count
37
     * @param string|null $parameter
38
     */
39
    public function __construct(int $limit = 25, int $count = 0, string $parameter = null)
40
    {
41
        $this->limit = $limit;
42
        $this->count = $count;
43
        $this->parameter = $parameter;
44
    }
45
46
    /**
47
     * Get parameter paginator depends on. Environment specific.
48
     *
49
     * @return null|string
50
     */
51
    public function getParameter(): ?string
52
    {
53
        return $this->parameter;
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     *
59
     * @return self
60
     */
61
    public function withLimit(int $limit): self
62
    {
63
        $paginator = clone $this;
64
        $paginator->limit = $limit;
65
66
        return $paginator;
67
    }
68
69
    /**
70
     * {@inheritdoc}
71
     */
72
    public function getLimit(): int
73
    {
74
        return $this->limit;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function withPage(int $number): self
81
    {
82
        $paginator = clone $this;
83
        $paginator->pageNumber = max($number, 0);
84
85
        //Real page number
86
        return $paginator;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     *
92
     * @return self
93
     */
94
    public function withCount(int $count): self
95
    {
96
        $paginator = clone $this;
97
98
        return $paginator->setCount($count);
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function getPage(): int
105
    {
106
        if ($this->pageNumber < 1) {
107
            return 1;
108
        }
109
110
        if ($this->pageNumber > $this->countPages) {
111
            return $this->countPages;
112
        }
113
114
        return $this->pageNumber;
115
    }
116
117
    /**
118
     * {@inheritdoc}
119
     */
120
    public function getOffset(): int
121
    {
122
        return ($this->getPage() - 1) * $this->limit;
123
    }
124
125
    /**
126
     * @inheritdoc
127
     */
128
    public function paginate(PaginableInterface $target): PaginatorInterface
129
    {
130
        $paginator = clone $this;
131
        if ($target instanceof \Countable && $paginator->count === 0) {
132
            $paginator->setCount($target->count());
133
        }
134
135
        $target->limit($paginator->getLimit());
136
        $target->offset($paginator->getOffset());
137
138
        return $paginator;
139
    }
140
141
    /**
142
     * @return int
143
     */
144
    public function count()
145
    {
146
        return $this->count;
147
    }
148
149
    /**
150
     * {@inheritdoc}
151
     */
152
    public function countPages(): int
153
    {
154
        return $this->countPages;
155
    }
156
157
    /**
158
     * {@inheritdoc}
159
     */
160
    public function countDisplayed(): int
161
    {
162
        if ($this->getPage() == $this->countPages) {
163
            return $this->count - $this->getOffset();
164
        }
165
166
        return $this->limit;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function isRequired(): bool
173
    {
174
        return ($this->countPages > 1);
175
    }
176
177
    /**
178
     * {@inheritdoc}
179
     */
180
    public function nextPage()
181
    {
182
        if ($this->getPage() != $this->countPages) {
183
            return $this->getPage() + 1;
184
        }
185
186
        return null;
187
    }
188
189
    /**
190
     * {@inheritdoc}
191
     */
192
    public function previousPage()
193
    {
194
        if ($this->getPage() > 1) {
195
            return $this->getPage() - 1;
196
        }
197
198
        return null;
199
    }
200
201
    /**
202
     * Non-Immutable version of withCount.
203
     *
204
     * @param int $count
205
     *
206
     * @return self|$this
207
     */
208
    private function setCount(int $count): self
209
    {
210
        $this->count = max($count, 0);
211
        if ($this->count > 0) {
212
            $this->countPages = (int)ceil($this->count / $this->limit);
213
        } else {
214
            $this->countPages = 1;
215
        }
216
217
        return $this;
218
    }
219
}
220