Passed
Push — master ( 6eb156...b34d93 )
by Thierry
04:25
created

PaginationRenderer::getPages()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 7
nc 1
nop 1
dl 0
loc 12
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PaginationRenderer.php - Paginator renderer
5
 *
6
 * Render pagination links.
7
 *
8
 * @package jaxon-core
0 ignored issues
show
Coding Style introduced by
Package name "jaxon-core" is not valid; consider "Jaxoncore" instead
Loading history...
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2016 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
0 ignored issues
show
Coding Style introduced by
PHP version not specified
Loading history...
Coding Style introduced by
Missing @category tag in file comment
Loading history...
14
15
namespace Jaxon\Ui\Pagination;
16
17
use Jaxon\Request\Call\Call;
18
use Jaxon\Request\Call\Parameter;
19
use Jaxon\Ui\View\ViewRenderer;
20
use Jaxon\Ui\View\Store;
21
22
use function array_map;
23
use function array_pop;
24
use function array_shift;
25
use function array_walk;
26
use function floor;
27
28
class PaginationRenderer
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class PaginationRenderer
Loading history...
29
{
30
    /**
31
     * The template renderer.
32
     *
33
     * Will be used to render HTML code for links.
34
     *
35
     * @var ViewRenderer
36
     */
37
    protected $xRenderer = null;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
38
39
    /**
40
     * The Jaxon request to be paginated
41
     *
42
     * @var Call
43
     */
44
    protected $xCall = null;
45
46
    /**
47
     * @var string
48
     */
49
    protected $sPreviousText = '&laquo;';
50
51
    /**
52
     * @var string
53
     */
54
    protected $sNextText = '&raquo;';
55
56
    /**
57
     * @var string
58
     */
59
    protected $sEllipsysText = '...';
60
61
    /**
62
     * @var integer
63
     */
64
    protected $nTotalPages = 0;
65
66
    /**
67
     * @var integer
68
     */
69
    protected $nCurrentPage = 0;
70
71
    /**
72
     * @var integer
73
     */
74
    protected $nMaxPages = 10;
75
76
    /**
77
     * The class constructor
78
     *
79
     * @param ViewRenderer  $xRenderer
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter type; 2 found
Loading history...
Coding Style introduced by
Missing parameter comment
Loading history...
80
     */
81
    public function __construct(ViewRenderer $xRenderer)
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines before function; 1 found
Loading history...
82
    {
83
        $this->xRenderer = $xRenderer;
84
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
85
86
    /**
87
     * Set the text for the previous page link
88
     *
89
     * @param string $sText    The text for the previous page link
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
90
     *
91
     * @return void
92
     */
93
    public function setPreviousText(string $sText)
94
    {
95
        $this->sPreviousText = $sText;
96
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
97
98
    /**
99
     * Set the text for the next page link
100
     *
101
     * @param string $sText    The text for the previous page link
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
102
     *
103
     * @return void
104
     */
105
    public function setNextText(string $sText)
106
    {
107
        $this->sNextText = $sText;
108
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
109
110
    /**
111
     * Set the request to be paginated
112
     *
113
     * @param Call $xCall    The request to be paginated
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
114
     *
115
     * @return void
116
     */
117
    public function setRequest(Call $xCall)
118
    {
119
        $this->xCall = $xCall;
120
        // Append the page number to the parameter list, if not yet given.
121
        if(!$this->xCall->hasPageNumber())
122
        {
123
            $this->xCall->addParameter(Parameter::PAGE_NUMBER, 0);
124
        }
125
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
126
127
    /**
128
     * Set the current page number
129
     *
130
     * @param int $nCurrentPage    The current page number
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
131
     *
132
     * @return void
133
     */
134
    public function setCurrentPage(int $nCurrentPage)
135
    {
136
        $this->nCurrentPage = $nCurrentPage;
137
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
138
139
    /**
140
     * Set the max number of pages to show
141
     *
142
     * @param int $nMaxPages    The max number of pages to show
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
143
     *
144
     * @return void
145
     */
146
    public function setMaxPages(int $nMaxPages)
147
    {
148
        $this->nMaxPages = $nMaxPages;
149
        if($this->nMaxPages < 4)
150
        {
151
            $this->nMaxPages = 4;
152
        }
153
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
154
155
    /**
156
     * Get the js call to a given page
157
     *
158
     * @param int $pageNum    The page number
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
159
     *
160
     * @return string
161
     */
162
    protected function getPageCall(int $pageNum): string
163
    {
164
        return $this->xCall->setPageNumber($pageNum)->getScript();
165
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
166
167
    /**
168
     * Render a link to a page.
169
     *
170
     * @param string $sTemplate    The template for the link to the page
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
171
     * @param string $sText    The text of the link if it is enabled
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
172
     * @param string $sCall    The call of the link if it is enabled
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 4 found
Loading history...
173
     *
174
     * @return null|Store
175
     */
176
    protected function renderLink(string $sTemplate, string $sText, string $sCall): ?Store
177
    {
178
        return $this->xRenderer->render('pagination::links/' . $sTemplate, [
179
            'text' => $sText,
180
            'call' => $sCall,
181
        ]);
182
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
183
184
    /**
185
     * Get the previous page data.
186
     *
187
     * @return array
188
     */
189
    protected function getPrevLink(): array
190
    {
191
        if($this->nCurrentPage <= 1)
192
        {
193
            return ['disabled', $this->sPreviousText, ''];
194
        }
195
        return ['enabled', $this->sPreviousText, $this->getPageCall($this->nCurrentPage - 1)];
196
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
197
198
    /**
199
     * Get the next page data.
200
     *
201
     * @return array
202
     */
203
    protected function getNextLink(): array
204
    {
205
        if($this->nCurrentPage >= $this->nTotalPages)
206
        {
207
            return ['disabled', $this->sNextText, ''];
208
        }
209
        return ['enabled', $this->sNextText, $this->getPageCall($this->nCurrentPage + 1)];
210
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
211
212
    /**
213
     * Get a page data.
214
     *
215
     * @param integer $nNumber    The page number
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
216
     *
217
     * @return array
218
     */
219
    protected function getPageLink(int $nNumber): array
220
    {
221
        if($nNumber < 1)
222
        {
223
            return ['disabled', $this->sEllipsysText, ''];
224
        }
225
        $sTemplate = ($nNumber === $this->nCurrentPage ? 'current' : 'enabled');
226
        return [$sTemplate, $nNumber, $this->getPageCall($nNumber)];
227
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
228
229
    /**
230
     * Get the array of page numbers to be printed.
231
     *
232
     * Example: [1, 0, 4, 5, 6, 0, 10]
233
     *
234
     * @return array
235
     */
236
    protected function getPageNumbers(): array
237
    {
238
        $aPageNumbers = [];
239
240
        if($this->nTotalPages <= $this->nMaxPages)
241
        {
242
            for($i = 0; $i < $this->nTotalPages; $i++)
243
            {
244
                $aPageNumbers[] = $i + 1;
245
            }
246
247
            return $aPageNumbers;
248
        }
249
250
        // Determine the sliding range, centered around the current page.
251
        $nNumAdjacents = (int)floor(($this->nMaxPages - 4) / 2);
252
253
        $nSlidingStart = 1;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
254
        $nSlidingEndOffset = $nNumAdjacents + 3 - $this->nCurrentPage;
255
        if($nSlidingEndOffset < 0)
256
        {
257
            $nSlidingStart = $this->nCurrentPage - $nNumAdjacents;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 5 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
258
            $nSlidingEndOffset = 0;
259
        }
260
261
        $nSlidingEnd = $this->nTotalPages;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
262
        $nSlidingStartOffset = $this->nCurrentPage + $nNumAdjacents + 2 - $this->nTotalPages;
263
        if($nSlidingStartOffset < 0)
264
        {
265
            $nSlidingEnd = $this->nCurrentPage + $nNumAdjacents;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 9 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
266
            $nSlidingStartOffset = 0;
267
        }
268
269
        // Build the list of page numbers.
270
        if($nSlidingStart > 1)
271
        {
272
            $aPageNumbers[] = 1;
273
            $aPageNumbers[] = 0; // Ellipsys;
274
        }
275
        for($i = $nSlidingStart - $nSlidingStartOffset; $i <= $nSlidingEnd + $nSlidingEndOffset; $i++)
276
        {
277
            $aPageNumbers[] = $i;
278
        }
279
        if($nSlidingEnd < $this->nTotalPages)
280
        {
281
            $aPageNumbers[] = 0; // Ellipsys;
282
            $aPageNumbers[] = $this->nTotalPages;
283
        }
284
285
        return $aPageNumbers;
286
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
287
288
    /**
289
     * Get the pages.
290
     *
291
     * @param integer $nTotalPages    The total number of pages
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
292
     *
293
     * @return array
294
     */
295
    public function getPages(int $nTotalPages): array
296
    {
297
        $this->nTotalPages = $nTotalPages;
298
299
        $aPageNumbers = $this->getPageNumbers();
300
        $aPages = [$this->getPrevLink()];
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 7 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
301
        array_walk($aPageNumbers, function($nNumber) use(&$aPages) {
302
            $aPages[] = $this->getPageLink($nNumber);
303
        });
304
        $aPages[] = $this->getNextLink();
305
306
        return $aPages;
307
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 1 found
Loading history...
308
309
    /**
310
     * Render an HTML pagination control.
311
     *
312
     * @param integer $nTotalPages    The total number of pages
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 4 found
Loading history...
313
     *
314
     * @return null|Store
315
     */
316
    public function render(int $nTotalPages): ?Store
317
    {
318
        $aLinks = array_map(function($aPage) {
319
            return $this->renderLink($aPage[0], $aPage[1], $aPage[2]);
320
        }, $this->getPages($nTotalPages));
321
322
        $aPrevLink = array_shift($aLinks); // The first entry in the array
323
        $aNextLink = array_pop($aLinks); // The last entry in the array
324
        return $this->xRenderer->render('pagination::wrapper',
325
            ['links' => $aLinks, 'prev' => $aPrevLink, 'next' => $aNextLink]);
326
    }
0 ignored issues
show
Coding Style introduced by
Expected 2 blank lines after function; 0 found
Loading history...
327
}
328