Completed
Branch FET-8385-datetime-ticket-selec... (ec342c)
by
unknown
45:18 queued 34:32
created

Registrations_Admin_Page::get_registrations()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 8
nop 4
dl 0
loc 18
rs 9.2
c 0
b 0
f 0
1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
    exit('No direct script access allowed');
3
}
4
5
6
/**
7
 * Event Espresso
8
 * Event Registration and Management Plugin for WordPress
9
 * @ package            Event Espresso
10
 * @ author                Seth Shoultes
11
 * @ copyright        (c) 2008-2011 Event Espresso  All Rights Reserved.
12
 * @ license            {@link http://eventespresso.com/support/terms-conditions/}   * see Plugin Licensing *
13
 * @ link                    {@link http://www.eventespresso.com}
14
 * @ since                4.0
15
 * ------------------------------------------------------------------------
16
 * Registrations_Admin_Page class
17
 *
18
 * @package               Event Espresso
19
 * @subpackage            includes/core/admin/transactions/Registrations_Admin_Page.core.php
20
 * @author                Brent Christensen
21
 *                        ------------------------------------------------------------------------
22
 */
23
class Registrations_Admin_Page extends EE_Admin_Page_CPT
24
{
25
26
    /**
27
     * @var EE_Registration
28
     */
29
    private $_registration;
30
31
    /**
32
     * @var EE_Event
33
     */
34
    private $_reg_event;
35
36
    /**
37
     * @var EE_Session
38
     */
39
    private $_session;
40
41
    private static $_reg_status;
42
43
    /**
44
     * Form for displaying the custom questions for this registration.
45
     * This gets used a few times throughout the request so its best to cache it
46
     *
47
     * @var EE_Registration_Custom_Questions_Form
48
     */
49
    protected $_reg_custom_questions_form = null;
50
51
52
    /**
53
     *        constructor
54
     *
55
     * @Constructor
56
     * @access public
57
     * @param bool $routing
58
     * @return Registrations_Admin_Page
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
59
     */
60
    public function __construct($routing = true)
61
    {
62
        parent::__construct($routing);
63
        add_action('wp_loaded', array($this, 'wp_loaded'));
64
    }
65
66
67
    public function wp_loaded()
68
    {
69
        // when adding a new registration...
70
        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'new_registration') {
71
            EE_System::do_not_cache();
72
            if ( ! isset($this->_req_data['processing_registration'])
73
                 || absint($this->_req_data['processing_registration']) !== 1
74
            ) {
75
                // and it's NOT the attendee information reg step
76
                // force cookie expiration by setting time to last week
77
                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
78
                // and update the global
79
                $_COOKIE['ee_registration_added'] = 0;
80
            }
81
        }
82
    }
83
84
85
    protected function _init_page_props()
86
    {
87
        $this->page_slug        = REG_PG_SLUG;
88
        $this->_admin_base_url  = REG_ADMIN_URL;
89
        $this->_admin_base_path = REG_ADMIN;
90
        $this->page_label       = __('Registrations', 'event_espresso');
91
        $this->_cpt_routes      = array(
92
            'add_new_attendee' => 'espresso_attendees',
93
            'edit_attendee'    => 'espresso_attendees',
94
            'insert_attendee'  => 'espresso_attendees',
95
            'update_attendee'  => 'espresso_attendees',
96
        );
97
        $this->_cpt_model_names = array(
98
            'add_new_attendee' => 'EEM_Attendee',
99
            'edit_attendee'    => 'EEM_Attendee',
100
        );
101
        $this->_cpt_edit_routes = array(
102
            'espresso_attendees' => 'edit_attendee',
103
        );
104
        $this->_pagenow_map     = array(
105
            'add_new_attendee' => 'post-new.php',
106
            'edit_attendee'    => 'post.php',
107
            'trash'            => 'post.php',
108
        );
109
        add_action('edit_form_after_title', array($this, 'after_title_form_fields'), 10);
110
        //add filters so that the comment urls don't take users to a confusing 404 page
111
        add_filter('get_comment_link', array($this, 'clear_comment_link'), 10, 3);
112
    }
113
114
115
    public function clear_comment_link($link, $comment, $args)
0 ignored issues
show
Unused Code introduced by
The parameter $args 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...
116
    {
117
        //gotta make sure this only happens on this route
118
        $post_type = get_post_type($comment->comment_post_ID);
119
        if ($post_type === 'espresso_attendees') {
120
            return '#commentsdiv';
121
        }
122
        return $link;
123
    }
124
125
126
    protected function _ajax_hooks()
127
    {
128
        //todo: all hooks for registrations ajax goes in here
129
        add_action('wp_ajax_toggle_checkin_status', array($this, 'toggle_checkin_status'));
130
    }
131
132
133
    protected function _define_page_props()
134
    {
135
        $this->_admin_page_title = $this->page_label;
136
        $this->_labels           = array(
137
            'buttons'                      => array(
138
                'add-registrant'      => __('Add New Registration', 'event_espresso'),
139
                'add-attendee'        => __('Add Contact', 'event_espresso'),
140
                'edit'                => __('Edit Contact', 'event_espresso'),
141
                'report'              => __("Event Registrations CSV Report", "event_espresso"),
142
                'report_all'          => __('All Registrations CSV Report', 'event_espresso'),
143
                'report_filtered'     => __('Filtered CSV Report', 'event_espresso'),
144
                'contact_list_report' => __('Contact List Report', 'event_espresso'),
145
                'contact_list_export' => __("Export Data", "event_espresso"),
146
            ),
147
            'publishbox'                   => array(
148
                'add_new_attendee' => __("Add Contact Record", 'event_espresso'),
149
                'edit_attendee'    => __("Update Contact Record", 'event_espresso'),
150
            ),
151
            'hide_add_button_on_cpt_route' => array(
152
                'edit_attendee' => true,
153
            ),
154
        );
155
    }
156
157
158
    /**
159
     *        grab url requests and route them
160
     *
161
     * @access private
162
     * @return void
163
     */
164
    public function _set_page_routes()
165
    {
166
        $this->_get_registration_status_array();
167
        $reg_id             = ! empty($this->_req_data['_REG_ID']) && ! is_array($this->_req_data['_REG_ID'])
168
            ? $this->_req_data['_REG_ID'] : 0;
169
        $att_id             = ! empty($this->_req_data['ATT_ID']) && ! is_array($this->_req_data['ATT_ID'])
170
            ? $this->_req_data['ATT_ID'] : 0;
171
        $att_id             = ! empty($this->_req_data['post']) && ! is_array($this->_req_data['post']) ? $this->_req_data['post']
172
            : $att_id;
173
        $this->_page_routes = array(
174
            'default'                            => array(
175
                'func'       => '_registrations_overview_list_table',
176
                'capability' => 'ee_read_registrations',
177
            ),
178
            'view_registration'                  => array(
179
                'func'       => '_registration_details',
180
                'capability' => 'ee_read_registration',
181
                'obj_id'     => $reg_id,
182
            ),
183
            'edit_registration'                  => array(
184
                'func'               => '_update_attendee_registration_form',
185
                'noheader'           => true,
186
                'headers_sent_route' => 'view_registration',
187
                'capability'         => 'ee_edit_registration',
188
                'obj_id'             => $reg_id,
189
                '_REG_ID'            => $reg_id,
190
            ),
191
            'trash_registrations'                => array(
192
                'func'       => '_trash_or_restore_registrations',
193
                'args'       => array('trash' => true),
194
                'noheader'   => true,
195
                'capability' => 'ee_delete_registrations',
196
            ),
197
            'restore_registrations'              => array(
198
                'func'       => '_trash_or_restore_registrations',
199
                'args'       => array('trash' => false),
200
                'noheader'   => true,
201
                'capability' => 'ee_delete_registrations',
202
            ),
203
            'delete_registrations'               => array(
204
                'func'       => '_delete_registrations',
205
                'noheader'   => true,
206
                'capability' => 'ee_delete_registrations',
207
            ),
208
            'new_registration'                   => array(
209
                'func'       => 'new_registration',
210
                'capability' => 'ee_edit_registrations',
211
            ),
212
            'process_reg_step'                   => array(
213
                'func'       => 'process_reg_step',
214
                'noheader'   => true,
215
                'capability' => 'ee_edit_registrations',
216
            ),
217
            'redirect_to_txn'                    => array(
218
                'func'       => 'redirect_to_txn',
219
                'noheader'   => true,
220
                'capability' => 'ee_edit_registrations',
221
            ),
222
            'change_reg_status'                  => array(
223
                'func'       => '_change_reg_status',
224
                'noheader'   => true,
225
                'capability' => 'ee_edit_registration',
226
                'obj_id'     => $reg_id,
227
            ),
228
            'approve_registration'               => array(
229
                'func'       => 'approve_registration',
230
                'noheader'   => true,
231
                'capability' => 'ee_edit_registration',
232
                'obj_id'     => $reg_id,
233
            ),
234
            'approve_and_notify_registration'    => array(
235
                'func'       => 'approve_registration',
236
                'noheader'   => true,
237
                'args'       => array(true),
238
                'capability' => 'ee_edit_registration',
239
                'obj_id'     => $reg_id,
240
            ),
241
            'decline_registration'               => array(
242
                'func'       => 'decline_registration',
243
                'noheader'   => true,
244
                'capability' => 'ee_edit_registration',
245
                'obj_id'     => $reg_id,
246
            ),
247
            'decline_and_notify_registration'    => array(
248
                'func'       => 'decline_registration',
249
                'noheader'   => true,
250
                'args'       => array(true),
251
                'capability' => 'ee_edit_registration',
252
                'obj_id'     => $reg_id,
253
            ),
254
            'pending_registration'               => array(
255
                'func'       => 'pending_registration',
256
                'noheader'   => true,
257
                'capability' => 'ee_edit_registration',
258
                'obj_id'     => $reg_id,
259
            ),
260
            'pending_and_notify_registration'    => array(
261
                'func'       => 'pending_registration',
262
                'noheader'   => true,
263
                'args'       => array(true),
264
                'capability' => 'ee_edit_registration',
265
                'obj_id'     => $reg_id,
266
            ),
267
            'no_approve_registration'            => array(
268
                'func'       => 'not_approve_registration',
269
                'noheader'   => true,
270
                'capability' => 'ee_edit_registration',
271
                'obj_id'     => $reg_id,
272
            ),
273
            'no_approve_and_notify_registration' => array(
274
                'func'       => 'not_approve_registration',
275
                'noheader'   => true,
276
                'args'       => array(true),
277
                'capability' => 'ee_edit_registration',
278
                'obj_id'     => $reg_id,
279
            ),
280
            'cancel_registration'                => array(
281
                'func'       => 'cancel_registration',
282
                'noheader'   => true,
283
                'capability' => 'ee_edit_registration',
284
                'obj_id'     => $reg_id,
285
            ),
286
            'cancel_and_notify_registration'     => array(
287
                'func'       => 'cancel_registration',
288
                'noheader'   => true,
289
                'args'       => array(true),
290
                'capability' => 'ee_edit_registration',
291
                'obj_id'     => $reg_id,
292
            ),
293
            'contact_list'                       => array(
294
                'func'       => '_attendee_contact_list_table',
295
                'capability' => 'ee_read_contacts',
296
            ),
297
            'add_new_attendee'                   => array(
298
                'func' => '_create_new_cpt_item',
299
                'args' => array(
300
                    'new_attendee' => true,
301
                    'capability'   => 'ee_edit_contacts',
302
                ),
303
            ),
304
            'edit_attendee'                      => array(
305
                'func'       => '_edit_cpt_item',
306
                'capability' => 'ee_edit_contacts',
307
                'obj_id'     => $att_id,
308
            ),
309
            'duplicate_attendee'                 => array(
310
                'func'       => '_duplicate_attendee',
311
                'noheader'   => true,
312
                'capability' => 'ee_edit_contacts',
313
                'obj_id'     => $att_id,
314
            ),
315
            'insert_attendee'                    => array(
316
                'func'       => '_insert_or_update_attendee',
317
                'args'       => array(
318
                    'new_attendee' => true,
319
                ),
320
                'noheader'   => true,
321
                'capability' => 'ee_edit_contacts',
322
            ),
323
            'update_attendee'                    => array(
324
                'func'       => '_insert_or_update_attendee',
325
                'args'       => array(
326
                    'new_attendee' => false,
327
                ),
328
                'noheader'   => true,
329
                'capability' => 'ee_edit_contacts',
330
                'obj_id'     => $att_id,
331
            ),
332
            'trash_attendees'                    => array(
333
                'func'       => '_trash_or_restore_attendees',
334
                'args'       => array(
335
                    'trash' => true,
336
                ),
337
                'noheader'   => true,
338
                'capability' => 'ee_delete_contacts',
339
                'obj_id'     => $att_id,
340
            ),
341
            'restore_attendees'                  => array(
342
                'func'       => '_trash_or_restore_attendees',
343
                'args'       => array(
344
                    'trash' => false,
345
                ),
346
                'noheader'   => true,
347
                'capability' => 'ee_delete_contacts',
348
                'obj_id'     => $att_id,
349
            ),
350
            'resend_registration'                => array(
351
                'func'       => '_resend_registration',
352
                'noheader'   => true,
353
                'capability' => 'ee_send_message',
354
            ),
355
            'registrations_report'               => array(
356
                'func'       => '_registrations_report',
357
                'noheader'   => true,
358
                'capability' => 'ee_read_registrations',
359
            ),
360
            'contact_list_export'                => array(
361
                'func'       => '_contact_list_export',
362
                'noheader'   => true,
363
                'capability' => 'export',
364
            ),
365
            'contact_list_report'                => array(
366
                'func'       => '_contact_list_report',
367
                'noheader'   => true,
368
                'capability' => 'ee_read_contacts',
369
            ),
370
        );
371
    }
372
373
374
    protected function _set_page_config()
375
    {
376
        $this->_page_config = array(
377
            'default'           => array(
378
                'nav'           => array(
379
                    'label' => __('Overview', 'event_espresso'),
380
                    'order' => 5,
381
                ),
382
                'help_tabs'     => array(
383
                    'registrations_overview_help_tab'                       => array(
384
                        'title'    => __('Registrations Overview', 'event_espresso'),
385
                        'filename' => 'registrations_overview',
386
                    ),
387
                    'registrations_overview_table_column_headings_help_tab' => array(
388
                        'title'    => __('Registrations Table Column Headings', 'event_espresso'),
389
                        'filename' => 'registrations_overview_table_column_headings',
390
                    ),
391
                    'registrations_overview_filters_help_tab'               => array(
392
                        'title'    => __('Registration Filters', 'event_espresso'),
393
                        'filename' => 'registrations_overview_filters',
394
                    ),
395
                    'registrations_overview_views_help_tab'                 => array(
396
                        'title'    => __('Registration Views', 'event_espresso'),
397
                        'filename' => 'registrations_overview_views',
398
                    ),
399
                    'registrations_regoverview_other_help_tab'              => array(
400
                        'title'    => __('Registrations Other', 'event_espresso'),
401
                        'filename' => 'registrations_overview_other',
402
                    ),
403
                ),
404
                'help_tour'     => array('Registration_Overview_Help_Tour'),
405
                'qtips'         => array('Registration_List_Table_Tips'),
406
                'list_table'    => 'EE_Registrations_List_Table',
407
                'require_nonce' => false,
408
            ),
409
            'view_registration' => array(
410
                'nav'           => array(
411
                    'label'      => __('REG Details', 'event_espresso'),
412
                    'order'      => 15,
413
                    'url'        => isset($this->_req_data['_REG_ID'])
414
                        ? add_query_arg(array('_REG_ID' => $this->_req_data['_REG_ID']), $this->_current_page_view_url)
415
                        : $this->_admin_base_url,
416
                    'persistent' => false,
417
                ),
418
                'help_tabs'     => array(
419
                    'registrations_details_help_tab'                    => array(
420
                        'title'    => __('Registration Details', 'event_espresso'),
421
                        'filename' => 'registrations_details',
422
                    ),
423
                    'registrations_details_table_help_tab'              => array(
424
                        'title'    => __('Registration Details Table', 'event_espresso'),
425
                        'filename' => 'registrations_details_table',
426
                    ),
427
                    'registrations_details_form_answers_help_tab'       => array(
428
                        'title'    => __('Registration Form Answers', 'event_espresso'),
429
                        'filename' => 'registrations_details_form_answers',
430
                    ),
431
                    'registrations_details_registrant_details_help_tab' => array(
432
                        'title'    => __('Contact Details', 'event_espresso'),
433
                        'filename' => 'registrations_details_registrant_details',
434
                    ),
435
                ),
436
                'help_tour'     => array('Registration_Details_Help_Tour'),
437
                'metaboxes'     => array_merge($this->_default_espresso_metaboxes,
438
                    array('_registration_details_metaboxes')),
439
                'require_nonce' => false,
440
            ),
441
            'new_registration'  => array(
442
                'nav'           => array(
443
                    'label'      => __('Add New Registration', 'event_espresso'),
444
                    'url'        => '#',
445
                    'order'      => 15,
446
                    'persistent' => false,
447
                ),
448
                'metaboxes'     => $this->_default_espresso_metaboxes,
449
                'labels'        => array(
450
                    'publishbox' => __('Save Registration', 'event_espresso'),
451
                ),
452
                'require_nonce' => false,
453
            ),
454
            'add_new_attendee'  => array(
455
                'nav'           => array(
456
                    'label'      => __('Add Contact', 'event_espresso'),
457
                    'order'      => 15,
458
                    'persistent' => false,
459
                ),
460
                'metaboxes'     => array_merge($this->_default_espresso_metaboxes,
461
                    array('_publish_post_box', 'attendee_editor_metaboxes')),
462
                'require_nonce' => false,
463
            ),
464
            'edit_attendee'     => array(
465
                'nav'           => array(
466
                    'label'      => __('Edit Contact', 'event_espresso'),
467
                    'order'      => 15,
468
                    'persistent' => false,
469
                    'url'        => isset($this->_req_data['ATT_ID'])
470
                        ? add_query_arg(array('ATT_ID' => $this->_req_data['ATT_ID']), $this->_current_page_view_url)
471
                        : $this->_admin_base_url,
472
                ),
473
                'metaboxes'     => array('attendee_editor_metaboxes'),
474
                'require_nonce' => false,
475
            ),
476
            'contact_list'      => array(
477
                'nav'           => array(
478
                    'label' => __('Contact List', 'event_espresso'),
479
                    'order' => 20,
480
                ),
481
                'list_table'    => 'EE_Attendee_Contact_List_Table',
482
                'help_tabs'     => array(
483
                    'registrations_contact_list_help_tab'                       => array(
484
                        'title'    => __('Registrations Contact List', 'event_espresso'),
485
                        'filename' => 'registrations_contact_list',
486
                    ),
487
                    'registrations_contact-list_table_column_headings_help_tab' => array(
488
                        'title'    => __('Contact List Table Column Headings', 'event_espresso'),
489
                        'filename' => 'registrations_contact_list_table_column_headings',
490
                    ),
491
                    'registrations_contact_list_views_help_tab'                 => array(
492
                        'title'    => __('Contact List Views', 'event_espresso'),
493
                        'filename' => 'registrations_contact_list_views',
494
                    ),
495
                    'registrations_contact_list_other_help_tab'                 => array(
496
                        'title'    => __('Contact List Other', 'event_espresso'),
497
                        'filename' => 'registrations_contact_list_other',
498
                    ),
499
                ),
500
                'help_tour'     => array('Contact_List_Help_Tour'),
501
                'metaboxes'     => array(),
502
                'require_nonce' => false,
503
            ),
504
            //override default cpt routes
505
            'create_new'        => '',
506
            'edit'              => '',
507
        );
508
    }
509
510
511
    /**
512
     * The below methods aren't used by this class currently
513
     */
514
    protected function _add_screen_options()
515
    {
516
    }
517
518
519
    protected function _add_feature_pointers()
520
    {
521
    }
522
523
524
    public function admin_init()
525
    {
526
        EE_Registry::$i18n_js_strings['update_att_qstns'] = __('click "Update Registration Questions" to save your changes',
527
            'event_espresso');
528
    }
529
530
531
    public function admin_notices()
532
    {
533
    }
534
535
536
    public function admin_footer_scripts()
537
    {
538
    }
539
540
541
    /**
542
     *        get list of registration statuses
543
     *
544
     * @access private
545
     * @return void
546
     */
547
    private function _get_registration_status_array()
548
    {
549
        self::$_reg_status = EEM_Registration::reg_status_array(array(), true);
550
    }
551
552
553
    protected function _add_screen_options_default()
554
    {
555
        $this->_per_page_screen_option();
556
    }
557
558
559 View Code Duplication
    protected function _add_screen_options_contact_list()
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...
560
    {
561
        $page_title              = $this->_admin_page_title;
562
        $this->_admin_page_title = __("Contacts", 'event_espresso');
563
        $this->_per_page_screen_option();
564
        $this->_admin_page_title = $page_title;
565
    }
566
567
568 View Code Duplication
    public function load_scripts_styles()
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...
569
    {
570
        //style
571
        //wp_register_style('espresso_attendees', ATT_ASSETS_URL . 'espresso_attendees_admin.css', array(), EVENT_ESPRESSO_VERSION );
572
        wp_register_style('espresso_reg', REG_ASSETS_URL . 'espresso_registrations_admin.css', array('ee-admin-css'),
573
            EVENT_ESPRESSO_VERSION);
574
        wp_enqueue_style('espresso_reg');
575
        //script
576
        wp_register_script('espresso_reg', REG_ASSETS_URL . 'espresso_registrations_admin.js',
577
            array('jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'), EVENT_ESPRESSO_VERSION, true);
578
        wp_enqueue_script('espresso_reg');
579
    }
580
581
582
    public function load_scripts_styles_edit_attendee()
583
    {
584
        //stuff to only show up on our attendee edit details page.
585
        $attendee_details_translations = array(
586
            'att_publish_text' => sprintf(__('Created on: <b>%1$s</b>', 'event_espresso'),
587
                $this->_cpt_model_obj->get_datetime('ATT_created')),
588
        );
589
        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
590
        wp_enqueue_script('jquery-validate');
591
    }
592
593
594
    public function load_scripts_styles_view_registration()
595
    {
596
        //styles
597
        wp_enqueue_style('espresso-ui-theme');
598
        //scripts
599
        $this->_get_reg_custom_questions_form($this->_registration->ID());
600
        $this->_reg_custom_questions_form->wp_enqueue_scripts(true);
601
    }
602
603
604
    public function load_scripts_styles_contact_list()
605
    {
606
        wp_deregister_style('espresso_reg');
607
        wp_register_style('espresso_att', REG_ASSETS_URL . 'espresso_attendees_admin.css', array('ee-admin-css'),
608
            EVENT_ESPRESSO_VERSION);
609
        wp_enqueue_style('espresso_att');
610
    }
611
612
613
    public function load_scripts_styles_new_registration()
614
    {
615
        wp_register_script('ee-spco-for-admin', REG_ASSETS_URL . 'spco_for_admin.js', array('underscore', 'jquery'),
616
            EVENT_ESPRESSO_VERSION, true);
617
        wp_enqueue_script('ee-spco-for-admin');
618
        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
619
        EE_Form_Section_Proper::wp_enqueue_scripts();
620
        EED_Ticket_Selector::load_tckt_slctr_assets();
621
        EE_Datepicker_Input::enqueue_styles_and_scripts();
622
    }
623
624
625
    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
626
    {
627
        add_filter('FHEE_load_EE_messages', '__return_true');
628
    }
629
630
631
    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
632
    {
633
        add_filter('FHEE_load_EE_messages', '__return_true');
634
    }
635
636
637
    protected function _set_list_table_views_default()
638
    {
639
        //for notification related bulk actions we need to make sure only active messengers have an option.
640
        EED_Messages::set_autoloaders();
641
        /** @type EE_Message_Resource_Manager $message_resource_manager */
642
        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
643
        $active_mts               = $message_resource_manager->list_of_active_message_types();
644
        //key= bulk_action_slug, value= message type.
645
        $match_array = array(
646
            'approve_registration'    => 'registration',
647
            'decline_registration'    => 'declined_registration',
648
            'pending_registration'    => 'pending_approval',
649
            'no_approve_registration' => 'not_approved_registration',
650
            'cancel_registration'     => 'cancelled_registration',
651
        );
652
        /** setup reg status bulk actions **/
653
        $def_reg_status_actions['approve_registration'] = __('Approve Registrations', 'event_espresso');
0 ignored issues
show
Coding Style Comprehensibility introduced by
$def_reg_status_actions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $def_reg_status_actions = 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...
654 View Code Duplication
        if (in_array($match_array['approve_registration'], $active_mts)
655
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'batch_send_messages')
656
        ) {
657
            $def_reg_status_actions['approve_and_notify_registration'] = __('Approve and Notify Registrations',
658
                'event_espresso');
659
        }
660
        $def_reg_status_actions['decline_registration'] = __('Decline Registrations', 'event_espresso');
661 View Code Duplication
        if (in_array($match_array['decline_registration'], $active_mts)
662
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'batch_send_messages')
663
        ) {
664
            $def_reg_status_actions['decline_and_notify_registration'] = __('Decline and Notify Registrations',
665
                'event_espresso');
666
        }
667
        $def_reg_status_actions['pending_registration'] = __('Set Registrations to Pending Payment', 'event_espresso');
668 View Code Duplication
        if (in_array($match_array['pending_registration'], $active_mts)
669
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'batch_send_messages')
670
        ) {
671
            $def_reg_status_actions['pending_and_notify_registration'] = __('Set Registrations to Pending Payment and Notify',
672
                'event_espresso');
673
        }
674
        $def_reg_status_actions['no_approve_registration'] = __('Set Registrations to Not Approved', 'event_espresso');
675 View Code Duplication
        if (in_array($match_array['no_approve_registration'], $active_mts)
676
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'batch_send_messages')
677
        ) {
678
            $def_reg_status_actions['no_approve_and_notify_registration'] = __('Set Registrations to Not Approved and Notify',
679
                'event_espresso');
680
        }
681
        $def_reg_status_actions['cancel_registration'] = __('Cancel Registrations', 'event_espresso');
682 View Code Duplication
        if (in_array($match_array['cancel_registration'], $active_mts)
683
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'batch_send_messages')
684
        ) {
685
            $def_reg_status_actions['cancel_and_notify_registration'] = __('Cancel Registrations and Notify',
686
                'event_espresso');
687
        }
688
        $this->_views = array(
689
            'all'   => array(
690
                'slug'        => 'all',
691
                'label'       => __('View All Registrations', 'event_espresso'),
692
                'count'       => 0,
693
                'bulk_action' => array_merge($def_reg_status_actions, array(
694
                    'trash_registrations' => __('Trash Registrations', 'event_espresso'),
695
                )),
696
            ),
697
            'month' => array(
698
                'slug'        => 'month',
699
                'label'       => __('This Month', 'event_espresso'),
700
                'count'       => 0,
701
                'bulk_action' => array_merge($def_reg_status_actions, array(
702
                    'trash_registrations' => __('Trash Registrations', 'event_espresso'),
703
                )),
704
            ),
705
            'today' => array(
706
                'slug'        => 'today',
707
                'label'       => sprintf(__('Today - %s', 'event_espresso'), date('M d, Y', current_time('timestamp'))),
708
                'count'       => 0,
709
                'bulk_action' => array_merge($def_reg_status_actions, array(
710
                    'trash_registrations' => __('Trash Registrations', 'event_espresso'),
711
                )),
712
            ),
713
        );
714
        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_registrations',
715
            'espresso_registrations_delete_registration')
716
        ) {
717
            $this->_views['incomplete'] = array(
718
                'slug'        => 'incomplete',
719
                'label'       => __('Incomplete', 'event_espresso'),
720
                'count'       => 0,
721
                'bulk_action' => array(
722
                    'trash_registrations' => __('Trash Registrations', 'event_espresso'),
723
                ),
724
            );
725
            $this->_views['trash']      = array(
726
                'slug'        => 'trash',
727
                'label'       => __('Trash', 'event_espresso'),
728
                'count'       => 0,
729
                'bulk_action' => array(
730
                    'restore_registrations' => __('Restore Registrations', 'event_espresso'),
731
                    'delete_registrations'  => __('Delete Registrations Permanently', 'event_espresso'),
732
                ),
733
            );
734
        }
735
    }
736
737
738
    protected function _set_list_table_views_contact_list()
739
    {
740
        $this->_views = array(
741
            'in_use' => array(
742
                'slug'        => 'in_use',
743
                'label'       => __('In Use', 'event_espresso'),
744
                'count'       => 0,
745
                'bulk_action' => array(
746
                    'trash_attendees' => __('Move to Trash', 'event_espresso'),
747
                ),
748
            ),
749
        );
750
        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_contacts',
751
            'espresso_registrations_trash_attendees')
752
        ) {
753
            $this->_views['trash'] = array(
754
                'slug'        => 'trash',
755
                'label'       => __('Trash', 'event_espresso'),
756
                'count'       => 0,
757
                'bulk_action' => array(
758
                    'restore_attendees' => __('Restore from Trash', 'event_espresso'),
759
                ),
760
            );
761
        }
762
    }
763
764
765
    protected function _registration_legend_items()
766
    {
767
        $fc_items = array(
768
            'star-icon'        => array(
769
                'class' => 'dashicons dashicons-star-filled lt-blue-icon ee-icon-size-8',
770
                'desc'  => __('This is the Primary Registrant', 'event_espresso'),
771
            ),
772
            'view_details'     => array(
773
                'class' => 'dashicons dashicons-clipboard',
774
                'desc'  => __('View Registration Details', 'event_espresso'),
775
            ),
776
            'edit_attendee'    => array(
777
                'class' => 'ee-icon ee-icon-user-edit ee-icon-size-16',
778
                'desc'  => __('Edit Contact Details', 'event_espresso'),
779
            ),
780
            'view_transaction' => array(
781
                'class' => 'dashicons dashicons-cart',
782
                'desc'  => __('View Transaction Details', 'event_espresso'),
783
            ),
784
            'view_invoice'     => array(
785
                'class' => 'dashicons dashicons-media-spreadsheet',
786
                'desc'  => __('View Transaction Invoice', 'event_espresso'),
787
            ),
788
        );
789
        if (EE_Registry::instance()->CAP->current_user_can('ee_send_message',
790
            'espresso_registrations_resend_registration')
791
        ) {
792
            $fc_items['resend_registration'] = array(
793
                'class' => 'dashicons dashicons-email-alt',
794
                'desc'  => __('Resend Registration Details', 'event_espresso'),
795
            );
796
        } else {
797
            $fc_items['blank'] = array('class' => 'blank', 'desc' => '');
798
        }
799 View Code Duplication
        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
800
            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
801
            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
802
                $fc_items['view_related_messages'] = array(
803
                    'class' => $related_for_icon['css_class'],
804
                    'desc'  => $related_for_icon['label'],
805
                );
806
            }
807
        }
808
        $sc_items = array(
809
            'approved_status'   => array(
810
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_approved,
811
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'),
812
            ),
813
            'pending_status'    => array(
814
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_pending_payment,
815
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'),
816
            ),
817
            'wait_list'         => array(
818
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_wait_list,
819
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'),
820
            ),
821
            'incomplete_status' => array(
822
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_incomplete,
823
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_incomplete, false, 'sentence'),
824
            ),
825
            'not_approved'      => array(
826
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_not_approved,
827
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'),
828
            ),
829
            'declined_status'   => array(
830
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_declined,
831
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'),
832
            ),
833
            'cancelled_status'  => array(
834
                'class' => 'ee-status-legend ee-status-legend-' . EEM_Registration::status_id_cancelled,
835
                'desc'  => EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'),
836
            ),
837
        );
838
        return array_merge($fc_items, $sc_items);
839
    }
840
841
842
843
    /***************************************        REGISTRATION OVERVIEW        **************************************/
844
    /**
845
     * @throws \EE_Error
846
     */
847
    protected function _registrations_overview_list_table()
848
    {
849
        $this->_template_args['admin_page_header'] = '';
850
        $EVT_ID                                    = ! empty($this->_req_data['event_id']) ? absint($this->_req_data['event_id']) : 0;
851
        if ($EVT_ID) {
852
            if (EE_Registry::instance()->CAP->current_user_can('ee_edit_registrations',
853
                'espresso_registrations_new_registration', $EVT_ID)
854
            ) {
855
                $this->_admin_page_title .= ' ' . $this->get_action_link_or_button('new_registration', 'add-registrant',
856
                        array('event_id' => $EVT_ID), 'add-new-h2');
857
            }
858
            $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
859
            if ($event instanceof EE_Event) {
860
                $this->_template_args['admin_page_header'] = sprintf(__('%s Viewing registrations for the event: %s%s',
861
                    'event_espresso'), '<h3 style="line-height:1.5em;">',
862
                    '<br /><a href="' . EE_Admin_Page::add_query_args_and_nonce(array(
863
                        'action' => 'edit',
864
                        'post'   => $event->ID(),
865
                    ), EVENTS_ADMIN_URL) . '">&nbsp;' . $event->get('EVT_name') . '&nbsp;</a>&nbsp;', '</h3>');
866
            }
867
            $DTT_ID   = ! empty($this->_req_data['datetime_id']) ? absint($this->_req_data['datetime_id']) : 0;
868
            $datetime = EEM_Datetime::instance()->get_one_by_ID($DTT_ID);
869 View Code Duplication
            if ($datetime instanceof EE_Datetime && $this->_template_args['admin_page_header'] !== '') {
870
                $this->_template_args['admin_page_header'] = substr($this->_template_args['admin_page_header'], 0, -5);
871
                $this->_template_args['admin_page_header'] .= ' &nbsp;<span class="drk-grey-text">';
872
                $this->_template_args['admin_page_header'] .= '<span class="dashicons dashicons-calendar"></span>';
873
                $this->_template_args['admin_page_header'] .= $datetime->name();
874
                $this->_template_args['admin_page_header'] .= ' ( ' . $datetime->start_date() . ' )';
875
                $this->_template_args['admin_page_header'] .= '</span></h3>';
876
            }
877
        }
878
        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
879
        $this->display_admin_list_table_page_with_no_sidebar();
880
    }
881
882
883
    /**
884
     * This sets the _registration property for the registration details screen
885
     *
886
     * @access private
887
     * @return bool
888
     */
889
    private function _set_registration_object()
890
    {
891
        //get out if we've already set the object
892
        if (is_object($this->_registration)) {
893
            return true;
894
        }
895
        $REG    = EEM_Registration::instance();
896
        $REG_ID = ( ! empty($this->_req_data['_REG_ID'])) ? absint($this->_req_data['_REG_ID']) : false;
897
        if ($this->_registration = $REG->get_one_by_ID($REG_ID)) {
0 ignored issues
show
Documentation Bug introduced by
It seems like $REG->get_one_by_ID($REG_ID) can also be of type object<EE_Base_Class>. However, the property $_registration is declared as type object<EE_Registration>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
898
            return true;
899
        } else {
900
            $error_msg = sprintf(__('An error occurred and the details for Registration ID #%s could not be retrieved.',
901
                'event_espresso'), $REG_ID);
902
            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
903
            $this->_registration = null;
904
            return false;
905
        }
906
    }
907
908
909
    /**
910
     * Used to retrieve registrations for the list table.
911
     *
912
     * @param int    $per_page
913
     * @param bool   $count
914
     * @param bool   $this_month 
915
     * @param bool   $today
916
     * @return \EE_Registration[]|int
917
     */
918
    public function get_registrations(
919
        $per_page = 10,
920
        $count = false,
921
        $this_month = false,
922
        $today = false
923
    ) {
924
        if( $this_month ) {
925
            $this->_req_data['status'] = 'month';
926
        }
927
        if( $today ) {
928
            $this->_req_data['status'] = 'today';
929
        }
930
        $query_params = $this->_get_registration_query_parameters($this->_req_data, $per_page, $count);
931
        return $count
932
            ? EEM_Registration::instance()->count($query_params)
933
            /** @type EE_Registration[] */
934
            : EEM_Registration::instance()->get_all($query_params);
935
    }
936
937
938
939
    /**
940
     * Retrieves the query parameters to be used by the Registration model for getting registrations.
941
     * Note: this listens to values on the request for some of the query parameters.
942
     *
943
     * @param array $request
944
     * @param int    $per_page
945
     * @param bool   $count
946
     * @return array
947
     */
948
    protected function _get_registration_query_parameters(
949
        $request = array(),
950
        $per_page = 10,
951
        $count = false
952
    ) {
953
954
        $query_params = array(
955
            0                          => $this->_get_where_conditions_for_registrations_query(
956
                $request
957
            ),
958
            'caps'                     => EEM_Registration::caps_read_admin,
959
            'default_where_conditions' => 'this_model_only',
960
        );
961
        if ( ! $count) {
962
            $query_params = array_merge(
963
                $query_params,
964
                $this->_get_orderby_for_registrations_query(),
965
                $this->_get_limit($per_page)
966
            );
967
        }
968
969
        return $query_params;
970
    }
971
972
973
    /**
974
     * This will add EVT_ID to the provided $where array for EE model query parameters.
975
     *
976
     * @param array $request usually the same as $this->_req_data but not necessarily
977
     * @return array
978
     */
979
    protected function _add_event_id_to_where_conditions(array $request)
980
    {
981
        $where = array();
982
        if ( ! empty($request['event_id'])) {
983
            $where['EVT_ID'] = absint($request['event_id']);
984
        }
985
        return $where;
986
    }
987
988
989
    /**
990
     * Adds category ID if it exists in the request to the where conditions for the registrations query.
991
     *
992
     * @param array $request usually the same as $this->_req_data but not necessarily
993
     * @return array
994
     */
995
    protected function _add_category_id_to_where_conditions(array $request)
996
    {
997
        $where = array();
998
        if ( ! empty($request['EVT_CAT']) && (int)$request['EVT_CAT'] !== -1) {
999
            $where['Event.Term_Taxonomy.term_id'] = absint($request['EVT_CAT']);
1000
        }
1001
        return $where;
1002
    }
1003
1004
1005
    /**
1006
     * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
1007
     *
1008
     * @param array $request usually the same as $this->_req_data but not necessarily
1009
     * @return array
1010
     */
1011
    protected function _add_datetime_id_to_where_conditions(array $request)
1012
    {
1013
        $where = array();
1014
        if ( ! empty($request['datetime_id'])) {
1015
            $where['Ticket.Datetime.DTT_ID'] = absint($request['datetime_id']);
1016
        }
1017
        if( ! empty($request['DTT_ID'])){
1018
            $where['Ticket.Datetime.DTT_ID'] = absint($request['DTT_ID']);
1019
        }
1020
        return $where;
1021
    }
1022
1023
1024
    /**
1025
     * Adds the correct registration status to the where conditions for the registrations query.
1026
     *
1027
     * @param array $request usually the same as $this->_req_data but not necessarily
1028
     * @return array
1029
     */
1030
    protected function _add_registration_status_to_where_conditions(array $request)
1031
    {
1032
        $where = array();
1033
        $view  = EEH_Array::is_set( $request, 'status', '' );
1034
        $registration_status = ! empty($request['_reg_status'])
1035
            ? sanitize_text_field($request['_reg_status'])
1036
            : '';
1037
1038
        /*
1039
         * If filtering by registration status, then we show registrations matching that status.
1040
         * If not filtering by specified status, then we show all registrations excluding incomplete registrations UNLESS
1041
         * viewing trashed registrations.
1042
         */
1043
        if ( ! empty($registration_status)) {
1044
            $where['STS_ID'] = $registration_status;
1045
        } else {
1046
            //make sure we exclude incomplete registrations, but only if not trashed.
1047
            if ($view === 'trash') {
1048
                $where['REG_deleted'] = true;
1049
            } else if ($view === 'incomplete') {
1050
                $where['STS_ID'] = EEM_Registration::status_id_incomplete;
1051
            } else {
1052
                $where['STS_ID'] = array('!=', EEM_Registration::status_id_incomplete);
1053
            }
1054
        }
1055
        return $where;
1056
    }
1057
1058
1059
    /**
1060
     * Adds any provided date restraints to the where conditions for the registrations query.
1061
     *
1062
     * @param array $request usually the same as $this->_req_data but not necessarily
1063
     * @return array
1064
     */
1065
    protected function _add_date_to_where_conditions(array $request)
1066
    {
1067
        $where = array();
1068
        $view  = EEH_Array::is_set( $request, 'status', '' );
1069
        $month_range             = ! empty($request['month_range'])
1070
            ? sanitize_text_field($request['month_range'])
1071
            : '';
1072
        $retrieve_for_today      = $view === 'today';
1073
        $retrieve_for_this_month = $view === 'month';
1074
1075
        if ($retrieve_for_today) {
1076
            $now               = date('Y-m-d', current_time('timestamp'));
1077
            $where['REG_date'] = array(
1078
                'BETWEEN',
1079
                array(
1080
                    EEM_Registration::instance()->convert_datetime_for_query(
1081
                        'REG_date',
1082
                        $now . ' 00:00:00',
1083
                        'Y-m-d H:i:s'
1084
                    ),
1085
                    EEM_Registration::instance()->convert_datetime_for_query(
1086
                        'REG_date',
1087
                        $now . ' 23:59:59',
1088
                        'Y-m-d H:i:s'
1089
                    ),
1090
                ),
1091
            );
1092
        } elseif ($retrieve_for_this_month) {
1093
            $current_year_and_month = date('Y-m', current_time('timestamp'));
1094
            $days_this_month        = date('t', current_time('timestamp'));
1095
            $where['REG_date']      = array(
1096
                'BETWEEN',
1097
                array(
1098
                    EEM_Registration::instance()->convert_datetime_for_query(
1099
                        'REG_date',
1100
                        $current_year_and_month . '-01 00:00:00',
1101
                        'Y-m-d H:i:s'
1102
                    ),
1103
                    EEM_Registration::instance()->convert_datetime_for_query(
1104
                        'REG_date',
1105
                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
1106
                        'Y-m-d H:i:s'
1107
                    ),
1108
                ),
1109
            );
1110
        } elseif ($month_range) {
1111
            $pieces          = explode(' ', $month_range, 3);
1112
            $month_requested = ! empty($pieces[0])
1113
                ? date('m', strtotime($month_range))
1114
                : '';
1115
            $year_requested  = ! empty($pieces[1])
1116
                ? $pieces[1]
1117
                : '';
1118
            //if there is not a month or year then we can't go further
1119
            if ($month_requested && $year_requested) {
1120
                $days_in_month     = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
1121
                $where['REG_date'] = array(
1122
                    'BETWEEN',
1123
                    array(
1124
                        EEM_Registration::instance()->convert_datetime_for_query(
1125
                            'REG_date',
1126
                            $year_requested . '-' . $month_requested . '-01 00:00:00',
1127
                            'Y-m-d H:i:s'
1128
                        ),
1129
                        EEM_Registration::instance()->convert_datetime_for_query(
1130
                            'REG_date',
1131
                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
1132
                            'Y-m-d H:i:s'
1133
                        ),
1134
                    ),
1135
                );
1136
            }
1137
        }
1138
        return $where;
1139
    }
1140
1141
1142
    /**
1143
     * Adds any provided search restraints to the where conditions for the registrations query
1144
     *
1145
     * @param array $request usually the same as $this->_req_data but not necessarily
1146
     * @return array
1147
     */
1148
    protected function _add_search_to_where_conditions(array $request)
1149
    {
1150
        $where = array();
1151
        if ( ! empty($request['s'])) {
1152
            $search_string = '%' . sanitize_text_field($request['s']) . '%';
1153
            $where['OR'] = array(
1154
                'Event.EVT_name'                          => array('LIKE', $search_string),
1155
                'Event.EVT_desc'                          => array('LIKE', $search_string),
1156
                'Event.EVT_short_desc'                    => array('LIKE', $search_string),
1157
                'Attendee.ATT_full_name'                  => array('LIKE', $search_string),
1158
                'Attendee.ATT_fname'                      => array('LIKE', $search_string),
1159
                'Attendee.ATT_lname'                      => array('LIKE', $search_string),
1160
                'Attendee.ATT_short_bio'                  => array('LIKE', $search_string),
1161
                'Attendee.ATT_email'                      => array('LIKE', $search_string),
1162
                'Attendee.ATT_address'                    => array('LIKE', $search_string),
1163
                'Attendee.ATT_address2'                   => array('LIKE', $search_string),
1164
                'Attendee.ATT_city'                       => array('LIKE', $search_string),
1165
                'REG_final_price'                         => array('LIKE', $search_string),
1166
                'REG_code'                                => array('LIKE', $search_string),
1167
                'REG_count'                               => array('LIKE', $search_string),
1168
                'REG_group_size'                          => array('LIKE', $search_string),
1169
                'Ticket.TKT_name'                         => array('LIKE', $search_string),
1170
                'Ticket.TKT_description'                  => array('LIKE', $search_string),
1171
                'Transaction.Payment.PAY_txn_id_chq_nmbr' => array('LIKE', $search_string),
1172
            );
1173
        }
1174
        return $where;
1175
    }
1176
1177
1178
    /**
1179
     * Sets up the where conditions for the registrations query.
1180
     *
1181
     * @param array $request
1182
     * @return array
1183
     */
1184
    protected function _get_where_conditions_for_registrations_query($request)
1185
    {
1186
        return array_merge(
1187
            $this->_add_event_id_to_where_conditions($request),
1188
            $this->_add_category_id_to_where_conditions($request),
1189
            $this->_add_datetime_id_to_where_conditions($request),
1190
            $this->_add_registration_status_to_where_conditions($request),
1191
            $this->_add_date_to_where_conditions($request),
1192
            $this->_add_search_to_where_conditions($request)
1193
        );
1194
    }
1195
1196
1197
    /**
1198
     * Sets up the orderby for the registrations query.
1199
     *
1200
     * @return array
1201
     */
1202
    protected function _get_orderby_for_registrations_query()
1203
    {
1204
        $orderby_field = ! empty($this->_req_data['orderby'])
1205
            ? sanitize_text_field($this->_req_data['orderby'])
1206
            : '';
1207
        switch ($orderby_field) {
1208
            case '_REG_ID':
1209
                $orderby_field = 'REG_ID';
1210
                break;
1211
            case '_Reg_status':
1212
                $orderby_field = 'STS_ID';
1213
                break;
1214
            case 'ATT_fname':
1215
                //just for spite, we're going to order it by their LAST name, NOT their first name. Now who's the boss?
1216
                //jk, we don't want to break existing links, and customers preferred ordering by last name
1217
                //besides, from the UI, its ambiguous as to whether we will order by first or last name
1218
                $orderby_field = 'Attendee.ATT_lname';
1219
                break;
1220
            case 'event_name':
1221
                $orderby_field = 'Event.EVT_name';
1222
                break;
1223
            case 'DTT_EVT_start':
1224
                $orderby_field = 'Event.Datetime.DTT_EVT_start';
1225
                break;
1226
            default: //'REG_date'
1227
                $orderby_field = 'REG_date';
1228
        }
1229
1230
        //order
1231
        $order = ! empty($this->_req_data['order'])
1232
            ? sanitize_text_field($this->_req_data['order'])
1233
            : 'DESC';
1234
        return array('order_by' => array($orderby_field => $order));
1235
    }
1236
1237
1238
    /**
1239
     * Sets up the limit for the registrations query.
1240
     *
1241
     * @param $per_page
1242
     * @return array
1243
     */
1244
    protected function _get_limit($per_page)
1245
    {
1246
        $current_page = ! empty($this->_req_data['paged'])
1247
            ? absint($this->_req_data['paged'])
1248
            : 1;
1249
        $per_page     = ! empty($this->_req_data['perpage'])
1250
            ? $this->_req_data['perpage']
1251
            : $per_page;
1252
1253
        //-1 means return all results so get out if that's set.
1254
        if ((int)$per_page === -1) {
1255
            return array();
1256
        }
1257
        $per_page = absint($per_page);
1258
        $offset   = ($current_page - 1) * $per_page;
1259
        return array('limit' => array($offset, $per_page));
1260
    }
1261
1262
1263
    public function get_registration_status_array()
1264
    {
1265
        return self::$_reg_status;
1266
    }
1267
1268
1269
1270
1271
    /***************************************        REGISTRATION DETAILS        ***************************************/
1272
    /**
1273
     *        generates HTML for the View Registration Details Admin page
1274
     *
1275
     * @access protected
1276
     * @return void
1277
     */
1278
    protected function _registration_details()
1279
    {
1280
        $this->_template_args = array();
1281
        $this->_set_registration_object();
1282
        if (is_object($this->_registration)) {
1283
            $transaction                                   = $this->_registration->transaction() ? $this->_registration->transaction()
1284
                : EE_Transaction::new_instance();
1285
            $this->_session                                = $transaction->session_data();
1286
            $event_id                                      = $this->_registration->event_ID();
1287
            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1288
            $this->_template_args['reg_nmbr']['label']     = __('Registration Number', 'event_espresso');
1289
            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1290
            $this->_template_args['reg_datetime']['label'] = __('Date', 'event_espresso');
1291
            $this->_template_args['grand_total']           = $transaction->total();
1292
            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1293
            // link back to overview
1294
            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1295
            $this->_template_args['registration']                = $this->_registration;
1296
            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(array(
1297
                'action'   => 'default',
1298
                'event_id' => $event_id,
1299
            ), REG_ADMIN_URL);
1300
            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
1301
                'action' => 'default',
1302
                'EVT_ID' => $event_id,
1303
                'page'   => 'espresso_transactions',
1304
            ), admin_url('admin.php'));
1305
            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(array(
1306
                'page'   => 'espresso_events',
1307
                'action' => 'edit',
1308
                'post'   => $event_id,
1309
            ), admin_url('admin.php'));
1310
            //next and previous links
1311
            $next_reg                                      = $this->_registration->next(null, array(), 'REG_ID');
1312
            $this->_template_args['next_registration']     = $next_reg
1313
                ? $this->_next_link(EE_Admin_Page::add_query_args_and_nonce(array(
1314
                    'action'  => 'view_registration',
1315
                    '_REG_ID' => $next_reg['REG_ID'],
1316
                ), REG_ADMIN_URL), 'dashicons dashicons-arrow-right ee-icon-size-22') : '';
1317
            $previous_reg                                  = $this->_registration->previous(null, array(), 'REG_ID');
1318
            $this->_template_args['previous_registration'] = $previous_reg
1319
                ? $this->_previous_link(EE_Admin_Page::add_query_args_and_nonce(array(
1320
                    'action'  => 'view_registration',
1321
                    '_REG_ID' => $previous_reg['REG_ID'],
1322
                ), REG_ADMIN_URL), 'dashicons dashicons-arrow-left ee-icon-size-22') : '';
1323
            // grab header
1324
            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1325
            $this->_template_args['REG_ID']            = $this->_registration->ID();
1326
            $this->_template_args['admin_page_header'] = EEH_Template::display_template($template_path,
1327
                $this->_template_args, true);
1328
        } else {
1329
            $this->_template_args['admin_page_header'] = $this->display_espresso_notices();
0 ignored issues
show
Bug introduced by
The method display_espresso_notices() does not exist on Registrations_Admin_Page. Did you maybe mean _display_espresso_notices()?

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...
1330
        }
1331
        // the details template wrapper
1332
        $this->display_admin_page_with_sidebar();
1333
    }
1334
1335
1336
    protected function _registration_details_metaboxes()
1337
    {
1338
        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1339
        $this->_set_registration_object();
1340
        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1341
        add_meta_box('edit-reg-status-mbox', __('Registration Status', 'event_espresso'),
1342
            array($this, 'set_reg_status_buttons_metabox'), $this->wp_page_slug, 'normal', 'high');
0 ignored issues
show
Bug introduced by
The property wp_page_slug does not seem to exist. Did you mean page_slug?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1343
        add_meta_box('edit-reg-details-mbox', __('Registration Details', 'event_espresso'),
1344
            array($this, '_reg_details_meta_box'), $this->wp_page_slug, 'normal', 'high');
0 ignored issues
show
Bug introduced by
The property wp_page_slug does not seem to exist. Did you mean page_slug?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1345
        if ($attendee instanceof EE_Attendee
1346
            && EE_Registry::instance()->CAP->current_user_can('ee_edit_registration', 'edit-reg-questions-mbox')
1347
        ) {
1348
            add_meta_box('edit-reg-questions-mbox', __('Registration Form Answers', 'event_espresso'),
1349
                array($this, '_reg_questions_meta_box'), $this->wp_page_slug, 'normal', 'high');
0 ignored issues
show
Bug introduced by
The property wp_page_slug does not seem to exist. Did you mean page_slug?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1350
        }
1351
        add_meta_box('edit-reg-registrant-mbox', __('Contact Details', 'event_espresso'),
1352
            array($this, '_reg_registrant_side_meta_box'), $this->wp_page_slug, 'side', 'high');
0 ignored issues
show
Bug introduced by
The property wp_page_slug does not seem to exist. Did you mean page_slug?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1353
        if ($this->_registration->group_size() > 1) {
1354
            add_meta_box('edit-reg-attendees-mbox', __('Other Registrations in this Transaction', 'event_espresso'),
1355
                array($this, '_reg_attendees_meta_box'), $this->wp_page_slug, 'normal', 'high');
0 ignored issues
show
Bug introduced by
The property wp_page_slug does not seem to exist. Did you mean page_slug?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1356
        }
1357
    }
1358
1359
1360
    /**
1361
     * set_reg_status_buttons_metabox
1362
     *
1363
     * @access protected
1364
     * @return string
1365
     * @throws \EE_Error
1366
     */
1367
    public function set_reg_status_buttons_metabox()
1368
    {
1369
        $this->_set_registration_object();
1370
        $change_reg_status_form = $this->_generate_reg_status_change_form();
1371
        echo $change_reg_status_form->form_open(self::add_query_args_and_nonce(array(
1372
            'action' => 'change_reg_status',
1373
        ), REG_ADMIN_URL));
1374
        echo $change_reg_status_form->get_html();
1375
        echo $change_reg_status_form->form_close();
1376
    }
1377
1378
1379
    /**
1380
     * @return EE_Form_Section_Proper
1381
     */
1382
    protected function _generate_reg_status_change_form()
1383
    {
1384
        return new EE_Form_Section_Proper(array(
1385
            'name'            => 'reg_status_change_form',
1386
            'html_id'         => 'reg-status-change-form',
1387
            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1388
            'subsections'     => array(
1389
                'return'             => new EE_Hidden_Input(array(
1390
                    'name'    => 'return',
1391
                    'default' => 'view_registration',
1392
                )),
1393
                'REG_ID'             => new EE_Hidden_Input(array(
1394
                    'name'    => 'REG_ID',
1395
                    'default' => $this->_registration->ID(),
1396
                )),
1397
                'current_status'     => new EE_Form_Section_HTML(EEH_HTML::tr(EEH_HTML::th(EEH_HTML::label(EEH_HTML::strong(__('Current Registration Status',
1398
                        'event_espresso')))) . EEH_HTML::td(EEH_HTML::strong($this->_registration->pretty_status(),
1399
                        '', 'status-' . $this->_registration->status_ID(),
1400
                        'line-height: 1em; font-size: 1.5em; font-weight: bold;')))),
1401
                'reg_status'         => new EE_Select_Input($this->_get_reg_statuses(), array(
1402
                    'html_label_text' => __('Change Registration Status to', 'event_espresso'),
1403
                    'default'         => $this->_registration->status_ID(),
1404
                )),
1405
                'send_notifications' => new EE_Yes_No_Input(array(
1406
                    'html_label_text' => __('Send Related Messages', 'event_espresso'),
1407
                    'default'         => false,
1408
                    'html_help_text'  => __('If set to "Yes", then the related messages will be sent to the registrant.',
1409
                        'event_espresso'),
1410
                )),
1411
                'submit'             => new EE_Submit_Input(array(
1412
                    'html_class'      => 'button-primary',
1413
                    'html_label_text' => '&nbsp;',
1414
                    'default'         => __('Update Registration Status', 'event_espresso'),
1415
                )),
1416
            ),
1417
        ));
1418
    }
1419
1420
1421
1422
    /**
1423
     * Returns an array of all the buttons for the various statuses and switch status actions
1424
     *
1425
     * @return array
1426
     */
1427
    protected function _get_reg_statuses()
1428
    {
1429
        $reg_status_array = EEM_Registration::instance()->reg_status_array();
1430
        unset ($reg_status_array[EEM_Registration::status_id_incomplete]);
1431
        // get current reg status
1432
        $current_status = $this->_registration->status_ID();
1433
        // is registration for free event? This will determine whether to display the pending payment option
1434
        if ($current_status != EEM_Registration::status_id_pending_payment
1435
            && $this->_registration->transaction()
1436
                                   ->is_free()
1437
        ) {
1438
            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1439
        }
1440
        return EEM_Status::instance()->localized_status($reg_status_array, false, 'sentence');
1441
    }
1442
1443
1444
    /**
1445
     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1446
     *
1447
     * @param bool $status REG status given for changing registrations to.
1448
     * @param bool $notify Whether to send messages notifications or not.
1449
     * @return array  (array with reg_id(s) updated and whether update was successful.
1450
     */
1451
    protected function _set_registration_status_from_request($status = false, $notify = false)
1452
    {
1453
        if (isset($this->_req_data['reg_status_change_form'])) {
1454
            $REG_IDs = isset($this->_req_data['reg_status_change_form']['REG_ID'])
1455
                ? (array)$this->_req_data['reg_status_change_form']['REG_ID'] : array();
1456
        } else {
1457
            $REG_IDs = isset($this->_req_data['_REG_ID']) ? (array)$this->_req_data['_REG_ID'] : array();
1458
        }
1459
        $success = $this->_set_registration_status($REG_IDs, $status);
1460
        //notify?
1461
        if ($success
0 ignored issues
show
Bug Best Practice introduced by
The expression $success of type array<string,array|boolean> is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
1462
            && $notify
1463
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message',
1464
                'espresso_registrations_resend_registration')
1465
        ) {
1466
            $this->_process_resend_registration();
1467
        }
1468
        return $success;
1469
    }
1470
1471
1472
    /**
1473
     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1474
     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1475
     *
1476
     * @param array $REG_IDs
1477
     * @param bool  $status
1478
     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1479
     *               the array of updated registrations).
1480
     */
1481
    protected function _set_registration_status($REG_IDs = array(), $status = false)
1482
    {
1483
        $success = false;
1484
        // typecast $REG_IDs
1485
        $REG_IDs = (array)$REG_IDs;
1486
        if ( ! empty($REG_IDs)) {
1487
            $success = true;
1488
            // set default status if none is passed
1489
            $status = $status ? $status : EEM_Registration::status_id_pending_payment;
1490
            // sanitize $REG_IDs
1491
            $REG_IDs = array_filter($REG_IDs, 'absint');
1492
            //loop through REG_ID's and change status
1493
            foreach ($REG_IDs as $REG_ID) {
1494
                $registration = EEM_Registration::instance()->get_one_by_ID($REG_ID);
1495
                if ($registration instanceof EE_Registration) {
1496
                    $registration->set_status($status);
1497
                    $result = $registration->save();
1498
                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1499
                    $success = $result !== false ? $success : false;
1500
                }
1501
            }
1502
        }
1503
        //reset _req_data['_REG_ID'] for any potential future messages notifications
1504
        $this->_req_data['_REG_ID'] = $REG_IDs;
1505
        //return $success and processed registrations
1506
        return array('REG_ID' => $REG_IDs, 'success' => $success);
1507
    }
1508
1509
1510
    /**
1511
     * Common logic for setting up success message and redirecting to appropriate route
1512
     *
1513
     * @param  string $STS_ID status id for the registration changed to
1514
     * @param   bool  $notify indicates whether the _set_registration_status_from_request does notifications or not.
1515
     * @return void
1516
     */
1517
    protected function _reg_status_change_return($STS_ID, $notify = false)
1518
    {
1519
        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
0 ignored issues
show
Documentation introduced by
$STS_ID is of type string, but the function expects a boolean.

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...
1520
            : array('success' => false);
1521
        $success = isset($result['success']) && $result['success'];
1522
        //setup success message
1523
        if ($success) {
1524
            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1525
                $msg = sprintf(__('Registration status has been set to %s', 'event_espresso'),
1526
                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1527
            } else {
1528
                $msg = sprintf(__('Registrations have been set to %s.', 'event_espresso'),
1529
                    EEH_Template::pretty_status($STS_ID, false, 'lower'));
1530
            }
1531
            EE_Error::add_success($msg);
1532
        } else {
1533
            EE_Error::add_error(__('Something went wrong, and the status was not changed', 'event_espresso'), __FILE__,
1534
                __LINE__, __FUNCTION__);
1535
        }
1536
        if (isset($this->_req_data['return']) && $this->_req_data['return'] == 'view_registration') {
1537
            $route = array('action' => 'view_registration', '_REG_ID' => reset($result['REG_ID']));
1538
        } else {
1539
            $route = array('action' => 'default');
1540
        }
1541
        //unset nonces
1542
        foreach ($this->_req_data as $ref => $value) {
1543
            if (strpos($ref, 'nonce') !== false) {
1544
                unset($this->_req_data[$ref]);
1545
                continue;
1546
            }
1547
            $value                 = is_array($value) ? array_map('urlencode', $value) : urlencode($value);
1548
            $this->_req_data[$ref] = $value;
1549
        }
1550
        //merge request vars so that the reloaded list table contains any existing filter query params
1551
        $route = array_merge($this->_req_data, $route);
1552
        $this->_redirect_after_action($success, '', '', $route, true);
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...
1553
    }
1554
1555
1556
    /**
1557
     * incoming reg status change from reg details page.
1558
     *
1559
     * @return void
1560
     */
1561
    protected function _change_reg_status()
1562
    {
1563
        $this->_req_data['return'] = 'view_registration';
1564
        //set notify based on whether the send notifications toggle is set or not
1565
        $notify = ! empty($this->_req_data['reg_status_change_form']['send_notifications']);
1566
        //$notify = ! empty( $this->_req_data['txn_reg_status_change']['send_notifications'] );
1567
        $this->_req_data['reg_status_change_form']['reg_status'] = isset($this->_req_data['reg_status_change_form']['reg_status'])
1568
            ? $this->_req_data['reg_status_change_form']['reg_status'] : '';
1569
        switch ($this->_req_data['reg_status_change_form']['reg_status']) {
1570
            case EEM_Registration::status_id_approved :
1571
            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence') :
1572
                $this->approve_registration($notify);
1573
                break;
1574
            case EEM_Registration::status_id_pending_payment :
1575
            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence') :
1576
                $this->pending_registration($notify);
1577
                break;
1578
            case EEM_Registration::status_id_not_approved :
1579
            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence') :
1580
                $this->not_approve_registration($notify);
1581
                break;
1582
            case EEM_Registration::status_id_declined :
1583
            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence') :
1584
                $this->decline_registration($notify);
1585
                break;
1586
            case EEM_Registration::status_id_cancelled :
1587
            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence') :
1588
                $this->cancel_registration($notify);
1589
                break;
1590
            case EEM_Registration::status_id_wait_list :
1591
            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence') :
1592
                $this->waitlist_registration($notify);
1593
                break;
1594
            case EEM_Registration::status_id_incomplete :
1595
            default :
1596
                $result['success'] = false;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$result was never initialized. Although not strictly required by PHP, it is generally a good practice to add $result = 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...
1597
                unset($this->_req_data['return']);
1598
                $this->_reg_status_change_return('', false);
1599
                break;
1600
        }
1601
    }
1602
1603
1604
    /**
1605
     * approve_registration
1606
     *
1607
     * @access protected
1608
     * @param bool $notify whether or not to notify the registrant about their approval.
1609
     * @return void
1610
     */
1611
    protected function approve_registration($notify = false)
1612
    {
1613
        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1614
    }
1615
1616
1617
    /**
1618
     *        decline_registration
1619
     *
1620
     * @access protected
1621
     * @param bool $notify whether or not to notify the registrant about their status change.
1622
     * @return void
1623
     */
1624
    protected function decline_registration($notify = false)
1625
    {
1626
        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1627
    }
1628
1629
1630
    /**
1631
     *        cancel_registration
1632
     *
1633
     * @access protected
1634
     * @param bool $notify whether or not to notify the registrant about their status change.
1635
     * @return void
1636
     */
1637
    protected function cancel_registration($notify = false)
1638
    {
1639
        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1640
    }
1641
1642
1643
    /**
1644
     *        not_approve_registration
1645
     *
1646
     * @access protected
1647
     * @param bool $notify whether or not to notify the registrant about their status change.
1648
     * @return void
1649
     */
1650
    protected function not_approve_registration($notify = false)
1651
    {
1652
        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1653
    }
1654
1655
1656
    /**
1657
     *        decline_registration
1658
     *
1659
     * @access protected
1660
     * @param bool $notify whether or not to notify the registrant about their status change.
1661
     * @return void
1662
     */
1663
    protected function pending_registration($notify = false)
1664
    {
1665
        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1666
    }
1667
1668
1669
    /**
1670
     * waitlist_registration
1671
     *
1672
     * @access protected
1673
     * @param bool $notify whether or not to notify the registrant about their status change.
1674
     * @return void
1675
     */
1676
    protected function waitlist_registration($notify = false)
1677
    {
1678
        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1679
    }
1680
1681
1682
    /**
1683
     *        generates HTML for the Registration main meta box
1684
     *
1685
     * @access public
1686
     * @return void
1687
     */
1688
    public function _reg_details_meta_box()
1689
    {
1690
        EEH_Autoloader::register_line_item_display_autoloaders();
1691
        EEH_Autoloader::register_line_item_filter_autoloaders();
1692
        EE_Registry::instance()->load_helper('Line_Item');
1693
        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
1694
            : EE_Transaction::new_instance();
1695
        $this->_session = $transaction->session_data();
1696
        $filters        = new EE_Line_Item_Filter_Collection();
1697
        //$filters->add( new EE_Non_Zero_Line_Item_Filter() );
1698
        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
1699
        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor($filters,
1700
            $transaction->total_line_item());
1701
        $filtered_line_item_tree                 = $line_item_filter_processor->process();
1702
        $line_item_display                       = new EE_Line_Item_Display('reg_admin_table',
1703
            'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
1704
        $this->_template_args['line_item_table'] = $line_item_display->display_line_item($filtered_line_item_tree,
0 ignored issues
show
Compatibility introduced by
$filtered_line_item_tree of type object<EEI_Line_Item> is not a sub-type of object<EE_Line_Item>. It seems like you assume a concrete implementation of the interface EEI_Line_Item to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
1705
            array('EE_Registration' => $this->_registration));
1706
        $attendee                                = $this->_registration->attendee();
1707
        if (EE_Registry::instance()->CAP->current_user_can('ee_read_transaction',
1708
            'espresso_transactions_view_transaction')
1709
        ) {
1710
            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array(
1711
                'action' => 'view_transaction',
1712
                'TXN_ID' => $transaction->ID(),
1713
            ), TXN_ADMIN_URL), esc_html__(' View Transaction'), 'button secondary-button right',
1714
                'dashicons dashicons-cart');
1715
        } else {
1716
            $this->_template_args['view_transaction_button'] = '';
1717
        }
1718
        if ($attendee instanceof EE_Attendee
1719
            && EE_Registry::instance()->CAP->current_user_can('ee_send_message',
1720
                'espresso_registrations_resend_registration')
1721
        ) {
1722
            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array(
1723
                'action'      => 'resend_registration',
1724
                '_REG_ID'     => $this->_registration->ID(),
1725
                'redirect_to' => 'view_registration',
1726
            ), REG_ADMIN_URL), esc_html__(' Resend Registration'), 'button secondary-button right',
1727
                'dashicons dashicons-email-alt');
1728
        } else {
1729
            $this->_template_args['resend_registration_button'] = '';
1730
        }
1731
        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
1732
        $payment                               = $transaction->get_first_related('Payment');
1733
        $payment                               = ! $payment instanceof EE_Payment ? EE_Payment::new_instance() : $payment;
1734
        $payment_method                        = $payment->get_first_related('Payment_Method');
1735
        $payment_method                        = ! $payment_method instanceof EE_Payment_Method ? EE_Payment_Method::new_instance()
1736
            : $payment_method;
1737
        $reg_details                           = array(
1738
            'payment_method'       => $payment_method->name(),
1739
            'response_msg'         => $payment->gateway_response(),
1740
            'registration_id'      => $this->_registration->get('REG_code'),
1741
            'registration_session' => $this->_registration->session_ID(),
1742
            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
1743
            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
1744
        );
1745
        if (isset($reg_details['registration_id'])) {
1746
            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
1747
            $this->_template_args['reg_details']['registration_id']['label'] = __('Registration ID', 'event_espresso');
1748
            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
1749
        }
1750
        if (isset($reg_details['payment_method'])) {
1751
            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
1752
            $this->_template_args['reg_details']['payment_method']['label'] = __('Most Recent Payment Method',
1753
                'event_espresso');
1754
            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
1755
            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
1756
            $this->_template_args['reg_details']['response_msg']['label']   = __('Payment method response',
1757
                'event_espresso');
1758
            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
1759
        }
1760
        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
1761
        $this->_template_args['reg_details']['registration_session']['label'] = __('Registration Session',
1762
            'event_espresso');
1763
        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
1764
        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
1765
        $this->_template_args['reg_details']['ip_address']['label']           = __('Registration placed from IP',
1766
            'event_espresso');
1767
        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
1768
        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
1769
        $this->_template_args['reg_details']['user_agent']['label']           = __('Registrant User Agent',
1770
            'event_espresso');
1771
        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
1772
        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(array(
1773
            'action'   => 'default',
1774
            'event_id' => $this->_registration->event_ID(),
1775
        ), REG_ADMIN_URL);
1776
        $this->_template_args['REG_ID']                                       = $this->_registration->ID();
1777
        $this->_template_args['event_id']                                     = $this->_registration->event_ID();
1778
        $template_path                                                        = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
1779
        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1780
    }
1781
1782
1783
    /**
1784
     * generates HTML for the Registration Questions meta box.
1785
     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
1786
     * otherwise uses new forms system
1787
     *
1788
     * @access public
1789
     * @return void
1790
     */
1791
    public function _reg_questions_meta_box()
1792
    {
1793
        //allow someone to override this method entirely
1794
        if (apply_filters('FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default', true, $this,
1795
            $this->_registration)) {
1796
            $form                                              = $this->_get_reg_custom_questions_form($this->_registration->ID());
1797
            $this->_template_args['att_questions']             = count($form->subforms()) > 0 ? $form->get_html_and_js() : '';
1798
            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
1799
            $this->_template_args['REG_ID']                    = $this->_registration->ID();
1800
            $template_path                                     = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
1801
            echo EEH_Template::display_template($template_path, $this->_template_args, true);
1802
        }
1803
    }
1804
1805
1806
    /**
1807
     * form_before_question_group
1808
     *
1809
     * @deprecated    as of 4.8.32.rc.000
1810
     * @access        public
1811
     * @param        string $output
1812
     * @return        string
1813
     */
1814 View Code Duplication
    public function form_before_question_group($output)
0 ignored issues
show
Unused Code introduced by
The parameter $output 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...
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...
1815
    {
1816
        EE_Error::doing_it_wrong(__CLASS__ . '::' . __FUNCTION__,
1817
            __('This method would have been protected but was used on a filter callback'
1818
               . 'so needed to be public. Please discontinue usage as it will be removed soon.', 'event_espresso'),
1819
            '4.8.32.rc.000');
1820
        return '
1821
	<table class="form-table ee-width-100">
1822
		<tbody>
1823
			';
1824
    }
1825
1826
1827
    /**
1828
     * form_after_question_group
1829
     *
1830
     * @deprecated    as of 4.8.32.rc.000
1831
     * @access        public
1832
     * @param        string $output
1833
     * @return        string
1834
     */
1835
    public function form_after_question_group($output)
0 ignored issues
show
Unused Code introduced by
The parameter $output 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...
1836
    {
1837
        EE_Error::doing_it_wrong(__CLASS__ . '::' . __FUNCTION__,
1838
            __('This method would have been protected but was used on a filter callback'
1839
               . 'so needed to be public. Please discontinue usage as it will be removed soon.', 'event_espresso'),
1840
            '4.8.32.rc.000');
1841
        return '
1842
			<tr class="hide-if-no-js">
1843
				<th> </th>
1844
				<td class="reg-admin-edit-attendee-question-td">
1845
					<a class="reg-admin-edit-attendee-question-lnk" href="#" title="'
1846
               . esc_attr__('click to edit question', 'event_espresso')
1847
               . '">
1848
						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
1849
               . __('edit the above question group', 'event_espresso')
1850
               . '</span>
1851
						<div class="dashicons dashicons-edit"></div>
1852
					</a>
1853
				</td>
1854
			</tr>
1855
		</tbody>
1856
	</table>
1857
';
1858
    }
1859
1860
1861
    /**
1862
     * form_form_field_label_wrap
1863
     *
1864
     * @deprecated    as of 4.8.32.rc.000
1865
     * @access        public
1866
     * @param        string $label
1867
     * @return        string
1868
     */
1869 View Code Duplication
    public function form_form_field_label_wrap($label)
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...
1870
    {
1871
        EE_Error::doing_it_wrong(__CLASS__ . '::' . __FUNCTION__,
1872
            __('This method would have been protected but was used on a filter callback'
1873
               . 'so needed to be public. Please discontinue usage as it will be removed soon.', 'event_espresso'),
1874
            '4.8.32.rc.000');
1875
        return '
1876
			<tr>
1877
				<th>
1878
					' . $label . '
1879
				</th>';
1880
    }
1881
1882
1883
    /**
1884
     * form_form_field_input__wrap
1885
     *
1886
     * @deprecated    as of 4.8.32.rc.000
1887
     * @access        public
1888
     * @param        string $input
1889
     * @return        string
1890
     */
1891 View Code Duplication
    public function form_form_field_input__wrap($input)
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...
1892
    {
1893
        EE_Error::doing_it_wrong(__CLASS__ . '::' . __FUNCTION__,
1894
            __('This method would have been protected but was used on a filter callback'
1895
               . 'so needed to be public. Please discontinue usage as it will be removed soon.', 'event_espresso'),
1896
            '4.8.32.rc.000');
1897
        return '
1898
				<td class="reg-admin-attendee-questions-input-td disabled-input">
1899
					' . $input . '
1900
				</td>
1901
			</tr>';
1902
    }
1903
1904
1905
    /**
1906
     * Updates the registration's custom questions according to the form info, if the form is submitted.
1907
     * If it's not a post, the "view_registrations" route will be called next on the SAME request
1908
     * to display the page
1909
     *
1910
     * @access protected
1911
     * @return void
1912
     */
1913
    protected function _update_attendee_registration_form()
1914
    {
1915
        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
1916
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
1917
            $REG_ID  = isset($this->_req_data['_REG_ID']) ? absint($this->_req_data['_REG_ID']) : false;
1918
            $success = $this->_save_reg_custom_questions_form($REG_ID);
1919
            if ($success) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $success of type integer|false is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
1920
                $what  = __('Registration Form', 'event_espresso');
1921
                $route = $REG_ID ? array('action' => 'view_registration', '_REG_ID' => $REG_ID)
1922
                    : array('action' => 'default');
1923
                $this->_redirect_after_action($success, $what, __('updated', 'event_espresso'), $route);
1924
            }
1925
        }
1926
    }
1927
1928
1929
    /**
1930
     * Gets the form for saving registrations custom questions (if done
1931
     * previously retrieves the cached form object, which may have validation errors in it)
1932
     *
1933
     * @param int $REG_ID
1934
     * @return EE_Registration_Custom_Questions_Form
1935
     */
1936
    protected function _get_reg_custom_questions_form($REG_ID)
1937
    {
1938
        if ( ! $this->_reg_custom_questions_form) {
1939
            require_once(REG_ADMIN . 'form_sections' . DS . 'EE_Registration_Custom_Questions_Form.form.php');
1940
            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(EEM_Registration::instance()
0 ignored issues
show
Documentation introduced by
\EEM_Registration::insta...>get_one_by_ID($REG_ID) is of type object<EE_Base_Class>|null, but the function expects a object<EE_Registration>.

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...
1941
                                                                                                          ->get_one_by_ID($REG_ID));
1942
            $this->_reg_custom_questions_form->_construct_finalize(null, null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<EE_Form_Section_Proper>.

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...
1943
        }
1944
        return $this->_reg_custom_questions_form;
1945
    }
1946
1947
1948
    /**
1949
     * Saves
1950
     *
1951
     * @access private
1952
     * @param bool $REG_ID
1953
     * @return bool
1954
     */
1955
    private function _save_reg_custom_questions_form($REG_ID = false)
1956
    {
1957
        if ( ! $REG_ID) {
1958
            EE_Error::add_error(__('An error occurred. No registration ID was received.', 'event_espresso'), __FILE__,
1959
                __FUNCTION__, __LINE__);
1960
        }
1961
        $form = $this->_get_reg_custom_questions_form($REG_ID);
0 ignored issues
show
Documentation introduced by
$REG_ID 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...
1962
        $form->receive_form_submission($this->_req_data);
1963
        $success = false;
1964
        if ($form->is_valid()) {
1965
            foreach ($form->subforms() as $question_group_id => $question_group_form) {
1966
                foreach ($question_group_form->inputs() as $question_id => $input) {
1967
                    $where_conditions    = array(
1968
                        'QST_ID' => $question_id,
1969
                        'REG_ID' => $REG_ID,
1970
                    );
1971
                    $possibly_new_values = array(
1972
                        'ANS_value' => $input->normalized_value(),
1973
                    );
1974
                    $answer              = EEM_Answer::instance()->get_one(array($where_conditions));
1975
                    if ($answer instanceof EE_Answer) {
1976
                        $success = $answer->save($possibly_new_values);
1977
                    } else {
1978
                        //insert it then
1979
                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
1980
                        $answer      = EE_Answer::new_instance($cols_n_vals);
1981
                        $success     = $answer->save();
1982
                    }
1983
                }
1984
            }
1985
        } else {
1986
            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
1987
        }
1988
        return $success;
1989
    }
1990
1991
1992
    /**
1993
     *        generates HTML for the Registration main meta box
1994
     *
1995
     * @access public
1996
     * @return void
1997
     */
1998
    public function _reg_attendees_meta_box()
1999
    {
2000
        $REG = EEM_Registration::instance();
2001
        //get all other registrations on this transaction, and cache
2002
        //the attendees for them so we don't have to run another query using force_join
2003
        $registrations                           = $REG->get_all(array(
2004
            array(
2005
                'TXN_ID' => $this->_registration->transaction_ID(),
2006
                'REG_ID' => array('!=', $this->_registration->ID()),
2007
            ),
2008
            'force_join' => array('Attendee'),
2009
        ));
2010
        $this->_template_args['attendees']       = array();
2011
        $this->_template_args['attendee_notice'] = '';
2012
        if (empty($registrations)
2013
            || (is_array($registrations)
2014
                && ! EEH_Array::get_one_item_from_array($registrations))
2015
        ) {
2016
            EE_Error::add_error(__('There are no records attached to this registration. Something may have gone wrong with the registration',
2017
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
2018
            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2019
        } else {
2020
            $att_nmbr = 1;
2021
            foreach ($registrations as $registration) {
2022
                /* @var $registration EE_Registration */
2023
                $attendee                                                    = $registration->attendee()
2024
                    ? $registration->attendee()
2025
                    : EEM_Attendee::instance()
2026
                                  ->create_default_object();
2027
                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2028
                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();//( isset( $registration->ATT_fname ) & ! empty( $registration->ATT_fname ) ) ? $registration->ATT_fname : '';
0 ignored issues
show
Documentation Bug introduced by
The method fname 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...
2029
                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();//( isset( $registration->ATT_lname ) & ! empty( $registration->ATT_lname ) ) ? $registration->ATT_lname : '';
0 ignored issues
show
Documentation Bug introduced by
The method lname 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...
2030
                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();//( isset( $registration->ATT_email ) & ! empty( $registration->ATT_email ) ) ? $registration->ATT_email : '';
0 ignored issues
show
Documentation Bug introduced by
The method email 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...
2031
                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();//( isset( $registration->REG_final_price ) & ! empty( $registration->REG_final_price ) ) ? $registration->REG_final_price : '';
2032
                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(', ',
2033
                    $attendee->full_address_as_array());
0 ignored issues
show
Documentation Bug introduced by
The method full_address_as_array 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...
2034
                $this->_template_args['attendees'][$att_nmbr]['att_link']    = self::add_query_args_and_nonce(array(
2035
                    'action' => 'edit_attendee',
2036
                    'post'   => $attendee->ID(),
2037
                ), REG_ADMIN_URL);
2038
                $this->_template_args['attendees'][$att_nmbr]['event_name']  = $registration->event_obj()->name();
2039
                $att_nmbr++;
2040
            }
2041
            //EEH_Debug_Tools::printr( $attendees, '$attendees  <br /><span style="font-size:10px;font-weight:normal;">( file: '. __FILE__ . ' - line no: ' . __LINE__ . ' )</span>', 'auto' );
2042
            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2043
            //			$this->_template_args['registration_form_url'] = add_query_arg( array( 'action' => 'edit_registration', 'process' => 'attendees'  ), REG_ADMIN_URL );
2044
        }
2045
        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2046
        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2047
    }
2048
2049
2050
    /**
2051
     *        generates HTML for the Edit Registration side meta box
2052
     *
2053
     * @access public
2054
     * @return void
2055
     */
2056
    public function _reg_registrant_side_meta_box()
2057
    {
2058
        /*@var $attendee EE_Attendee */
2059
        $att_check = $this->_registration->attendee();
2060
        $attendee  = $att_check instanceof EE_Attendee ? $att_check : EEM_Attendee::instance()->create_default_object();
2061
        //now let's determine if this is not the primary registration.  If it isn't then we set the primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the primary registration object (that way we know if we need to show create button or not)
2062
        if ( ! $this->_registration->is_primary_registrant()) {
2063
            $primary_registration = $this->_registration->get_primary_registration();
2064
            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2065
                : null;
2066
            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2067
                //in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own custom attendee object so let's not worry about the primary reg.
2068
                $primary_registration = null;
2069
            }
2070
        } else {
2071
            $primary_registration = null;
2072
        }
2073
        $this->_template_args['ATT_ID']            = $attendee->ID();
2074
        $this->_template_args['fname']             = $attendee->fname();//$this->_registration->ATT_fname;
0 ignored issues
show
Documentation Bug introduced by
The method fname 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...
2075
        $this->_template_args['lname']             = $attendee->lname();//$this->_registration->ATT_lname;
0 ignored issues
show
Documentation Bug introduced by
The method lname 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...
2076
        $this->_template_args['email']             = $attendee->email();//$this->_registration->ATT_email;
0 ignored issues
show
Documentation Bug introduced by
The method email 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...
2077
        $this->_template_args['phone']             = $attendee->phone();
0 ignored issues
show
Documentation Bug introduced by
The method phone 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...
2078
        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2079
        //edit link
2080
        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(array(
2081
            'action' => 'edit_attendee',
2082
            'post'   => $attendee->ID(),
2083
        ), REG_ADMIN_URL);
2084
        $this->_template_args['att_edit_label'] = __('View/Edit Contact', 'event_espresso');
2085
        //create link
2086
        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2087
            ? EE_Admin_Page::add_query_args_and_nonce(array(
2088
                'action'  => 'duplicate_attendee',
2089
                '_REG_ID' => $this->_registration->ID(),
2090
            ), REG_ADMIN_URL) : '';
2091
        $this->_template_args['create_label'] = __('Create Contact', 'event_espresso');
2092
        $this->_template_args['att_check']    = $att_check;
2093
        $template_path                        = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2094
        echo EEH_Template::display_template($template_path, $this->_template_args, true);
2095
    }
2096
2097
2098
    /**
2099
     * trash or restore registrations
2100
     *
2101
     * @param  boolean $trash whether to archive or restore
2102
     * @access protected
2103
     * @return void
2104
     */
2105
    protected function _trash_or_restore_registrations($trash = true)
2106
    {
2107
        $REGM    = EEM_Registration::instance();
2108
        $success = 1;
2109
        $error   = 0;
2110
        $tickets = array();
2111
        $dtts    = array();
2112
        //if empty _REG_ID then get out because there's nothing to do
2113 View Code Duplication
        if (empty($this->_req_data['_REG_ID'])) {
2114
            $msg = $trash
2115
                ? __('In order to trash registrations you must select which ones you wish to trash by clicking the checkboxes.',
2116
                    'event_espresso')
2117
                : __('In order to restore registrations you must select which ones you wish to restore by clicking the checkboxes.',
2118
                    'event_espresso');
2119
            EE_Error::add_error($msg, __FILE__, __LINE__, __FUNCTION__);
2120
            $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...
2121
        }
2122
        //Checkboxes
2123
        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2124
            // if array has more than one element than success message should be plural
2125
            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2126
            // cycle thru checkboxes
2127
            while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
0 ignored issues
show
Unused Code introduced by
The assignment to $ind 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...
2128
                /** @var EE_Registration $REG */
2129
                $REG           = $REGM->get_one_by_ID($REG_ID);
2130
                $payment_count = $REG->get_first_related('Transaction')->count_related('Payment');
2131
                if ($payment_count > 0) {
2132
                    $name    = $REG->attendee() instanceof EE_Attendee ? $REG->attendee()->full_name()
2133
                        : __('Unknown Attendee', 'event_espresso');
2134
                    $error   = 1;
2135
                    $success = 0;
2136
                    EE_Error::add_error(sprintf(__('The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2137
                        'event_espresso'), $name), __FILE__, __FUNCTION__, __LINE__);
2138
                    continue; //can't trash this registration because it has payments.
2139
                }
2140
                $ticket                 = $REG->get_first_related('Ticket');
2141
                $tickets[$ticket->ID()] = $ticket;
2142
                $dtt                    = $ticket->get_many_related('Datetime');
2143
                $dtts                   = array_merge($dtts, $dtt);
2144
                $updated                = $trash ? $REG->delete() : $REG->restore();
2145
                if ( ! $updated) {
2146
                    $success = 0;
2147
                } else {
2148
                    $success = 2;
2149
                }/**/
2150
            }
2151
        } else {
2152
            // grab single id and delete
2153
            $REG_ID                 = absint($this->_req_data['_REG_ID']);
2154
            $REG                    = $REGM->get_one_by_ID($REG_ID);
2155
            $ticket                 = $REG->get_first_related('Ticket');
2156
            $tickets[$ticket->ID()] = $ticket;
2157
            $dtts                   = $ticket->get_many_related('Datetime');
2158
            $updated                = $trash ? $REG->delete() : $REG->restore();
0 ignored issues
show
Documentation Bug introduced by
The method restore 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...
2159
            if ( ! $updated) {
2160
                $success = 0;
2161
            }
2162
        }
2163
        //now let's update counts
2164
        EEM_Ticket::instance()->update_tickets_sold($tickets);
2165
        EEM_Datetime::instance()->update_sold($dtts);
2166
        $what           = $success > 1 ? __('Registrations', 'event_espresso') : __('Registration', 'event_espresso');
2167
        $action_desc    = $trash ? __('moved to the trash', 'event_espresso') : __('restored', 'event_espresso');
2168
        $overwrite_msgs = $error ? true : false;
2169
        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'default'), $overwrite_msgs);
2170
    }
2171
2172
2173
    /**
2174
     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2175
     * registration but also.
2176
     * 1. Removing relations to EE_Attendee
2177
     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2178
     * ALSO trashed.
2179
     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2180
     * 4. Removing relationships between all tickets and the related registrations
2181
     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2182
     * 6. Deleting permanently any related Checkins.
2183
     *
2184
     * @return void
2185
     */
2186
    protected function _delete_registrations()
2187
    {
2188
        $REG_MDL = EEM_Registration::instance();
2189
        $success = 1;
2190
        //Checkboxes
2191
        if ( ! empty($this->_req_data['_REG_ID']) && is_array($this->_req_data['_REG_ID'])) {
2192
            // if array has more than one element than success message should be plural
2193
            $success = count($this->_req_data['_REG_ID']) > 1 ? 2 : 1;
2194
            // cycle thru checkboxes
2195
            while (list($ind, $REG_ID) = each($this->_req_data['_REG_ID'])) {
0 ignored issues
show
Unused Code introduced by
The assignment to $ind 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...
2196
                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2197
                if ( ! $REG instanceof EE_Registration) {
2198
                    continue;
2199
                }
2200
                $deleted = $this->_delete_registration($REG);
2201
                if ( ! $deleted) {
2202
                    $success = 0;
2203
                }
2204
            }
2205
        } else {
2206
            // grab single id and delete
2207
            $REG_ID  = $this->_req_data['_REG_ID'];
2208
            $REG     = $REG_MDL->get_one_by_ID($REG_ID);
2209
            $deleted = $this->_delete_registration($REG);
0 ignored issues
show
Documentation introduced by
$REG is of type object<EE_Base_Class>|null, but the function expects a object<EE_Registration>.

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...
2210
            if ( ! $deleted) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $deleted of type false|integer is loosely compared to false; this is ambiguous if the integer can be zero. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
2211
                $success = 0;
2212
            }
2213
        }
2214
        $what        = $success > 1 ? __('Registrations', 'event_espresso') : __('Registration', 'event_espresso');
2215
        $action_desc = __('permanently deleted.', 'event_espresso');
2216
        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'default'), true);
2217
    }
2218
2219
2220
    /**
2221
     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2222
     * models get affected.
2223
     *
2224
     * @param  EE_Registration $REG registration to be deleted permenantly
2225
     * @return boolean              true = successful deletion, false = fail.
2226
     */
2227
    protected function _delete_registration(EE_Registration $REG)
2228
    {
2229
        //first we start with the transaction... ultimately, we WILL not delete permanently if there are any related registrations on the transaction that are NOT trashed.
2230
        $TXN         = $REG->get_first_related('Transaction');
2231
        $REGS        = $TXN->get_many_related('Registration');
2232
        $all_trashed = true;
2233
        foreach ($REGS as $registration) {
2234
            if ( ! $registration->get('REG_deleted')) {
2235
                $all_trashed = false;
2236
            }
2237
        }
2238
        if ( ! $all_trashed) {
2239
            EE_Error::add_error(__('Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2240
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
2241
            return false;
2242
        }
2243
        //k made it here so that means we can delete all the related transactions and their answers (but let's do them separately from THIS one).
2244
        foreach ($REGS as $registration) {
2245
            //delete related answers
2246
            $registration->delete_related_permanently('Answer');
2247
            //remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2248
            $attendee = $registration->get_first_related('Attendee');
2249
            if ($attendee instanceof EE_Attendee) {
2250
                $registration->_remove_relation_to($attendee, 'Attendee');
2251
            }
2252
            //now remove relationships to tickets on this registration.
2253
            $registration->_remove_relations('Ticket');
2254
            //now delete permanently the checkins related to this registration.
2255
            $registration->delete_related_permanently('Checkin');
2256
            if ($registration->ID() === $REG->ID()) {
2257
                continue;
2258
            } //we don't want to delete permanently the existing registration just yet.
2259
            //remove relation to transaction for these registrations if NOT the existing registrations
2260
            $registration->_remove_relations('Transaction');
2261
            //delete permanently any related messages.
2262
            $registration->delete_related_permanently('Message');
2263
            //now delete this registration permanently
2264
            $registration->delete_permanently();
2265
        }
2266
        //now all related registrations on the transaction are handled.  So let's just handle this registration itself (the transaction and line items should be all that's left).
2267
        //delete the line items related to the transaction for this registration.
2268
        $TXN->delete_related_permanently('Line_Item');
2269
        //we need to remove all the relationships on the transaction
2270
        $TXN->delete_related_permanently('Payment');
2271
        $TXN->delete_related_permanently('Extra_Meta');
2272
        $TXN->delete_related_permanently('Message');
2273
        //now we can delete this REG permanently (and the transaction of course)
2274
        $REG->delete_related_permanently('Transaction');
2275
        return $REG->delete_permanently();
2276
    }
2277
2278
2279
    /**
2280
     *    generates HTML for the Register New Attendee Admin page
2281
     *
2282
     * @access private
2283
     * @throws \EE_Error
2284
     * @return void
2285
     */
2286
    public function new_registration()
2287
    {
2288
        if ( ! $this->_set_reg_event()) {
2289
            throw new EE_Error(__('Unable to continue with registering because there is no Event ID in the request',
2290
                'event_espresso'));
2291
        }
2292
        EE_Registry::instance()->REQ->set_espresso_page(true);
2293
        // gotta start with a clean slate if we're not coming here via ajax
2294
        if ( ! defined('DOING_AJAX')
2295
             && ( ! isset($this->_req_data['processing_registration']) || isset($this->_req_data['step_error']))
2296
        ) {
2297
            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2298
        }
2299
        $this->_template_args['event_name'] = '';
2300
        // event name
2301
        if ($this->_reg_event) {
2302
            $this->_template_args['event_name'] = $this->_reg_event->name();
2303
            $edit_event_url                     = self::add_query_args_and_nonce(array(
2304
                'action' => 'edit',
2305
                'post'   => $this->_reg_event->ID(),
2306
            ), EVENTS_ADMIN_URL);
2307
            $edit_event_lnk                     = '<a href="'
2308
                                                  . $edit_event_url
2309
                                                  . '" title="'
2310
                                                  . esc_attr__('Edit ', 'event_espresso')
2311
                                                  . $this->_reg_event->name()
2312
                                                  . '">'
2313
                                                  . __('Edit Event', 'event_espresso')
2314
                                                  . '</a>';
2315
            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2316
                                                   . $edit_event_lnk
2317
                                                   . '</span>';
2318
        }
2319
        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2320
        if (defined('DOING_AJAX')) {
2321
            $this->_return_json();
2322
        }
2323
        // grab header
2324
        $template_path                              = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2325
        $this->_template_args['admin_page_content'] = EEH_Template::display_template($template_path,
2326
            $this->_template_args, true);
2327
        //$this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2328
        // the details template wrapper
2329
        $this->display_admin_page_with_sidebar();
2330
    }
2331
2332
2333
    /**
2334
     * This returns the content for a registration step
2335
     *
2336
     * @access protected
2337
     * @return string html
2338
     */
2339
    protected function _get_registration_step_content()
2340
    {
2341
        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2342
            $warning_msg = sprintf(__('%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2343
                'event_espresso'), '<br />', '<h3 class="important-notice">', '</h3>', '<div class="float-right">',
2344
                '<span id="redirect_timer" class="important-notice">30</span>', '</div>', '<b>', '</b>');
2345
            return '
2346
	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2347
	<script >
2348
		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2349
		// after just adding a new registration... we gotta try to put a stop to that !!!
2350
		var timer = 30;
2351
		setInterval( function () {
2352
			jQuery("#redirect_timer").html( parseInt( timer ) );
2353
	        if ( --timer < 0 ) {
2354
	            window.history.forward()
2355
	        }
2356
	    }, 800 );
2357
	</script >';
2358
        }
2359
        $template_args = array(
2360
            'title'                    => '',
2361
            'content'                  => '',
2362
            'step_button_text'         => '',
2363
            'show_notification_toggle' => false,
2364
        );
2365
        //to indicate we're processing a new registration
2366
        $hidden_fields = array(
2367
            'processing_registration' => array(
2368
                'type'  => 'hidden',
2369
                'value' => 0,
2370
            ),
2371
            'event_id'                => array(
2372
                'type'  => 'hidden',
2373
                'value' => $this->_reg_event->ID(),
2374
            ),
2375
        );
2376
        //if the cart is empty then we know we're at step one so we'll display ticket selector
2377
        $cart = EE_Registry::instance()->SSN->cart();
2378
        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2379
        switch ($step) {
2380
            case 'ticket' :
2381
                $hidden_fields['processing_registration']['value'] = 1;
2382
                $template_args['title']                            = __('Step One: Select the Ticket for this registration',
2383
                    'event_espresso');
2384
                $template_args['content']                          = EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
0 ignored issues
show
Documentation introduced by
$this->_reg_event is of type object<EE_Event>, but the function expects a object<WP_Post>|integer|null.

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...
2385
                $template_args['step_button_text']                 = __('Add Tickets and Continue to Registrant Details',
2386
                    'event_espresso');
2387
                $template_args['show_notification_toggle']         = false;
2388
                break;
2389
            case 'questions' :
2390
                $hidden_fields['processing_registration']['value'] = 2;
2391
                $template_args['title']                            = __('Step Two: Add Registrant Details for this Registration',
2392
                    'event_espresso');
2393
                //in theory we should be able to run EED_SPCO at this point because the cart should have been setup properly by the first process_reg_step run.
2394
                $template_args['content']                  = EED_Single_Page_Checkout::registration_checkout_for_admin();
2395
                $template_args['step_button_text']         = __('Save Registration and Continue to Details',
2396
                    'event_espresso');
2397
                $template_args['show_notification_toggle'] = true;
2398
                break;
2399
        }
2400
        $this->_set_add_edit_form_tags('process_reg_step',
2401
            $hidden_fields); //we come back to the process_registration_step route.
2402
        return EEH_Template::display_template(REG_TEMPLATE_PATH
2403
                                              . 'reg_admin_register_new_attendee_step_content.template.php',
2404
            $template_args, true);
2405
    }
2406
2407
2408
    /**
2409
     *        set_reg_event
2410
     *
2411
     * @access private
2412
     * @return boolean
2413
     */
2414
    private function _set_reg_event()
2415
    {
2416
        if (is_object($this->_reg_event)) {
2417
            return true;
2418
        }
2419
        $EVT_ID = ( ! empty($this->_req_data['event_id'])) ? absint($this->_req_data['event_id']) : false;
2420
        if ( ! $EVT_ID) {
2421
            return false;
2422
        }
2423
        $this->_reg_event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
0 ignored issues
show
Documentation Bug introduced by
It seems like \EEM_Event::instance()->get_one_by_ID($EVT_ID) can also be of type object<EE_Base_Class>. However, the property $_reg_event is declared as type object<EE_Event>. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

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

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
2424
        return true;
2425
    }
2426
2427
2428
    /**
2429
     * process_reg_step
2430
     *
2431
     * @access        public
2432
     * @return        string
2433
     * @throws \RuntimeException
2434
     * @throws \EE_Error
2435
     */
2436
    public function process_reg_step()
2437
    {
2438
        EE_System::do_not_cache();
2439
        $this->_set_reg_event();
2440
        EE_Registry::instance()->REQ->set_espresso_page(true);
2441
        EE_Registry::instance()->REQ->set('uts', time());
2442
        //what step are we on?
2443
        $cart = EE_Registry::instance()->SSN->cart();
2444
        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2445
        //if doing ajax then we need to verify the nonce
2446 View Code Duplication
        if (defined('DOING_AJAX')) {
2447
            $nonce = isset($this->_req_data[$this->_req_nonce])
2448
                ? sanitize_text_field($this->_req_data[$this->_req_nonce]) : '';
2449
            $this->_verify_nonce($nonce, $this->_req_nonce);
2450
        }
2451
        switch ($step) {
2452
            case 'ticket' :
2453
                //process ticket selection
2454
                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
2455
                if ($success) {
2456
                    EE_Error::add_success(esc_html__('Tickets Selected. Now complete the registration.',
2457
                        'event_espresso'));
2458
                } else {
2459
                    $query_args['step_error'] = $this->_req_data['step_error'] = true;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$query_args was never initialized. Although not strictly required by PHP, it is generally a good practice to add $query_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...
2460
                }
2461 View Code Duplication
                if (defined('DOING_AJAX')) {
2462
                    $this->new_registration(); //display next step
2463
                } else {
2464
                    $query_args = array(
2465
                        'action'                  => 'new_registration',
2466
                        'processing_registration' => 1,
2467
                        'event_id'                => $this->_reg_event->ID(),
2468
                        'uts'                     => time(),
2469
                    );
2470
                    $this->_redirect_after_action(false, '', '', $query_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...
2471
                }
2472
                break;
2473
            case 'questions' :
2474
                if ( ! isset($this->_req_data['txn_reg_status_change'], $this->_req_data['txn_reg_status_change']['send_notifications'])) {
2475
                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
2476
                }
2477
                //process registration
2478
                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
2479
                if ($cart instanceof EE_Cart) {
2480
                    $grand_total = $cart->get_cart_grand_total();
2481
                    if ($grand_total instanceof EE_Line_Item) {
2482
                        $grand_total->save_this_and_descendants_to_txn();
2483
                    }
2484
                }
2485 View Code Duplication
                if ( ! $transaction instanceof EE_Transaction) {
2486
                    $query_args = array(
2487
                        'action'                  => 'new_registration',
2488
                        'processing_registration' => 2,
2489
                        'event_id'                => $this->_reg_event->ID(),
2490
                        'uts'                     => time(),
2491
                    );
2492
                    if (defined('DOING_AJAX')) {
2493
                        //display registration form again because there are errors (maybe validation?)
2494
                        $this->new_registration();
2495
                        return;
2496
                    } else {
2497
                        $this->_redirect_after_action(false, '', '', $query_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...
2498
                        return;
2499
                    }
2500
                }
2501
                // maybe update status, and make sure to save transaction if not done already
2502
                if ( ! $transaction->update_status_based_on_total_paid()) {
2503
                    $transaction->save();
2504
                }
2505
                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2506
                $this->_req_data = array();
2507
                $query_args      = array(
2508
                    'action'        => 'redirect_to_txn',
2509
                    'TXN_ID'        => $transaction->ID(),
2510
                    'EVT_ID'        => $this->_reg_event->ID(),
2511
                    'event_name'    => urlencode($this->_reg_event->name()),
2512
                    'redirect_from' => 'new_registration',
2513
                );
2514
                $this->_redirect_after_action(false, '', '', $query_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...
2515
                break;
2516
        }
2517
        //what are you looking here for?  Should be nothing to do at this point.
2518
    }
2519
2520
2521
    /**
2522
     * redirect_to_txn
2523
     *
2524
     * @access public
2525
     * @return void
2526
     */
2527
    public function redirect_to_txn()
2528
    {
2529
        EE_System::do_not_cache();
2530
        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2531
        $query_args = array(
2532
            'action' => 'view_transaction',
2533
            'TXN_ID' => isset($this->_req_data['TXN_ID']) ? absint($this->_req_data['TXN_ID']) : 0,
2534
            'page'   => 'espresso_transactions',
2535
        );
2536
        if (isset($this->_req_data['EVT_ID'], $this->_req_data['redirect_from'])) {
2537
            $query_args['EVT_ID']        = $this->_req_data['EVT_ID'];
2538
            $query_args['event_name']    = urlencode($this->_req_data['event_name']);
2539
            $query_args['redirect_from'] = $this->_req_data['redirect_from'];
2540
        }
2541
        EE_Error::add_success(__('Registration Created.  Please review the transaction and add any payments as necessary',
2542
            'event_espresso'));
2543
        $this->_redirect_after_action(false, '', '', $query_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...
2544
    }
2545
2546
2547
    /**
2548
     *        generates HTML for the Attendee Contact List
2549
     *
2550
     * @access protected
2551
     * @return void
2552
     */
2553
    protected function _attendee_contact_list_table()
2554
    {
2555
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2556
        $this->_search_btn_label = __('Contacts', 'event_espresso');
2557
        $this->display_admin_list_table_page_with_no_sidebar();
2558
    }
2559
2560
2561
    /**
2562
     *        get_attendees
2563
     *
2564
     * @param bool $count whether to return count or data.
2565
     * @access public
2566
     * @return array
2567
     */
2568
    public function get_attendees($per_page, $count = false, $trash = false)
2569
    {
2570
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2571
        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
2572
        $ATT_MDL                    = EEM_Attendee::instance();
2573
        $this->_req_data['orderby'] = ! empty($this->_req_data['orderby']) ? $this->_req_data['orderby'] : '';
2574
        switch ($this->_req_data['orderby']) {
2575
            case 'ATT_ID':
2576
                $orderby = 'ATT_ID';
2577
                break;
2578
            case 'ATT_fname':
2579
                $orderby = 'ATT_fname';
2580
                break;
2581
            case 'ATT_email':
2582
                $orderby = 'ATT_email';
2583
                break;
2584
            case 'ATT_city':
2585
                $orderby = 'ATT_city';
2586
                break;
2587
            case 'STA_ID':
2588
                $orderby = 'STA_ID';
2589
                break;
2590
            case 'CNT_ID':
2591
                $orderby = 'CNT_ID';
2592
                break;
2593
            default:
2594
                $orderby = 'ATT_lname';
2595
        }
2596
        $sort         = (isset($this->_req_data['order']) && ! empty($this->_req_data['order'])) ? $this->_req_data['order']
2597
            : 'ASC';
2598
        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
2599
            ? $this->_req_data['paged'] : 1;
2600
        $per_page     = isset($per_page) && ! empty($per_page) ? $per_page : 10;
2601
        $per_page     = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
2602
            ? $this->_req_data['perpage'] : $per_page;
2603
        $_where       = array();
2604
        if ( ! empty($this->_req_data['s'])) {
2605
            $sstr         = '%' . $this->_req_data['s'] . '%';
2606
            $_where['OR'] = array(
2607
                'Registration.Event.EVT_name'       => array('LIKE', $sstr),
2608
                'Registration.Event.EVT_desc'       => array('LIKE', $sstr),
2609
                'Registration.Event.EVT_short_desc' => array('LIKE', $sstr),
2610
                'ATT_fname'                         => array('LIKE', $sstr),
2611
                'ATT_lname'                         => array('LIKE', $sstr),
2612
                'ATT_short_bio'                     => array('LIKE', $sstr),
2613
                'ATT_email'                         => array('LIKE', $sstr),
2614
                'ATT_address'                       => array('LIKE', $sstr),
2615
                'ATT_address2'                      => array('LIKE', $sstr),
2616
                'ATT_city'                          => array('LIKE', $sstr),
2617
                'Country.CNT_name'                  => array('LIKE', $sstr),
2618
                'State.STA_name'                    => array('LIKE', $sstr),
2619
                'ATT_phone'                         => array('LIKE', $sstr),
2620
                'Registration.REG_final_price'      => array('LIKE', $sstr),
2621
                'Registration.REG_code'             => array('LIKE', $sstr),
2622
                'Registration.REG_count'            => array('LIKE', $sstr),
2623
                'Registration.REG_group_size'       => array('LIKE', $sstr),
2624
            );
2625
        }
2626
        $offset = ($current_page - 1) * $per_page;
2627
        $limit  = $count ? null : array($offset, $per_page);
2628
        if ($trash) {
2629
            $_where['status'] = array('!=', 'publish');
2630
            $all_attendees    = $count
2631
                ? $ATT_MDL->count(array(
2632
                    $_where,
2633
                    'order_by' => array($orderby => $sort),
2634
                    'limit'    => $limit,
2635
                ), 'ATT_ID', true)
2636
                : $ATT_MDL->get_all(array(
2637
                    $_where,
2638
                    'order_by' => array($orderby => $sort),
2639
                    'limit'    => $limit,
2640
                ));
2641
        } else {
2642
            $_where['status'] = array('IN', array('publish'));
2643
            $all_attendees    = $count
2644
                ? $ATT_MDL->count(array(
2645
                    $_where,
2646
                    'order_by' => array($orderby => $sort),
2647
                    'limit'    => $limit,
2648
                ), 'ATT_ID', true)
2649
                : $ATT_MDL->get_all(array(
2650
                    $_where,
2651
                    'order_by' => array($orderby => $sort),
2652
                    'limit'    => $limit,
2653
                ));
2654
        }
2655
        return $all_attendees;
2656
    }
2657
2658
2659
    /**
2660
     * This is just taking care of resending the registration confirmation
2661
     *
2662
     * @access protected
2663
     * @return void
2664
     */
2665
    protected function _resend_registration()
2666
    {
2667
        $this->_process_resend_registration();
2668
        $query_args = isset($this->_req_data['redirect_to'])
2669
            ? array('action' => $this->_req_data['redirect_to'], '_REG_ID' => $this->_req_data['_REG_ID'])
2670
            : array(
2671
                'action' => 'default',
2672
            );
2673
        $this->_redirect_after_action(false, '', '', $query_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...
2674
    }
2675
2676
    /**
2677
     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
2678
     * to use when selecting registrations
2679
     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
2680
     *                                                     the query parameters from the request
2681
     * @return void ends the request with a redirect or download
2682
     */
2683
    public function _registrations_report_base( $method_name_for_getting_query_params )
2684
    {
2685
        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
2686
            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
2687
                'page'        => 'espresso_batch',
2688
                'batch'       => 'file',
2689
                'EVT_ID'      => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
2690
                'filters'     => urlencode(
2691
                    serialize(
2692
                        call_user_func(
2693
                            array( $this, $method_name_for_getting_query_params ),
2694
                            EEH_Array::is_set(
2695
                                $this->_req_data,
2696
                                'filters',
2697
                                array()
2698
                            )
2699
                        )
2700
                    )
2701
                ),
2702
                'use_filters' => EEH_Array::is_set($this->_req_data, 'use_filters', false),
2703
                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
2704
                'return_url'  => urlencode($this->_req_data['return_url']),
2705
            )));
2706
        } else {
2707
            $new_request_args = array(
2708
                'export' => 'report',
2709
                'action' => 'registrations_report_for_event',
2710
                'EVT_ID' => isset($this->_req_data['EVT_ID']) ? $this->_req_data['EVT_ID'] : null,
2711
            );
2712
            $this->_req_data = array_merge($this->_req_data, $new_request_args);
2713
            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
2714
                require_once(EE_CLASSES . 'EE_Export.class.php');
2715
                $EE_Export = EE_Export::instance($this->_req_data);
2716
                $EE_Export->export();
2717
            }
2718
        }
2719
    }
2720
2721
2722
2723
    /**
2724
     * Creates a registration report using only query parameters in the request
2725
     * @return void
2726
     */
2727
    public function _registrations_report()
2728
    {
2729
        $this->_registrations_report_base( '_get_registration_query_parameters' );
2730
    }
2731
2732
2733
    public function _contact_list_export()
2734
    {
2735
        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
2736
            require_once(EE_CLASSES . 'EE_Export.class.php');
2737
            $EE_Export = EE_Export::instance($this->_req_data);
2738
            $EE_Export->export_attendees();
2739
        }
2740
    }
2741
2742
2743
    public function _contact_list_report()
2744
    {
2745
        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
2746
            wp_redirect(EE_Admin_Page::add_query_args_and_nonce(array(
2747
                'page'        => 'espresso_batch',
2748
                'batch'       => 'file',
2749
                'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
2750
                'return_url'  => urlencode($this->_req_data['return_url']),
2751
            )));
2752
        } else {
2753
            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
2754
                require_once(EE_CLASSES . 'EE_Export.class.php');
2755
                $EE_Export = EE_Export::instance($this->_req_data);
2756
                $EE_Export->report_attendees();
2757
            }
2758
        }
2759
    }
2760
2761
2762
2763
2764
2765
    /***************************************        ATTENDEE DETAILS        ***************************************/
2766
    /**
2767
     * This duplicates the attendee object for the given incoming registration id and attendee_id.
2768
     *
2769
     * @return void
2770
     */
2771
    protected function _duplicate_attendee()
2772
    {
2773
        $action = ! empty($this->_req_data['return']) ? $this->_req_data['return'] : 'default';
2774
        //verify we have necessary info
2775 View Code Duplication
        if (empty($this->_req_data['_REG_ID'])) {
2776
            EE_Error::add_error(__('Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
2777
                'event_espresso'), __FILE__, __LINE__, __FUNCTION__);
2778
            $query_args = array('action' => $action);
2779
            $this->_redirect_after_action('', '', '', $query_args, true);
2780
        }
2781
        //okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
2782
        $registration = EEM_Registration::instance()->get_one_by_ID($this->_req_data['_REG_ID']);
2783
        $attendee     = $registration->attendee();
0 ignored issues
show
Documentation Bug introduced by
The method attendee 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...
2784
        //remove relation of existing attendee on registration
2785
        $registration->_remove_relation_to($attendee, 'Attendee');
2786
        //new attendee
2787
        $new_attendee = clone $attendee;
2788
        $new_attendee->set('ATT_ID', 0);
2789
        $new_attendee->save();
2790
        //add new attendee to reg
2791
        $registration->_add_relation_to($new_attendee, 'Attendee');
2792
        EE_Error::add_success(__('New Contact record created.  Now make any edits you wish to make for this contact.',
2793
            'event_espresso'));
2794
        //redirect to edit page for attendee
2795
        $query_args = array('post' => $new_attendee->ID(), 'action' => 'edit_attendee');
2796
        $this->_redirect_after_action('', '', '', $query_args, true);
2797
    }
2798
2799
2800
    //related to cpt routes
2801
    protected function _insert_update_cpt_item($post_id, $post)
2802
    {
2803
        $success  = true;
2804
        $attendee = EEM_Attendee::instance()->get_one_by_ID($post_id);
2805
        //for attendee updates
2806
        if ($post->post_type = 'espresso_attendees' && ! empty($attendee)) {
0 ignored issues
show
Comprehensibility introduced by
Consider adding parentheses for clarity. Current Interpretation: $post->post_type = ('esp...' && !empty($attendee)), Probably Intended Meaning: ($post->post_type = 'esp...') && !empty($attendee)
Loading history...
2807
            //note we should only be UPDATING attendees at this point.
2808
            $updated_fields = array(
2809
                'ATT_fname'     => $this->_req_data['ATT_fname'],
2810
                'ATT_lname'     => $this->_req_data['ATT_lname'],
2811
                'ATT_full_name' => $this->_req_data['ATT_fname'] . ' ' . $this->_req_data['ATT_lname'],
2812
                'ATT_address'   => isset($this->_req_data['ATT_address']) ? $this->_req_data['ATT_address'] : '',
2813
                'ATT_address2'  => isset($this->_req_data['ATT_address2']) ? $this->_req_data['ATT_address2'] : '',
2814
                'ATT_city'      => isset($this->_req_data['ATT_city']) ? $this->_req_data['ATT_city'] : '',
2815
                'STA_ID'        => isset($this->_req_data['STA_ID']) ? $this->_req_data['STA_ID'] : '',
2816
                'CNT_ISO'       => isset($this->_req_data['CNT_ISO']) ? $this->_req_data['CNT_ISO'] : '',
2817
                'ATT_zip'       => isset($this->_req_data['ATT_zip']) ? $this->_req_data['ATT_zip'] : '',
2818
                'ATT_email'     => isset($this->_req_data['ATT_email']) ? $this->_req_data['ATT_email'] : '',
2819
                'ATT_phone'     => isset($this->_req_data['ATT_phone']) ? $this->_req_data['ATT_phone'] : '',
2820
            );
2821
            foreach ($updated_fields as $field => $value) {
2822
                $attendee->set($field, $value);
2823
            }
2824
            $success                   = $attendee->save();
2825
            $attendee_update_callbacks = apply_filters('FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
2826
                array());
2827
            foreach ($attendee_update_callbacks as $a_callback) {
2828
                if (false === call_user_func_array($a_callback, array($attendee, $this->_req_data))) {
2829
                    throw new EE_Error(sprintf(__('The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
2830
                        'event_espresso'), $a_callback));
2831
                }
2832
            }
2833
        }
2834
        if ($success === false) {
2835
            EE_Error::add_error(__('Something went wrong with updating the meta table data for the registration.',
2836
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
2837
        }
2838
    }
2839
2840
2841
    public function trash_cpt_item($post_id)
2842
    {
2843
    }
2844
2845
2846
    public function delete_cpt_item($post_id)
2847
    {
2848
    }
2849
2850
2851
    public function restore_cpt_item($post_id)
2852
    {
2853
    }
2854
2855
2856
    protected function _restore_cpt_item($post_id, $revision_id)
2857
    {
2858
    }
2859
2860
2861
    public function attendee_editor_metaboxes()
2862
    {
2863
        $this->verify_cpt_object();
2864
        remove_meta_box('postexcerpt', __('Excerpt'), 'post_excerpt_meta_box', $this->_cpt_routes[$this->_req_action],
2865
            'normal', 'core');
2866
        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal', 'core');
2867 View Code Duplication
        if (post_type_supports('espresso_attendees', 'excerpt')) {
2868
            add_meta_box('postexcerpt', __('Short Biography', 'event_espresso'), 'post_excerpt_meta_box',
2869
                $this->_cpt_routes[$this->_req_action], 'normal');
2870
        }
2871 View Code Duplication
        if (post_type_supports('espresso_attendees', 'comments')) {
2872
            add_meta_box('commentsdiv', __('Notes on the Contact', 'event_espresso'), 'post_comment_meta_box',
2873
                $this->_cpt_routes[$this->_req_action], 'normal', 'core');
2874
        }
2875
        add_meta_box('attendee_contact_info', __('Contact Info', 'event_espresso'),
2876
            array($this, 'attendee_contact_info'), $this->_cpt_routes[$this->_req_action], 'side', 'core');
2877
        add_meta_box('attendee_details_address', __('Address Details', 'event_espresso'),
2878
            array($this, 'attendee_address_details'), $this->_cpt_routes[$this->_req_action], 'normal', 'core');
2879
        add_meta_box('attendee_registrations', __('Registrations for this Contact', 'event_espresso'),
2880
            array($this, 'attendee_registrations_meta_box'), $this->_cpt_routes[$this->_req_action], 'normal', 'high');
2881
    }
2882
2883
2884
    /**
2885
     * Metabox for attendee contact info
2886
     *
2887
     * @param  WP_Post $post wp post object
2888
     * @return string        attendee contact info ( and form )
2889
     */
2890
    public function attendee_contact_info($post)
0 ignored issues
show
Unused Code introduced by
The parameter $post 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...
2891
    {
2892
        //get attendee object ( should already have it )
2893
        $this->_template_args['attendee'] = $this->_cpt_model_obj;
2894
        $template                         = REG_TEMPLATE_PATH . 'attendee_contact_info_metabox_content.template.php';
2895
        EEH_Template::display_template($template, $this->_template_args);
2896
    }
2897
2898
2899
    /**
2900
     * Metabox for attendee details
2901
     *
2902
     * @param  WP_Post $post wp post object
2903
     * @return string        attendee address details (and form)
2904
     */
2905
    public function attendee_address_details($post)
0 ignored issues
show
Unused Code introduced by
The parameter $post 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...
2906
    {
2907
        //get attendee object (should already have it)
2908
        $this->_template_args['attendee']     = $this->_cpt_model_obj;
2909
        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(new EE_Question_Form_Input(EE_Question::new_instance(array(
2910
            'QST_ID'           => 0,
2911
            'QST_display_text' => __('State/Province', 'event_espresso'),
2912
            'QST_system'       => 'admin-state',
2913
        )), EE_Answer::new_instance(array(
2914
            'ANS_ID'    => 0,
2915
            'ANS_value' => $this->_cpt_model_obj->state_ID(),
0 ignored issues
show
Documentation Bug introduced by
The method state_ID 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...
2916
        )), array(
2917
            'input_id'       => 'STA_ID',
2918
            'input_name'     => 'STA_ID',
2919
            'input_prefix'   => '',
2920
            'append_qstn_id' => false,
2921
        )));
2922
        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(new EE_Question_Form_Input(EE_Question::new_instance(array(
2923
            'QST_ID'           => 0,
2924
            'QST_display_text' => __('Country', 'event_espresso'),
2925
            'QST_system'       => 'admin-country',
2926
        )), EE_Answer::new_instance(array(
2927
            'ANS_ID'    => 0,
2928
            'ANS_value' => $this->_cpt_model_obj->country_ID(),
0 ignored issues
show
Documentation Bug introduced by
The method country_ID 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...
2929
        )), array(
2930
            'input_id'       => 'CNT_ISO',
2931
            'input_name'     => 'CNT_ISO',
2932
            'input_prefix'   => '',
2933
            'append_qstn_id' => false,
2934
        )));
2935
        $template                             = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
2936
        EEH_Template::display_template($template, $this->_template_args);
2937
    }
2938
2939
2940
    /**
2941
     *        _attendee_details
2942
     *
2943
     * @access protected
2944
     * @return void
2945
     */
2946
    public function attendee_registrations_meta_box($post)
0 ignored issues
show
Unused Code introduced by
The parameter $post 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...
2947
    {
2948
        $this->_template_args['attendee']      = $this->_cpt_model_obj;
2949
        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
2950
        $template                              = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
2951
        EEH_Template::display_template($template, $this->_template_args);
2952
    }
2953
2954
2955
    /**
2956
     * add in the form fields for the attendee edit
2957
     *
2958
     * @param  WP_Post $post wp post object
2959
     * @return string        html for new form.
2960
     */
2961
    public function after_title_form_fields($post)
2962
    {
2963
        if ($post->post_type == 'espresso_attendees') {
2964
            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
2965
            $template_args['attendee'] = $this->_cpt_model_obj;
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...
2966
            EEH_Template::display_template($template, $template_args);
2967
        }
2968
    }
2969
2970
2971
    /**
2972
     *        _trash_or_restore_attendee
2973
     *
2974
     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
2975
     * @access protected
2976
     * @return void
2977
     */
2978
    protected function _trash_or_restore_attendees($trash = true)
2979
    {
2980
        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2981
        $ATT_MDL = EEM_Attendee::instance();
2982
        $success = 1;
2983
        //Checkboxes
2984
        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
2985
            // if array has more than one element than success message should be plural
2986
            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
2987
            // cycle thru checkboxes
2988
            while (list($ATT_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...
2989
                $updated = $trash ? $ATT_MDL->update_by_ID(array('status' => 'trash'), $ATT_ID)
2990
                    : $ATT_MDL->update_by_ID(array('status' => 'publish'), $ATT_ID);
2991
                if ( ! $updated) {
2992
                    $success = 0;
2993
                }
2994
            }
2995
        } else {
2996
            // grab single id and delete
2997
            $ATT_ID = absint($this->_req_data['ATT_ID']);
2998
            //get attendee
2999
            $att     = $ATT_MDL->get_one_by_ID($ATT_ID);
3000
            $updated = $trash ? $att->set_status('trash') : $att->set_status('publish');
0 ignored issues
show
Documentation Bug introduced by
The method set_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...
Unused Code introduced by
$updated 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...
3001
            $updated = $att->save();
3002
            if ( ! $updated) {
3003
                $success = 0;
3004
            }
3005
        }
3006
        $what        = $success > 1 ? __('Contacts', 'event_espresso') : __('Contact', 'event_espresso');
3007
        $action_desc = $trash ? __('moved to the trash', 'event_espresso') : __('restored', 'event_espresso');
3008
        $this->_redirect_after_action($success, $what, $action_desc, array('action' => 'contact_list'));
3009
    }
3010
3011
}
3012
3013
3014
3015
// end of file:  includes/core/admin/transactions/Registrations_Admin_Page.core.php
3016