Completed
Branch TASK-9118-extensions-page (04eaec)
by
unknown
856:31 queued 840:33
created

Extend_Registrations_Admin_Page   F

Complexity

Total Complexity 130

Size/Duplication

Total Lines 932
Duplicated Lines 8.91 %

Coupling/Cohesion

Components 1
Dependencies 18

Importance

Changes 0
Metric Value
dl 83
loc 932
rs 1.0434
c 0
b 0
f 0
wmc 130
lcom 1
cbo 18

24 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
B _extend_page_config() 0 115 6
A _ajax_hooks() 0 4 1
A load_scripts_styles() 0 13 2
A load_scripts_styles_reports() 0 13 2
A _add_screen_options_event_registrations() 0 3 1
A _add_screen_options_registration_checkins() 6 6 1
A _set_list_table_views_event_registrations() 13 13 2
A _set_list_table_views_registration_checkins() 10 10 1
F get_newsletter_form_content() 12 45 10
B add_newsletter_action_buttons() 0 20 8
B newsletter_send_form_skeleton() 0 37 5
C _newsletter_selected_send() 6 57 16
A _registration_reports() 19 19 1
B _registrations_per_day_report() 6 46 5
B _get_registrations_per_event_report() 0 37 4
D _registration_checkin_list_table() 0 28 8
A toggle_checkin_status() 6 23 3
D _toggle_checkin_status() 0 32 10
A _toggle_checkin() 0 11 2
C _delete_checkin_rows() 0 26 8
B _delete_checkin_row() 0 18 5
B _event_registrations_list_table() 0 54 5
F get_event_attendees() 5 117 23

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_Registrations_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_Registrations_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_Registrations_Admin_Page
20
 *
21
 * This is the Registrations Caffeinated admin page.
22
 *
23
 *
24
 * @package		Extend_Registrations_Admin_Page
25
 * @subpackage	caffeinated/admin/extend/registrations/Extend_Registrations_Admin_Page.core.php
26
 * @author		Darren Ethier
27
 *
28
 * ------------------------------------------------------------------------
29
 */
30
class Extend_Registrations_Admin_Page extends Registrations_Admin_Page {
31
32
	public function __construct( $routing = TRUE ) {
33
		parent::__construct( $routing );
34
		define( 'REG_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/templates/');
35
		define( 'REG_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'registrations/assets/');
36
		define( 'REG_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registrations/assets/');
37
	}
38
39
40
41
42
43
44
	protected function _extend_page_config() {
45
		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'registrations';
46
47
		$reg_id = ! empty( $this->_req_data['_REG_ID'] ) && ! is_array( $this->_req_data['_REG_ID'] ) ? $this->_req_data['_REG_ID'] : 0;
48
		$att_id = ! empty( $this->_req_data[ 'ATT_ID' ] ) ? ! is_array( $this->_req_data['ATT_ID'] ) : 0;
49
		$att_id = ! empty( $this->_req_data['post'] ) && ! is_array( $this->_req_data['post'] ) ? $this->_req_data['post'] : $att_id;
0 ignored issues
show
Unused Code introduced by
$att_id 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...
50
51
		$new_page_routes = array(
52
			'reports' => array(
53
				'func' => '_registration_reports',
54
				'capability' => 'ee_read_registrations'
55
				),
56
			'registration_checkins' => array(
57
				'func' => '_registration_checkin_list_table',
58
				'capability' => 'ee_read_checkins'
59
				),
60
			'newsletter_selected_send' => array(
61
				'func' => '_newsletter_selected_send',
62
				'noheader' => TRUE,
63
				'capability' => 'ee_send_message'
64
				),
65
			'delete_checkin_rows' => array(
66
					'func' => '_delete_checkin_rows',
67
					'noheader' => TRUE,
68
					'capability' => 'ee_delete_checkins'
69
				),
70
			'delete_checkin_row' => array(
71
					'func' => '_delete_checkin_row',
72
					'noheader' => TRUE,
73
					'capability' => 'ee_delete_checkin',
74
					'obj_id' => $reg_id
75
				),
76
			'toggle_checkin_status'	=> array(
77
					'func' => '_toggle_checkin_status',
78
					'noheader' => TRUE,
79
					'capability' => 'ee_edit_checkin',
80
					'obj_id' => $reg_id
81
				),
82
			'event_registrations'=> array(
83
				'func' => '_event_registrations_list_table',
84
				'capability' => 'ee_read_checkins',
85
				)
86
			);
87
88
		$this->_page_routes = array_merge( $this->_page_routes, $new_page_routes );
89
90
		$new_page_config = array(
91
			'reports' => array(
92
				'nav' => array(
93
					'label' => __('Reports', 'event_espresso'),
94
					'order' => 30
95
					),
96
				 'help_tabs' => array(
97
					'registrations_reports_help_tab' => array(
98
						'title' => __('Registration Reports', 'event_espresso'),
99
						'filename' => 'registrations_reports'
100
						)
101
					),
102
				'help_tour' => array( 'Registration_Reports_Help_Tour' ),
103
				'require_nonce' => FALSE
104
				),
105
			'event_registrations' => array(
106
				'nav' => array(
107
					'label' => __('Event Check-In', 'event_espresso'),
108
					'order' => 10,
109
					'persistent' => true
110
					),
111
					'help_tabs' => array(
112
					'registrations_event_checkin_help_tab' => array(
113
						'title' => __('Registrations Event Check-In', 'event_espresso'),
114
						'filename' => 'registrations_event_checkin'
115
					),
116
					'registrations_event_checkin_table_column_headings_help_tab' => array(
117
						'title' => __('Event Check-In Table Column Headings', 'event_espresso'),
118
						'filename' => 'registrations_event_checkin_table_column_headings'
119
					),
120
					'registrations_event_checkin_filters_help_tab' => array(
121
						'title' => __('Event Check-In Filters', 'event_espresso'),
122
						'filename' => 'registrations_event_checkin_filters'
123
					),
124
					'registrations_event_checkin_views_help_tab' => array(
125
						'title' => __('Event Check-In Views', 'event_espresso'),
126
						'filename' => 'registrations_event_checkin_views'
127
					),
128
					'registrations_event_checkin_other_help_tab' => array(
129
						'title' => __('Event Check-In Other', 'event_espresso'),
130
						'filename' => 'registrations_event_checkin_other'
131
					)
132
				),
133
				'help_tour' => array( 'Event_Checkin_Help_Tour' ),
134
				'qtips' => array('Registration_List_Table_Tips' ),
135
				'list_table' => 'EE_Event_Registrations_List_Table',
136
				'metaboxes' => array(),
137
				'require_nonce' => FALSE
138
				),
139
			'registration_checkins' => array(
140
				'nav' => array(
141
					'label' => __('Check-In Records', 'event_espresso'),
142
					'order' => 15,
143
					'persistent' => FALSE
144
					),
145
				'list_table' => 'EE_Registration_CheckIn_List_Table',
146
				//'help_tour' => array( 'Checkin_Toggle_View_Help_Tour' ),
147
				'metaboxes' => array(),
148
				'require_nonce' => FALSE
149
				),
150
			);
151
152
		// var_dump($this->_req_data);
153
		// exit();
154
155
		$this->_page_config = array_merge( $this->_page_config, $new_page_config );
156
		$this->_page_config['contact_list']['list_table'] = 'Extend_EE_Attendee_Contact_List_Table';
157
		$this->_page_config['default']['list_table'] = 'Extend_EE_Registrations_List_Table';
158
	}
159
160
161
162
	protected function _ajax_hooks() {
163
		parent::_ajax_hooks();
164
		add_action('wp_ajax_get_newsletter_form_content', array( $this, 'get_newsletter_form_content') );
165
	}
166
167
168
169
	public function load_scripts_styles() {
170
		parent::load_scripts_styles();
171
172
		//if newsletter message type is active then let's add filter and load js for it.
173
		EE_Registry::instance()->load_helper('MSG_Template');
174
		if ( EEH_MSG_Template::is_mt_active('newsletter') ) {
175
			//enqueue newsletter js
176
			wp_enqueue_script( 'ee-newsletter-trigger', REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.js', array( 'ee-dialog'), EVENT_ESPRESSO_VERSION, TRUE );
177
			wp_enqueue_style( 'ee-newsletter-trigger-css', REG_CAF_ASSETS_URL . 'ee-newsletter-trigger.css', array(), EVENT_ESPRESSO_VERSION );
178
			//hook in buttons for newsletter message type trigger.
179
			add_action('AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons', array( $this, 'add_newsletter_action_buttons'), 10 );
180
		}
181
	}
182
183
184
185
	public function load_scripts_styles_reports() {
186
		//styles
187
		wp_enqueue_style('jquery-jqplot-css');
188
189
		//scripts
190
		global $is_IE;
191
		if ( $is_IE ) {
192
			wp_enqueue_script( 'excanvas' );
193
		}
194
195
		wp_register_script('espresso_reg_admin_regs_per_day', REG_CAF_ASSETS_URL  . 'espresso_reg_admin_regs_per_day_report.js', array('jqplot-all'), EVENT_ESPRESSO_VERSION, TRUE );
196
		wp_register_script('espresso_reg_admin_regs_per_event', REG_CAF_ASSETS_URL . 'espresso_reg_admin_regs_per_event_report.js', array('jqplot-all'), EVENT_ESPRESSO_VERSION, TRUE );
197
	}
198
199
200
201
202
	protected function _add_screen_options_event_registrations() {
203
		$this->_per_page_screen_option();
204
	}
205
206
207
208
209
210 View Code Duplication
	protected function _add_screen_options_registration_checkins() {
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...
211
		$page_title = $this->_admin_page_title;
212
		$this->_admin_page_title = __('Check-In Records', 'event_espresso');
213
		$this->_per_page_screen_option();
214
		$this->_admin_page_title = $page_title;
215
	}
216
217
218
219
220
221 View Code Duplication
	protected function _set_list_table_views_event_registrations() {
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...
222
		$this->_views = array(
223
			'all' => array(
224
				'slug' => 'all',
225
				'label' => __('All', 'event_espresso'),
226
				'count' => 0,
227
				'bulk_action' => !isset( $this->_req_data['event_id'] ) ? array() : array(
228
					'toggle_checkin_status' => __('Toggle Check-In', 'event_espresso'),
229
					//'trash_registrations' => __('Trash Registrations', 'event_espresso')
230
					)
231
				),
232
			);
233
	}
234
235
236
237
238
239 View Code Duplication
	protected function _set_list_table_views_registration_checkins() {
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...
240
		$this->_views = array(
241
			'all' => array(
242
				'slug' => 'all',
243
				'label' => __('All', 'event_espresso'),
244
				'count' => 0,
245
				'bulk_action' => array( 'delete_checkin_rows' => __('Delete Check-In Rows', 'event_espresso') )
246
				),
247
			);
248
	}
249
250
251
252
	/**
253
	 * callback for ajax action.
254
	 *
255
	 * @since 4.3.0
256
	 *
257
	 * @return json
258
	 */
259
	public function get_newsletter_form_content() {
260
		//do a nonce check cause we're not coming in from an normal route here.
261
		$nonce = isset( $this->_req_data['get_newsletter_form_content_nonce'] ) ? sanitize_text_field( $this->_req_data['get_newsletter_form_content_nonce'] ) : '';
262
		$nonce_ref = 'get_newsletter_form_content_nonce';
263
264
		$this->_verify_nonce( $nonce, $nonce_ref );
265
		//let's get the mtp for the incoming MTP_ ID
266 View Code Duplication
		if ( !isset( $this->_req_data['GRP_ID'] ) ) {
267
			EE_Error::add_error( __('There must be something broken with the js or html structure because the required data for getting a message template group is not present (need an GRP_ID).', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
268
			$this->_template_args['success'] = FALSE;
269
			$this->_template_args['error'] = TRUE;
270
			$this->_return_json();
271
		}
272
		$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $this->_req_data['GRP_ID'] );
273 View Code Duplication
		if ( ! $MTPG instanceof EE_Message_Template_Group ) {
274
			EE_Error::add_error( sprintf( __('The GRP_ID given (%d) does not appear to have a corresponding row in the database.', 'event_espresso'), $this->_req_data['GRP_ID'] ), __FILE__, __FUNCTION__, __LINE__  );
275
			$this->_template_args['success'] = FALSE;
276
			$this->_template_args['error'] = TRUE;
277
			$this->_return_json();
278
		}
279
280
		$MTPs = $MTPG->context_templates();
0 ignored issues
show
Documentation Bug introduced by
The method context_templates 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...
281
		$MTPs = $MTPs['attendee'];
282
		$template_fields = array();
283
		foreach ( $MTPs as $MTP ) {
284
			$field = $MTP->get('MTP_template_field');
285
			if ( $field == 'content'  ) {
286
				$content = $MTP->get('MTP_content');
287
				if ( !empty( $content['newsletter_content'] ) ) {
288
					$template_fields['newsletter_content'] = $content['newsletter_content'];
289
					}
290
				continue;
291
			}
292
			$template_fields[$MTP->get('MTP_template_field')] = $MTP->get('MTP_content');
293
		}
294
295
		$this->_template_args['success'] = TRUE;
296
		$this->_template_args['error'] = FALSE;
297
		$this->_template_args['data'] = array(
298
			'batch_message_from' => isset($template_fields['from']) ? $template_fields['from'] : '',
299
			'batch_message_subject' => isset($template_fields['subject']) ? $template_fields['subject'] : '',
300
			'batch_message_content' => isset( $template_fields['newsletter_content'] ) ? $template_fields['newsletter_content'] : ''
301
			);
302
		$this->_return_json();
303
	}
304
305
306
307
308
	/**
309
	 * callback for AHEE__EE_Admin_List_Table__extra_tablenav__after_bottom_buttons action
310
	 *
311
	 * @since 4.3.0
312
	 *
313
	 * @param EE_Admin_List_Table $list_table
314
	 * @return string html string for extra buttons
315
	 */
316
	public function add_newsletter_action_buttons( EE_Admin_List_Table $list_table ) {
0 ignored issues
show
Unused Code introduced by
The parameter $list_table 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...
317
		if ( ! EE_Registry::instance()->CAP->current_user_can( 'ee_send_message', 'espresso_registrations_newsletter_selected_send' ) ) {
318
			return '';
319
		}
320
321
		$routes_to_add_to = array(
322
			'contact_list',
323
			'event_registrations',
324
			'default'
325
			);
326
		if ( $this->_current_page == 'espresso_registrations' && in_array( $this->_req_action, $routes_to_add_to )  ) {
327
			if ( ( $this->_req_action == 'event_registrations' && empty( $this->_req_data['event_id'] ) ) || ( isset( $this->_req_data['status'] ) && $this->_req_data['status'] == 'trash' ) ) {
328
				echo '';
329
			} else {
330
				$button_text = sprintf( __('Send Batch Message (%s selected)', 'event_espresso'), '<span class="send-selected-newsletter-count">0</span>' );
331
				echo '<button id="selected-batch-send-trigger" class="button secondary-button"><span class="dashicons dashicons-email "></span>' . $button_text . '</button>';
332
				add_action('admin_footer', array( $this, 'newsletter_send_form_skeleton') );
333
			}
334
		}
335
	}
336
337
338
339
340
	public function newsletter_send_form_skeleton() {
341
		$list_table = $this->_list_table_object;
342
		$codes = array();
343
		//need to templates for the newsletter message type for the template selector.
344
		$values[] = array( 'text' => __('Select Template to Use', 'event_espresso'), 'id' => 0 );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$values was never initialized. Although not strictly required by PHP, it is generally a good practice to add $values = 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...
345
		$mtps = EEM_Message_Template_Group::instance()->get_all( array( array( 'MTP_message_type' => 'newsletter', 'MTP_messenger' => 'email' ) ) );
346
		foreach ( $mtps as $mtp ) {
347
			$name = $mtp->name();
348
			$values[] = array(
349
				'text' => empty( $name ) ? __('Global', 'event_espresso') : $name,
350
				'id' => $mtp->ID()
351
				);
352
		}
353
354
		//need to get a list of shortcodes that are available for the newsletter message type.
355
		EE_Registry::instance()->load_helper('MSG_Template');
356
		$shortcodes = EEH_MSG_Template::get_shortcodes( 'newsletter', 'email', array(), 'attendee', FALSE );
357
		foreach ( $shortcodes as $field => $shortcode_array ) {
358
			$codes[$field] = implode(', ', array_keys($shortcode_array ) );
359
		}
360
361
		$shortcodes = $codes;
362
363
		$form_template = REG_CAF_TEMPLATE_PATH . 'newsletter-send-form.template.php';
364
		$form_template_args = array(
365
			'form_action' => admin_url('admin.php?page=espresso_registrations'),
366
			'form_route' => 'newsletter_selected_send',
367
			'form_nonce_name' => 'newsletter_selected_send_nonce',
368
			'form_nonce' => wp_create_nonce( 'newsletter_selected_send_nonce' ),
369
			'redirect_back_to' => $this->_req_action,
370
			'ajax_nonce' => wp_create_nonce( 'get_newsletter_form_content_nonce'),
371
			'template_selector' => EEH_Form_Fields::select_input('newsletter_mtp_selected', $values ),
372
			'shortcodes' => $shortcodes,
373
			'id_type' => $list_table instanceof EE_Attendee_Contact_List_Table ? 'contact' : 'registration'
374
			);
375
		EEH_Template::display_template( $form_template, $form_template_args );
376
	}
377
378
379
380
	/**
381
	 * Handles sending selected registrations/contacts a newsletter.
382
	 *
383
	 * @since  4.3.0
384
	 *
385
	 * @return void
386
	 */
387
	protected function _newsletter_selected_send() {
388
		$success = TRUE;
389
		//first we need to make sure we have a GRP_ID so we know what template we're sending and updating!
390
		if ( empty( $this->_req_data['newsletter_mtp_selected'] ) ) {
391
			EE_Error::add_error( __('In order to send a message, a Message Template GRP_ID is needed. It was not provided so messages were not sent.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
392
			$success = FALSE;
393
		}
394
395
		if ( $success ) {
396
			//update Message template in case there are any changes
397
			$MTPG = EEM_Message_Template_Group::instance()->get_one_by_ID( $this->_req_data['newsletter_mtp_selected'] );
398
			$MTPs = $MTPG instanceof EE_Message_Template_Group ? $MTPG->context_templates() : array();
399
			if ( empty( $MTPs ) ) {
400
				EE_Error::add_error( __('Unable to retrieve message template fields from the db. Messages not sent.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
401
				$success = FALSE;
0 ignored issues
show
Unused Code introduced by
$success 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...
402
			}
403
404
			//let's just update the specific fields
405
			foreach ( $MTPs['attendee'] as $MTP ) {
406
				$field = $MTP->get('MTP_template_field');
407
				$content = $MTP->get('MTP_content');
408
				$new_content = $content;
409
				switch( $field ) {
410 View Code Duplication
					case 'from' :
411
						$new_content = !empty( $this->_req_data['batch_message']['from'] ) ? $this->_req_data['batch_message']['from'] : $content;
412
						break;
413 View Code Duplication
					case 'subject' :
414
						$new_content = !empty( $this->_req_data['batch_message']['subject'] ) ? $this->_req_data['batch_message']['subject'] : $content;
415
						break;
416
					case 'content' :
417
						$new_content = $content;
418
						$new_content['newsletter_content'] = !empty( $this->_req_data['batch_message']['content'] ) ? $this->_req_data['batch_message']['content'] : $content['newsletter_content'];
419
						break;
420
					default :
421
						continue;
422
						break;
0 ignored issues
show
Unused Code introduced by
break; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
423
				}
424
				$MTP->set('MTP_content', $new_content);
425
				$MTP->save();
426
			}
427
428
			//great fields are updated!  now let's make sure we just have contact objects (EE_Attendee).
429
			$id_type = !empty( $this->_req_data['batch_message']['id_type'] ) ? $this->_req_data['batch_message']['id_type'] : 'registration';
430
431
			//id_type will affect how we assemble the ids.
432
			$ids = !empty( $this->_req_data['batch_message']['ids'] ) ? json_decode( stripslashes($this->_req_data['batch_message']['ids']) ) : array();
433
434
			$contacts = $id_type == 'registration' ? EEM_Attendee::instance()->get_array_of_contacts_from_reg_ids( $ids ) : EEM_Attendee::instance()->get_all( array( array( 'ATT_ID' => array('in', $ids ) ) ) );
435
436
			//we do _action because ALL triggers are handled in EED_Messages.
437
			do_action('AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send', $contacts, $MTPG->ID() );
438
		}
439
		$query_args = array(
440
			'action' => !empty( $this->_req_data['redirect_back_to'] ) ? $this->_req_data['redirect_back_to'] : 'default'
441
			);
442
		$this->_redirect_after_action( FALSE, '', '', $query_args, TRUE );
443
	}
444
445
446
447
448
	/**
449
	 * 		generates Business Reports regarding Registrations
450
	*		@access protected
451
	*		@return void
452
	*/
453 View Code Duplication
	protected function _registration_reports() {
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...
454
455
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' );
456
457
		$page_args = array();
458
459
		$page_args['admin_reports'][] = $this->_registrations_per_day_report( '-1 month' );  //  option: '-1 week', '-2 weeks' defaults to '-1 month'
460
		$page_args['admin_reports'][] = $this->_get_registrations_per_event_report( '-1 month' ); //  option: '-1 week', '-2 weeks' defaults to '-1 month'
461
//		$page_args['admin_reports'][] = 'chart1';
462
463
		$template_path = EE_ADMIN_TEMPLATE . 'admin_reports.template.php';
464
		$this->_template_args['admin_page_content'] = EEH_Template::display_template( $template_path, $page_args, TRUE );
465
466
//		EEH_Debug_Tools::printr( $page_args, '$page_args' );
467
468
		// the final template wrapper
469
		$this->display_admin_page_with_no_sidebar();
470
471
	}
472
473
474
475
476
477
478
	/**
479
	 * 		generates Business Report showing total registratiopns per day
480
	*		@access private
481
	*		@return void
482
	*/
483
	private function _registrations_per_day_report( $period = '-1 month' ) {
484
485
		$report_ID = 'reg-admin-registrations-per-day-report-dv';
486
		$report_JS = 'espresso_reg_admin_regs_per_day';
487
488
		wp_enqueue_script( $report_JS );
489
490
		$REG = EEM_Registration::instance();
491
492
		$results = $REG->get_registrations_per_day_report( $period );
493
494
		//EEH_Debug_Tools::printr( $results, '$registrations_per_day' );
495
		$regs = array();
496
		$xmin = date( 'Y-m-d', strtotime( '+1 year' ));
497
		$xmax = 0;
498
		$ymax = 0;
499
		$results = (array) $results;
500 View Code Duplication
		foreach ( $results as $result ) {
501
			$regs[] = array( $result->regDate, (int)$result->total );
502
			$xmin = strtotime( $result->regDate ) < strtotime( $xmin ) ? $result->regDate : $xmin;
503
			$xmax = strtotime( $result->regDate ) > strtotime( $xmax ) ? $result->regDate : $xmax;
504
			$ymax = $result->total > $ymax ? $result->total : $ymax;
505
		}
506
507
		$xmin = date( 'Y-m-d', strtotime( date( 'Y-m-d', strtotime($xmin)) . ' -1 day' ));
508
		$xmax = date( 'Y-m-d', strtotime( date( 'Y-m-d', strtotime($xmax)) . ' +1 day' ));
509
		// calculate # days between our min and max dates
510
		$span = floor( (strtotime($xmax) - strtotime($xmin)) / (60*60*24)) + 1;
511
512
		$report_title = __( 'Total Registrations per Day', 'event_espresso' );
513
514
		$report_params = array(
515
				'title' 	=> $report_title,
516
				'id' 		=> $report_ID,
517
				'regs' 	=> $regs,
518
				'xmin' 	=> $xmin,
519
				'xmax' 	=> $xmax,
520
				'ymax' 	=> ceil($ymax * 1.25),
521
				'span' 	=> $span,
522
				'width'	=> ceil(900 / $span),
523
				'noRegsMsg' => sprintf( __('<h2>%s</h2><p>There are currently no registration records in the last month for this report.</p>', 'event_espresso'), $report_title )
524
			);
525
		wp_localize_script( $report_JS, 'regPerDay', $report_params );
526
527
		return $report_ID;
528
	}
529
530
531
532
533
534
535
	/**
536
	 * 		generates Business Report showing total registratiopns per event
537
	*		@access private
538
	*		@return void
539
	*/
540
	private function _get_registrations_per_event_report( $period = '-1 month' ) {
541
542
		$report_ID = 'reg-admin-registrations-per-event-report-dv';
543
		$report_JS = 'espresso_reg_admin_regs_per_event';
544
545
		wp_enqueue_script( $report_JS );
546
547
		require_once ( EE_MODELS . 'EEM_Registration.model.php' );
548
		$REG = EEM_Registration::instance();
549
550
		$results = $REG->get_registrations_per_event_report( $period );
551
		//EEH_Debug_Tools::printr( $results, '$registrations_per_event' );
552
		$regs = array();
553
		$ymax = 0;
554
		$results = (array) $results;
555
		foreach ( $results as $result ) {
556
			$regs[] = array( wp_trim_words( $result->event_name, 4, '...' ), (int)$result->total );
557
			$ymax = $result->total > $ymax ? $result->total : $ymax;
558
		}
559
560
		$span = $period == 'week' ? 9 : 33;
561
562
		$report_title = __( 'Total Registrations per Event', 'event_espresso' );
563
564
		$report_params = array(
565
			'title' 	=> $report_title,
566
			'id' 		=> $report_ID,
567
			'regs' 	=> $regs,
568
			'ymax' 	=> ceil($ymax * 1.25),
569
			'span' 	=> $span,
570
			'width'	=> ceil(900 / $span),
571
			'noRegsMsg' => sprintf( __('<h2>%s</h2><p>There are currently no registration records in the last month for this report.</p>', 'event_espresso'), $report_title )
572
		);
573
		wp_localize_script( $report_JS, 'regPerEvent', $report_params );
574
575
		return $report_ID;
576
	}
577
578
579
580
581
	/**
582
	 * generates HTML for the Registration Check-in list table (showing all Check-ins for a specific registration)
583
	 * @access protected
584
	 * @return void
585
	 */
586
	protected function _registration_checkin_list_table() {
587
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' );
588
		$reg_id = isset( $this->_req_data['_REGID'] ) ? $this->_req_data['_REGID'] : null;
589
		$reg = EEM_Registration::instance()->get_one_by_ID($reg_id);
590
		$this->_admin_page_title .= $this->get_action_link_or_button('new_registration', 'add-registrant', array('event_id' => $reg->event_ID()), 'add-new-h2');
0 ignored issues
show
Documentation Bug introduced by
The method event_ID 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...
591
592
		$legend_items = array(
593
			'checkin' => array(
594
				'class' => 'ee-icon ee-icon-check-in',
595
				'desc' => __('This indicates the attendee has been checked in', 'event_espresso')
596
				),
597
			'checkout' => array(
598
				'class' => 'ee-icon ee-icon-check-out',
599
				'desc' => __('This indicates the attendee has been checked out', 'event_espresso')
600
				)
601
			);
602
		$this->_template_args['after_list_table'] = $this->_display_legend( $legend_items );
603
604
605
		$dtt_id = isset(  $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : NULL;
606
		$go_back_url = !empty( $reg_id )  ? EE_Admin_Page::add_query_args_and_nonce(array('action' => 'event_registrations', 'event_id' => EEM_Registration::instance()->get_one_by_ID($reg_id)->get_first_related('Event')->ID(), 'DTT_ID' => $dtt_id ), $this->_admin_base_url ) : '';
607
608
		$this->_template_args['before_list_table'] = !empty( $reg_id ) && !empty( $dtt_id ) ? '<h2>' . sprintf(__("%s's check in records for %s at the event, %s", 'event_espresso'), '<span id="checkin-attendee-name">' . EEM_Registration::instance()->get_one_by_ID($reg_id)->get_first_related('Attendee')->full_name() . '</span>', '<span id="checkin-dtt"><a href="' . $go_back_url . '">' . EEM_Datetime::instance()->get_one_by_ID($dtt_id)->start_date_and_time() . ' - ' . EEM_Datetime::instance()->get_one_by_ID($dtt_id)->end_date_and_time() . '</a></span>', '<span id="checkin-event-name">' . EEM_Datetime::instance()->get_one_by_ID($dtt_id)->get_first_related('Event')->get('EVT_name') . '</span>' ) . '</h2>' : '';
0 ignored issues
show
Documentation Bug introduced by
The method start_date_and_time 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...
Documentation Bug introduced by
The method end_date_and_time 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...
609
		$this->_template_args['list_table_hidden_fields'] = !empty( $reg_id ) ? '<input type="hidden" name="_REGID" value="' . $reg_id . '">' : '';
610
		$this->_template_args['list_table_hidden_fields'] .= !empty( $dtt_id ) ? '<input type="hidden" name="DTT_ID" value="' . $dtt_id . '">' : '';
611
612
		$this->display_admin_list_table_page_with_no_sidebar();
613
	}
614
615
616
617
	/**
618
	 * toggle the Check-in status for the given registration (coming from ajax)
619
	 * @return json
620
	 */
621
	public function toggle_checkin_status() {
622
		//first make sure we have the necessary data
623 View Code Duplication
		if ( !isset( $this->_req_data['_regid'] ) ) {
624
			EE_Error::add_error( __('There must be something broken with the html structure because the required data for toggling the Check-in status is not being sent via ajax', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
625
			$this->_template_args['success'] = FALSE;
626
			$this->_template_args['error'] = TRUE;
627
			$this->_return_json();
628
		};
629
630
		//do a nonce check cause we're not coming in from an normal route here.
631
		$nonce = isset( $this->_req_data['checkinnonce'] ) ? sanitize_text_field( $this->_req_data['checkinnonce'] ) : '';
632
		$nonce_ref = 'checkin_nonce';
633
634
		$this->_verify_nonce( $nonce, $nonce_ref );
635
636
		//beautiful! Made it this far so let's get the status.
637
		$new_status = $this->_toggle_checkin_status();
638
639
		//setup new class to return via ajax
640
		$this->_template_args['admin_page_content'] = 'clickable trigger-checkin checkin-icons checkedin-status-' . $new_status;
641
		$this->_template_args['success'] = TRUE;
642
		$this->_return_json();
643
	}
644
645
646
647
648
649
650
	/**
651
	 * 		handles toggleing the checkin status for the registration,
652
	*		@access protected
653
	*		@param boolean 	$check_in
0 ignored issues
show
Bug introduced by
There is no parameter named $check_in. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
654
	*		@return void
655
	*/
656
	protected function _toggle_checkin_status() {
657
		//first let's get the query args out of the way for the redirect
658
		$query_args = array(
659
			'action' => 'event_registrations',
660
			'event_id' => isset( $this->_req_data['event_id'] ) ? $this->_req_data['event_id'] : NULL,
661
			'DTT_ID' => isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : NULL
662
			);
663
		$new_status = FALSE;
664
665
		// bulk action check in toggle
666
		if ( ! empty( $this->_req_data['checkbox'] ) && is_array( $this->_req_data['checkbox'] )) {
667
			// cycle thru checkboxes
668
			while ( list( $REG_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...
669
				$DTT_ID = isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : NULL;
670
				$new_status = $this->_toggle_checkin($REG_ID, $DTT_ID);
671
			}
672
673
		} elseif ( isset( $this->_req_data['_regid'] ) ) {
674
			//coming from ajax request
675
			$DTT_ID = isset( $this->_req_data['dttid'] ) ? $this->_req_data['dttid'] : NULL;
676
			$query_args['DTT_ID'] = $DTT_ID;
677
			$new_status = $this->_toggle_checkin($this->_req_data['_regid'], $DTT_ID);
678
		} else {
679
			EE_Error::add_error(__('Missing some required data to toggle the Check-in', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__  );
680
		}
681
682
		if ( defined('DOING_AJAX' ) )
683
			return $new_status;
684
685
		$this->_redirect_after_action( FALSE,'', '', $query_args, TRUE );
686
687
	}
688
689
690
691
692
693
	/**
694
	 * This is toggles a single Check-in for the given registration and datetime.
695
	 * @param  int    $REG_ID The registration we're toggling
696
	 * @param  int    $DTT_ID The datetime we're toggling
697
	 * @return int            The new status toggled to.
698
	 */
699
	private function _toggle_checkin($REG_ID, $DTT_ID) {
700
		$REG = EEM_Registration::instance()->get_one_by_ID($REG_ID);
701
		$new_status = $REG->toggle_checkin_status( $DTT_ID );
0 ignored issues
show
Documentation Bug introduced by
The method toggle_checkin_status 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...
702
		if ( $new_status !== FALSE ) {
703
			EE_Error::add_success($REG->get_checkin_msg($DTT_ID) );
0 ignored issues
show
Documentation Bug introduced by
The method get_checkin_msg 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...
704
		} else {
705
			EE_Error::add_error($REG->get_checkin_msg($DTT_ID, TRUE), __FILE__, __FUNCTION__, __LINE__ );
0 ignored issues
show
Documentation Bug introduced by
The method get_checkin_msg 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...
706
			$new_status = FALSE;
707
		}
708
		return $new_status;
709
	}
710
711
712
	/**
713
	 * Takes care of deleting multiple EE_Checkin table rows
714
	 *
715
	 * @access protected
716
	 * @return void
717
	 */
718
	protected function _delete_checkin_rows() {
719
		$query_args = array(
720
			'action' => 'registration_checkins',
721
			'DTT_ID' => isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : 0,
722
			'_REGID' => isset( $this->_req_data['_REGID'] ) ? $this->_req_data['_REGID'] : 0
723
			);
724
		if ( !empty( $this->_req_data['checkbox'] ) && is_array( $this->_req_data['checkbox'] ) ) {
725
			while ( list( $CHK_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...
726
				$errors = 0;
727
				if ( ! EEM_Checkin::instance()->delete_by_ID($CHK_ID ) ) {
728
					$errors++;
729
				}
730
			}
731
		} else {
732
			EE_Error::add_error(__('So, something went wrong with the bulk delete because there was no data received for instructions on WHAT to delete!', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
733
			$this->_redirect_after_action( FALSE, '', '', $query_args, TRUE );
734
		}
735
736
		if ( $errors > 0 ) {
737
			EE_Error::add_error( sprintf( __('There were %d records that did not delete successfully', 'event_espresso'), $errors ), __FILE__, __FUNCTION__, __LINE__ );
0 ignored issues
show
Bug introduced by
The variable $errors 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...
738
		} else {
739
			EE_Error::add_success( __('Records were successfully deleted', 'event_espresso') );
740
		}
741
742
		$this->_redirect_after_action( FALSE, '', '', $query_args, TRUE );
743
	}
744
745
746
747
	/**
748
	 * Deletes a single EE_Checkin row
749
	 * @return void
750
	 */
751
	protected function _delete_checkin_row() {
752
		$query_args = array(
753
			'action' => 'registration_checkins',
754
			'DTT_ID' => isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : 0,
755
			'_REGID' => isset( $this->_req_data['_REGID'] ) ? $this->_req_data['_REGID'] : 0
756
			);
757
758
		if ( !empty( $this->_req_data['CHK_ID'] ) ) {
759
			if ( ! EEM_Checkin::instance()->delete_by_ID($this->_req_data['CHK_ID'] ) ) {
760
				EE_Error::add_error(__('Something went wrong and this check-in record was not deleted', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
761
			} else {
762
				EE_Error::add_success( __('Check-In record successfully deleted', 'event_espresso') );
763
			}
764
		} else {
765
			EE_Error::add_error(__('In order to delete a Check-in record, there must be a Check-In ID available. There is not. It is not your fault, there is just a gremlin living in the code', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__ );
766
		}
767
		$this->_redirect_after_action( FALSE, '', '', $query_args, TRUE );
768
	}
769
770
771
772
773
774
	/**
775
	 * 		generates HTML for the Event Registrations List Table
776
	*		@access protected
777
	*		@return void
778
	*/
779
	protected function _event_registrations_list_table() {
780
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' );
781
		$this->_admin_page_title .= isset( $this->_req_data['event_id'] ) ? $this->get_action_link_or_button('new_registration', 'add-registrant', array('event_id' => $this->_req_data['event_id']), 'add-new-h2') : '';
782
783
		$legend_items = array(
784
			'star-icon' => array(
785
				'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
786
				'desc' => __('This Registrant is the Primary Registrant', 'event_espresso')
787
				),
788
			'checkin' => array(
789
				'class' => 'ee-icon ee-icon-check-in',
790
				'desc' => __('This Registrant has been Checked In', 'event_espresso')
791
				),
792
			'checkout' => array(
793
				'class' => 'ee-icon ee-icon-check-out',
794
				'desc' => __('This Registrant has been Checked Out', 'event_espresso')
795
				),
796
			'nocheckinrecord' => array(
797
				'class' => 'dashicons dashicons-no',
798
				'desc' => __('No Check-in Record has been Created for this Registrant', 'event_espresso')
799
				),
800
			'view_details' => array(
801
				'class' => 'dashicons dashicons-search',
802
				'desc' => __('View All Check-in Records for this Registrant', 'event_espresso')
803
				),
804
			'approved_status' => array(
805
				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
806
				'desc' => EEH_Template::pretty_status( EEM_Registration::status_id_approved, FALSE, 'sentence' )
807
				),
808
            'cancelled_status' => array(
809
				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
810
				'desc' => EEH_Template::pretty_status( EEM_Registration::status_id_cancelled, FALSE, 'sentence' )
811
				),
812
            'declined_status' => array(
813
				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
814
				'desc' => EEH_Template::pretty_status( EEM_Registration::status_id_declined, FALSE, 'sentence' )
815
				),
816
			'not_approved' => array(
817
				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
818
				'desc' => EEH_Template::pretty_status( EEM_Registration::status_id_not_approved, FALSE, 'sentence' )
819
				),
820
			'pending_status' => array(
821
				'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
822
				'desc' => EEH_Template::pretty_status( EEM_Registration::status_id_pending_payment, FALSE, 'sentence' )
823
				)/**/
824
			);
825
		$this->_template_args['after_list_table'] = $this->_display_legend( $legend_items );
826
827
		$event_id = isset( $this->_req_data['event_id'] ) ? $this->_req_data['event_id'] : null;
828
		$this->_template_args['before_list_table'] = !empty( $event_id ) ? '<h2>' . sprintf(__('Viewing Registrations for Event: %s', 'event_espresso'), EEM_Event::instance()->get_one_by_ID($event_id)->get('EVT_name') ) . '</h2>' : '';
829
		$this->_template_args['list_table_hidden_fields'] = !empty( $event_id ) ? '<input type="hidden" name="event_id" value="' . $event_id . '">' : '';
830
831
		$this->display_admin_list_table_page_with_no_sidebar();
832
	}
833
834
835
836
837
	/**
838
	 * 		get_attendees
839
	 * 		@param bool $count whether to return count or data.
840
	*		@access public
841
	*		@return array
842
	*/
843
	public function get_event_attendees( $per_page = 10, $count = FALSE, $trash = FALSE, $orderby = '' ) {
844
845
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, '' );
846
		require_once(EE_MODELS . 'EEM_Attendee.model.php');
847
		//$ATT_MDL = EEM_Attendee::instance();
848
849
		$EVT_ID = isset($this->_req_data['event_id']) ? absint( $this->_req_data['event_id'] ) : FALSE;
850
		$CAT_ID = isset($this->_req_data['category_id']) ? absint( $this->_req_data['category_id'] ) : FALSE;
851
		$DTT_ID = isset( $this->_req_data['DTT_ID'] ) ? $this->_req_data['DTT_ID'] : NULL;
852
853
		$this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : $orderby;
854
855
		switch ($this->_req_data['orderby']) {
856
			case '_REG_date':
857
				$orderby = 'REG_date';
858
				break;
859
			default :
860
				$orderby = 'Attendee.ATT_lname';
861
//				$orderby = 'reg.REG_final_price';
862
		}
863
864
		$sort = ( isset( $this->_req_data['order'] ) && ! empty( $this->_req_data['order'] )) ? $this->_req_data['order'] : 'ASC';
865
866
		$current_page = isset( $this->_req_data['paged'] ) && !empty( $this->_req_data['paged'] ) ? $this->_req_data['paged'] : 1;
867
		$per_page = isset( $this->_req_data['perpage'] ) && !empty( $this->_req_data['perpage'] ) ? $this->_req_data['perpage'] : $per_page;
868
869
870
		$offset = ($current_page-1)*$per_page;
871
		$limit = $count ? NULL : array( $offset, $per_page );
872
		$query_params = array(array('Event.status'=>array('IN',  array_keys(EEM_Event::instance()->get_status_array()))));
873
		if ($EVT_ID){
874
			$query_params[0]['EVT_ID']=$EVT_ID;
875
		}
876
		if($CAT_ID){
877
			throw new EE_Error("You specified a Category Id for this query. Thats odd because we are now using terms and taxonomies. So did you mean the term taxonomy id o rthe term id?");
878
		}
879
880
		//if DTT is included we do multiple datetimes.
881
		if ( $DTT_ID ) {
882
			$query_params[0]['Ticket.Datetime.DTT_ID'] = $DTT_ID;
883
		}
884
885
		//make sure we only have default where on the current regs
886
		$query_params['default_where_conditions'] = 'this_model_only';
887
888
		$status_ids_array = apply_filters( 'FHEE__Extend_Registrations_Admin_Page__get_event_attendees__status_ids_array', array( EEM_Registration::status_id_pending_payment, EEM_Registration::status_id_approved ) );
889
890
		$query_params[0]['STS_ID']= array('IN', $status_ids_array );
891
892
		if($trash){
893
			$query_params[0]['Attendee.status']=  EEM_CPT_Base::post_status_trashed;
894
		}
895
896
		if ( isset( $this->_req_data['s'] ) ) {
897
			$sstr = '%' . $this->_req_data['s'] . '%';
898
			$query_params[0]['OR'] = array(
899
				'Event.EVT_name' => array( 'LIKE', $sstr),
900
				'Event.EVT_desc' => array( 'LIKE', $sstr ),
901
				'Event.EVT_short_desc' => array( 'LIKE' , $sstr ),
902
				'Attendee.ATT_fname' => array( 'LIKE', $sstr ),
903
				'Attendee.ATT_lname' => array( 'LIKE', $sstr ),
904
				'Attendee.ATT_short_bio' => array( 'LIKE', $sstr ),
905
				'Attendee.ATT_email' => array('LIKE', $sstr ),
906
				'Attendee.ATT_address' => array( 'LIKE', $sstr ),
907
				'Attendee.ATT_address2' => array( 'LIKE', $sstr ),
908
				'Attendee.ATT_city' => array( 'LIKE', $sstr ),
909
				'REG_final_price' => array( 'LIKE', $sstr ),
910
				'REG_code' => array( 'LIKE', $sstr ),
911
				'REG_count' => array( 'LIKE' , $sstr ),
912
				'REG_group_size' => array( 'LIKE' , $sstr ),
913
				'Ticket.TKT_name' => array( 'LIKE', $sstr ),
914
				'Ticket.TKT_description' => array( 'LIKE', $sstr )
915
				);
916
		}
917
918
		$query_params['order_by'][$orderby] = $sort;
919
		$query_params['limit'] = $limit;
920
		$query_params['force_join'] = array('Attendee');//force join to attendee model so that it gets cached, because we're going to need the attendee for each registration
921
		if($count){
922
			$registrations = EEM_Registration::instance()->count(array($query_params[0], 'default_where_conditions' => 'this_model_only' ));
923
		}else{
924
			$registrations = EEM_Registration::instance()->get_all($query_params);
925
926
927
	//		$registrations = EEM_Registration::instance();
928
	//		$all_attendees = EEM_Attendee::instance()->get_event_attendees( $EVT_ID, $CAT_ID, $reg_status, $trash, $orderby, $sort, $limit, $output );
929
			if ( isset( $registrations[0] ) && $registrations[0] instanceof EE_Registration ) {
930
				//EEH_Debug_Tools::printr( $all_attendees[0], '$all_attendees[0]  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
931
				// name
932
				$first_registration = $registrations[0];
933
				$event_obj = $first_registration->event_obj();
934
				if($event_obj){
935
					$event_name = $first_registration->event_obj()->name();
936
					$event_date = 'TODO: we need to get date from earliest price date or should this be the actual event date?';//$first_registration->date_obj()->reg_start_date_and_time('l F j, Y,', ' g:i:s a');// isset( $registrations[0]->DTT_EVT_start ) ? date( 'l F j, Y,    g:i:s a', $registrations[0]->DTT_EVT_start ) : '';
937
					// edit event link
938 View Code Duplication
					if ( $event_name != '' ) {
939
						$edit_event_url = self::add_query_args_and_nonce( array( 'action'=>'edit_event', 'EVT_ID'=>$EVT_ID ), EVENTS_ADMIN_URL );
940
						$edit_event_lnk = '<a href="'.$edit_event_url.'" title="' . esc_attr__( 'Edit ', 'event_espresso' ) . $event_name . '">' . __( 'Edit Event', 'event_espresso' ) . '</a>';
941
						$event_name .= ' <span class="admin-page-header-edit-lnk not-bold">' . $edit_event_lnk . '</span>' ;
942
					}
943
944
					$back_2_reg_url = self::add_query_args_and_nonce( array( 'action'=>'default' ), REG_ADMIN_URL );
945
					$back_2_reg_lnk = '<a href="'.$back_2_reg_url.'" title="' . esc_attr__( 'click to return to viewing all registrations ', 'event_espresso' ) . '">&laquo; ' . __( 'Back to All Registrations', 'event_espresso' ) . '</a>';
946
947
					$this->_template_args['before_admin_page_content'] = '
948
				<div id="admin-page-header">
949
					<h1><span class="small-text not-bold">'.__( 'Event: ', 'event_espresso' ).'</span>'. $event_name .'</h1>
950
					<h3><span class="small-text not-bold">'.__( 'Date: ', 'event_espresso' ). '</span>'. $event_date .'</h3>
951
					<span class="admin-page-header-go-back-lnk not-bold">' . $back_2_reg_lnk . '</span>
952
				</div>
953
				';
954
				}
955
			}
956
		}
957
958
		return $registrations;
959
	}
960
961
} //end class Registrations Admin Page
962