Passed
Pull Request — master (#1115)
by Maxim
22:29
created

Paginator   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Test Coverage

Coverage 86.27%

Importance

Changes 0
Metric Value
wmc 22
eloc 40
dl 0
loc 127
ccs 44
cts 51
cp 0.8627
rs 10
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A withPage() 0 7 1
A withLimit() 0 6 1
A countDisplayed() 0 7 2
A count() 0 3 1
A getParameter() 0 3 1
A getLimit() 0 3 1
A countPages() 0 3 1
A nextPage() 0 7 2
A setCount() 0 6 2
A withCount() 0 3 1
A __construct() 0 6 1
A isRequired() 0 3 1
A getOffset() 0 3 1
A previousPage() 0 7 2
A paginate() 0 11 3
A getPage() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Pagination;
6
7
/**
8
 * Simple predictable paginator.
9
 */
10
final class Paginator implements PaginatorInterface, \Countable
11
{
12
    private int $pageNumber = 1;
13
    private int $countPages = 1;
14
    private int $count;
15
16 14
    public function __construct(
17
        private int $limit = 25,
18
        int $count = 0,
19
        private readonly ?string $parameter = null,
20
    ) {
21 14
        $this->setCount($count);
22
    }
23
24
    /**
25
     * Get parameter paginator depends on. Environment specific.
26
     */
27 1
    public function getParameter(): ?string
28
    {
29 1
        return $this->parameter;
30
    }
31
32 1
    public function withLimit(int $limit): self
33
    {
34 1
        $paginator = clone $this;
35 1
        $paginator->limit = $limit;
36
37 1
        return $paginator;
38
    }
39
40 2
    public function getLimit(): int
41
    {
42 2
        return $this->limit;
43
    }
44
45 7
    public function withPage(int $number): self
46
    {
47 7
        $paginator = clone $this;
48 7
        $paginator->pageNumber = \max($number, 0);
49
50
        //Real page number
51 7
        return $paginator;
52
    }
53
54 9
    public function withCount(int $count): self
55
    {
56 9
        return (clone $this)->setCount($count);
57
    }
58
59 9
    public function getPage(): int
60
    {
61
        return match (true) {
62 9
            $this->pageNumber < 1 => 1,
63 6
            $this->pageNumber > $this->countPages => $this->countPages,
64 9
            default => $this->pageNumber
65
        };
66
    }
67
68 6
    public function getOffset(): int
69
    {
70 6
        return ($this->getPage() - 1) * $this->limit;
71
    }
72
73
    public function paginate(PaginableInterface $target): PaginatorInterface
74
    {
75
        $paginator = clone $this;
76
        if ($target instanceof \Countable && $paginator->count === 0) {
77
            $paginator->setCount($target->count());
78
        }
79
80
        $target->limit($paginator->getLimit());
81
        $target->offset($paginator->getOffset());
82
83
        return $paginator;
84
    }
85
86 8
    public function count(): int
87
    {
88 8
        return $this->count;
89
    }
90
91 7
    public function countPages(): int
92
    {
93 7
        return $this->countPages;
94
    }
95
96 6
    public function countDisplayed(): int
97
    {
98 6
        if ($this->getPage() === $this->countPages) {
99 4
            return $this->count - $this->getOffset();
100
        }
101
102 2
        return $this->limit;
103
    }
104
105 1
    public function isRequired(): bool
106
    {
107 1
        return ($this->countPages > 1);
108
    }
109
110 4
    public function nextPage(): ?int
111
    {
112 4
        if ($this->getPage() !== $this->countPages) {
113 3
            return $this->getPage() + 1;
114
        }
115
116 2
        return null;
117
    }
118
119 4
    public function previousPage(): ?int
120
    {
121 4
        if ($this->getPage() > 1) {
122 2
            return $this->getPage() - 1;
123
        }
124
125 3
        return null;
126
    }
127
128
    /**
129
     * Non-Immutable version of withCount.
130
     */
131 14
    private function setCount(int $count): self
132
    {
133 14
        $this->count = \max($count, 0);
134 14
        $this->countPages = $this->count > 0 ? (int)\ceil($this->count / $this->limit) : 1;
135
136 14
        return $this;
137
    }
138
}
139