Completed
Push — master ( c9b7ea...c1fd74 )
by Mihail
02:38
created

SimplePagination::display()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 66
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 66
rs 7.0832
cc 7
eloc 34
nc 6
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Ffcms\Core\Helper\HTML;
4
5
use Ffcms\Core\Helper\Type\Any;
6
use Ffcms\Core\Helper\Type\Arr;
7
use Ffcms\Core\Helper\Type\Obj;
8
9
/**
10
 * Class SimplePagination. Build and display html pagination block
11
 * @package Ffcms\Core\Helper\HTML
12
 */
13
class SimplePagination
14
{
15
    protected $url;
16
    protected $page;
17
    protected $step;
18
    protected $total;
19
20
    /**
21
     * SimplePagination constructor. Parse passed elements
22
     * @param array $elements
23
     */
24
    public function __construct(array $elements)
25
    {
26
        $this->url = $elements['url'];
27
        $this->page = (int)$elements['page'];
28
        $this->step = (int)$elements['step'] > 0 ? (int)$elements['step'] : 5;
29
        $this->total = (int)$elements['total'];
30
    }
31
32
    /**
33
     * Display pagination html code. Must be initialized via (new SimplePagination([params]))->display(['class' => 'test'])
34
     * @param array|null $property
35
     * @return null|string
36
     */
37
    public function display(array $property = null): ?string
38
    {
39
        // total items is less to pagination requirement
40
        if (($this->page * $this->step) + 1 > $this->total)
41
            return null;
42
43
        $lastPage = ceil($this->total / $this->step); // 6/5 ~ 2 = 0..2
0 ignored issues
show
Unused Code Comprehensibility introduced by
39% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
44
45
        if ($lastPage <= 1)
46
            return null;
47
48
        // prevent hack-boy's any try
49
        if ($this->page > $lastPage)
50
            return null;
51
52
        $items = [];
0 ignored issues
show
Unused Code introduced by
$items is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
53
        // more then 10 items in pagination
54
        if ($lastPage > 10) {
55
            if ($this->page < 4 || $lastPage - $this->page <= 4) { // list start, page in [0..4]
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
56
                // from start to 4
57
                $items = $this->generateItems(0, 4);
58
59
                // add "..." button
60
                $items[] = [
61
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
62
                ];
63
                // add middle page
64
                $middlePage = ceil($lastPage / 2);
65
                $items[] = [
66
                    'type' => 'link', 'link' => $this->setUrlPage($middlePage), 'text' => $middlePage + 1
67
                ];
68
                // add "..." button
69
                $items[] = [
70
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
71
                ];
72
                $items = Arr::merge($items, $this->generateItems($lastPage - 4, $lastPage));
73
            } else { // meanwhile on middle
74
                // generate 1-2 pages
75
                $items = $this->generateItems(0, 2);
76
77
                // add "..." button
78
                $items[] = [
79
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
80
                ];
81
82
                // add middle variance -3..mid..+3
83
                $items = Arr::merge($items, $this->generateItems($this->page - 3, $this->page + 3));
84
85
                // add "..." button
86
                $items[] = [
87
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
88
                ];
89
90
                // add latest 2 items
91
                $items = Arr::merge($items, $this->generateItems($lastPage - 2, $lastPage));
92
            }
93
        } else { // less then 10 items in pagination
94
            $items = $this->generateItems(0, $lastPage);
95
        }
96
97
        return Listing::display([
98
            'type' => 'ul',
99
            'property' => $property,
100
            'items' => $items
101
        ]);
102
    }
103
104
    /**
105
     * Set GET param to property array
106
     * @param int|string $pageId
107
     * @return array
108
     */
109
    protected function setUrlPage($pageId)
110
    {
111
        $url = $this->url;
112
        switch (count($url)) { // check nulls if not set
113
            case 1: // only controller/action is defined
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
114
                $url[1] = null;
115
                $url[2] = null;
116
                break;
117
            case 2:
118
                $url[2] = null;
119
                break;
120
        }
121
122
        // add page param if > 0
123
        if ((int)$pageId > 0) {
124
            // merge with ?page if query is not empty
125
            $url[3] = (Any::isArray($url[3]) ? Arr::merge($url[3], ['page' => $pageId]) : ['page' => $pageId]);
126
        }
127
128
        return $url;
129
    }
130
131
    /**
132
     * Generate item array to build pagination listing
133
     * @param int $start
134
     * @param int $end
135
     * @return array|null
136
     */
137
    protected function generateItems($start, $end)
138
    {
139
        // prevent any shit's
140
        if ($end <= $start)
141
            return null;
142
143
        $items = [];
144
        for ($i = $start; $i < $end; $i++) {
145
            $items[] = [
146
                'type' => 'link', 'link' => $this->setUrlPage($i), 'text' => $i + 1
147
            ];
148
        }
149
        return $items;
150
    }
151
}