Completed
Push — master ( 8400ab...233003 )
by
unknown
02:27
created

DefaultView::previous()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
3
/*
4
 * This file is part of the Pagerfanta package.
5
 *
6
 * (c) Pablo Díez <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Pagerfanta\View;
13
14
use Pagerfanta\PagerfantaInterface;
15
use Pagerfanta\View\Template\TemplateInterface;
16
use Pagerfanta\View\Template\DefaultTemplate;
17
18
/**
19
 * @author Pablo Díez <[email protected]>
20
 */
21
class DefaultView implements ViewInterface
22
{
23
    private $template;
24
25
    private $pagerfanta;
26
    private $proximity;
27
28
    private $currentPage;
29
    private $nbPages;
30
31
    private $startPage;
32
    private $endPage;
33
34 52
    public function __construct(TemplateInterface $template = null)
35
    {
36 52
        $this->template = $template ?: $this->createDefaultTemplate();
37 52
    }
38
39 11
    protected function createDefaultTemplate()
40
    {
41 11
        return new DefaultTemplate();
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 52
    public function render(PagerfantaInterface $pagerfanta, $routeGenerator, array $options = array())
48
    {
49 52
        $this->initializePagerfanta($pagerfanta);
50 52
        $this->initializeOptions($options);
51
52 52
        $this->configureTemplate($routeGenerator, $options);
53
54 52
        return $this->generate();
55
    }
56
57 52
    private function initializePagerfanta(PagerfantaInterface $pagerfanta)
58
    {
59 52
        $this->pagerfanta = $pagerfanta;
60
61 52
        $this->currentPage = $pagerfanta->getCurrentPage();
62 52
        $this->nbPages = $pagerfanta->getNbPages();
63 52
    }
64
65 52
    private function initializeOptions($options)
66
    {
67 52
        $this->proximity = isset($options['proximity']) ?
68 5
                           (int) $options['proximity'] :
69 47
                           $this->getDefaultProximity();
70 52
    }
71
72 11
    protected function getDefaultProximity()
73
    {
74 11
        return 2;
75
    }
76
77 52
    private function configureTemplate($routeGenerator, $options)
78
    {
79 52
        $this->template->setRouteGenerator($routeGenerator);
80 52
        $this->template->setOptions($options);
81 52
    }
82
83 52
    private function generate()
84
    {
85 52
        $pages = $this->generatePages();
86
87 52
        return $this->generateContainer($pages);
88
    }
89
90 52
    private function generateContainer($pages)
91
    {
92 52
        return str_replace('%pages%', $pages, $this->template->container());
93
    }
94
95 52
    private function generatePages()
96
    {
97 52
        $this->calculateStartAndEndPage();
98
99 52
        return $this->previous().
100 52
               $this->first().
101 52
               $this->secondIfStartIs3().
102 52
               $this->dotsIfStartIsOver3().
103 52
               $this->pages().
104 52
               $this->dotsIfEndIsUnder3ToLast().
105 52
               $this->secondToLastIfEndIs3ToLast().
106 52
               $this->last().
107 52
               $this->next();
108
    }
109
110 52
    private function calculateStartAndEndPage()
111
    {
112 52
        $startPage = $this->currentPage - $this->proximity;
113 52
        $endPage = $this->currentPage + $this->proximity;
114
115 52
        if ($this->startPageUnderflow($startPage)) {
116 11
            $endPage = $this->calculateEndPageForStartPageUnderflow($startPage, $endPage);
117 11
            $startPage = 1;
118
        }
119 52
        if ($this->endPageOverflow($endPage)) {
120 5
            $startPage = $this->calculateStartPageForEndPageOverflow($startPage, $endPage);
121 5
            $endPage = $this->nbPages;
122
        }
123
124 52
        $this->startPage = $startPage;
125 52
        $this->endPage = $endPage;
126 52
    }
127
128 52
    private function startPageUnderflow($startPage)
129
    {
130 52
        return $startPage < 1;
131
    }
132
133 52
    private function endPageOverflow($endPage)
134
    {
135 52
        return $endPage > $this->nbPages;
136
    }
137
138 11
    private function calculateEndPageForStartPageUnderflow($startPage, $endPage)
139
    {
140 11
        return min($endPage + (1 - $startPage), $this->nbPages);
141
    }
142
143 5
    private function calculateStartPageForEndPageOverflow($startPage, $endPage)
144
    {
145 5
        return max($startPage - ($endPage - $this->nbPages), 1);
146
    }
147
148 52
    private function previous()
149
    {
150 52
        if ($this->pagerfanta->hasPreviousPage()) {
151 41
            return $this->template->previousEnabled($this->pagerfanta->getPreviousPage());
152
        }
153
154 11
        return $this->template->previousDisabled();
155
    }
156
157 52
    private function first()
158
    {
159 52
        if ($this->startPage > 1) {
160 37
            return $this->template->first();
161
        }
162 15
    }
163
164 52
    private function secondIfStartIs3()
165
    {
166 52
        if ($this->startPage == 3) {
167 1
            return $this->template->page(2);
168
        }
169 51
    }
170
171 52
    private function dotsIfStartIsOver3()
172
    {
173 52
        if ($this->startPage > 3) {
174 31
            return $this->template->separator();
175
        }
176 21
    }
177
178 52
    private function pages()
179
    {
180 52
        $pages = '';
181
182 52
        foreach (range($this->startPage, $this->endPage) as $page) {
183 52
            $pages .= $this->page($page);
184
        }
185
186 52
        return $pages;
187
    }
188
189 52
    private function page($page)
190
    {
191 52
        if ($page == $this->currentPage) {
192 52
            return $this->template->current($page);
193
        }
194
195 52
        return $this->template->page($page);
196
    }
197
198 52
    private function dotsIfEndIsUnder3ToLast()
199
    {
200 52
        if ($this->endPage < $this->toLast(3)) {
201 37
            return $this->template->separator();
202
        }
203 15
    }
204
205 52
    private function secondToLastIfEndIs3ToLast()
206
    {
207 52
        if ($this->endPage == $this->toLast(3)) {
208 1
            return $this->template->page($this->toLast(2));
209
        }
210 51
    }
211
212 52
    private function toLast($n)
213
    {
214 52
        return $this->pagerfanta->getNbPages() - ($n - 1);
215
    }
216
217 52
    private function last()
218
    {
219 52
        if ($this->pagerfanta->getNbPages() > $this->endPage) {
220 43
            return $this->template->last($this->pagerfanta->getNbPages());
221
        }
222 9
    }
223
224 52
    private function next()
225
    {
226 52
        if ($this->pagerfanta->hasNextPage()) {
227 47
            return $this->template->nextEnabled($this->pagerfanta->getNextPage());
228
        }
229
230 5
        return $this->template->nextDisabled();
231
    }
232
233
    /**
234
     * {@inheritdoc}
235
     */
236
    public function getName()
237
    {
238
        return 'default';
239
    }
240
}
241
242
/*
243
244
CSS:
245
246
.pagerfanta {
247
}
248
249
.pagerfanta a,
250
.pagerfanta span {
251
    display: inline-block;
252
    border: 1px solid blue;
253
    color: blue;
254
    margin-right: .2em;
255
    padding: .25em .35em;
256
}
257
258
.pagerfanta a {
259
    text-decoration: none;
260
}
261
262
.pagerfanta a:hover {
263
    background: #ccf;
264
}
265
266
.pagerfanta .dots {
267
    border-width: 0;
268
}
269
270
.pagerfanta .current {
271
    background: #ccf;
272
    font-weight: bold;
273
}
274
275
.pagerfanta .disabled {
276
    border-color: #ccf;
277
    color: #ccf;
278
}
279
280
COLORS:
281
282
.pagerfanta a,
283
.pagerfanta span {
284
    border-color: blue;
285
    color: blue;
286
}
287
288
.pagerfanta a:hover {
289
    background: #ccf;
290
}
291
292
.pagerfanta .current {
293
    background: #ccf;
294
}
295
296
.pagerfanta .disabled {
297
    border-color: #ccf;
298
    color: #cf;
299
}
300
301
*/
302