Completed
Branch Gutenberg/event-attendees-bloc... (e27df5)
by
unknown
42:51 queued 28:10
created

Tickets_Admin_Page   B

Complexity

Total Complexity 52

Size/Duplication

Total Lines 313
Duplicated Lines 48.24 %

Coupling/Cohesion

Components 6
Dependencies 2

Importance

Changes 0
Metric Value
dl 151
loc 313
rs 7.44
c 0
b 0
f 0
wmc 52
lcom 6
cbo 2

19 Methods

Rating   Name   Duplication   Size   Complexity  
A _init_page_props() 0 7 1
A _ajax_hooks() 0 3 1
A _define_page_props() 10 11 1
A _set_page_routes() 0 48 3
A _set_page_config() 12 13 1
A _add_screen_options() 0 3 1
A _add_screen_options_default() 0 4 1
A _add_feature_pointers() 0 3 1
A load_scripts_styles() 0 3 1
A load_scripts_styles_default() 0 3 1
A admin_footer_scripts() 0 3 1
A admin_init() 0 3 1
A admin_notices() 0 3 1
A _set_list_table_views_default() 21 22 1
A _tickets_overview_list_table() 0 5 1
F get_default_tickets() 64 66 15
C _trash_or_restore_ticket() 26 41 12
B _delete_ticket() 18 29 7
A _delete_the_ticket() 0 8 1

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 Tickets_Admin_Page 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 Tickets_Admin_Page, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Tickets_Admin_Page class
4
 *
5
 * @package            Event Espresso
6
 * @subpackage         caffeinated/admin/new/tickets/Tickets_Admin_Page.core.php
7
 * @author             Darren Ethier
8
 *
9
 * ------------------------------------------------------------------------
10
 */
11
class Tickets_Admin_Page extends EE_Admin_Page
12
{
13
14
15
    protected function _init_page_props()
16
    {
17
        $this->page_slug = TICKETS_PG_SLUG;
18
        $this->page_label = TICKETS_LABEL;
19
        $this->_admin_base_url = TICKETS_ADMIN_URL;
20
        $this->_admin_base_path = TICKETS_ADMIN;
21
    }
22
23
24
    protected function _ajax_hooks()
25
    {
26
    }
27
28
29 View Code Duplication
    protected function _define_page_props()
30
    {
31
        $this->_admin_page_title = TICKETS_LABEL;
32
        $this->_labels = array(
33
            'buttons' => array(
34
                'add'    => __('Add New Default Ticket', 'event_espresso'),
35
                'edit'   => __('Edit Default Ticket', 'event_espresso'),
36
                'delete' => __('Delete Default Ticket', 'event_espresso'),
37
            ),
38
        );
39
    }
40
41
42
    protected function _set_page_routes()
43
    {
44
45
        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
46
            ? $this->_req_data['TKT_ID'] : 0;
47
48
        $this->_page_routes = array(
49
            'default'         => array(
50
                'func'       => '_tickets_overview_list_table',
51
                'capability' => 'ee_read_default_tickets',
52
            ),
53
            'trash_ticket'    => array(
54
                'func'       => '_trash_or_restore_ticket',
55
                'noheader'   => true,
56
                'args'       => array('trash' => true),
57
                'capability' => 'ee_delete_default_ticket',
58
                'obj_id'     => $tkt_id,
59
            ),
60
            'trash_tickets'   => array(
61
                'func'       => '_trash_or_restore_ticket',
62
                'noheader'   => true,
63
                'args'       => array('trash' => true),
64
                'capability' => 'ee_delete_default_tickets',
65
            ),
66
            'restore_ticket'  => array(
67
                'func'       => '_trash_or_restore_ticket',
68
                'noheader'   => true,
69
                'capability' => 'ee_delete_default_ticket',
70
                'obj_id'     => $tkt_id,
71
            ),
72
            'restore_tickets' => array(
73
                'func'       => '_trash_or_restore_ticket',
74
                'noheader'   => true,
75
                'capability' => 'ee_delete_default_tickets',
76
            ),
77
            'delete_ticket'   => array(
78
                'func'       => '_delete_ticket',
79
                'noheader'   => true,
80
                'capability' => 'ee_delete_default_ticket',
81
                'obj_id'     => $tkt_id,
82
            ),
83
            'delete_tickets'  => array(
84
                'func'       => '_delete_ticket',
85
                'noheader'   => true,
86
                'capability' => 'ee_delete_default_tickets',
87
            ),
88
        );
89
    }
90
91
92 View Code Duplication
    protected function _set_page_config()
93
    {
94
        $this->_page_config = array(
95
            'default' => array(
96
                'nav'           => array(
97
                    'label' => __('Default Tickets', 'event_espresso'),
98
                    'order' => 10,
99
                ),
100
                'list_table'    => 'Tickets_List_Table',
101
                'require_nonce' => false,
102
            ),
103
        );
104
    }
105
106
107
    protected function _add_screen_options()
108
    {
109
    }
110
111
    protected function _add_screen_options_default()
112
    {
113
        $this->_per_page_screen_option();
114
    }
115
116
117
    protected function _add_feature_pointers()
118
    {
119
    }
120
121
    public function load_scripts_styles()
122
    {
123
    }
124
125
    public function load_scripts_styles_default()
126
    {
127
    }
128
129
    public function admin_footer_scripts()
130
    {
131
    }
132
133
    public function admin_init()
134
    {
135
    }
136
137
    public function admin_notices()
138
    {
139
    }
140
141
142 View Code Duplication
    public function _set_list_table_views_default()
143
    {
144
        $this->_views = array(
145
            'all'     => array(
146
                'slug'        => 'all',
147
                'label'       => __('All', 'event_espresso'),
148
                'count'       => 0,
149
                'bulk_action' => array(
150
                    'trash_tickets' => __('Move to Trash', 'event_espresso'),
151
                ),
152
            ),
153
            'trashed' => array(
154
                'slug'        => 'trashed',
155
                'label'       => __('Trash', 'event_espresso'),
156
                'count'       => 0,
157
                'bulk_action' => array(
158
                    'restore_tickets' => __('Restore from Trash', 'event_espresso'),
159
                    'delete_tickets'  => __('Delete Permanently', 'event_espresso'),
160
                ),
161
            ),
162
        );
163
    }
164
165
166
    public function _tickets_overview_list_table()
167
    {
168
        $this->_search_btn_label = __('Tickets', 'event_espresso');
169
        $this->display_admin_list_table_page_with_no_sidebar();
170
    }
171
172
173 View Code Duplication
    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
174
    {
175
176
        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
177
        $order = empty($this->_req_data['order']) ? 'ASC' : $order;
0 ignored issues
show
Bug introduced by
The variable $order seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
178
179
        switch ($orderby) {
180
            case 'TKT_name':
181
                $orderby = array('TKT_name' => $order);
182
                break;
183
184
            case 'TKT_price':
185
                $orderby = array('TKT_price' => $order);
186
                break;
187
188
            case 'TKT_uses':
189
                $orderby = array('TKT_uses' => $order);
190
                break;
191
192
            case 'TKT_min':
193
                $orderby = array('TKT_min' => $order);
194
                break;
195
196
            case 'TKT_max':
197
                $orderby = array('TKT_max' => $order);
198
                break;
199
200
            case 'TKT_qty':
201
                $orderby = array('TKT_qty' => $order);
202
                break;
203
        }
204
205
        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
206
            ? $this->_req_data['paged'] : 1;
207
        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
208
            ? $this->_req_data['perpage'] : $per_page;
209
210
        $_where = array(
211
            'TKT_is_default' => 1,
212
            'TKT_deleted'    => $trashed,
213
        );
214
215
        $offset = ($current_page - 1) * $per_page;
216
        $limit = array($offset, $per_page);
217
218
        if (isset($this->_req_data['s'])) {
219
            $sstr = '%' . $this->_req_data['s'] . '%';
220
            $_where['OR'] = array(
221
                'TKT_name'        => array('LIKE', $sstr),
222
                'TKT_description' => array('LIKE', $sstr),
223
            );
224
        }
225
226
        $query_params = array(
227
            $_where,
228
            'order_by' => $orderby,
229
            'limit'    => $limit,
230
            'group_by' => 'TKT_ID',
231
        );
232
233
        if ($count) {
234
            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
235
        } else {
236
            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
237
        }
238
    }
239
240
241
    protected function _trash_or_restore_ticket($trash = false)
242
    {
243
        $success = 1;
244
245
        $TKT = EEM_Ticket::instance();
246
247
        // checkboxes?
248 View Code Duplication
        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
249
            // if array has more than one element then success message should be plural
250
            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
251
252
            // cycle thru the boxes
253
            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
0 ignored issues
show
Unused Code introduced by
The assignment to $value is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
254
                if ($trash) {
255
                    if (! $TKT->delete_by_ID($TKT_ID)) {
256
                        $success = 0;
257
                    }
258
                } else {
259
                    if (! $TKT->restore_by_ID($TKT_ID)) {
260
                        $success = 0;
261
                    }
262
                }
263
            }
264
        } else {
265
            // grab single id and trash
266
            $TKT_ID = absint($this->_req_data['TKT_ID']);
267
268
            if ($trash) {
269
                if (! $TKT->delete_by_ID($TKT_ID)) {
270
                    $success = 0;
271
                }
272
            } else {
273
                if (! $TKT->restore_by_ID($TKT_ID)) {
274
                    $success = 0;
275
                }
276
            }
277
        }
278
279
        $action_desc = $trash ? 'moved to the trash' : 'restored';
280
        $this->_redirect_after_action($success, 'Tickets', $action_desc, array());
281
    }
282
283
284
    protected function _delete_ticket()
285
    {
286
        $success = 1;
287
288
        $TKT = EEM_Ticket::instance();
0 ignored issues
show
Unused Code introduced by
$TKT 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...
289
290
        // checkboxes?
291 View Code Duplication
        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
292
            // if array has more than one element then success message should be plural
293
            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
294
295
            // cycle thru the boxes
296
            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
0 ignored issues
show
Unused Code introduced by
The assignment to $value is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
297
                // delete
298
                if (! $this->_delete_the_ticket($TKT_ID)) {
299
                    $success = 0;
300
                }
301
            }
302
        } else {
303
            // grab single id and trash
304
            $TKT_ID = absint($this->_req_data['TKT_ID']);
305
            if (! $this->_delete_the_ticket($TKT_ID)) {
306
                $success = 0;
307
            }
308
        }
309
310
        $action_desc = 'deleted';
311
        $this->_redirect_after_action($success, 'Tickets', $action_desc, array());
312
    }
313
314
315
    protected function _delete_the_ticket($TKT_ID)
316
    {
317
        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
318
319
        // delete all related prices first
320
        $tkt->delete_related_permanently('Price');
321
        return $tkt->delete_permanently();
322
    }
323
}
324