Completed
Push — master ( 48735e...1bc6cd )
by Mihail
02:17
created

SimplePagination::display()   C

Complexity

Conditions 7
Paths 6

Size

Total Lines 69
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 69
rs 6.9081
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
44
        $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...
45
46
        if ($lastPage <= 1) {
47
            return null;
48
        }
49
50
        // prevent hack-boy's any try
51
        if ($this->page > $lastPage) {
52
            return null;
53
        }
54
55
        $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...
56
        // more then 10 items in pagination
57
        if ($lastPage > 10) {
58
            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...
59
                // from start to 4
60
                $items = $this->generateItems(0, 4);
61
62
                // add "..." button
63
                $items[] = [
64
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
65
                ];
66
                // add middle page
67
                $middlePage = ceil($lastPage / 2);
68
                $items[] = [
69
                    'type' => 'link', 'link' => $this->setUrlPage($middlePage), 'text' => $middlePage + 1
70
                ];
71
                // add "..." button
72
                $items[] = [
73
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
74
                ];
75
                $items = Arr::merge($items, $this->generateItems($lastPage - 4, $lastPage));
76
            } else { // meanwhile on middle
77
                // generate 1-2 pages
78
                $items = $this->generateItems(0, 2);
79
80
                // add "..." button
81
                $items[] = [
82
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
83
                ];
84
85
                // add middle variance -3..mid..+3
86
                $items = Arr::merge($items, $this->generateItems($this->page - 3, $this->page + 3));
87
88
                // add "..." button
89
                $items[] = [
90
                    'type' => 'link', 'link' => '#', 'text' => '...', 'property' => ['class' => 'disabled']
91
                ];
92
93
                // add latest 2 items
94
                $items = Arr::merge($items, $this->generateItems($lastPage - 2, $lastPage));
95
            }
96
        } else { // less then 10 items in pagination
97
            $items = $this->generateItems(0, $lastPage);
98
        }
99
100
        return Listing::display([
101
            'type' => 'ul',
102
            'property' => $property,
103
            'items' => $items
104
        ]);
105
    }
106
107
    /**
108
     * Set GET param to property array
109
     * @param int|string $pageId
110
     * @return array
111
     */
112
    protected function setUrlPage($pageId)
113
    {
114
        $url = $this->url;
115
        switch (count($url)) { // check nulls if not set
116
            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...
117
                $url[1] = null;
118
                $url[2] = null;
119
                break;
120
            case 2:
121
                $url[2] = null;
122
                break;
123
        }
124
125
        // add page param if > 0
126
        if ((int)$pageId > 0) {
127
            // merge with ?page if query is not empty
128
            $url[3] = (Any::isArray($url[3]) ? Arr::merge($url[3], ['page' => $pageId]) : ['page' => $pageId]);
129
        }
130
131
        return $url;
132
    }
133
134
    /**
135
     * Generate item array to build pagination listing
136
     * @param int $start
137
     * @param int $end
138
     * @return array|null
139
     */
140
    protected function generateItems($start, $end)
141
    {
142
        // prevent any shit's
143
        if ($end <= $start) {
144
            return null;
145
        }
146
147
        $items = [];
148
        for ($i = $start; $i < $end; $i++) {
149
            $items[] = [
150
                'type' => 'link', 'link' => $this->setUrlPage($i), 'text' => $i + 1
151
            ];
152
        }
153
        return $items;
154
    }
155
}
156