Completed
Push — master ( 29f185...9200bf )
by Michael
18s
created

XoopsPageNav::renderNav()   D

Complexity

Conditions 20
Paths 25

Size

Total Lines 87
Code Lines 74

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 53
CRAP Score 27.3515

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 87
ccs 53
cts 72
cp 0.7361
rs 4.7294
cc 20
eloc 74
nc 25
nop 5
crap 27.3515

How to fix   Long Method    Complexity   

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
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
/**
13
 * XOOPS page navigation
14
 *
15
 * @copyright   XOOPS Project (http://xoops.org)
16
 * @license     GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
17
 * @package     class
18
 * @since       2.0.0
19
 * @author      Kazumi Ono (http://www.myweb.ne.jp/, http://jp.xoops.org/)
20
 * @version     $Id$
21
 */
22
23
class XoopsPageNav
24
{
25
    /**
26
     * *#@+
27
     *
28
     * @access private
29
     */
30
    /**
31
     * @var int
32
     */
33
    private $total;
34
35
    /**
36
     * @var int
37
     */
38
    private $perpage;
39
40
    /**
41
     * @var int
42
     */
43
    private $current;
44
45
    /**
46
     * @var string
47
     */
48
    private $extra;
49
50
    /**
51
     * @var string
52
     */
53
    private $url;
54
55
    /**
56
     * Constructor
57
     *
58
     * @param int    $total_items   Total number of items
59
     * @param int    $items_perpage Number of items per page
60
     * @param int    $current_start First item on the current page
61
     * @param string $start_name    Name for "start" or "offset"
62
     * @param string $extra_arg     Additional arguments to pass in the URL
63
     */
64 3
    public function __construct($total_items, $items_perpage, $current_start, $start_name = "start", $extra_arg = "")
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
65
    {
66 3
        $this->total = (int)($total_items);
67 3
        $this->perpage = (int)($items_perpage);
68 3
        $this->current = (int)($current_start);
69 3
        $this->extra = $extra_arg;
70 3
        if ($extra_arg != '' && (substr($extra_arg, - 5) !== '&amp;' || substr($extra_arg, - 1) !== '&')) {
71 1
            $this->extra = '&amp;' . $extra_arg;
72
        }
73 3
        $this->url = $_SERVER['PHP_SELF'] . '?' . trim($start_name) . '=';
74 3
    }
75
76
    /**
77
     * Create text navigation
78
     *
79
     * @param integer $offset    offset
80
     * @param string  $size      of pagination (Value: 'large', '', 'small', 'mini')
81
     * @param string  $align     of pagination (Value: 'right', 'centered')
82
     * @param string  $prev_text text for previous
83
     * @param string  $next_text text for next
84
     *
85
     * @return string
86
     */
87 2
    public function renderNav($offset = 4, $size = "", $align = "right", $prev_text = "&laquo;", $next_text = "&raquo;")
88
    {
89 2
        $xoops = Xoops::getInstance();
90 2
        $ret = '';
91 2
        $nav = array();
92 2
        if ($this->total <= $this->perpage) {
93
            return $ret;
94
        }
95 2
        if (($this->total != 0) && ($this->perpage != 0)) {
96 2
            $total_pages = ceil($this->total / $this->perpage);
97 2
            if ($total_pages > 1) {
98 2
                $prev = $this->current - $this->perpage;
99 2
                if ($prev >= 0) {
100
                    $xoops->tpl()->assign('prev_text', $prev_text);
101
                    $xoops->tpl()->assign('prev_url', $this->url . $prev . $this->extra);
102
                }
103 2
                $last = 0;
104 2
                $last_text = '';
105 2
                $last_url = '';
106 2
                $first = 0;
107 2
                $first_text = '';
108 2
                $first_url = '';
109 2
                $counter = 1;
110 2
                $current_page = (int)(floor(($this->current + $this->perpage) / $this->perpage));
111 2
                while ($counter <= $total_pages) {
112 2
                    if ($counter == $current_page) {
113 2
                        $nav['text'] = $counter;
114 2
                        $nav['url'] = '';
115 2
                        $nav['active'] = 0;
116 2
                    } elseif (($counter > $current_page - $offset && $counter < $current_page + $offset) || $counter == 1 || $counter == $total_pages) {
117 2
                        if ($counter == $total_pages && $current_page < $total_pages - $offset) {
118
                            $nav['text'] = '...';
119
                            $nav['url'] = '';
120
                            $nav['active'] = 0;
121
                            $last = 1;
122
                            $last_text = $counter;
123
                            $last_url = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
124
                        } else {
125 2
                            $nav['text'] = $counter;
126 2
                            $nav['url'] = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
127 2
                            $nav['active'] = 1;
128
                        }
129 2
                        if ($counter == 1 && $current_page > 1 + $offset) {
130
                            $nav['text'] = '...';
131
                            $nav['url'] = '';
132
                            $nav['active'] = 0;
133
                            $first = 1;
134
                            $first_text = $counter;
135
                            $first_url = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
136
                        }
137
                    }
138 2
                    $xoops->tpl()->appendByRef('xo_nav', $nav);
139 2
                    unset($nav);
140 2
                    ++$counter;
141
                }
142 2
                $xoops->tpl()->assign('last', $last);
143 2
                $xoops->tpl()->assign('last_text', $last_text);
144 2
                $xoops->tpl()->assign('last_url', $last_url);
145 2
                $xoops->tpl()->assign('first', $first);
146 2
                $xoops->tpl()->assign('first_text', $first_text);
147 2
                $xoops->tpl()->assign('first_url', $first_url);
148
149 2
                $next = $this->current + $this->perpage;
150 2
                if ($this->total > $next) {
151 2
                    $xoops->tpl()->assign('next_text', $next_text);
152 2
                    $xoops->tpl()->assign('next_url', $this->url . $next . $this->extra);
153
                }
154
            }
155
        }
156 2
        switch (strtolower($size)) {
157 2
            case 'large':
158
                $size = ' pagination-lg';
159
                break;
160 2
            case 'small':
161 2
            case 'mini':
162
                $size = ' pagination-sm';
163
                break;
164
            default:
165 2
                $size = '';
166
        }
167 2
        $xoops->tpl()->assign('size', $size);
168 2
        $xoops->tpl()->assign('align', ' pagination-' . $align);
169 2
        $xoops->tpl()->assign('pagination_nav', true);
170 2
        $ret = $xoops->tpl()->fetch('module:system/system_pagenav.tpl');
171 2
        $xoops->tpl()->clearAssign('xo_nav');
172 2
        return $ret;
173
    }
174
175
    /**
176
     * Create a navigational dropdown list
177
     *
178
     * @param boolean $showbutton Show the "Go" button?
179
     *
180
     * @return string|false
181
     */
182
    public function renderSelect($align = "right", $showbutton = false)
183
    {
184
        $xoops = Xoops::getInstance();
185
        $ret = '';
186
        if ($this->total < $this->perpage) {
187
            return $ret;
188
        }
189
        $total_pages = ceil($this->total / $this->perpage);
190
        if ($total_pages > 1) {
191
            $counter = 1;
192
            $current_page = (int)(floor(($this->current + $this->perpage) / $this->perpage));
193
            while ($counter <= $total_pages) {
194
                $select['text'] = $counter;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$select was never initialized. Although not strictly required by PHP, it is generally a good practice to add $select = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
195
                $select['value'] = $this->url . (($counter - 1) * $this->perpage) . $this->extra;
0 ignored issues
show
Bug introduced by
The variable $select does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
196
                if ($counter == $current_page) {
197
                    $select['selected'] = 1;
198
                } else {
199
                    $select['selected'] = 0;
200
                }
201
                $xoops->tpl()->appendByRef('xo_select', $select);
202
                unset($select);
203
                ++$counter;
204
            }
205
        }
206
        $xoops->tpl()->assign('onchange', "location=this.options[this.options.selectedIndex].value;");
207
        $xoops->tpl()->assign('pagination_select', true);
208
        $xoops->tpl()->assign('showbutton', $showbutton);
209
        $xoops->tpl()->assign('align', ' pagination-' . $align);
210
        $ret = $xoops->tpl()->fetch('module:system/system_pagenav.tpl');
211
        $xoops->tpl()->clearAssign('xo_select');
212
        return $ret;
213
    }
214
215
    /**
216
     * Create navigation with images
217
     *
218
     * @param integer $offset
219
     *
220
     * @return string
221
     */
222
    public function renderImageNav($offset = 4)
223
    {
224
        $xoops = Xoops::getInstance();
225
        $xoops->deprecated('renderImageNav() is deprecated since 2.6.0. Please use renderNav()');
226
        return $this->renderNav($offset);
227
    }
228
}
229