Completed
Pull Request — master (#4194)
by Craig
20:07 queued 01:41
created

Paginator::getLastPage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 1
b 0
f 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula Foundation - https://ziku.la/
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Zikula\Bundle\CoreBundle\Doctrine;
15
16
use Doctrine\ORM\QueryBuilder as DoctrineQueryBuilder;
17
use Doctrine\ORM\Tools\Pagination\CountWalker;
18
use Doctrine\ORM\Tools\Pagination\Paginator as DoctrinePaginator;
19
20
/**
21
 * @author Javier Eguiluz <[email protected]>
22
 * Most of this file is copied from https://github.com/javiereguiluz/symfony-demo/blob/master/src/Pagination/Paginator.php
23
 *
24
 * usage:
25
 *     in Repository class:
26
 *         return (new Paginator($qb, $pageSize))->paginate($pageNumber);
27
 *     in controller:
28
 *         $latestPosts = $repository->getLatestPosts($criteria, $pageSize);
29
 *         return $this->render('blog/index.'.$_format.'.twig', [
30
 *             'paginator' => $latestPosts,
31
 *         ]);
32
 *     results in template {% for post in paginator.results %}
33
 *     include template: {{ include(paginator.template) }}
34
 */
35
class Paginator
36
{
37
    private const PAGE_SIZE = 25;
38
39
    private $queryBuilder;
40
41
    private $currentPage;
42
43
    private $pageSize;
44
45
    private $results;
46
47
    private $numResults;
48
49
    private $route;
50
51
    private $routeParameters;
52
53
    private $template = '@Core/Paginator/Paginator.html.twig';
54
55
    public function __construct(DoctrineQueryBuilder $queryBuilder, int $pageSize = self::PAGE_SIZE)
56
    {
57
        $this->queryBuilder = $queryBuilder;
58
        $this->pageSize = $pageSize;
59
    }
60
61
    public function paginate(int $page = 1): self
62
    {
63
        $this->currentPage = max(1, $page);
64
        $firstResult = ($this->currentPage - 1) * $this->pageSize;
65
66
        $query = $this->queryBuilder
67
            ->setFirstResult($firstResult)
68
            ->setMaxResults($this->pageSize)
69
            ->getQuery();
70
71
        if (0 === \count($this->queryBuilder->getDQLPart('join'))) {
72
            $query->setHint(CountWalker::HINT_DISTINCT, false);
73
        }
74
75
        $paginator = new DoctrinePaginator($query, true);
76
77
        $useOutputWalkers = \count($this->queryBuilder->getDQLPart('having') ?: []) > 0;
78
        $paginator->setUseOutputWalkers($useOutputWalkers);
79
80
        $this->results = $paginator->getIterator();
81
        $this->numResults = $paginator->count();
82
83
        return $this;
84
    }
85
86
    public function getCurrentPage(): int
87
    {
88
        return $this->currentPage;
89
    }
90
91
    public function getLastPage(): int
92
    {
93
        return (int) ceil($this->numResults / $this->pageSize);
94
    }
95
96
    public function getPageSize(): int
97
    {
98
        return $this->pageSize;
99
    }
100
101
    public function hasPreviousPage(): bool
102
    {
103
        return $this->currentPage > 1;
104
    }
105
106
    public function getPreviousPage(): int
107
    {
108
        return max(1, $this->currentPage - 1);
109
    }
110
111
    public function hasNextPage(): bool
112
    {
113
        return $this->currentPage < $this->getLastPage();
114
    }
115
116
    public function getNextPage(): int
117
    {
118
        return min($this->getLastPage(), $this->currentPage + 1);
119
    }
120
121
    public function hasToPaginate(): bool
122
    {
123
        return $this->numResults > $this->pageSize;
124
    }
125
126
    public function getNumResults(): int
127
    {
128
        return $this->numResults;
129
    }
130
131
    public function getResults(): \Traversable
132
    {
133
        return $this->results;
134
    }
135
136
    public function setRoute(string $route): self
137
    {
138
        $this->route = $route;
139
140
        return $this;
141
    }
142
143
    public function getRoute(): string
144
    {
145
        return $this->route;
146
    }
147
148
    public function setRouteParameters(array $parameters): self
149
    {
150
        $this->routeParameters = $parameters;
151
152
        return $this;
153
    }
154
155
    public function setRouteParameter(string $name, string $value): void
156
    {
157
        $this->routeParameters[$name] = $value;
158
    }
159
160
    public function getRouteParameters(): array
161
    {
162
        return $this->routeParameters;
163
    }
164
165
    public function setTemplate(string $templateName): void
166
    {
167
        $this->template = $templateName;
168
    }
169
170
    public function getTemplate(): string
171
    {
172
        return $this->template;
173
    }
174
}
175