Passed
Pull Request — master (#49)
by
unknown
14:57
created

CycleDataPaginator::getCurrentPage()   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
namespace App;
4
5
use Closure;
6
use Countable;
7
use Cycle\ORM\Select;
8
use IteratorAggregate;
9
use Spiral\Database\Query\QueryInterface;
10
use Spiral\Pagination\PaginableInterface;
11
12
class CycleDataPaginator implements DataPaginatorInterface
13
{
14
    private int $count;
15
    private int $pagesCount = 1;
16
    private int $limit;
17
    private int $currentPage = 1;
18
    private array $pageTokens = [];
19
    private ?Closure $tokenGenerator = null;
20
    private object $dataQuery;
21
    private ?iterable $dataCache = null;
22
23
    /**
24
     * CycleDataPaginator constructor.
25
     * @param Select|QueryInterface $query
26
     * @param int $limit
27
     * @param int $count
28
     */
29
    public function __construct($query, int $limit = 25, int $count = 0)
30
    {
31
        $this->dataQuery = $query;
32
        if ($count > 0) {
33
            $this->count = $count;
34
        } elseif ($query instanceof Countable) {
35
            $this->count = $query->count();
36
        }
37
        $this->limit = max($limit, 1);
38
        $this->calcPages();
39
    }
40
    public function __clone()
41
    {
42
        $this->dataCache = null;
43
    }
44
45
    public function read(): iterable
46
    {
47
        if ($this->dataCache !== null) {
48
            return $this->dataCache;
49
        }
50
        $this->paginate();
51
        // if ($this->dataQuery instanceof IteratorAggregate) {
52
        //     return $this->dataQuery->getIterator();
53
        // }
54
        return $this->dataCache = $this->dataQuery->fetchAll();
55
    }
56
    public function getCurrentPageSize(): int
57
    {
58
        if ($this->dataCache instanceof Countable) {
59
            return $this->dataCache->count();
0 ignored issues
show
Bug introduced by
The method count() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

59
            return $this->dataCache->/** @scrutinizer ignore-call */ count();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
60
        }
61
        if ($this->pagesCount === 1) {
62
            return $this->count;
63
        }
64
        if ($this->currentPage === $this->pagesCount) {
65
            return $this->count - ($this->currentPage - 1) * $this->limit;
66
        }
67
        return $this->limit;
68
    }
69
    public function getItemsCount(): int
70
    {
71
        return $this->count;
72
    }
73
    public function withTokenGenerator(?Closure $closure): self
74
    {
75
        $paginator = clone $this;
76
        $paginator->tokenGenerator = $closure;
77
        return $paginator;
78
    }
79
    public function isOnLastPage(): bool
80
    {
81
        return $this->currentPage === $this->pagesCount;
82
    }
83
    public function isOnFirstPage(): bool
84
    {
85
        return $this->currentPage === 1;
86
    }
87
    public function getPageToken(int $page): ?string
88
    {
89
        if ($page < 1 || $page > $this->pagesCount) {
90
            return null;
91
        }
92
        if (isset($this->pageTokens[$this->limit][$page])) {
93
            return $this->pageTokens[$this->limit][$page];
94
        }
95
        return $this->tokenGenerator === null ? null : ($this->tokenGenerator)($page);
96
    }
97
    public function withPreviousPageToken(?string $token): self
98
    {
99
        $paginator = clone $this;
100
        $paginator->pageTokens[$paginator->limit][$paginator->currentPage - 1] = $token;
101
        return $paginator;
102
    }
103
    public function withNextPageToken(?string $token): self
104
    {
105
        $paginator = clone $this;
106
        $paginator->pageTokens[$paginator->limit][$paginator->currentPage + 1] = $token;
107
        return $paginator;
108
    }
109
    public function getPreviousPageToken(): ?string
110
    {
111
        return $this->getPageToken($this->currentPage - 1);
112
    }
113
    public function getNextPageToken(): ?string
114
    {
115
        return $this->getPageToken($this->currentPage + 1);
116
    }
117
    public function withCurrentPage(int $num): self
118
    {
119
        $paginator = clone $this;
120
        $paginator->currentPage = max(1, min($num, $this->pagesCount));
121
        return $paginator;
122
    }
123
    public function withPageSize(int $limit): self
124
    {
125
        $paginator = clone $this;
126
        $paginator->limit = max($limit, 1);
127
        $paginator->calcPages();
128
        return $paginator;
129
    }
130
    public function getPageSize(): int
131
    {
132
        return $this->limit;
133
    }
134
    public function getCurrentPage(): int
135
    {
136
        return $this->currentPage;
137
    }
138
    public function getTotalPages(): int
139
    {
140
        return $this->pagesCount;
141
    }
142
    public function getOffset(): int
143
    {
144
        return ($this->currentPage - 1) * $this->limit;
145
    }
146
147
    private function calcPages(): self
148
    {
149
        $this->pagesCount = $this->count > 0
150
            ? (int)ceil($this->count / $this->limit)
151
            : $this->pagesCount = 1;
152
        return $this;
153
    }
154
    private function paginate(): self
155
    {
156
        $this->dataQuery = clone $this->dataQuery;
157
        $offset = $this->getOffset();
158
        if ($this->dataQuery instanceof PaginableInterface) {
159
            $this->dataQuery->limit($this->limit);
160
            $this->dataQuery->offset($offset);
161
        }
162
        return $this;
163
    }
164
}
165