Completed
Push — development ( 67765c...7029e6 )
by Andrij
18:12
created

MY_Pagination   F

Complexity

Total Complexity 77

Size/Duplication

Total Lines 342
Duplicated Lines 18.13 %

Coupling/Cohesion

Components 0
Dependencies 0

Importance

Changes 0
Metric Value
dl 62
loc 342
rs 2.1739
c 0
b 0
f 0
wmc 77
lcom 0
cbo 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
F create_links() 41 175 46
F create_links_ajax() 21 148 30

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like MY_Pagination often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use MY_Pagination, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
if (!defined('BASEPATH')) {
4
    exit('No direct script access allowed');
5
}
6
7
class MY_Pagination extends CI_Pagination
8
{
0 ignored issues
show
introduced by
Opening brace of a class must be on the same line as the definition
Loading history...
9
10
    public $container = 'page';
11
12
    public function __construct() {
13
14
        parent::__construct();
15
        $this->first_link = '&lsaquo; ' . lang('First');
16
        $this->last_link = lang('Last') . ' &rsaquo;';
17
    }
18
19
    /**
20
     * Fix & -> ? first param
21
     * @return string
22
     */
23
    public function create_links() {
24
        // If our item count or per-page total is zero there is no need to continue.
25
        if ($this->total_rows == 0 OR $this->per_page == 0) {
26
            return '';
27
        }
28
29
        // Calculate the total number of pages
30
        $num_pages = ceil($this->total_rows / $this->per_page);
31
32
        // Is there only one page? Hm... nothing more to do here then.
33
        if ($num_pages == 1) {
34
            return '';
35
        }
36
37
        // Set the base page index for starting page number
38
        if ($this->use_page_numbers) {
39
            $base_page = 1;
40
        } else {
41
            $base_page = 0;
42
        }
43
44
        // Determine the current page number.
45
        $CI =& get_instance();
46
47 View Code Duplication
        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE) {
48
            if ($CI->input->get($this->query_string_segment) != $base_page) {
49
                $this->cur_page = $CI->input->get($this->query_string_segment);
50
51
                // Prep the current page - no funny business!
52
                $this->cur_page = (int) $this->cur_page;
53
            }
54
        } else {
55
            if ($CI->uri->segment($this->uri_segment) != $base_page) {
56
                $this->cur_page = $CI->uri->segment($this->uri_segment);
57
58
                // Prep the current page - no funny business!
59
                $this->cur_page = (int) $this->cur_page;
60
            }
61
        }
62
63
        // Set current page to 1 if using page numbers instead of offset
64
        if ($this->use_page_numbers AND $this->cur_page == 0) {
65
            $this->cur_page = $base_page;
66
        }
67
68
        $this->num_links = (int) $this->num_links;
69
70
        if ($this->num_links < 1) {
71
            show_error('Your number of links must be a positive number.');
72
        }
73
74
        if (!is_numeric($this->cur_page)) {
75
            $this->cur_page = $base_page;
76
        }
77
78
        // Is the page number beyond the result range?
79
        // If so we show the last page
80
        if ($this->use_page_numbers) {
81
            if ($this->cur_page > $num_pages) {
82
                $this->cur_page = $num_pages;
83
            }
84
        } else {
85
            if ($this->cur_page > $this->total_rows) {
86
                $this->cur_page = ($num_pages - 1) * $this->per_page;
87
            }
88
        }
89
90
        $uri_page_number = $this->cur_page;
91
92
        if (!$this->use_page_numbers) {
93
            $this->cur_page = floor(($this->cur_page / $this->per_page) + 1);
94
        }
95
96
        // Calculate the start and end numbers. These determine
97
        // which number to start and end the digit links with
98
        $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
99
        $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
100
101
        // Is pagination being used over GET or POST?  If get, add a per_page query
102
        // string. If post, add a trailing slash to the base URL if needed
103
        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE) {
104
            if (strpos($this->base_url, '?') === false) {
105
                $this->base_url = rtrim($this->base_url) . '?' . $this->query_string_segment . '=';
106
            } else {
107
                $this->base_url = rtrim($this->base_url) . '&amp;' . $this->query_string_segment . '=';
108
109
            }
110
        } else {
111
            $this->base_url = rtrim($this->base_url, '/') . '/';
112
        }
113
114
        // And here we go...
115
        $output = '';
116
117
        // Render the "First" link
118
        if ($this->first_link !== FALSE AND $this->cur_page > ($this->num_links + 1)) {
119
            $first_url = ($this->first_url == '') ? $this->base_url : $this->first_url;
120
            $output .= $this->first_tag_open . '<a ' . $this->anchor_class . 'href="' . $first_url . '">' . $this->first_link . '</a>' . $this->first_tag_close;
121
        }
122
123
        // Render the "previous" link
124
        if ($this->prev_link !== FALSE AND $this->cur_page != 1) {
125
            if ($this->use_page_numbers) {
126
                $i = $uri_page_number - 1;
127
            } else {
128
                $i = $uri_page_number - $this->per_page;
129
            }
130
131
            if ($i == 0 && $this->first_url != '') {
132
                $output .= $this->prev_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->first_url . '">' . $this->prev_link . '</a>' . $this->prev_tag_close;
133 View Code Duplication
            } else {
134
                $i = ($i == 0) ? '' : $this->prefix . $i . $this->suffix;
135
                $output .= $this->prev_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->base_url . $i . '">' . $this->prev_link . '</a>' . $this->prev_tag_close;
136
            }
137
138
        }
139
140
        // Render the pages
141
        if ($this->display_pages !== FALSE) {
142
            // Write the digit links
143
            for ($loop = $start - 1; $loop <= $end; $loop++) {
144
                if ($this->use_page_numbers) {
145
                    $i = $loop;
146
                } else {
147
                    $i = ($loop * $this->per_page) - $this->per_page;
148
                }
149
150
                if ($i >= $base_page) {
151
                    if ($this->cur_page == $loop) {
152
                        $output .= $this->cur_tag_open . $loop . $this->cur_tag_close; // Current page
153
                    } else {
154
                        $n = ($i == $base_page) ? '' : $i;
155
156
                        if ($n == '' && $this->first_url != '') {
157
                            $output .= $this->num_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->first_url . '">' . $loop . '</a>' . $this->num_tag_close;
158 View Code Duplication
                        } else {
159
                            $n = ($n == '') ? '' : $this->prefix . $n . $this->suffix;
160
161
                            $output .= $this->num_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->base_url . $n . '">' . $loop . '</a>' . $this->num_tag_close;
162
                        }
163
                    }
164
                }
165
            }
166
        }
167
168
        // Render the "next" link
169 View Code Duplication
        if ($this->next_link !== FALSE AND $this->cur_page < $num_pages) {
170
            if ($this->use_page_numbers) {
171
                $i = $this->cur_page + 1;
172
            } else {
173
                $i = ($this->cur_page * $this->per_page);
174
            }
175
176
            $output .= $this->next_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->base_url . $this->prefix . $i . $this->suffix . '">' . $this->next_link . '</a>' . $this->next_tag_close;
177
        }
178
179
        // Render the "Last" link
180 View Code Duplication
        if ($this->last_link !== FALSE AND ($this->cur_page + $this->num_links) < $num_pages) {
181
            if ($this->use_page_numbers) {
182
                $i = $num_pages;
183
            } else {
184
                $i = (($num_pages * $this->per_page) - $this->per_page);
185
            }
186
            $output .= $this->last_tag_open . '<a ' . $this->anchor_class . 'href="' . $this->base_url . $this->prefix . $i . $this->suffix . '">' . $this->last_link . '</a>' . $this->last_tag_close;
187
        }
188
189
        // Kill double slashes.  Note: Sometimes we can end up with a double slash
190
        // in the penultimate link so we'll kill all double slashes.
191
        $output = preg_replace('#([^:])//+#', "\\1/", $output);
192
193
        // Add the wrapper HTML if exists
194
        $output = $this->full_tag_open . $output . $this->full_tag_close;
195
196
        return $output;
197
    }
198
199
    public function create_links_ajax() {
200
201
        $CI = &get_instance();
202
203
        // If our item count or per-page total is zero there is no need to continue.
204
        if ($this->total_rows == 0 OR $this->per_page == 0) {
205
            return '';
206
        }
207
208
        // Calculate the total number of pages
209
        $num_pages = ceil($this->total_rows / $this->per_page);
210
211
        // Is there only one page? Hm... nothing more to do here then.
212
        if ($num_pages == 1) {
213
            return '';
214
        }
215
216
        // Determine the current page number.
217
        $CI = &get_instance();
218
219 View Code Duplication
        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE) {
220
            if ($CI->input->get($this->query_string_segment) != 0) {
221
                $this->cur_page = $CI->input->get($this->query_string_segment);
222
223
                // Prep the current page - no funny business!
224
                $this->cur_page = (int) $this->cur_page;
225
            }
226
        } else {
227
            if ($CI->uri->segment($this->uri_segment) != 0) {
228
                $this->cur_page = $CI->uri->segment($this->uri_segment);
229
230
                // Prep the current page - no funny business!
231
                $this->cur_page = (int) $this->cur_page;
232
            }
233
        }
234
235
        $this->num_links = (int) $this->num_links;
236
237
        if ($this->num_links < 1) {
238
            show_error('Your number of links must be a positive number.');
239
        }
240
241
        if (!is_numeric($this->cur_page)) {
242
            $this->cur_page = 0;
243
        }
244
245
        // Is the page number beyond the result range?
246
        // If so we show the last page
247
        if ($this->cur_page > $this->total_rows) {
248
            $this->cur_page = ($num_pages - 1) * $this->per_page;
249
        }
250
251
        $uri_page_number = $this->cur_page;
252
        $this->cur_page = floor(($this->cur_page / $this->per_page) + 1);
253
254
        // Calculate the start and end numbers. These determine
255
        // which number to start and end the digit links with
256
        $start = (($this->cur_page - $this->num_links) > 0) ? $this->cur_page - ($this->num_links - 1) : 1;
257
        $end = (($this->cur_page + $this->num_links) < $num_pages) ? $this->cur_page + $this->num_links : $num_pages;
258
259
        // Is pagination being used over GET or POST?  If get, add a per_page query
260
        // string. If post, add a trailing slash to the base URL if needed
261
        if ($CI->config->item('enable_query_strings') === TRUE OR $this->page_query_string === TRUE) {
262
            $this->base_url = rtrim($this->base_url) . '&' . $this->query_string_segment . '=';
263
        } else {
264
            $this->base_url = rtrim($this->base_url, '/') . '/';
265
        }
266
267
        // And here we go...
268
        $output = '';
269
270
        // Check for separated controls
271
        if ($this->separate_controls) {
272
            $controls_output = '';
273
        }
274
275
        // Render the "First" link
276 View Code Duplication
        if ($this->cur_page > $this->num_links) {
277
            $output .= $this->first_tag_open . '<a href="' . $this->base_url . 'offset' . '/' . $this->suffix . '">' . $this->first_link . '</a>' . $this->first_tag_close;
278
        }
279
280
        // Render the "previous" link
281
        if ($this->cur_page != 1) {
282
            $i = $uri_page_number - $this->per_page;
283
            if ($i == 0) {
284
                $i = 'offset';
285
            }
286
287
            if (!$this->separate_controls) {
288
                $output .= $this->prev_tag_open . '<a href="' . $this->base_url . $i . '/' . $this->suffix . '">' . $this->prev_link . '</a>' . $this->prev_tag_close;
289
            } else {
290
                $controls_output .= $this->prev_tag_open . '<a href="' . $this->base_url . $i . '/' . $this->suffix . '">' . $this->prev_link . '</a>' . $this->prev_tag_close;
291
            }
292
        } else {
293
            if ($this->separate_controls) {
294
                $controls_output .= str_replace('>', ' class="disabled">', $this->prev_tag_open) . '<span>' . $this->prev_link . '</span>' . $this->prev_tag_close;
295
            }
296
        }
297
298
        // Write the digit links
299
        for ($loop = $start - 1; $loop <= $end; $loop++) {
300
            $i = ($loop * $this->per_page) - $this->per_page;
301
302
            if ($i >= 0) {
303
                if ($this->cur_page == $loop) {
304
                    $output .= $this->cur_tag_open . $loop . $this->cur_tag_close; // Current page
305
                } else {
306
                    $n = ($i == 0) ? 'offset' : $i;
307
                    $output .= $this->num_tag_open . '<a href="' . $this->base_url . $n . '/' . $this->suffix . '">' . $loop . '</a>' . $this->num_tag_close;
308
                }
309
            }
310
        }
311
312
        // Render the "next" link
313
        if ($this->cur_page < $num_pages) {
314
            if (!$this->separate_controls) {
315
                $output .= $this->next_tag_open . '<a href="' . $this->base_url . ($this->cur_page * $this->per_page) . '/' . $this->suffix . '">' . $this->next_link . '</a>' . $this->next_tag_close;
316 View Code Duplication
            } else {
317
                $controls_output .= $this->next_tag_open . '<a href="' . $this->base_url . ($this->cur_page * $this->per_page) . '/' . $this->suffix . '">' . $this->next_link . '</a>' . $this->next_tag_close;
318
            }
319
        } else {
320
            if ($this->separate_controls) {
321
                $controls_output .= str_replace('>', ' class="disabled">', $this->next_tag_open) . '<span>' . $this->next_link . '</span>' . $this->next_tag_close;
322
            }
323
        }
324
325
        // Render the "Last" link
326
        if (($this->cur_page + $this->num_links) < $num_pages) {
327
            $i = (($num_pages * $this->per_page) - $this->per_page);
328
            $output .= $this->last_tag_open . '<a href="' . $this->base_url . $i . '/' . $this->suffix . '">' . $this->last_link . '</a>' . $this->last_tag_close;
329
        }
330
331
        // Kill double slashes.  Note: Sometimes we can end up with a double slash
332
        // in the penultimate link so we'll kill all double slashes.
333
        $output = preg_replace('#([^:])//+#', "\\1/", $output);
334
335
        // Add the wrapper HTML if exists
336
        $output = $this->full_tag_open . $output . $this->full_tag_close;
337
338
        if ($this->separate_controls) {
339
            $controls_output = preg_replace('#([^:])//+#', "\\1/", $controls_output);
340
            $controls_output = $this->controls_tag_open . $controls_output . $this->controls_tag_close;
341
342
            $output = $output . $controls_output;
343
        }
344
345
        return $output;
346
    }
347
348
}