Completed
Branch BUG-9774-email-validation (c72797)
by
unknown
680:01 queued 665:37
created

Extend_Events_Admin_Page   F

Complexity

Total Complexity 128

Size/Duplication

Total Lines 1159
Duplicated Lines 16.22 %

Coupling/Cohesion

Components 6
Dependencies 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 188
loc 1159
rs 0.6314
wmc 128
lcom 6
cbo 20

38 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
C _extend_page_config() 0 174 7
A admin_init() 0 13 1
A heartbeat_response() 0 11 2
A _add_screen_options_ticket_list_table() 0 3 1
A extra_permalink_field_buttons() 0 10 2
A _set_list_table_views_ticket_list_table() 21 21 1
A load_scripts_styles_edit() 0 14 1
A add_additional_datetime_button() 0 3 1
A add_datetime_clone_button() 0 3 1
A datetime_timezones_template() 0 3 1
B _set_list_table_views_default() 0 35 3
A _set_list_table_views_category_list() 0 4 1
B additional_legend_items() 9 18 5
D _duplicate_event() 14 153 18
A _import_page() 0 15 1
A _import_events() 0 6 1
B _events_export() 0 22 4
A _categories_export() 18 18 2
A _sample_export_file() 0 4 1
A _template_settings() 0 12 1
B _update_template_settings() 0 26 3
A _premium_event_editor_meta_boxes() 0 15 1
A registration_options_meta_box() 0 18 1
A event_type_meta_box() 0 5 1
C wp_terms_radio() 0 62 10
A list_table_filters() 0 19 4
B espresso_event_months_dropdown() 0 14 6
A active_status_dropdown() 0 7 1
A category_dropdown() 0 5 2
A total_events_today() 0 11 1
A total_events_this_month() 0 15 1
A _tickets_overview_list_table() 0 4 1
F get_default_tickets() 64 64 15
C _trash_or_restore_ticket() 26 40 13
C _delete_ticket() 18 36 8
A _delete_the_ticket() 0 7 1
A extra_list_table_actions() 18 21 3

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

1
<?php
2
if (!defined('EVENT_ESPRESSO_VERSION') )
3
	exit('NO direct script access allowed');
4
5
/**
6
 * Event Espresso
7
 *
8
 * Event Registration and Management Plugin for Wordpress
9
 *
10
 * @package		Event Espresso
11
 * @author		Seth Shoultes
12
 * @copyright	(c)2009-2012 Event Espresso All Rights Reserved.
13
 * @license		http://eventespresso.com/support/terms-conditions/  ** see Plugin Licensing **
14
 * @link		http://www.eventespresso.com
15
 * @version		4.0
16
 *
17
 * ------------------------------------------------------------------------
18
 *
19
 * Extend_Events_Admin_Page
20
 *
21
 * This is the Events Caffeinated admin page.
22
 *
23
 *
24
 * @package		Extend_Events_Admin_Page
25
 * @subpackage	includes/core/admin/Extend_Events_Admin_Page.core.php
26
 * @author		Darren Ethier
27
 *
28
 * ------------------------------------------------------------------------
29
 */
30
class Extend_Events_Admin_Page extends Events_Admin_Page {
31
32
33
	public function __construct( $routing = TRUE ) {
34
		parent::__construct( $routing );
35
		define( 'EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
36
		define( 'EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
37
		define( 'EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
38
	}
39
40
41
	protected function _extend_page_config() {
42
43
		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
44
		$default_espresso_boxes = $this->_default_espresso_metaboxes;
0 ignored issues
show
Unused Code introduced by
$default_espresso_boxes 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...
45
46
		//is there a evt_id in the request?
47
		$evt_id = ! empty( $this->_req_data['EVT_ID'] ) && ! is_array( $this->_req_data['EVT_ID'] ) ? $this->_req_data['EVT_ID'] : 0;
48
		$evt_id = ! empty( $this->_req_data['post'] ) ? $this->_req_data['post'] : $evt_id;
49
50
		//tkt_id?
51
		$tkt_id = !empty( $this->_req_data['TKT_ID'] ) && ! is_array( $this->_req_data['TKT_ID'] ) ? $this->_req_data['TKT_ID'] : 0;
52
53
		$new_page_routes = array(
54
			'duplicate_event' => array(
55
				'func' => '_duplicate_event',
56
				'capability' => 'ee_edit_event',
57
				'obj_id' => $evt_id,
58
				'noheader' => TRUE
59
				),
60
			'ticket_list_table' => array(
61
				'func' => '_tickets_overview_list_table',
62
				'capability' => 'ee_read_default_tickets'
63
				),
64
			'trash_ticket' => array(
65
				'func' => '_trash_or_restore_ticket',
66
				'capability' => 'ee_delete_default_ticket',
67
				'obj_id' => $tkt_id,
68
				'noheader' => TRUE,
69
				'args' => array( 'trash' => TRUE )
70
				),
71
			'trash_tickets' => array(
72
				'func' => '_trash_or_restore_ticket',
73
				'capability' => 'ee_delete_default_tickets',
74
				'noheader' => TRUE,
75
				'args' => array( 'trash' => TRUE )
76
				),
77
			'restore_ticket' => array(
78
				'func' => '_trash_or_restore_ticket',
79
				'capability' => 'ee_delete_default_ticket',
80
				'obj_id' => $tkt_id,
81
				'noheader' => TRUE
82
				),
83
			'restore_tickets' => array(
84
				'func' => '_trash_or_restore_ticket',
85
				'capability' => 'ee_delete_default_tickets',
86
				'noheader' => TRUE
87
				),
88
			'delete_ticket' => array(
89
				'func' => '_delete_ticket',
90
				'capability' => 'ee_delete_default_ticket',
91
				'obj_id' => $tkt_id,
92
				'noheader' => TRUE
93
				),
94
			'delete_tickets' => array(
95
				'func' => '_delete_ticket',
96
				'capability' => 'ee_delete_default_tickets',
97
				'noheader' => TRUE
98
				),
99
			'import_page'=> array(
100
				'func' => '_import_page',
101
				'capability' => 'import'
102
				),
103
			'import' => array(
104
				'func'=>'_import_events',
105
				'capability' => 'import',
106
				'noheader'=>TRUE,
107
				),
108
			'import_events' => array(
109
				'func'=>'_import_events',
110
				'capability' => 'import',
111
				'noheader'=>TRUE,
112
				),
113
			'export_events' => array(
114
				'func' => '_events_export',
115
				'capability' => 'export',
116
				'noheader' => true
117
			),
118
			'export_categories' => array(
119
				'func' => '_categories_export',
120
				'capability' => 'export',
121
				'noheader' => TRUE
122
				),
123
			'sample_export_file'=>array(
124
				'func'=>'_sample_export_file',
125
				'capability' => 'export',
126
				'noheader'=>TRUE
127
				),
128
			'update_template_settings' => array(
129
				'func' => '_update_template_settings',
130
				'capability' => 'manage_options',
131
				'noheader' => true
132
				)
133
			);
134
135
		$this->_page_routes = array_merge( $this->_page_routes, $new_page_routes );
136
137
138
		//partial route/config override
139
		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
140
		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
141
		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
142
		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
143
		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
144
		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
145
146
		//add tickets tab but only if there are more than one default ticket!
147
		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(array( array('TKT_is_default' => 1 ) ), 'TKT_ID', TRUE );
148
		if ( $tkt_count > 1 ) {
149
			$new_page_config = array(
150
				'ticket_list_table' => array(
151
					'nav' => array(
152
						'label' => __('Default Tickets', 'event_espresso'),
153
						'order' => 60
154
						),
155
					'list_table' => 'Tickets_List_Table',
156
					'require_nonce' => FALSE
157
					)
158
				);
159
		}
160
161
		//template settings
162
		$new_page_config['template_settings'] = array(
0 ignored issues
show
Bug introduced by
The variable $new_page_config 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...
163
			'nav' => array(
164
				'label' => __('Templates'),
165
				'order' => 30
166
			),
167
			'metaboxes' => array_merge( $this->_default_espresso_metaboxes, array( '_publish_post_box' ) ),
168
			'help_tabs' => array(
169
				'general_settings_templates_help_tab' => array(
170
					'title' => __('Templates', 'event_espresso'),
171
					'filename' => 'general_settings_templates'
172
				)
173
			),
174
			'help_tour' => array( 'Templates_Help_Tour' ),
175
			'require_nonce' => FALSE
176
		);
177
178
//		$new_page_config['import_page'] = array(
179
//				'nav' => array(
180
//					'label' => __('Import', 'event_espresso'),
181
//					'order' => 30
182
//				),
183
//				'help_tabs' => array(
184
//					'import_help_tab' => array(
185
//						'title' => __('Event Espresso Import', 'event_espresso'),
186
//						'filename' => 'import_page'
187
//						)
188
//					),
189
//				'help_tour' => array('Event_Import_Help_Tour'),
190
//				'metaboxes' => $default_espresso_boxes,
191
//				'require_nonce' => FALSE
192
//		);
193
		$this->_page_config = array_merge( $this->_page_config, $new_page_config );
194
195
		//add filters and actions
196
		//modifying _views
197
		add_filter('FHEE_event_datetime_metabox_add_additional_date_time_template', array( $this, 'add_additional_datetime_button' ), 10, 2 );
198
		add_filter('FHEE_event_datetime_metabox_clone_button_template', array( $this, 'add_datetime_clone_button' ), 10, 2 );
199
		add_filter('FHEE_event_datetime_metabox_timezones_template', array( $this, 'datetime_timezones_template'), 10, 2 );
200
201
202
		//filters for event list table
203
		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array( $this, 'list_table_filters'), 10, 2);
204
		add_filter('FHEE__Events_Admin_List_Table__column_actions__action_links', array( $this, 'extra_list_table_actions'), 10, 2 );
205
206
		//legend item
207
		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array( $this, 'additional_legend_items') );
208
209
		add_action('admin_init', array( $this, 'admin_init') );
210
211
		//heartbeat stuff
212
		add_filter( 'heartbeat_received', array( $this, 'heartbeat_response' ), 10, 2 );
213
214
	}
215
216
217
218
	/**
219
	 * admin_init
220
	 */
221
	public function admin_init() {
222
		EE_Registry::$i18n_js_strings = array_merge(
223
			EE_Registry::$i18n_js_strings,
224
			array(
225
				'image_confirm'          => __( 'Do you really want to delete this image? Please remember to update your event to complete the removal.', 'event_espresso' ),
226
				'event_starts_on'        => __( 'Event Starts on', 'event_espresso' ),
227
				'event_ends_on'          => __( 'Event Ends on', 'event_espresso' ),
228
				'event_datetime_actions' => __( 'Actions', 'event_espresso' ),
229
				'event_clone_dt_msg'     => __( 'Clone this Event Date and Time', 'event_espresso' ),
230
				'remove_event_dt_msg'    => __( 'Remove this Event Time', 'event_espresso' )
231
			)
232
		);
233
	}
234
235
236
237
	/**
238
	 * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle accordingly.
239
	 *
240
	 * @param array  $response The existing heartbeat response array.
241
	 * @param array  $data        The incoming data package.
242
	 *
243
	 * @return array  possibly appended response.
244
	 */
245
	public function heartbeat_response( $response, $data ) {
246
		/**
247
		 * check whether count of tickets is approaching the potential
248
		 * limits for the server.
249
		 */
250
		if ( ! empty( $data['input_count'] ) ) {
251
			$response['max_input_vars_check'] = EE_Registry::instance()->CFG->environment->max_input_vars_limit_check($data['input_count']);
252
		}
253
254
		return $response;
255
	}
256
257
258
259
	protected function _add_screen_options_ticket_list_table() {
260
		$this->_per_page_screen_option();
261
	}
262
263
264
265
	public function extra_permalink_field_buttons( $return, $id, $new_title, $new_slug ) {
266
		$return = parent::extra_permalink_field_buttons( $return, $id, $new_title, $new_slug );
267
		//make sure this is only when editing
268
		if ( !empty( $id ) ) {
269
			$href = EE_Admin_Page::add_query_args_and_nonce( array('action' => 'duplicate_event', 'EVT_ID' => $id), $this->_admin_base_url );
270
			$title = esc_attr__('Duplicate Event', 'event_espresso');
271
			$return .= '<a href="' . $href . '" title="' . $title . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">' . $title  . '</button>';
272
		}
273
		return $return;
274
	}
275
276
277
278
279 View Code Duplication
	public function _set_list_table_views_ticket_list_table() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
		$this->_views = array(
281
			'all' => array(
282
				'slug' => 'all',
283
				'label' => __('All', 'event_espresso'),
284
				'count' => 0,
285
				'bulk_action' => array(
286
					'trash_tickets' => __('Move to Trash', 'event_espresso')
287
					)
288
				),
289
			'trashed' => array(
290
				'slug' => 'trashed',
291
				'label' => __('Trash', 'event_espresso'),
292
				'count' => 0,
293
				'bulk_action' => array(
294
					'restore_tickets' => __('Restore from Trash' , 'event_espresso'),
295
					'delete_tickets' => __('Delete Permanently', 'event_espresso')
296
					)
297
				)
298
			);
299
	}
300
301
302
303
	public function load_scripts_styles_edit() {
304
		wp_register_script( 'ee-event-editor-heartbeat', EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js', array( 'ee_admin_js', 'heartbeat' ), EVENT_ESPRESSO_VERSION, TRUE );
305
306
		/**
307
		 * load accounting js.
308
		 */
309
		add_filter('FHEE_load_accounting_js', '__return_true');
310
311
		//styles
312
		wp_enqueue_style('espresso-ui-theme');
313
		wp_enqueue_script('event_editor_js');
314
		wp_enqueue_script('ee-event-editor-heartbeat');
315
316
	}
317
318
319
320
321
322
323
	public function add_additional_datetime_button( $template, $template_args ) {
324
		return EEH_Template::display_template( EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php', $template_args, TRUE);
325
	}
326
327
328
329
	public function add_datetime_clone_button( $template, $template_args ) {
330
		return EEH_Template::display_template( EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php', $template_args, TRUE );
331
	}
332
333
334
335
	public function datetime_timezones_template( $template, $template_args ) {
336
		return EEH_Template::display_template( EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php', $template_args, TRUE );
337
	}
338
339
340
341
342
	protected function _set_list_table_views_default() {
343
		parent::_set_list_table_views_default();
344
		$export_label = __('Export Events', 'event_espresso');
0 ignored issues
show
Unused Code introduced by
$export_label 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...
345
		if ( EE_Registry::instance()->CAP->current_user_can( 'export', 'espresso_events_export' ) ) {
346
//			$this->_views['all']['bulk_action']['export_events'] = $export_label;
347
//			$this->_views['draft']['bulk_action']['export_events'] = $export_label;
348
349
			if ( EE_Registry::instance()->CAP->current_user_can( 'ee_delete_events', 'espresso_events_trash_events' ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
350
//				$this->_views['trash']['bulk_action']['export_events'] = $export_label;
351
			}
352
		}
353
354
		$new_views = array(
355
			'today' => array(
356
				'slug' => 'today',
357
				'label' => __('Today', 'event_espresso'),
358
				'count' => $this->total_events_today(),
359
				'bulk_action' => array(
360
//					'export_events' => __('Export Events', 'event_espresso'),
361
					'trash_events' => __('Move to Trash', 'event_espresso')
362
				)
363
			),
364
			'month' => array(
365
				'slug' => 'month',
366
				'label' => __('This Month', 'event_espresso'),
367
				'count' => $this->total_events_this_month(),
368
				'bulk_action' => array(
369
//					'export_events' => __('Export Events', 'event_espresso'),
370
					'trash_events' => __('Move to Trash', 'event_espresso')
371
				)
372
			)
373
		);
374
375
		$this->_views = array_merge( $this->_views, $new_views);
376
	}
377
378
379
380
381
	protected function _set_list_table_views_category_list() {
382
		parent::_set_list_table_views_category_list();
383
//		$this->_views['all']['bulk_action']['export_categories'] = __('Export Categories', 'event_espresso');
384
	}
385
386
387
388
389
	public function extra_list_table_actions( $actionlinks, $event ) {
390 View Code Duplication
		if ( EE_Registry::instance()->CAP->current_user_can( 'ee_read_registrations', 'espresso_registrations_reports', $event->ID() ) ) {
391
			$reports_query_args = array(
392
					'action' => 'reports',
393
					'EVT_ID' => $event->ID()
394
				);
395
			$reports_link = EE_Admin_Page::add_query_args_and_nonce( $reports_query_args, REG_ADMIN_URL );
396
			$actionlinks[] = '<a href="' . $reports_link . '" title="' .  esc_attr__('View Report', 'event_espresso') . '"><div class="dashicons dashicons-chart-bar"></div></a>' . "\n\t";
397
		}
398 View Code Duplication
		if ( EE_Registry::instance()->CAP->current_user_can( 'ee_read_global_messages', 'view_filtered_messages' ) ) {
399
			EE_Registry::instance()->load_helper( 'MSG_Template' );
400
			$actionlinks[] = EEH_MSG_Template::get_message_action_link(
401
				'see_notifications_for',
402
				null,
403
				array(
404
					'EVT_ID' => $event->ID()
405
				)
406
			);
407
		}
408
		return $actionlinks;
409
	}
410
411
412
413
	public function additional_legend_items($items) {
414
		if ( EE_Registry::instance()->CAP->current_user_can( 'ee_read_registrations', 'espresso_registrations_reports' ) ) {
415
			$items['reports'] = array(
416
					'class' => 'dashicons dashicons-chart-bar',
417
					'desc' => __('Event Reports', 'event_espresso')
418
				);
419
		}
420 View Code Duplication
		if ( EE_Registry::instance()->CAP->current_user_can( 'ee_read_global_messages', 'view_filtered_messages' ) ) {
421
			$related_for_icon = EEH_MSG_Template::get_message_action_icon( 'see_notifications_for' );
422
			if ( isset( $related_for_icon['css_class']) && isset( $related_for_icon['label'] ) ) {
423
				$items['view_related_messages'] = array(
424
					'class' => $related_for_icon['css_class'],
425
					'desc' => $related_for_icon['label'],
426
				);
427
			}
428
		}
429
		return $items;
430
	}
431
432
433
434
	/**
435
	 * This is the callback method for the duplicate event route
436
	 *
437
	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
438
	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
439
	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
440
	 * After duplication the redirect is to the new event edit page.
441
	 * @return void
442
	 * @access protected
443
	 * @throws EE_Error If EE_Event is not available with given ID
444
	 */
445
	protected function _duplicate_event() {
446
		//first make sure the ID for the event is in the request.  If it isnt' then we need to bail and redirect back to overview list table (cause how did we get here?)
447
		if ( !isset( $this->_req_data['EVT_ID'] ) ) {
448
			EE_Error::add_error( __('In order to duplicate an event an Event ID is required.  None was given.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
449
			$this->_redirect_after_action( FALSE, '', '', array(), TRUE );
0 ignored issues
show
Documentation introduced by
FALSE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
450
			return;
451
		}
452
453
		//k we've got EVT_ID so let's use that to get the event we'll duplicate
454
		$orig_event = EEM_Event::instance()->get_one_by_ID( $this->_req_data['EVT_ID'] );
455
456
		if ( ! $orig_event instanceof EE_Event )
457
			throw new EE_Error( sprintf( __('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso '), $this->_req_data['EVT_ID'] ) );
458
459
		//k now let's clone the $orig_event before getting relations
460
		$new_event = clone $orig_event;
461
462
		//original datetimes
463
		$orig_datetimes = $orig_event->get_many_related('Datetime');
464
465
		//other original relations
466
		$orig_ven = $orig_event->get_many_related('Venue');
467
468
469
		//reset the ID and modify other details to make it clear this is a dupe
470
		$new_event->set( 'EVT_ID', 0 );
471
		$new_name = $new_event->name() . ' ' . __('**DUPLICATE**', 'event_espresso');
472
		$new_event->set( 'EVT_name',  $new_name );
473
		$new_event->set( 'EVT_slug',  wp_unique_post_slug( sanitize_title( $orig_event->name() ), 0, 'publish', 'espresso_events', 0 ) );
474
		$new_event->set( 'status', 'draft' );
475
476
		//duplicate discussion settings
477
		$new_event->set( 'comment_status', $orig_event->get('comment_status') );
478
		$new_event->set( 'ping_status', $orig_event->get( 'ping_status' ) );
479
480
		//save the new event
481
		$new_event->save();
482
483
		//venues
484
		foreach( $orig_ven as $ven ) {
485
			$new_event->_add_relation_to( $ven, 'Venue' );
486
		}
487
		$new_event->save();
488
489
490
		//now we need to get the question group relations and handle that
491
		//first primary question groups
492
		$orig_primary_qgs = $orig_event->get_many_related('Question_Group', array( array('Event_Question_Group.EQG_primary' => 1 ) ) );
493 View Code Duplication
		if ( !empty( $orig_primary_qgs ) ) {
494
			foreach ( $orig_primary_qgs as $id => $obj ) {
495
				if ( $obj instanceof EE_Question_Group ) {
496
					$new_event->_add_relation_to( $obj, 'Question_Group', array( 'EQG_primary' => 1 ) );
497
				}
498
			}
499
		}
500
501
		//next additional attendee question groups
502
		$orig_additional_qgs = $orig_event->get_many_related('Question_Group', array( array('Event_Question_Group.EQG_primary' => 0 ) ) );
503 View Code Duplication
		if ( !empty( $orig_additional_qgs ) ) {
504
			foreach ( $orig_additional_qgs as $id => $obj ) {
505
				if ( $obj instanceof EE_Question_Group ) {
506
					$new_event->_add_relation_to( $obj, 'Question_Group', array( 'EQG_primary' => 0 ) );
507
				}
508
			}
509
		}
510
511
		//now save
512
		$new_event->save();
513
514
515
		//k now that we have the new event saved we can loop through the datetimes and start adding relations.
516
		$cloned_tickets = array();
517
		foreach ( $orig_datetimes as $orig_dtt ) {
518
			$new_dtt = clone $orig_dtt;
519
			$orig_tkts = $orig_dtt->tickets();
0 ignored issues
show
Documentation Bug introduced by
The method tickets does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
520
521
			//save new dtt then add to event
522
			$new_dtt->set('DTT_ID', 0);
523
			$new_dtt->set('DTT_sold', 0);
524
			$new_dtt->save();
525
			$new_event->_add_relation_to( $new_dtt, 'Datetime');
526
			$new_event->save();
527
528
			//now let's get the ticket relations setup.
529
			foreach ( (array) $orig_tkts as $orig_tkt ) {
530
				//it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
531
				if ( ! $orig_tkt instanceof EE_Ticket )
532
					continue;
533
534
				//is this ticket archived?  If it is then let's skip
535
				if ( $orig_tkt->get( 'TKT_deleted' ) ) {
536
					continue;
537
				}
538
539
				//does this original ticket already exist in the clone_tickets cache?  If so we'll just use the new ticket from it.
540
				if ( isset( $cloned_tickets[$orig_tkt->ID()] ) ) {
541
					$new_tkt = $cloned_tickets[$orig_tkt->ID()];
542
				} else {
543
					$new_tkt = clone $orig_tkt;
544
					//get relations on the $orig_tkt that we need to setup.
545
					$orig_prices = $orig_tkt->prices();
546
					$new_tkt->set('TKT_ID', 0);
547
					$new_tkt->set('TKT_sold', 0);
548
549
					$new_tkt->save(); //make sure new ticket has ID.
550
551
					//price relations on new ticket need to be setup.
552
					foreach ( $orig_prices as $orig_price ) {
553
						$new_price = clone $orig_price;
554
						$new_price->set('PRC_ID', 0);
555
						$new_price->save();
556
						$new_tkt->_add_relation_to($new_price, 'Price');
557
						$new_tkt->save();
558
					}
559
				}
560
561
				//k now we can add the new ticket as a relation to the new datetime and make sure its added to our cached $cloned_tickets array for use with later datetimes that have the same ticket.
562
				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
563
				$new_dtt->save();
564
				$cloned_tickets[$orig_tkt->ID()] = $new_tkt;
565
			}
566
		}
567
568
		//clone taxonomy information
569
		$taxonomies_to_clone_with = apply_filters( 'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone', array( 'espresso_event_categories', 'espresso_event_type', 'post_tag' ) );
570
571
		//get terms for original event (notice)
572
		$orig_terms = wp_get_object_terms( $orig_event->ID(), $taxonomies_to_clone_with );
573
574
		//loop through terms and add them to new event.
575
		foreach ( $orig_terms as $term ) {
576
			wp_set_object_terms( $new_event->ID(), $term->term_id, $term->taxonomy, true );
577
		}
578
579
580
		do_action( 'AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event );
581
582
		//now let's redirect to the edit page for this duplicated event if we have a new event id.
583
		if ( $new_event->ID() ) {
584
			$redirect_args = array(
585
				'post' => $new_event->ID(),
586
				'action' => 'edit'
587
			);
588
			EE_Error::add_success( __('Event successfully duplicated.  Please review the details below and make any necessary edits', 'event_espresso') );
589
		} else {
590
			$redirect_args = array(
591
				'action' => 'default'
592
				);
593
			EE_Error::add_error( __('Not able to duplicate event.  Something went wrong.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
594
		}
595
596
		$this->_redirect_after_action(FALSE, '', '', $redirect_args, TRUE );
0 ignored issues
show
Documentation introduced by
FALSE is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
597
	}
598
599
600
601
	protected function _import_page(){
602
603
		$title = __('Import', 'event_espresso');
604
		$intro = __('If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ', 'event_espresso');
605
		$form_url = EVENTS_ADMIN_URL;
606
		$action = 'import_events';
607
		$type = 'csv';
608
		$this->_template_args['form'] = EE_Import::instance()->upload_form($title, $intro, $form_url, $action, $type);
609
		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(array('action'=>'sample_export_file'),$this->_admin_base_url);
610
		$content = EEH_Template::display_template(EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',$this->_template_args,true);
611
612
613
		$this->_template_args['admin_page_content'] = $content;
614
		$this->display_admin_page_with_sidebar();
615
	}
616
	/**
617
	 * _import_events
618
	 * This handles displaying the screen and running imports for importing events.
619
	 *
620
	 * @return string html
621
	 */
622
	protected function _import_events() {
623
		require_once(EE_CLASSES . 'EE_Import.class.php');
624
		$success = EE_Import::instance()->import();
625
		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'),true);
0 ignored issues
show
Documentation introduced by
$success is of type boolean|null, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
626
627
	}
628
629
630
631
	/**
632
	 * _events_export
633
	 * Will export all (or just the given event) to a Excel compatible file.
634
	 *
635
	 * @access protected
636
	 * @return file
637
	 */
638
	protected function _events_export() {
639
		if(isset($this->_req_data['EVT_ID'])){
640
			$event_ids = $this->_req_data['EVT_ID'];
641
		}elseif(isset($this->_req_data['EVT_IDs'])){
642
			$event_ids = $this->_req_data['EVT_IDs'];
643
		}else{
644
			$event_ids = NULL;
645
		}
646
		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
647
		$new_request_args = array(
648
			'export' => 'report',
649
			'action' => 'all_event_data',
650
			'EVT_ID' => $event_ids ,
651
		);
652
		$this->_req_data = array_merge($this->_req_data, $new_request_args);
653
654
		if ( is_readable(EE_CLASSES . 'EE_Export.class.php')) {
655
			require_once(EE_CLASSES . 'EE_Export.class.php');
656
			$EE_Export = EE_Export::instance($this->_req_data);
657
			$EE_Export->export();
658
		}
659
	}
660
661
662
663
664
	/**
665
	 * handle category exports()
666
	 * @return file export
667
	 */
668 View Code Duplication
	protected function _categories_export() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
669
670
		//todo: I don't like doing this but it'll do until we modify EE_Export Class.
671
		$new_request_args = array(
672
			'export' => 'report',
673
			'action' => 'categories',
674
			'category_ids' => $this->_req_data['EVT_CAT_ID']
675
			);
676
677
		$this->_req_data = array_merge( $this->_req_data, $new_request_args );
678
679
		if ( is_readable( EE_CLASSES . 'EE_Export.class.php') ) {
680
			require_once( EE_CLASSES . 'EE_Export.class.php');
681
			$EE_Export = EE_Export::instance( $this->_req_data );
682
			$EE_Export->export();
683
		}
684
685
	}
686
687
688
689
	/**
690
	 * Creates a sample CSV file for importing
691
	 */
692
	protected function _sample_export_file(){
693
//		require_once(EE_CLASSES . 'EE_Export.class.php');
694
		EE_Export::instance()->export_sample();
695
	}
696
697
698
699
	/*************		Template Settings 		*************/
700
701
702
703
	protected function _template_settings() {
704
		$this->_template_args['values'] = $this->_yes_no_values;
705
		/**
706
		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
707
		 * from General_Settings_Admin_Page to here.
708
		 */
709
		$this->_template_args = apply_filters( 'FHEE__General_Settings_Admin_Page__template_settings__template_args', $this->_template_args );
710
		$this->_set_add_edit_form_tags( 'update_template_settings' );
711
		$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
712
		$this->_template_args['admin_page_content'] = EEH_Template::display_template( EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php', $this->_template_args, TRUE );
713
		$this->display_admin_page_with_sidebar();
714
	}
715
716
717
718
	protected function _update_template_settings() {
719
720
		/**
721
		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
722
		 * from General_Settings_Admin_Page to here.
723
		 */
724
		EE_Registry::instance()->CFG->template_settings = apply_filters( 'FHEE__General_Settings_Admin_Page__update_template_settings__data', EE_Registry::instance()->CFG->template_settings, $this->_req_data );
725
726
727
		//update custom post type slugs and detect if we need to flush rewrite rules
728
		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
729
		EE_Registry::instance()->CFG->core->event_cpt_slug = empty( $this->_req_data['event_cpt_slug'] ) ? EE_Registry::instance()->CFG->core->event_cpt_slug : sanitize_title_with_dashes( $this->_req_data['event_cpt_slug'] );
730
731
732
		$what = 'Template Settings';
733
		$success = $this->_update_espresso_configuration( $what, EE_Registry::instance()->CFG->template_settings, __FILE__, __FUNCTION__, __LINE__ );
734
735
736
		if ( EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug ) {
737
			update_option( 'ee_flush_rewrite_rules', true );
738
		}
739
740
741
		$this->_redirect_after_action( $success, $what, 'updated', array( 'action' => 'template_settings' ) );
0 ignored issues
show
Documentation introduced by
$success is of type boolean, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
742
743
	}
744
745
746
747
748
	/**
749
	 * _premium_event_editor_meta_boxes
750
	 * add all metaboxes related to the event_editor
751
	 *
752
	 * @access protected
753
	 * @return void
754
	 */
755
	protected function _premium_event_editor_meta_boxes() {
756
757
		$this->verify_cpt_object();
758
759
		add_meta_box('espresso_event_editor_event_options', __('Event Registration Options', 'event_espresso'), array( $this, 'registration_options_meta_box' ), $this->page_slug, 'side', 'core');
760
		//add_meta_box('espresso_event_types', __('Event Type', 'event_espresso'), array( $this, 'event_type_meta_box' ), $this->page_slug, 'side', 'default' ); //add this back in when the feature is ready.
761
762
		//todo feature in progress
763
		//add_meta_box('espresso_event_editor_promo_box', __('Event Promotions', 'event_espresso'), array( $this, 'promotions_meta_box' ), $this->_current_screen->id, 'side', 'core');
764
765
		//todo, this will morph into the "Person" metabox once events are converted to cpts and we have the persons cpt in place.
766
		/*if ( EE_Registry::instance()->CFG->admin->use_personnel_manager ) {
767
			add_meta_box('espresso_event_editor_personnel_box', __('Event Staff / Speakers', 'event_espresso'), array( $this, 'personnel_metabox' ), $this->page_slug, 'side', 'default');
768
		}/**/
769
	}
770
771
772
773
	/**
774
	 * override caf metabox
775
	 * @return string html contents
776
	 */
777
	public function registration_options_meta_box() {
778
779
		$yes_no_values = array(
780
			array('id' => true, 'text' => __('Yes', 'event_espresso')),
781
			array('id' => false, 'text' => __('No', 'event_espresso'))
782
		);
783
		$default_reg_status_values = EEM_Registration::reg_status_array(array(EEM_Registration::status_id_cancelled, EEM_Registration::status_id_declined, EEM_Registration::status_id_incomplete ), TRUE);
784
		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(FALSE);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$template_args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $template_args = 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...
Bug introduced by
The method pretty_active_status() does not exist on EE_CPT_Base. Did you maybe mean status()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
785
		$template_args['_event'] = $this->_cpt_model_obj;
786
		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
0 ignored issues
show
Documentation Bug introduced by
The method additional_limit does not exist on object<EE_CPT_Base>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
787
		$template_args['default_registration_status'] = EEH_Form_Fields::select_input('default_reg_status', $default_reg_status_values, $this->_cpt_model_obj->default_registration_status());
0 ignored issues
show
Bug introduced by
The method default_registration_status() does not exist on EE_CPT_Base. Did you maybe mean status()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
788
		$template_args['display_description'] = EEH_Form_Fields::select_input('display_desc', $yes_no_values, $this->_cpt_model_obj->display_description());
0 ignored issues
show
Documentation Bug introduced by
The method display_description does not exist on object<EE_CPT_Base>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
789
		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input('display_ticket_selector', $yes_no_values, $this->_cpt_model_obj->display_ticket_selector(), '', '', false);
0 ignored issues
show
Documentation Bug introduced by
The method display_ticket_selector does not exist on object<EE_CPT_Base>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
790
		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input('EVT_default_registration_status', $default_reg_status_values, $this->_cpt_model_obj->default_registration_status() );
0 ignored issues
show
Bug introduced by
The method default_registration_status() does not exist on EE_CPT_Base. Did you maybe mean status()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
791
		$template_args['additional_registration_options'] = apply_filters( 'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options', '', $template_args, $yes_no_values, $default_reg_status_values );
792
		$templatepath = EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php';
793
		EEH_Template::display_template($templatepath, $template_args);
794
	}
795
796
797
798
799
	/**
800
	 * event type metabox for events
801
	 * @param  object $post current post object
802
	 * @param  array  $box  metabox args
803
	 * @return string       metabox contents
804
	 */
805
	public function event_type_meta_box( $post, $box ) {
0 ignored issues
show
Unused Code introduced by
The parameter $box is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
806
		$template_args['radio_list'] = $this->wp_terms_radio($post->ID, array( 'taxonomy' => 'espresso_event_type' ) );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$template_args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $template_args = 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...
807
		$template = EVENTS_CAF_TEMPLATE_PATH . 'event_type_metabox_contents.template.php';
808
		EEH_Template::display_template($template, $template_args);
809
	}
810
811
812
813
814
815
816
817
	public function wp_terms_radio( $post_id = 0, $args = array() ) {
818
		$defaults = array(
819
			'descendants_and_self' => 0,
820
			'selected_cats' => false,
821
			'popular_cats' => false,
822
			'walker' => null,
823
			'taxonomy' => 'category',
824
			'checked_ontop' => true
825
		);
826
		$args = apply_filters( 'wp_terms_checklist_args', $args, $post_id );
827
828
		extract( wp_parse_args($args, $defaults), EXTR_SKIP );
829
830
		if ( empty($walker) || !is_a($walker, 'Walker') )
831
			$walker = new Walker_Radio_Checklist;
832
833
		$descendants_and_self = (int) $descendants_and_self;
834
835
		$args = array('taxonomy' => $taxonomy);
836
837
		$tax = get_taxonomy($taxonomy);
838
		$args['disabled'] = !current_user_can($tax->cap->assign_terms);
839
840
		if ( is_array( $selected_cats ) )
841
			$args['selected_cats'] = $selected_cats;
842
		elseif ( $post_id )
843
			$args['selected_cats'] = wp_get_object_terms($post_id, $taxonomy, array_merge($args, array('fields' => 'ids')));
844
		else
845
			$args['selected_cats'] = array();
846
847
		if ( is_array( $popular_cats ) )
848
			$args['popular_cats'] = $popular_cats;
849
		else
850
			$args['popular_cats'] = get_terms( $taxonomy, array( 'fields' => 'ids', 'orderby' => 'count', 'order' => 'DESC', 'number' => 10, 'hierarchical' => false ) );
851
852
		if ( $descendants_and_self ) {
853
			$categories = (array) get_terms($taxonomy, array( 'child_of' => $descendants_and_self, 'hierarchical' => 0, 'hide_empty' => 0 ) );
854
			$self = get_term( $descendants_and_self, $taxonomy );
855
			array_unshift( $categories, $self );
856
		} else {
857
			$categories = (array) get_terms($taxonomy, array('get' => 'all'));
858
		}
859
860
		if ( $checked_ontop ) {
861
			// Post process $categories rather than adding an exclude to the get_terms() query to keep the query the same across all posts (for any query cache)
862
			$checked_categories = array();
863
			$keys = array_keys( $categories );
864
865
			foreach( $keys as $k ) {
866
				if ( in_array( $categories[$k]->term_id, $args['selected_cats'] ) ) {
867
					$checked_categories[] = $categories[$k];
868
					unset( $categories[$k] );
869
				}
870
			}
871
872
			// Put checked cats on top
873
			$list = call_user_func_array(array(&$walker, 'walk'), array($checked_categories, 0, $args));
874
		}
875
		// Then the rest of them
876
		$list .= call_user_func_array(array(&$walker, 'walk'), array($categories, 0, $args));
877
		return $list;
878
	}
879
880
881
	/**
882
	 * wp_list_table_mods for caf
883
	 * ============================
884
	 */
885
886
887
	/**
888
	 * hook into list table filters and provide filters for caffeinated list table
889
	 * @param  array  $oldfilters     any existing filters present
890
	 * @param  array  $list_table_obj the list table object
891
	 * @return array                  new filters
892
	 */
893
	public function list_table_filters( $oldfilters, $list_table_obj ) {
0 ignored issues
show
Unused Code introduced by
The parameter $list_table_obj is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
894
		$filters = array();
895
896
		//first month/year filters
897
		$filters[] = $this->espresso_event_months_dropdown();
898
899
900
		$status = isset( $this->_req_data['status'] ) ? $this->_req_data['status'] : NULL;
901
902
		//active status dropdown
903
		if ( $status !== 'draft' )
904
			$filter[] = $this->active_status_dropdown( isset( $this->_req_data['active_status'] ) ? $this->_req_data['active_status'] : '' );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$filter was never initialized. Although not strictly required by PHP, it is generally a good practice to add $filter = 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...
905
906
		//category filter
907
		$filters[] = $this->category_dropdown();
908
909
910
		return array_merge($oldfilters, $filters);
911
	}
912
913
914
915
916
917
918
	/**
919
	 * espresso_event_months_dropdown
920
	 *
921
	 * @access public
922
	 * @return string                dropdown listing month/year selections for events.
923
	 */
924
	public function espresso_event_months_dropdown() {
925
		//what we need to do is get all PRIMARY datetimes for all events to filter on. Note we need to include any other filters that are set!
926
		$status = isset( $this->_req_data['status'] ) ? $this->_req_data['status'] : NULL;
927
928
		//categories?
929
		$category = isset( $this->_req_data['EVT_CAT'] ) && $this->_req_data['EVT_CAT'] > 0 ? $this->_req_data['EVT_CAT'] : NULL;
930
931
		//active status?
932
		$active_status = isset( $this->_req_data['active_status'] ) ? $this->_req_data['active_status'] : NULL;
933
934
		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
935
936
		return EEH_Form_Fields::generate_event_months_dropdown( $cur_date, $status, $category, $active_status );
937
	}
938
939
940
941
942
	/**
943
	 * returns a list of "active" statuses on the event
944
	 * @param  string $current_value whatever the ucrrent active status is
945
	 * @return string                html dropdown.
946
	 */
947
	public function  active_status_dropdown( $current_value = '' ) {
948
		$select_name = 'active_status';
949
		$values = array('none' => __('Show Active/Inactive', 'event_espresso'), 'active' => __('Active', 'event_espresso'), 'upcoming' => __('Upcoming', 'event_espresso'), 'expired' => __('Expired', 'event_espresso'), 'inactive' => __('Inactive', 'event_espresso') );
950
		$id = 'id="espresso-active-status-dropdown-filter"';
951
		$class = 'wide';
952
		echo EEH_Form_Fields::select_input( $select_name, $values, $current_value, $id, $class );
953
	}
954
955
956
957
	/**
958
	 * output a dropdown of the categories for the category filter on the event admin list table
959
	 *
960
	 * @access  public
961
	 * @return string html
962
	 */
963
	public function category_dropdown() {
964
		$cur_cat = isset( $this->_req_data['EVT_CAT'] ) ? $this->_req_data['EVT_CAT'] : -1;
965
966
		return EEH_Form_Fields::generate_event_category_dropdown( $cur_cat );
967
	}
968
969
970
971
	/**
972
	 * get total number of events today
973
	 *
974
	 * @access public
975
	 * @return int
976
	 */
977
	public function total_events_today() {
978
		$start = EEM_Datetime::instance()->convert_datetime_for_query( 'DTT_EVT_start', date('Y-m-d' ) . ' 00:00:00', 'Y-m-d H:i:s', 'UTC' );
979
		$end = EEM_Datetime::instance()->convert_datetime_for_query( 'DTT_EVT_start', date('Y-m-d' ) . ' 23:59:59', 'Y-m-d H:i:s', 'UTC' );
980
981
		$where = array(
982
			'Datetime.DTT_EVT_start' => array( 'BETWEEN', array($start, $end ) )
983
			);
984
985
		$count = EEM_Event::instance()->count( array( $where, 'caps' => 'read_admin' ), 'EVT_ID', true );
986
		return $count;
987
	}
988
989
	/**
990
	 * get total number of events this month
991
	 *
992
	 * @access public
993
	 * @return int
994
	 */
995
	public function total_events_this_month() {
996
		//Dates
997
		$this_year_r = date('Y');
998
		$this_month_r = date('m');
999
		$days_this_month = date('t');
1000
		$start = EEM_Datetime::instance()->convert_datetime_for_query( 'DTT_EVT_start', $this_year_r . '-' . $this_month_r . '-01 00:00:00', 'Y-m-d H:i:s', 'UTC' );
1001
		$end = EEM_Datetime::instance()->convert_datetime_for_query( 'DTT_EVT_start', $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59', 'Y-m-d H:i:s', 'UTC' );
1002
1003
		$where = array(
1004
			'Datetime.DTT_EVT_start' => array( 'BETWEEN', array($start, $end ) )
1005
			);
1006
1007
		$count = EEM_Event::instance()->count( array( $where, 'caps' => 'read_admin' ), 'EVT_ID', true );
1008
		return $count;
1009
	}
1010
1011
1012
1013
1014
	/** DEFAULT TICKETS STUFF **/
1015
1016
	public function _tickets_overview_list_table() {
1017
		$this->_search_btn_label = __('Tickets', 'event_espresso');
1018
		$this->display_admin_list_table_page_with_no_sidebar();
1019
	}
1020
1021
1022
1023
1024 View Code Duplication
	public function get_default_tickets( $per_page = 10, $count = FALSE, $trashed = FALSE ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1025
1026
		$orderby= empty( $this->_req_data['orderby'] ) ? 'TKT_name' : $this->_req_data['orderby'];
1027
		$order = empty( $this->_req_data['order'] ) ? 'ASC' : $this->_req_data['order'];
1028
1029
		switch ( $orderby ) {
1030
			case 'TKT_name' :
1031
				$orderby = array( 'TKT_name' => $order );
1032
				break;
1033
1034
			case 'TKT_price' :
1035
				$orderby = array( 'TKT_price' => $order );
1036
				break;
1037
1038
			case 'TKT_uses' :
1039
				$orderby = array( 'TKT_uses' => $order );
1040
				break;
1041
1042
			case 'TKT_min' :
1043
				$orderby = array( 'TKT_min' => $order );
1044
				break;
1045
1046
			case 'TKT_max' :
1047
				$orderby = array( 'TKT_max' => $order );
1048
				break;
1049
1050
			case 'TKT_qty' :
1051
				$orderby = array( 'TKT_qty' => $order );
1052
				break;
1053
		}
1054
1055
		$current_page = isset( $this->_req_data['paged'] ) && !empty( $this->_req_data['paged'] ) ? $this->_req_data['paged'] : 1;
1056
		$per_page = isset( $this->_req_data['perpage'] ) && !empty( $this->_req_data['perpage'] ) ? $this->_req_data['perpage'] : $per_page;
1057
1058
		$_where = array(
1059
			'TKT_is_default' => 1,
1060
			'TKT_deleted' => $trashed
1061
			);
1062
1063
		$offset = ($current_page-1)*$per_page;
1064
		$limit = array( $offset, $per_page );
1065
1066
		if ( isset( $this->_req_data['s'] ) ) {
1067
			$sstr = '%' . $this->_req_data['s'] . '%';
1068
			$_where['OR'] = array(
1069
				'TKT_name' => array('LIKE',$sstr ),
1070
				'TKT_description' => array('LIKE',$sstr )
1071
				);
1072
		}
1073
1074
		$query_params = array(
1075
			$_where,
1076
			'order_by'=>$orderby,
1077
			'limit'=>$limit,
1078
			'group_by'=>'TKT_ID'
1079
			);
1080
1081
		if($count){
1082
			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1083
		}else{
1084
			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1085
		}
1086
1087
	}
1088
1089
1090
1091
1092
1093
	protected function _trash_or_restore_ticket(  $trash = FALSE ) {
1094
		$success = 1;
1095
1096
		$TKT = EEM_Ticket::instance();
1097
1098
		//checkboxes?
1099 View Code Duplication
		if ( !empty( $this->_req_data['checkbox'] ) && is_array( $this->_req_data['checkbox'] ) ) {
1100
			//if array has more than one element then success message should be plural
1101
			$success = count( $this->_req_data['checkbox'] ) > 1 ? 2 : 1;
1102
1103
			//cycle thru the boxes
1104
			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...
1105
				if ( $trash ) {
1106
					if ( ! $TKT->delete_by_ID( $TKT_ID ) )
1107
						$success = 0;
1108
				} else {
1109
					if ( ! $TKT->restore_by_ID( $TKT_ID ) )
1110
						$success = 0;
1111
				}
1112
			}
1113
		} else {
1114
			//grab single id and trash
1115
			$TKT_ID = absint( $this->_req_data['TKT_ID'] );
1116
1117
			if ( $trash ) {
1118
				if ( ! $TKT->delete_by_ID( $TKT_ID ) )
1119
					$success = 0;
1120
			} else {
1121
				if ( ! $TKT->restore_by_ID( $TKT_ID ) )
1122
					$success = 0;
1123
			}
1124
		}
1125
1126
		$action_desc = $trash ? 'moved to the trash' : 'restored';
1127
		$query_args = array(
1128
			'action' => 'ticket_list_table',
1129
			'status' => $trash ? '' : 'trashed'
1130
			);
1131
		$this->_redirect_after_action( $success, 'Tickets', $action_desc, $query_args );
1132
	}
1133
1134
1135
1136
1137
1138
	protected function _delete_ticket() {
1139
		$success = 1;
1140
1141
		$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...
1142
1143
		//checkboxes?
1144 View Code Duplication
		if ( !empty( $this->_req_data['checkbox'] ) && is_array( $this->_req_data['checkbox'] ) ) {
1145
			//if array has more than one element then success message should be plural
1146
			$success = count( $this->_req_data['checkbox'] ) > 1 ? 2 : 1;
1147
1148
			//cycle thru the boxes
1149
			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...
1150
				//delete
1151
				if ( ! $this->_delete_the_ticket( $TKT_ID ) ) {
1152
					$success = 0;
1153
				}
1154
			}
1155
		} else {
1156
			//grab single id and trash
1157
			$TKT_ID = absint( $this->_req_data['TKT_ID'] );
1158
			if ( ! $this->_delete_the_ticket( $TKT_ID ) ) {
1159
					$success = 0;
1160
				}
1161
		}
1162
1163
		$action_desc = 'deleted';
1164
		$query_args = array(
1165
			'action' => 'ticket_list_table',
1166
			'status' => 'trashed'
1167
			);
1168
1169
		//failsafe.  If the default ticket count === 1 then we need to redirect to event overview.
1170
		if ( EEM_Ticket::instance()->count_deleted_and_undeleted( array( array( 'TKT_is_default' => 1 ) ), 'TKT_ID', TRUE ) )
1171
			$query_args = array();
1172
		$this->_redirect_after_action( $success, 'Tickets', $action_desc, $query_args );
1173
	}
1174
1175
1176
1177
1178
	protected function _delete_the_ticket( $TKT_ID ) {
1179
		$tkt = EEM_Ticket::instance()->get_one_by_ID( $TKT_ID );
1180
		$tkt->_remove_relations('Datetime');
1181
		//delete all related prices first
1182
		$tkt->delete_related_permanently('Price');
1183
		return $tkt->delete_permanently();
1184
	}
1185
1186
1187
1188
} //end class Events_Admin_Page
1189
1190
/*
1191
// Walker_Radio_Checklist isn't used anywhere in EE4 core currently, commenting out for now
1192
// The version check was added to make sure Walker_Category_Checklist class is available
1193
global $wp_version;
1194
if ( $wp_version >= 4.4 ){
1195
	require_once ABSPATH . 'wp-admin/includes/class-walker-category-checklist.php';
1196
} else {
1197
	require_once ABSPATH . 'wp-admin/includes/template.php';
1198
}
1199
1200
class Walker_Radio_Checklist extends Walker_Category_Checklist {
1201
1202
	function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
1203
		extract($args);
1204
		if ( empty($taxonomy) )
1205
			$taxonomy = 'category';
1206
1207
		if ( $taxonomy == 'category' )
1208
			$name = 'post_category';
1209
		else
1210
			$name = 'tax_input['.$taxonomy.']';
1211
1212
		$class = '';
1213
		$output .= "\n<li id='{$taxonomy}-{$category->term_id}'$class>" . '<label class="selectit"><input value="' . $category->term_id . '" type="radio" name="'.$name.'[]" id="in-'.$taxonomy.'-' . $category->term_id . '"' . checked( in_array( $category->term_id, $selected_cats ), true, false ) . disabled( empty( $args['disabled'] ), false, false ) . ' /> ' . esc_html( apply_filters('the_category', $category->name )) . '</label>';
1214
	}
1215
}
1216
*/
1217