Passed
Push — feature/code_improvement ( c2d86d...84d6ec )
by Thierry
02:38
created

Paginator::getCurrentPageFirstItem()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 11
rs 9.9
c 0
b 0
f 0
1
<?php
2
0 ignored issues
show
Coding Style introduced by
You must use "/**" style comments for a file comment
Loading history...
3
/*
4
The MIT License (MIT)
0 ignored issues
show
Coding Style introduced by
First line of comment not aligned correctly; expected 4 spaces but found 0
Loading history...
5
6
Copyright (c) 2014 Jason Grimes
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
7
8
Permission is hereby granted, free of charge, to any person obtaining a copy
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
9
of this software and associated documentation files (the "Software"), to deal
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
10
in the Software without restriction, including without limitation the rights
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
11
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
12
copies of the Software, and to permit persons to whom the Software is
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
13
furnished to do so, subject to the following conditions:
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
14
15
The above copyright notice and this permission notice shall be included in all
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
16
copies or substantial portions of the Software.
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
17
18
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
19
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
20
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
21
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
22
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
23
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
24
SOFTWARE.
0 ignored issues
show
Coding Style introduced by
Comment line indented incorrectly; expected at least 4 spaces but found 0
Loading history...
25
*/
26
27
/**
28
 * Paginator.php - Jaxon Paginator
29
 *
30
 * Create pagination links from  an Jaxon request and a data array.
31
 *
32
 * @package jaxon-core
33
 * @author Jason Grimes
34
 * @author Thierry Feuzeu
35
 * @copyright 2014 Jason Grimes
36
 * @copyright 2016 Thierry Feuzeu
37
 * @license https://opensource.org/licenses/MIT MIT License
38
 * @link https://github.com/jaxon-php/jaxon-core
39
 */
40
41
namespace Jaxon\Utils\Pagination;
42
43
use Jaxon\Request\Factory\Request;
44
use Jaxon\Request\Factory\Parameter;
45
46
class Paginator
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class Paginator
Loading history...
47
{
48
    /**
49
     * @var integer
50
     */
51
    protected $totalItems = 0;
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line(s) before first member var; 0 found
Loading history...
52
53
    /**
54
     * @var integer
55
     */
56
    protected $numPages = 0;
57
58
    /**
59
     * @var integer
60
     */
61
    protected $itemsPerPage = 0;
62
63
    /**
64
     * @var integer
65
     */
66
    protected $currentPage = 0;
67
68
    /**
69
     * @var integer
70
     */
71
    protected $maxPagesToShow = 10;
72
73
    /**
74
     * @var string
75
     */
76
    protected $previousText = '&laquo;';
77
78
    /**
79
     * @var string
80
     */
81
    protected $nextText = '&raquo;';
82
83
    /**
84
     * The pagination renderer
85
     *
86
     * @var Renderer
87
     */
88
    protected $renderer = null;
89
90
    /**
91
     * The Jaxon request to be paginated
92
     *
93
     * @var Request
94
     */
95
    protected $request = null;
96
97
    /**
98
     * The constructor
99
     *
100
     * @param Renderer $renderer
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
101
     */
102
    public function __construct(Renderer $renderer)
103
    {
104
        $this->renderer = $renderer;
105
    }
106
107
    /**
108
     * Update the number of pages
109
     *
110
     * @return void
111
     */
112
    protected function updateNumPages()
113
    {
114
        $this->numPages = ($this->itemsPerPage == 0 ? 0 : (int)ceil($this->totalItems / $this->itemsPerPage));
115
    }
116
117
    /**
118
     * Set the max number of pages to show
119
     *
120
     * @param int $maxPagesToShow The max number of pages to show
121
     *
122
     * @return void
123
     * @throws \InvalidArgumentException if $maxPagesToShow is less than 3.
124
     */
125
    public function setMaxPagesToShow($maxPagesToShow)
126
    {
127
        if($maxPagesToShow < 4)
128
        {
129
            throw new \InvalidArgumentException('maxPagesToShow cannot be less than 4.');
130
        }
131
        $this->maxPagesToShow = $maxPagesToShow;
132
    }
133
134
    /**
135
     * Get the max number of pages to show
136
     *
137
     * @return int
138
     */
139
    public function getMaxPagesToShow()
140
    {
141
        return $this->maxPagesToShow;
142
    }
143
144
    /**
145
     * Set the current page number
146
     *
147
     * @param int $currentPage The current page number
148
     *
149
     * @return void
150
     */
151
    public function setCurrentPage($currentPage)
152
    {
153
        $this->currentPage = $currentPage;
154
    }
155
156
    /**
157
     * Get the current page number
158
     *
159
     * @return int
160
     */
161
    public function getCurrentPage()
162
    {
163
        return $this->currentPage;
164
    }
165
166
    /**
167
     * Set the number of items per page
168
     *
169
     * @param int $itemsPerPage The number of items per page
170
     *
171
     * @return void
172
     */
173
    public function setItemsPerPage($itemsPerPage)
174
    {
175
        $this->itemsPerPage = $itemsPerPage;
176
        $this->updateNumPages();
177
    }
178
179
    /**
180
     * Get the number of items per page
181
     *
182
     * @return int
183
     */
184
    public function getItemsPerPage()
185
    {
186
        return $this->itemsPerPage;
187
    }
188
189
    /**
190
     * Set the total number of items
191
     *
192
     * @param int $totalItems The total number of items
193
     *
194
     * @return void
195
     */
196
    public function setTotalItems($totalItems)
197
    {
198
        $this->totalItems = $totalItems;
199
        $this->updateNumPages();
200
    }
201
202
    /**
203
     * Get the total number of items
204
     *
205
     * @return int
206
     */
207
    public function getTotalItems()
208
    {
209
        return $this->totalItems;
210
    }
211
212
    /**
213
     * Get the total number of pages
214
     *
215
     * @return int
216
     */
217
    public function getNumPages()
218
    {
219
        return $this->numPages;
220
    }
221
222
    /**
223
     * Set the request to be paginated
224
     *
225
     * @param Request $request The request to be paginated
226
     *
227
     * @return void
228
     */
229
    public function setRequest(Request $request)
230
    {
231
        $this->request = $request;
232
        // Append the page number to the parameter list, if not yet given.
233
        if(($this->request) && !$this->request->hasPageNumber())
234
        {
235
            $this->request->addParameter(Parameter::PAGE_NUMBER, 0);
236
        }
237
    }
238
239
    /**
240
     * Get the request to be paginated
241
     *
242
     * @return Request
243
     */
244
    public function getRequest()
245
    {
246
        return $this->request;
247
    }
248
249
    /**
250
     * Setup the paginator
251
     *
252
     * @param int $totalItems The total number of items
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 3 spaces after parameter name; 1 found
Loading history...
253
     * @param int $itemsPerPage The number of items per page
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
254
     * @param int $currentPage The current page number
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter type; 1 found
Loading history...
Coding Style introduced by
Expected 2 spaces after parameter name; 1 found
Loading history...
255
     * @param Request $request The request to be paginated
0 ignored issues
show
Coding Style introduced by
Expected 6 spaces after parameter name; 1 found
Loading history...
256
     *
257
     * @return Paginator
258
     */
259
    public function setup($totalItems, $itemsPerPage, $currentPage, $request)
260
    {
261
        $this->setTotalItems($totalItems);
262
        $this->setItemsPerPage($itemsPerPage);
263
        $this->setCurrentPage($currentPage);
264
        $this->setRequest($request);
265
266
        return $this;
267
    }
268
269
    /**
270
     * Get the js call to a given page
271
     *
272
     * @param int $pageNum The page number
273
     *
274
     * @return string
275
     */
276
    public function getPageCall($pageNum)
277
    {
278
        return $this->request->setPageNumber($pageNum)->getScript();
279
    }
280
281
    /**
282
     * Get the next page number
283
     *
284
     * @return integer|null
285
     */
286
    public function getNextPage()
287
    {
288
        if($this->currentPage < $this->numPages)
289
        {
290
            return $this->currentPage + 1;
291
        }
292
        return null;
293
    }
294
295
    /**
296
     * Get the previous page number
297
     *
298
     * @return integer|null
299
     */
300
    public function getPrevPage()
301
    {
302
        if($this->currentPage > 1)
303
        {
304
            return $this->currentPage - 1;
305
        }
306
        return null;
307
    }
308
309
    /**
310
     * Get the js call to the next page
311
     *
312
     * @return string|null
313
     */
314
    public function getNextCall()
315
    {
316
        if(!$this->getNextPage())
317
        {
318
            return null;
319
        }
320
        return $this->getPageCall($this->getNextPage());
321
    }
322
323
    /**
324
     * Get the js call to the previous page
325
     *
326
     * @return string|null
327
     */
328
    public function getPrevCall()
329
    {
330
        if(!$this->getPrevPage())
331
        {
332
            return null;
333
        }
334
        return $this->getPageCall($this->getPrevPage());
335
    }
336
337
    /**
338
     * Get an array of paginated page data.
339
     *
340
     * Example:
341
     * [
342
     *     array ('num' => 1,     'call' => '/example/page/1',  'isCurrent' => false),
343
     *     array ('num' => '...', 'call' => NULL,               'isCurrent' => false),
344
     *     array ('num' => 3,     'call' => '/example/page/3',  'isCurrent' => false),
345
     *     array ('num' => 4,     'call' => '/example/page/4',  'isCurrent' => true ),
346
     *     array ('num' => 5,     'call' => '/example/page/5',  'isCurrent' => false),
347
     *     array ('num' => '...', 'call' => NULL,               'isCurrent' => false),
348
     *     array ('num' => 10,    'call' => '/example/page/10', 'isCurrent' => false),
349
     * ]
350
     *
351
     * @return array
352
     */
353
    public function getPages()
354
    {
355
        $pages = [];
356
357
        if($this->numPages <= 1)
358
        {
359
            return [];
360
        }
361
362
        if($this->numPages <= $this->maxPagesToShow)
363
        {
364
            for($i = 1; $i <= $this->numPages; $i++)
365
            {
366
                $pages[] = $this->createPage($i);
367
            }
368
        }
369
        else
370
        {
371
            // Determine the sliding range, centered around the current page.
372
            $numAdjacents = (int)floor(($this->maxPagesToShow - 4) / 2);
373
374
            $slidingStart = 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...
375
            $slidingEndOffset = $numAdjacents + 3 - $this->currentPage;
376
            if($slidingEndOffset < 0)
377
            {
378
                $slidingStart = $this->currentPage - $numAdjacents;
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...
379
                $slidingEndOffset = 0;
380
            }
381
382
            $slidingEnd = $this->numPages;
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...
383
            $slidingStartOffset = $this->currentPage + $numAdjacents + 2 - $this->numPages;
384
            if($slidingStartOffset < 0)
385
            {
386
                $slidingEnd = $this->currentPage + $numAdjacents;
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...
387
                $slidingStartOffset = 0;
388
            }
389
390
            // Build the list of pages.
391
            if($slidingStart > 1)
392
            {
393
                $pages[] = $this->createPage(1);
394
                $pages[] = $this->createPageEllipsis();
395
            }
396
            for($i = $slidingStart - $slidingStartOffset; $i <= $slidingEnd + $slidingEndOffset; $i++)
397
            {
398
                $pages[] = $this->createPage($i);
399
            }
400
            if($slidingEnd < $this->numPages)
401
            {
402
                $pages[] = $this->createPageEllipsis();
403
                $pages[] = $this->createPage($this->numPages);
404
            }
405
        }
406
407
        return $pages;
408
    }
409
410
411
    /**
412
     * Create a page data structure.
413
     *
414
     * @param int $pageNum
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
415
     *
416
     * @return array<string,integer|string|boolean>
417
     */
418
    protected function createPage($pageNum)
419
    {
420
        return [
421
            'num' => $pageNum,
422
            'call' => $this->getPageCall($pageNum),
423
            'isCurrent' => ($this->currentPage == $pageNum),
424
        ];
425
    }
426
427
    /**
428
     * Get the page ellipsis
429
     *
430
     * @return array<string,string|null|false>
431
     */
432
    protected function createPageEllipsis()
433
    {
434
        return [
435
            'num' => '...',
436
            'call' => null,
437
            'isCurrent' => false,
438
        ];
439
    }
440
441
    /**
442
     * Set the text for the previous page link
443
     *
444
     * @param string $text The text for the previous page link
445
     *
446
     * @return Paginator
447
     */
448
    public function setPreviousText($text)
449
    {
450
        $this->previousText = $text;
451
        return $this;
452
    }
453
454
    /**
455
     * Get the text for the previous page link
456
     *
457
     * @return string
458
     */
459
    public function getPreviousText()
460
    {
461
        return $this->previousText;
462
    }
463
464
    /**
465
     * Set the text for the next page link
466
     *
467
     * @param string $text The text for the previous page link
468
     *
469
     * @return Paginator
470
     */
471
    public function setNextText($text)
472
    {
473
        $this->nextText = $text;
474
        return $this;
475
    }
476
477
    /**
478
     * Get the text for the next page link
479
     *
480
     * @return string
481
     */
482
    public function getNextText()
483
    {
484
        return $this->nextText;
485
    }
486
487
    /**
488
     * Render an HTML pagination control.
489
     *
490
     * @return string
491
     */
492
    public function render()
493
    {
494
        if($this->getNumPages() <= 1)
495
        {
496
            return '';
497
        }
498
        return $this->renderer->render($this);
499
    }
500
501
    /**
502
     * Render an HTML pagination control.
503
     *
504
     * @return string
505
     */
506
    public function __toString()
507
    {
508
        return $this->render();
509
    }
510
}
511