Completed
Branch dev (3710f0)
by
unknown
25:03 queued 15:31
created
admin_pages/transactions/Transactions_Admin_Page.core.php 2 patches
Indentation   +2518 added lines, -2518 removed lines patch added patch discarded remove patch
@@ -13,2522 +13,2522 @@
 block discarded – undo
13 13
  */
14 14
 class Transactions_Admin_Page extends EE_Admin_Page
15 15
 {
16
-    /**
17
-     * @var EE_Transaction
18
-     */
19
-    private $_transaction;
20
-
21
-    /**
22
-     * @var EE_Session
23
-     */
24
-    private $_session;
25
-
26
-    /**
27
-     * @var array $_txn_status
28
-     */
29
-    private static $_txn_status;
30
-
31
-    /**
32
-     * @var array $_pay_status
33
-     */
34
-    private static $_pay_status;
35
-
36
-    /**
37
-     * @var array $_existing_reg_payment_REG_IDs
38
-     */
39
-    protected $_existing_reg_payment_REG_IDs;
40
-
41
-
42
-    /**
43
-     *    _init_page_props
44
-     *
45
-     * @return void
46
-     */
47
-    protected function _init_page_props()
48
-    {
49
-        $this->page_slug        = TXN_PG_SLUG;
50
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
51
-        $this->_admin_base_url  = TXN_ADMIN_URL;
52
-        $this->_admin_base_path = TXN_ADMIN;
53
-    }
54
-
55
-
56
-    /**
57
-     *    _ajax_hooks
58
-     *
59
-     * @return void
60
-     */
61
-    protected function _ajax_hooks()
62
-    {
63
-        // add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
-        // add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
-        // add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
-    }
67
-
68
-
69
-    /**
70
-     *    _define_page_props
71
-     *
72
-     * @return void
73
-     */
74
-    protected function _define_page_props()
75
-    {
76
-        $this->_admin_page_title = $this->page_label;
77
-        $this->_labels           = [
78
-            'buttons' => [
79
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
-            ],
83
-        ];
84
-    }
85
-
86
-
87
-    /**
88
-     *        grab url requests and route them
89
-     *
90
-     * @access private
91
-     * @return void
92
-     * @throws EE_Error
93
-     * @throws InvalidArgumentException
94
-     * @throws InvalidDataTypeException
95
-     * @throws InvalidInterfaceException
96
-     */
97
-    public function _set_page_routes()
98
-    {
99
-
100
-        $this->_set_transaction_status_array();
101
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
-
103
-        $this->_page_routes = [
104
-
105
-            'default' => [
106
-                'func'       => '_transactions_overview_list_table',
107
-                'capability' => 'ee_read_transactions',
108
-            ],
109
-
110
-            'view_transaction' => [
111
-                'func'       => '_transaction_details',
112
-                'capability' => 'ee_read_transaction',
113
-                'obj_id'     => $TXN_ID,
114
-            ],
115
-
116
-            'send_payment_reminder' => [
117
-                'func'       => '_send_payment_reminder',
118
-                'noheader'   => true,
119
-                'capability' => 'ee_send_message',
120
-            ],
121
-
122
-            'espresso_apply_payment' => [
123
-                'func'       => 'apply_payments_or_refunds',
124
-                'noheader'   => true,
125
-                'capability' => 'ee_edit_payments',
126
-            ],
127
-
128
-            'espresso_apply_refund' => [
129
-                'func'       => 'apply_payments_or_refunds',
130
-                'noheader'   => true,
131
-                'capability' => 'ee_edit_payments',
132
-            ],
133
-
134
-            'espresso_delete_payment' => [
135
-                'func'       => [$this, 'delete_payment'],
136
-                'noheader'   => true,
137
-                'capability' => 'ee_delete_payments',
138
-            ],
139
-
140
-            'espresso_recalculate_line_items' => [
141
-                'func'       => 'recalculateLineItems',
142
-                'noheader'   => true,
143
-                'capability' => 'ee_edit_payments',
144
-            ],
145
-
146
-        ];
147
-    }
148
-
149
-
150
-    protected function _set_page_config()
151
-    {
152
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
-        $this->_page_config = [
154
-            'default'          => [
155
-                'nav'           => [
156
-                    'label' => esc_html__('Overview', 'event_espresso'),
157
-                    'icon' => 'dashicons-list-view',
158
-                    'order' => 10,
159
-                ],
160
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
161
-                'help_tabs'     => [
162
-                    'transactions_overview_help_tab'                       => [
163
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
164
-                        'filename' => 'transactions_overview',
165
-                    ],
166
-                    'transactions_overview_table_column_headings_help_tab' => [
167
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
168
-                        'filename' => 'transactions_overview_table_column_headings',
169
-                    ],
170
-                    'transactions_overview_views_filters_help_tab'         => [
171
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
172
-                        'filename' => 'transactions_overview_views_filters_search',
173
-                    ],
174
-                ],
175
-                'require_nonce' => false,
176
-            ],
177
-            'view_transaction' => [
178
-                'nav'       => [
179
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
180
-                    'icon' => 'dashicons-cart',
181
-                    'order'      => 5,
182
-                    'url'        => $TXN_ID
183
-                        ? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
184
-                        : $this->_admin_base_url,
185
-                    'persistent' => false,
186
-                ],
187
-                'help_tabs' => [
188
-                    'transactions_view_transaction_help_tab'                                              => [
189
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
190
-                        'filename' => 'transactions_view_transaction',
191
-                    ],
192
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => [
193
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
194
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
195
-                    ],
196
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => [
197
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
198
-                        'filename' => 'transactions_view_transaction_attendees_registered',
199
-                    ],
200
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
201
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
202
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
203
-                    ],
204
-                ],
205
-                'qtips'     => ['Transaction_Details_Tips'],
206
-                'metaboxes' => ['_transaction_details_metaboxes'],
207
-
208
-                'require_nonce' => false,
209
-            ],
210
-        ];
211
-    }
212
-
213
-
214
-    /**
215
-     * The below methods aren't used by this class currently
216
-     */
217
-    protected function _add_screen_options()
218
-    {
219
-        // noop
220
-    }
221
-
222
-
223
-    protected function _add_feature_pointers()
224
-    {
225
-        // noop
226
-    }
227
-
228
-
229
-    public function admin_init()
230
-    {
231
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
232
-        $event_name = $this->request->getRequestParam('event_name');
233
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
234
-        // IF a registration was JUST added via the admin...
235
-        if ($EVT_ID && $event_name && $redirect_from) {
236
-            // then set a cookie so that we can block any attempts to use
237
-            // the back button as a way to enter another registration.
238
-            setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
239
-            // and update the global
240
-            $_COOKIE['ee_registration_added'] = $EVT_ID;
241
-        }
242
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
243
-            'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
244
-            'event_espresso'
245
-        );
246
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
247
-            'An error occurred! Please refresh the page and try again.',
248
-            'event_espresso'
249
-        );
250
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
251
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
252
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
253
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
254
-            'This transaction has been overpaid ! Payments Total',
255
-            'event_espresso'
256
-        );
257
-    }
258
-
259
-
260
-    public function admin_notices()
261
-    {
262
-        // noop
263
-    }
264
-
265
-
266
-    public function admin_footer_scripts()
267
-    {
268
-        // noop
269
-    }
270
-
271
-
272
-    /**
273
-     * _set_transaction_status_array
274
-     * sets list of transaction statuses
275
-     *
276
-     * @access private
277
-     * @return void
278
-     * @throws EE_Error
279
-     * @throws InvalidArgumentException
280
-     * @throws InvalidDataTypeException
281
-     * @throws InvalidInterfaceException
282
-     */
283
-    private function _set_transaction_status_array()
284
-    {
285
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
286
-    }
287
-
288
-
289
-    /**
290
-     * get_transaction_status_array
291
-     * return the transaction status array for wp_list_table
292
-     *
293
-     * @access public
294
-     * @return array
295
-     */
296
-    public function get_transaction_status_array()
297
-    {
298
-        return self::$_txn_status;
299
-    }
300
-
301
-
302
-    /**
303
-     *    get list of payment statuses
304
-     *
305
-     * @access private
306
-     * @return void
307
-     * @throws EE_Error
308
-     * @throws InvalidArgumentException
309
-     * @throws InvalidDataTypeException
310
-     * @throws InvalidInterfaceException
311
-     */
312
-    private function _get_payment_status_array()
313
-    {
314
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
315
-        $this->_template_args['payment_status'] = self::$_pay_status;
316
-    }
317
-
318
-
319
-    /**
320
-     *    _add_screen_options_default
321
-     *
322
-     * @access protected
323
-     * @return void
324
-     * @throws InvalidArgumentException
325
-     * @throws InvalidDataTypeException
326
-     * @throws InvalidInterfaceException
327
-     */
328
-    protected function _add_screen_options_default()
329
-    {
330
-        $this->_per_page_screen_option();
331
-    }
332
-
333
-
334
-    /**
335
-     * load_scripts_styles
336
-     *
337
-     * @access public
338
-     * @return void
339
-     */
340
-    public function load_scripts_styles()
341
-    {
342
-        // enqueue style
343
-        wp_register_style(
344
-            'espresso_txn',
345
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
346
-            [],
347
-            EVENT_ESPRESSO_VERSION
348
-        );
349
-        wp_enqueue_style('espresso_txn');
350
-        // scripts
351
-        wp_register_script(
352
-            'espresso_txn',
353
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
354
-            [
355
-                'ee_admin_js',
356
-                'ee-datepicker',
357
-                'jquery-ui-datepicker',
358
-                'jquery-ui-draggable',
359
-                'ee-dialog',
360
-                'ee-accounting',
361
-                'ee-serialize-full-array',
362
-            ],
363
-            EVENT_ESPRESSO_VERSION,
364
-            true
365
-        );
366
-        wp_enqueue_script('espresso_txn');
367
-    }
368
-
369
-
370
-    /**
371
-     *    load_scripts_styles_view_transaction
372
-     *
373
-     * @access public
374
-     * @return void
375
-     */
376
-    public function load_scripts_styles_view_transaction()
377
-    {
378
-        // styles
379
-        wp_enqueue_style('espresso-ui-theme');
380
-    }
381
-
382
-
383
-    /**
384
-     *    load_scripts_styles_default
385
-     *
386
-     * @access public
387
-     * @return void
388
-     */
389
-    public function load_scripts_styles_default()
390
-    {
391
-        // styles
392
-        wp_enqueue_style('espresso-ui-theme');
393
-    }
394
-
395
-
396
-    /**
397
-     *    _set_list_table_views_default
398
-     *
399
-     * @access protected
400
-     * @return void
401
-     */
402
-    protected function _set_list_table_views_default()
403
-    {
404
-        $this->_views = [
405
-            'all'        => [
406
-                'slug'  => 'all',
407
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
408
-                'count' => 0,
409
-            ],
410
-            'abandoned'  => [
411
-                'slug'  => 'abandoned',
412
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
413
-                'count' => 0,
414
-            ],
415
-            'incomplete' => [
416
-                'slug'  => 'incomplete',
417
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
418
-                'count' => 0,
419
-            ],
420
-        ];
421
-        if (
422
-            /**
423
-             * Filters whether a link to the "Failed Transactions" list table
424
-             * appears on the Transactions Admin Page list table.
425
-             * List display can be turned back on via the following:
426
-             * add_filter(
427
-             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
428
-             *     '__return_true'
429
-             * );
430
-             *
431
-             * @param boolean                 $display_failed_txns_list
432
-             * @param Transactions_Admin_Page $this
433
-             * @since 4.9.70.p
434
-             */
435
-            apply_filters(
436
-                'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
437
-                false,
438
-                $this
439
-            )
440
-        ) {
441
-            $this->_views['failed'] = [
442
-                'slug'  => 'failed',
443
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
444
-                'count' => 0,
445
-            ];
446
-        }
447
-    }
448
-
449
-
450
-    /**
451
-     * _set_transaction_object
452
-     * This sets the _transaction property for the transaction details screen
453
-     *
454
-     * @access private
455
-     * @return void
456
-     * @throws EE_Error
457
-     * @throws InvalidArgumentException
458
-     * @throws RuntimeException
459
-     * @throws InvalidDataTypeException
460
-     * @throws InvalidInterfaceException
461
-     * @throws ReflectionException
462
-     */
463
-    private function _set_transaction_object()
464
-    {
465
-        if ($this->_transaction instanceof EE_Transaction) {
466
-            return;
467
-        } //get out we've already set the object
468
-
469
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
470
-
471
-        // get transaction object
472
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
473
-        $this->_session     = $this->_transaction instanceof EE_Transaction
474
-            ? $this->_transaction->session_data()
475
-            : null;
476
-        if ($this->_transaction instanceof EE_Transaction) {
477
-            $this->_transaction->verify_abandoned_transaction_status();
478
-        }
479
-
480
-        if (! $this->_transaction instanceof EE_Transaction) {
481
-            $error_msg = sprintf(
482
-                esc_html__(
483
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
484
-                    'event_espresso'
485
-                ),
486
-                $TXN_ID
487
-            );
488
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
489
-        }
490
-    }
491
-
492
-
493
-    /**
494
-     *    _transaction_legend_items
495
-     *
496
-     * @access protected
497
-     * @return array
498
-     * @throws EE_Error
499
-     * @throws InvalidArgumentException
500
-     * @throws ReflectionException
501
-     * @throws InvalidDataTypeException
502
-     * @throws InvalidInterfaceException
503
-     */
504
-    protected function _transaction_legend_items()
505
-    {
506
-        EE_Registry::instance()->load_helper('MSG_Template');
507
-        $items = [];
508
-
509
-        if (
510
-            EE_Registry::instance()->CAP->current_user_can(
511
-                'ee_read_global_messages',
512
-                'view_filtered_messages'
513
-            )
514
-        ) {
515
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
516
-            if (
517
-                is_array($related_for_icon)
518
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
519
-            ) {
520
-                $items['view_related_messages'] = [
521
-                    'class' => $related_for_icon['css_class'],
522
-                    'desc'  => $related_for_icon['label'],
523
-                ];
524
-            }
525
-        }
526
-
527
-        $items = apply_filters(
528
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
529
-            array_merge(
530
-                $items,
531
-                [
532
-                    'view_details'          => [
533
-                        'class' => 'dashicons dashicons-cart',
534
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
535
-                    ],
536
-                    'view_invoice'          => [
537
-                        'class' => 'dashicons dashicons-media-spreadsheet',
538
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
539
-                    ],
540
-                    'view_receipt'          => [
541
-                        'class' => 'dashicons dashicons-text-page',
542
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
543
-                    ],
544
-                    'view_registration'     => [
545
-                        'class' => 'dashicons dashicons-clipboard',
546
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
547
-                    ],
548
-                    'payment_overview_link' => [
549
-                        'class' => 'dashicons dashicons-money',
550
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
551
-                    ],
552
-                ]
553
-            )
554
-        );
555
-
556
-        if (
557
-            EEH_MSG_Template::is_mt_active('payment_reminder')
558
-            && EE_Registry::instance()->CAP->current_user_can(
559
-                'ee_send_message',
560
-                'espresso_transactions_send_payment_reminder'
561
-            )
562
-        ) {
563
-            $items['send_payment_reminder'] = [
564
-                'class' => 'dashicons dashicons-email-alt',
565
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
566
-            ];
567
-        } else {
568
-            $items['blank*'] = [
569
-                'class' => '',
570
-                'desc'  => '',
571
-            ];
572
-        }
573
-        $more_items = apply_filters(
574
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
575
-            [
576
-                'overpaid'   => [
577
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
578
-                    'desc'  => EEH_Template::pretty_status(
579
-                        EEM_Transaction::overpaid_status_code,
580
-                        false,
581
-                        'sentence'
582
-                    ),
583
-                ],
584
-                'complete'   => [
585
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
586
-                    'desc'  => EEH_Template::pretty_status(
587
-                        EEM_Transaction::complete_status_code,
588
-                        false,
589
-                        'sentence'
590
-                    ),
591
-                ],
592
-                'incomplete' => [
593
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
594
-                    'desc'  => EEH_Template::pretty_status(
595
-                        EEM_Transaction::incomplete_status_code,
596
-                        false,
597
-                        'sentence'
598
-                    ),
599
-                ],
600
-                'abandoned'  => [
601
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
602
-                    'desc'  => EEH_Template::pretty_status(
603
-                        EEM_Transaction::abandoned_status_code,
604
-                        false,
605
-                        'sentence'
606
-                    ),
607
-                ],
608
-                'failed'     => [
609
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
610
-                    'desc'  => EEH_Template::pretty_status(
611
-                        EEM_Transaction::failed_status_code,
612
-                        false,
613
-                        'sentence'
614
-                    ),
615
-                ],
616
-            ]
617
-        );
618
-
619
-        return array_merge($items, $more_items);
620
-    }
621
-
622
-
623
-    /**
624
-     *    _transactions_overview_list_table
625
-     *
626
-     * @access protected
627
-     * @return void
628
-     * @throws DomainException
629
-     * @throws EE_Error
630
-     * @throws InvalidArgumentException
631
-     * @throws InvalidDataTypeException
632
-     * @throws InvalidInterfaceException
633
-     * @throws ReflectionException
634
-     */
635
-    protected function _transactions_overview_list_table()
636
-    {
637
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
638
-
639
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
640
-        $event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
641
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
642
-            ? sprintf(
643
-                esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
644
-                '<h3>',
645
-                '<a href="'
646
-                . EE_Admin_Page::add_query_args_and_nonce(
647
-                    ['action' => 'edit', 'post' => $event->ID()],
648
-                    EVENTS_ADMIN_URL
649
-                )
650
-                . '" aria-label="'
651
-                . esc_attr__('Click to Edit event', 'event_espresso')
652
-                . '">' . $event->name() . '</a>',
653
-                '</h3>'
654
-            )
655
-            : '';
656
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
657
-        $this->display_admin_list_table_page_with_no_sidebar();
658
-    }
659
-
660
-
661
-    /**
662
-     *    _transaction_details
663
-     * generates HTML for the View Transaction Details Admin page
664
-     *
665
-     * @access protected
666
-     * @return void
667
-     * @throws DomainException
668
-     * @throws EE_Error
669
-     * @throws InvalidArgumentException
670
-     * @throws InvalidDataTypeException
671
-     * @throws InvalidInterfaceException
672
-     * @throws RuntimeException
673
-     * @throws ReflectionException
674
-     */
675
-    protected function _transaction_details()
676
-    {
677
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
678
-
679
-        $this->_set_transaction_status_array();
680
-
681
-        $this->_template_args                      = [];
682
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
683
-
684
-        $this->_set_transaction_object();
685
-
686
-        if (! $this->_transaction instanceof EE_Transaction) {
687
-            return;
688
-        }
689
-
690
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
691
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
692
-
693
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
694
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
695
-
696
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
697
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
698
-        $this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
699
-
700
-        $txn_total  = $this->_transaction->total();
701
-        $total_paid = $this->_transaction->paid();
702
-        $amount_due = $txn_total - $total_paid;
703
-
704
-        $this->_template_args['grand_total'] = $txn_total;
705
-        $this->_template_args['total_paid']  = $total_paid;
706
-
707
-        $this->_template_args['amount_due'] = EEH_Template::format_currency($amount_due, false, false);
708
-
709
-        $this->_template_args['amount_due_class'] = '';
710
-
711
-        if ($txn_total === (float) 0) {
712
-            // free event
713
-            $this->_template_args['amount_due'] = false;
714
-        } elseif ($amount_due < (float) 0) {
715
-            // overpaid
716
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
717
-        } elseif ($amount_due > (float) 0) {
718
-            // monies owing
719
-            $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
720
-        } elseif ($total_paid === (float) 0) {
721
-            // no payments made yet
722
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
723
-        }
724
-
725
-        $payment_method = $this->_transaction->payment_method();
726
-
727
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
728
-            ? $payment_method->admin_name()
729
-            : esc_html__('Unknown', 'event_espresso');
730
-
731
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
732
-        // link back to overview
733
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
734
-            'HTTP_REFERER',
735
-            TXN_ADMIN_URL
736
-        );
737
-
738
-
739
-        // next link
740
-        $next_txn                                 = $this->_transaction->next(
741
-            null,
742
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
743
-            'TXN_ID'
744
-        );
745
-        $this->_template_args['next_transaction'] = $next_txn
746
-            ? $this->_next_link(
747
-                EE_Admin_Page::add_query_args_and_nonce(
748
-                    ['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
749
-                    TXN_ADMIN_URL
750
-                ),
751
-                'dashicons dashicons-arrow-right ee-icon-size-22'
752
-            )
753
-            : '';
754
-        // previous link
755
-        $previous_txn                                 = $this->_transaction->previous(
756
-            null,
757
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
758
-            'TXN_ID'
759
-        );
760
-        $this->_template_args['previous_transaction'] = $previous_txn
761
-            ? $this->_previous_link(
762
-                EE_Admin_Page::add_query_args_and_nonce(
763
-                    ['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
764
-                    TXN_ADMIN_URL
765
-                ),
766
-                'dashicons dashicons-arrow-left ee-icon-size-22'
767
-            )
768
-            : '';
769
-
770
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
771
-        $event_name    = $this->request->getRequestParam('event_name');
772
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
773
-
774
-        // were we just redirected here after adding a new registration ???
775
-        if ($EVT_ID && $event_name && $redirect_from) {
776
-            if (
777
-                EE_Registry::instance()->CAP->current_user_can(
778
-                    'ee_edit_registrations',
779
-                    'espresso_registrations_new_registration',
780
-                    $EVT_ID
781
-                )
782
-            ) {
783
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
784
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
785
-                    [
786
-                        'page'     => 'espresso_registrations',
787
-                        'action'   => 'new_registration',
788
-                        'return'   => 'default',
789
-                        'TXN_ID'   => $this->_transaction->ID(),
790
-                        'event_id' => $EVT_ID,
791
-                    ],
792
-                    REG_ADMIN_URL
793
-                );
794
-                $this->_admin_page_title .= '">';
795
-
796
-                $this->_admin_page_title .= sprintf(
797
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
798
-                    htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
799
-                );
800
-                $this->_admin_page_title .= '</a>';
801
-            }
802
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
803
-        }
804
-        // grab messages at the last second
805
-        $this->_template_args['notices'] = EE_Error::get_notices();
806
-        // path to template
807
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
808
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
809
-            $template_path,
810
-            $this->_template_args,
811
-            true
812
-        );
813
-
814
-        // the details template wrapper
815
-        $this->display_admin_page_with_sidebar();
816
-    }
817
-
818
-
819
-    /**
820
-     *        _transaction_details_metaboxes
821
-     *
822
-     * @access protected
823
-     * @return void
824
-     * @throws EE_Error
825
-     * @throws InvalidArgumentException
826
-     * @throws InvalidDataTypeException
827
-     * @throws InvalidInterfaceException
828
-     * @throws RuntimeException
829
-     * @throws ReflectionException
830
-     */
831
-    protected function _transaction_details_metaboxes()
832
-    {
833
-
834
-        $this->_set_transaction_object();
835
-
836
-        if (! $this->_transaction instanceof EE_Transaction) {
837
-            return;
838
-        }
839
-        $this->addMetaBox(
840
-            'edit-txn-details-mbox',
841
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
842
-            . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
843
-            [$this, 'txn_details_meta_box'],
844
-            $this->_wp_page_slug
845
-        );
846
-        $this->addMetaBox(
847
-            'edit-txn-attendees-mbox',
848
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
849
-            . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
850
-            [$this, 'txn_attendees_meta_box'],
851
-            $this->_wp_page_slug,
852
-            'normal',
853
-            'high',
854
-            ['TXN_ID' => $this->_transaction->ID()]
855
-        );
856
-        $this->addMetaBox(
857
-            'edit-txn-registrant-mbox',
858
-            esc_html__('Primary Contact', 'event_espresso'),
859
-            [$this, 'txn_registrant_side_meta_box'],
860
-            $this->_wp_page_slug,
861
-            'side'
862
-        );
863
-        $this->addMetaBox(
864
-            'edit-txn-billing-info-mbox',
865
-            esc_html__('Billing Information', 'event_espresso'),
866
-            [$this, 'txn_billing_info_side_meta_box'],
867
-            $this->_wp_page_slug,
868
-            'side'
869
-        );
870
-    }
871
-
872
-
873
-    /**
874
-     * Callback for transaction actions metabox.
875
-     *
876
-     * @param EE_Transaction|null $transaction
877
-     * @return string
878
-     * @throws DomainException
879
-     * @throws EE_Error
880
-     * @throws InvalidArgumentException
881
-     * @throws InvalidDataTypeException
882
-     * @throws InvalidInterfaceException
883
-     * @throws ReflectionException
884
-     * @throws RuntimeException
885
-     */
886
-    public function getActionButtons(EE_Transaction $transaction = null)
887
-    {
888
-        $content = '';
889
-        $actions = [];
890
-        if (! $transaction instanceof EE_Transaction) {
891
-            return $content;
892
-        }
893
-        /** @var EE_Registration $primary_registration */
894
-        $primary_registration = $transaction->primary_registration();
895
-        $attendee             = $primary_registration instanceof EE_Registration
896
-            ? $primary_registration->attendee()
897
-            : null;
898
-
899
-        if (
900
-            $attendee instanceof EE_Attendee
901
-            && EE_Registry::instance()->CAP->current_user_can(
902
-                'ee_send_message',
903
-                'espresso_transactions_send_payment_reminder'
904
-            )
905
-        ) {
906
-            $actions['payment_reminder'] =
907
-                EEH_MSG_Template::is_mt_active('payment_reminder')
908
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
909
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
910
-                    ? EEH_Template::get_button_or_link(
911
-                        EE_Admin_Page::add_query_args_and_nonce(
912
-                            [
913
-                            'action'      => 'send_payment_reminder',
914
-                            'TXN_ID'      => $this->_transaction->ID(),
915
-                            'redirect_to' => 'view_transaction',
916
-                            ],
917
-                            TXN_ADMIN_URL
918
-                        ),
919
-                        esc_html__(' Send Payment Reminder', 'event_espresso'),
920
-                        'button button--secondary',
921
-                        'dashicons dashicons-email-alt'
922
-                    )
923
-                    : '';
924
-        }
925
-
926
-        if (
927
-            EE_Registry::instance()->CAP->current_user_can(
928
-                'ee_edit_payments',
929
-                'espresso_transactions_recalculate_line_items'
930
-            )
931
-        ) {
932
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
933
-                EE_Admin_Page::add_query_args_and_nonce(
934
-                    [
935
-                        'action'      => 'espresso_recalculate_line_items',
936
-                        'TXN_ID'      => $this->_transaction->ID(),
937
-                        'redirect_to' => 'view_transaction',
938
-                    ],
939
-                    TXN_ADMIN_URL
940
-                ),
941
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
942
-                'button button--secondary',
943
-                'dashicons dashicons-update'
944
-            );
945
-        }
946
-
947
-        if (
948
-            $primary_registration instanceof EE_Registration
949
-            && EEH_MSG_Template::is_mt_active('receipt')
950
-        ) {
951
-            $actions['receipt'] = EEH_Template::get_button_or_link(
952
-                $primary_registration->receipt_url(),
953
-                esc_html__('View Receipt', 'event_espresso'),
954
-                'button button--secondary',
955
-                'dashicons dashicons-text-page'
956
-            );
957
-        }
958
-
959
-        if (
960
-            $primary_registration instanceof EE_Registration
961
-            && EEH_MSG_Template::is_mt_active('invoice')
962
-        ) {
963
-            $actions['invoice'] = EEH_Template::get_button_or_link(
964
-                $primary_registration->invoice_url(),
965
-                esc_html__('View Invoice', 'event_espresso'),
966
-                'button button--secondary',
967
-                'dashicons dashicons-media-spreadsheet'
968
-            );
969
-        }
970
-        $actions = array_filter(
971
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
972
-        );
973
-        if ($actions) {
974
-            $content .= implode('', $actions);
975
-        }
976
-        return $content;
977
-    }
978
-
979
-
980
-    /**
981
-     * txn_details_meta_box
982
-     * generates HTML for the Transaction main meta box
983
-     *
984
-     * @return void
985
-     * @throws DomainException
986
-     * @throws EE_Error
987
-     * @throws InvalidArgumentException
988
-     * @throws InvalidDataTypeException
989
-     * @throws InvalidInterfaceException
990
-     * @throws RuntimeException
991
-     * @throws ReflectionException
992
-     */
993
-    public function txn_details_meta_box()
994
-    {
995
-        $this->_set_transaction_object();
996
-        $this->_template_args['TXN_ID']              = $this->_transaction->ID();
997
-        $this->_template_args['attendee']            =
998
-            $this->_transaction->primary_registration() instanceof EE_Registration
999
-                ? $this->_transaction->primary_registration()->attendee()
1000
-                : null;
1001
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1002
-            'ee_edit_payments',
1003
-            'apply_payment_or_refund_from_registration_details'
1004
-        );
1005
-        $this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1006
-            'ee_delete_payments',
1007
-            'delete_payment_from_registration_details'
1008
-        );
1009
-
1010
-        // get line table
1011
-        EEH_Autoloader::register_line_item_display_autoloaders();
1012
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1013
-            'admin_table',
1014
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1015
-        );
1016
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1017
-            $this->_transaction->total_line_item()
1018
-        );
1019
-        $this->_template_args['REG_code']        =
1020
-            $this->_transaction->primary_registration() instanceof EE_Registration
1021
-                ? $this->_transaction->primary_registration()->reg_code()
1022
-                : null;
1023
-        // process taxes
1024
-        $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1025
-        $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1026
-
1027
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1028
-            $this->_transaction->total(),
1029
-            false,
1030
-            false
1031
-        );
1032
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1033
-        $this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1034
-
1035
-        // process payment details
1036
-        $payments = $this->_transaction->payments();
1037
-        if (! empty($payments)) {
1038
-            $this->_template_args['payments']              = $payments;
1039
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1040
-        } else {
1041
-            $this->_template_args['payments']              = false;
1042
-            $this->_template_args['existing_reg_payments'] = [];
1043
-        }
1044
-
1045
-        $this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1046
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1047
-            ['action' => 'espresso_delete_payment'],
1048
-            TXN_ADMIN_URL
1049
-        );
1050
-
1051
-        if (isset($txn_details['invoice_number'])) {
1052
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1053
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1054
-                'Invoice Number',
1055
-                'event_espresso'
1056
-            );
1057
-        }
1058
-
1059
-        $this->_template_args['txn_details']['registration_session']['value'] =
1060
-            $this->_transaction->primary_registration() instanceof EE_Registration
1061
-                ? $this->_transaction->primary_registration()->session_ID()
1062
-                : null;
1063
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1064
-            'Registration Session',
1065
-            'event_espresso'
1066
-        );
1067
-
1068
-        $this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1069
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1070
-            'Transaction placed from IP',
1071
-            'event_espresso'
1072
-        );
1073
-
1074
-        $this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1075
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1076
-            'Registrant User Agent',
1077
-            'event_espresso'
1078
-        );
1079
-
1080
-        $reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1081
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1082
-            if ($reg_step_status === true) {
1083
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1084
-                              . sprintf(
1085
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1086
-                                  ucwords(str_replace('_', ' ', $reg_step))
1087
-                              )
1088
-                              . '</div>';
1089
-            } elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1090
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1091
-                              . sprintf(
1092
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1093
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1094
-                                  date(
1095
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1096
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1097
-                                  )
1098
-                              )
1099
-                              . '</div>';
1100
-            } else {
1101
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1102
-                              . sprintf(
1103
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1104
-                                  ucwords(str_replace('_', ' ', $reg_step))
1105
-                              )
1106
-                              . '</div>';
1107
-            }
1108
-        }
1109
-        $reg_steps                                                 .= '</ul>';
1110
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1111
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1112
-            'Registration Step Progress',
1113
-            'event_espresso'
1114
-        );
1115
-
1116
-
1117
-        $this->_get_registrations_to_apply_payment_to();
1118
-        $this->_get_payment_methods($payments);
1119
-        $this->_get_payment_status_array();
1120
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1121
-
1122
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1123
-            [
1124
-                'action'  => 'edit_transaction',
1125
-                'process' => 'transaction',
1126
-            ],
1127
-            TXN_ADMIN_URL
1128
-        );
1129
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1130
-            [
1131
-                'page'   => 'espresso_transactions',
1132
-                'action' => 'espresso_apply_payment',
1133
-            ],
1134
-            TXN_ADMIN_URL
1135
-        );
1136
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1137
-            [
1138
-                'page'   => 'espresso_transactions',
1139
-                'action' => 'espresso_delete_payment',
1140
-            ],
1141
-            TXN_ADMIN_URL
1142
-        );
1143
-
1144
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1145
-
1146
-        // 'espresso_delete_payment_nonce'
1147
-
1148
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1149
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1150
-    }
1151
-
1152
-
1153
-    /**
1154
-     * _get_registration_payment_IDs
1155
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1156
-     *
1157
-     * @access protected
1158
-     * @param EE_Payment[] $payments
1159
-     * @return array
1160
-     * @throws EE_Error
1161
-     * @throws InvalidArgumentException
1162
-     * @throws InvalidDataTypeException
1163
-     * @throws InvalidInterfaceException
1164
-     * @throws ReflectionException
1165
-     */
1166
-    protected function _get_registration_payment_IDs($payments = [])
1167
-    {
1168
-        $existing_reg_payments = [];
1169
-        // get all reg payments for these payments
1170
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1171
-            [
1172
-                [
1173
-                    'PAY_ID' => [
1174
-                        'IN',
1175
-                        array_keys($payments),
1176
-                    ],
1177
-                ],
1178
-            ]
1179
-        );
1180
-        if (! empty($reg_payments)) {
1181
-            foreach ($payments as $payment) {
1182
-                if (! $payment instanceof EE_Payment) {
1183
-                    continue;
1184
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1185
-                    $existing_reg_payments[ $payment->ID() ] = [];
1186
-                }
1187
-                foreach ($reg_payments as $reg_payment) {
1188
-                    if (
1189
-                        $reg_payment instanceof EE_Registration_Payment
1190
-                        && $reg_payment->payment_ID() === $payment->ID()
1191
-                    ) {
1192
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1193
-                    }
1194
-                }
1195
-            }
1196
-        }
1197
-
1198
-        return $existing_reg_payments;
1199
-    }
1200
-
1201
-
1202
-    /**
1203
-     * _get_registrations_to_apply_payment_to
1204
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1205
-     * which allows the admin to only apply the payment to the specific registrations
1206
-     *
1207
-     * @access protected
1208
-     * @return void
1209
-     * @throws EE_Error
1210
-     * @throws InvalidArgumentException
1211
-     * @throws InvalidDataTypeException
1212
-     * @throws InvalidInterfaceException
1213
-     * @throws ReflectionException
1214
-     */
1215
-    protected function _get_registrations_to_apply_payment_to()
1216
-    {
1217
-        // we want any registration with an active status (ie: not deleted or cancelled)
1218
-        $query_params                      = [
1219
-            [
1220
-                'STS_ID' => [
1221
-                    'IN',
1222
-                    [
1223
-                        EEM_Registration::status_id_approved,
1224
-                        EEM_Registration::status_id_pending_payment,
1225
-                        EEM_Registration::status_id_not_approved,
1226
-                    ],
1227
-                ],
1228
-            ],
1229
-        ];
1230
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1231
-            '',
1232
-            'txn-admin-apply-payment-to-registrations-dv',
1233
-            '',
1234
-            'clear: both; margin: 1.5em 0 0; display: none;'
1235
-        );
1236
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1237
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1238
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1239
-            EEH_HTML::tr(
1240
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1241
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1242
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1243
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1244
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1245
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1246
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1247
-            )
1248
-        );
1249
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1250
-        // get registrations for TXN
1251
-        $registrations         = $this->_transaction->registrations($query_params);
1252
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1253
-        foreach ($registrations as $registration) {
1254
-            if ($registration instanceof EE_Registration) {
1255
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
1256
-                    ? $registration->attendee()->full_name()
1257
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1258
-                $owing                             = $registration->final_price() - $registration->paid();
1259
-                $taxable                           = $registration->ticket()->taxable()
1260
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1261
-                    : '';
1262
-                $checked                           = empty($existing_reg_payments)
1263
-                                                     || in_array($registration->ID(), $existing_reg_payments, true)
1264
-                    ? ' checked'
1265
-                    : '';
1266
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1267
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1268
-                    EEH_HTML::td($registration->ID()) .
1269
-                    EEH_HTML::td($attendee_name) .
1270
-                    EEH_HTML::td(
1271
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1272
-                    ) .
1273
-                    EEH_HTML::td($registration->event_name()) .
1274
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1275
-                    EEH_HTML::td(
1276
-                        EEH_Template::format_currency($owing),
1277
-                        '',
1278
-                        'txn-admin-payment-owing-td jst-cntr'
1279
-                    ) .
1280
-                    EEH_HTML::td(
1281
-                        '<input type="checkbox" value="' . $registration->ID()
1282
-                        . '" name="txn_admin_payment[registrations]"'
1283
-                        . $checked . $disabled . '>',
1284
-                        '',
1285
-                        'jst-cntr'
1286
-                    ),
1287
-                    'apply-payment-registration-row-' . $registration->ID()
1288
-                );
1289
-            }
1290
-        }
1291
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1292
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1293
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1294
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1295
-            esc_html__(
1296
-                'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1297
-                'event_espresso'
1298
-            ),
1299
-            '',
1300
-            'clear description'
1301
-        );
1302
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1303
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1304
-    }
1305
-
1306
-
1307
-    /**
1308
-     * _get_reg_status_selection
1309
-     *
1310
-     * @return void
1311
-     * @throws EE_Error
1312
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1313
-     *         instead of events.
1314
-     * @access protected
1315
-     */
1316
-    protected function _get_reg_status_selection()
1317
-    {
1318
-        // first get all possible statuses
1319
-        $statuses = EEM_Registration::reg_status_array([], true);
1320
-        // let's add a "don't change" option.
1321
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1322
-        $status_array                                        = array_merge($status_array, $statuses);
1323
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1324
-            'txn_reg_status_change[reg_status]',
1325
-            $status_array,
1326
-            'NAN',
1327
-            'id="txn-admin-payment-reg-status-inp"',
1328
-            'txn-reg-status-change-reg-status'
1329
-        );
1330
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1331
-            'delete_txn_reg_status_change[reg_status]',
1332
-            $status_array,
1333
-            'NAN',
1334
-            'delete-txn-admin-payment-reg-status-inp',
1335
-            'delete-txn-reg-status-change-reg-status'
1336
-        );
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     *    _get_payment_methods
1342
-     * Gets all the payment methods available generally, or the ones that are already
1343
-     * selected on these payments (in case their payment methods are no longer active).
1344
-     * Has the side-effect of updating the template args' payment_methods item
1345
-     *
1346
-     * @access private
1347
-     * @param EE_Payment[] to show on this page
1348
-     * @return void
1349
-     * @throws EE_Error
1350
-     * @throws InvalidArgumentException
1351
-     * @throws InvalidDataTypeException
1352
-     * @throws InvalidInterfaceException
1353
-     * @throws ReflectionException
1354
-     */
1355
-    private function _get_payment_methods($payments = [])
1356
-    {
1357
-        $payment_methods_of_payments = [];
1358
-        foreach ($payments as $payment) {
1359
-            if ($payment instanceof EE_Payment) {
1360
-                $payment_methods_of_payments[] = $payment->ID();
1361
-            }
1362
-        }
1363
-        if ($payment_methods_of_payments) {
1364
-            $query_args = [
1365
-                [
1366
-                    'OR*payment_method_for_payment' => [
1367
-                        'PMD_ID'    => ['IN', $payment_methods_of_payments],
1368
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1369
-                    ],
1370
-                ],
1371
-            ];
1372
-        } else {
1373
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1374
-        }
1375
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1376
-    }
1377
-
1378
-
1379
-    /**
1380
-     * txn_attendees_meta_box
1381
-     *    generates HTML for the Attendees Transaction main meta box
1382
-     *
1383
-     * @access public
1384
-     * @param WP_Post $post
1385
-     * @param array   $metabox
1386
-     * @return void
1387
-     * @throws DomainException
1388
-     * @throws EE_Error
1389
-     * @throws InvalidArgumentException
1390
-     * @throws InvalidDataTypeException
1391
-     * @throws InvalidInterfaceException
1392
-     * @throws ReflectionException
1393
-     */
1394
-    public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1395
-    {
1396
-
1397
-        /** @noinspection NonSecureExtractUsageInspection */
1398
-        extract($metabox['args']);
1399
-        $this->_template_args['post']            = $post;
1400
-        $this->_template_args['event_attendees'] = [];
1401
-        // process items in cart
1402
-        $line_items = $this->_transaction->get_many_related(
1403
-            'Line_Item',
1404
-            [['LIN_type' => 'line-item']]
1405
-        );
1406
-        if (! empty($line_items)) {
1407
-            foreach ($line_items as $item) {
1408
-                if ($item instanceof EE_Line_Item) {
1409
-                    switch ($item->OBJ_type()) {
1410
-                        case 'Event':
1411
-                            break;
1412
-                        case 'Ticket':
1413
-                            $ticket = $item->ticket();
1414
-                            // right now we're only handling tickets here.
1415
-                            // Cause its expected that only tickets will have attendees right?
1416
-                            if (! $ticket instanceof EE_Ticket) {
1417
-                                break;
1418
-                            }
1419
-                            try {
1420
-                                $event_name = $ticket->get_event_name();
1421
-                            } catch (Exception $e) {
1422
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1423
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1424
-                            }
1425
-                            $event_name   .= ' - ' . $item->name();
1426
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1427
-                            // now get all of the registrations for this transaction that use this ticket
1428
-                            $registrations = $ticket->registrations(
1429
-                                [['TXN_ID' => $this->_transaction->ID()]]
1430
-                            );
1431
-                            foreach ($registrations as $registration) {
1432
-                                if (! $registration instanceof EE_Registration) {
1433
-                                    break;
1434
-                                }
1435
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1436
-                                    = $registration->status_ID();
1437
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1438
-                                    = $registration->count();
1439
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1440
-                                    = $event_name;
1441
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1442
-                                    = $ticket_price;
1443
-                                // attendee info
1444
-                                $attendee = $registration->get_first_related('Attendee');
1445
-                                if ($attendee instanceof EE_Attendee) {
1446
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1447
-                                        = $attendee->ID();
1448
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1449
-                                        = $attendee->full_name();
1450
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1451
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1452
-                                          . esc_html__(
1453
-                                              ' Event',
1454
-                                              'event_espresso'
1455
-                                          )
1456
-                                          . '">' . $attendee->email() . '</a>';
1457
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1458
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1459
-                                } else {
1460
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1461
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1462
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1463
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1464
-                                }
1465
-                            }
1466
-                            break;
1467
-                    }
1468
-                }
1469
-            }
1470
-
1471
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1472
-                [
1473
-                    'action'  => 'edit_transaction',
1474
-                    'process' => 'attendees',
1475
-                ],
1476
-                TXN_ADMIN_URL
1477
-            );
1478
-            echo EEH_Template::display_template(
1479
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1480
-                $this->_template_args,
1481
-                true
1482
-            );
1483
-        } else {
1484
-            printf(
1485
-                esc_html__(
1486
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1487
-                    'event_espresso'
1488
-                ),
1489
-                '<p class="important-notice">',
1490
-                '</p>'
1491
-            );
1492
-        }
1493
-    }
1494
-
1495
-
1496
-    /**
1497
-     * txn_registrant_side_meta_box
1498
-     * generates HTML for the Edit Transaction side meta box
1499
-     *
1500
-     * @access public
1501
-     * @return void
1502
-     * @throws DomainException
1503
-     * @throws EE_Error
1504
-     * @throws InvalidArgumentException
1505
-     * @throws InvalidDataTypeException
1506
-     * @throws InvalidInterfaceException
1507
-     * @throws ReflectionException
1508
-     */
1509
-    public function txn_registrant_side_meta_box()
1510
-    {
1511
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1512
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1513
-            : null;
1514
-        if (! $primary_att instanceof EE_Attendee) {
1515
-            $this->_template_args['no_attendee_message'] = esc_html__(
1516
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1517
-                'event_espresso'
1518
-            );
1519
-            $primary_att                           = EEM_Attendee::instance()->create_default_object();
1520
-        }
1521
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1522
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1523
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1524
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1525
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1526
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1527
-            [
1528
-                'action' => 'edit_attendee',
1529
-                'post'   => $primary_att->ID(),
1530
-            ],
1531
-            REG_ADMIN_URL
1532
-        );
1533
-        // get formatted address for registrant
1534
-        $formatted_address = EEH_Address::format($primary_att);
1535
-        $formatted_address = $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1536
-            ? $formatted_address
1537
-            : '';
1538
-        $this->_template_args['formatted_address'] = $formatted_address;
1539
-        echo EEH_Template::display_template(
1540
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1541
-            $this->_template_args,
1542
-            true
1543
-        );
1544
-    }
1545
-
1546
-
1547
-    /**
1548
-     * txn_billing_info_side_meta_box
1549
-     *    generates HTML for the Edit Transaction side meta box
1550
-     *
1551
-     * @access public
1552
-     * @return void
1553
-     * @throws DomainException
1554
-     * @throws EE_Error
1555
-     * @throws ReflectionException
1556
-     */
1557
-    public function txn_billing_info_side_meta_box()
1558
-    {
1559
-
1560
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1561
-        $this->_template_args['billing_form_url'] = add_query_arg(
1562
-            ['action' => 'edit_transaction', 'process' => 'billing'],
1563
-            TXN_ADMIN_URL
1564
-        );
1565
-
1566
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1567
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1568
-    }
1569
-
1570
-
1571
-    /**
1572
-     * apply_payments_or_refunds
1573
-     *    registers a payment or refund made towards a transaction
1574
-     *
1575
-     * @access public
1576
-     * @return void
1577
-     * @throws EE_Error
1578
-     * @throws InvalidArgumentException
1579
-     * @throws ReflectionException
1580
-     * @throws RuntimeException
1581
-     * @throws InvalidDataTypeException
1582
-     * @throws InvalidInterfaceException
1583
-     */
1584
-    public function apply_payments_or_refunds()
1585
-    {
1586
-        $valid_data         = $this->_validate_payment_request_data();
1587
-        $has_access         = EE_Registry::instance()->CAP->current_user_can(
1588
-            'ee_edit_payments',
1589
-            'apply_payment_or_refund_from_registration_details'
1590
-        );
1591
-        $TXD_ID = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1592
-        $amount = 0;
1593
-        if (! empty($valid_data) && $has_access) {
1594
-            $PAY_ID = $valid_data['PAY_ID'];
1595
-            // save  the new payment
1596
-            $payment = $this->_create_payment_from_request_data($valid_data);
1597
-            $amount = $payment->amount();
1598
-            // get the TXN for this payment
1599
-            $transaction = $payment->transaction();
1600
-            // verify transaction
1601
-            if ($transaction instanceof EE_Transaction) {
1602
-                // calculate_total_payments_and_update_status
1603
-                $this->_process_transaction_payments($transaction);
1604
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1605
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1606
-                // apply payment to registrations (if applicable)
1607
-                if (! empty($REG_IDs)) {
1608
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1609
-                    $this->_maybe_send_notifications();
1610
-                    // now process status changes for the same registrations
1611
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1612
-                }
1613
-                $this->_maybe_send_notifications($payment);
1614
-                // prepare to render page
1615
-                do_action(
1616
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1617
-                    $transaction,
1618
-                    $payment
1619
-                );
1620
-            } else {
1621
-                EE_Error::add_error(
1622
-                    esc_html__(
1623
-                        'A valid Transaction for this payment could not be retrieved.',
1624
-                        'event_espresso'
1625
-                    ),
1626
-                    __FILE__,
1627
-                    __FUNCTION__,
1628
-                    __LINE__
1629
-                );
1630
-            }
1631
-        } elseif ($has_access) {
1632
-            EE_Error::add_error(
1633
-                esc_html__(
1634
-                    'The payment form data could not be processed. Please try again.',
1635
-                    'event_espresso'
1636
-                ),
1637
-                __FILE__,
1638
-                __FUNCTION__,
1639
-                __LINE__
1640
-            );
1641
-        } else {
1642
-            EE_Error::add_error(
1643
-                esc_html__(
1644
-                    'You do not have access to apply payments or refunds to a registration.',
1645
-                    'event_espresso'
1646
-                ),
1647
-                __FILE__,
1648
-                __FUNCTION__,
1649
-                __LINE__
1650
-            );
1651
-        }
1652
-        $query_args = [
1653
-            'page' => 'espresso_transactions',
1654
-             'action' => 'view_transaction',
1655
-             'TXN_ID' => $TXD_ID
1656
-        ];
1657
-
1658
-        $this->_redirect_after_action(
1659
-            ! EE_Error::has_error(),
1660
-            $amount > 0
1661
-                ? esc_html__('payment', 'event_espresso')
1662
-                : esc_html__('refund', 'event_espresso'),
1663
-            esc_html__('processed', 'event_espresso'),
1664
-            $query_args
1665
-        );
1666
-    }
1667
-
1668
-
1669
-    /**
1670
-     * _validate_payment_request_data
1671
-     *
1672
-     * @return array
1673
-     * @throws EE_Error
1674
-     * @throws InvalidArgumentException
1675
-     * @throws InvalidDataTypeException
1676
-     * @throws InvalidInterfaceException
1677
-     */
1678
-    protected function _validate_payment_request_data()
1679
-    {
1680
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1681
-            return [];
1682
-        }
1683
-        $payment_form = $this->_generate_payment_form_section();
1684
-        try {
1685
-            if ($payment_form->was_submitted()) {
1686
-                $payment_form->receive_form_submission();
1687
-                if (! $payment_form->is_valid()) {
1688
-                    $submission_error_messages = [];
1689
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1690
-                        if ($validation_error instanceof EE_Validation_Error) {
1691
-                            $form_input = $validation_error->get_form_section();
1692
-                            $submission_error_messages[] = sprintf(
1693
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1694
-                                $form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1695
-                                $validation_error->getMessage()
1696
-                            );
1697
-                        }
1698
-                    }
1699
-                    EE_Error::add_error(
1700
-                        implode('<br />', $submission_error_messages),
1701
-                        __FILE__,
1702
-                        __FUNCTION__,
1703
-                        __LINE__
1704
-                    );
1705
-                    return [];
1706
-                }
1707
-            }
1708
-        } catch (EE_Error $e) {
1709
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1710
-            return [];
1711
-        }
1712
-
1713
-        return $payment_form->valid_data();
1714
-    }
1715
-
1716
-
1717
-    /**
1718
-     * _generate_payment_form_section
1719
-     *
1720
-     * @return EE_Form_Section_Proper
1721
-     * @throws EE_Error
1722
-     */
1723
-    protected function _generate_payment_form_section()
1724
-    {
1725
-        return new EE_Form_Section_Proper(
1726
-            [
1727
-                'name'        => 'txn_admin_payment',
1728
-                'subsections' => [
1729
-                    'PAY_ID'          => new EE_Text_Input(
1730
-                        [
1731
-                            'default'               => 0,
1732
-                            'required'              => false,
1733
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1734
-                            'validation_strategies' => [new EE_Int_Normalization()],
1735
-                        ]
1736
-                    ),
1737
-                    'TXN_ID'          => new EE_Text_Input(
1738
-                        [
1739
-                            'default'               => 0,
1740
-                            'required'              => true,
1741
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1742
-                            'validation_strategies' => [new EE_Int_Normalization()],
1743
-                        ]
1744
-                    ),
1745
-                    'type'            => new EE_Text_Input(
1746
-                        [
1747
-                            'default'               => 1,
1748
-                            'required'              => true,
1749
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1750
-                            'validation_strategies' => [new EE_Int_Normalization()],
1751
-                        ]
1752
-                    ),
1753
-                    'amount'          => new EE_Text_Input(
1754
-                        [
1755
-                            'default'               => 0,
1756
-                            'required'              => true,
1757
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1758
-                            'validation_strategies' => [new EE_Float_Normalization()],
1759
-                        ]
1760
-                    ),
1761
-                    'status'          => new EE_Text_Input(
1762
-                        [
1763
-                            'default'         => EEM_Payment::status_id_approved,
1764
-                            'required'        => true,
1765
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1766
-                        ]
1767
-                    ),
1768
-                    'PMD_ID'          => new EE_Text_Input(
1769
-                        [
1770
-                            'default'               => 2,
1771
-                            'required'              => true,
1772
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1773
-                            'validation_strategies' => [new EE_Int_Normalization()],
1774
-                        ]
1775
-                    ),
1776
-                    'date'            => new EE_Text_Input(
1777
-                        [
1778
-                            'default'         => time(),
1779
-                            'required'        => true,
1780
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1781
-                        ]
1782
-                    ),
1783
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1784
-                        [
1785
-                            'default'               => '',
1786
-                            'required'              => false,
1787
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1788
-                            'validation_strategies' => [
1789
-                                new EE_Max_Length_Validation_Strategy(
1790
-                                    esc_html__('Input too long', 'event_espresso'),
1791
-                                    100
1792
-                                ),
1793
-                            ],
1794
-                        ]
1795
-                    ),
1796
-                    'po_number'       => new EE_Text_Input(
1797
-                        [
1798
-                            'default'               => '',
1799
-                            'required'              => false,
1800
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1801
-                            'validation_strategies' => [
1802
-                                new EE_Max_Length_Validation_Strategy(
1803
-                                    esc_html__('Input too long', 'event_espresso'),
1804
-                                    100
1805
-                                ),
1806
-                            ],
1807
-                        ]
1808
-                    ),
1809
-                    'accounting'      => new EE_Text_Input(
1810
-                        [
1811
-                            'default'               => '',
1812
-                            'required'              => false,
1813
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1814
-                            'validation_strategies' => [
1815
-                                new EE_Max_Length_Validation_Strategy(
1816
-                                    esc_html__('Input too long', 'event_espresso'),
1817
-                                    100
1818
-                                ),
1819
-                            ],
1820
-                        ]
1821
-                    ),
1822
-                ],
1823
-            ]
1824
-        );
1825
-    }
1826
-
1827
-
1828
-    /**
1829
-     * _create_payment_from_request_data
1830
-     *
1831
-     * @param array $valid_data
1832
-     * @return EE_Payment
1833
-     * @throws EE_Error
1834
-     * @throws InvalidArgumentException
1835
-     * @throws InvalidDataTypeException
1836
-     * @throws InvalidInterfaceException
1837
-     * @throws ReflectionException
1838
-     */
1839
-    protected function _create_payment_from_request_data($valid_data)
1840
-    {
1841
-        $PAY_ID = $valid_data['PAY_ID'];
1842
-        // get payment amount
1843
-        $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1844
-        // payments have a type value of 1 and refunds have a type value of -1
1845
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1846
-        $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1847
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1848
-        $date    = $valid_data['date']
1849
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1850
-            : date('Y-m-d g:i a', current_time('timestamp'));
1851
-        $payment = EE_Payment::new_instance(
1852
-            [
1853
-                'TXN_ID'              => $valid_data['TXN_ID'],
1854
-                'STS_ID'              => $valid_data['status'],
1855
-                'PAY_timestamp'       => $date,
1856
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1857
-                'PMD_ID'              => $valid_data['PMD_ID'],
1858
-                'PAY_amount'          => $amount,
1859
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1860
-                'PAY_po_number'       => $valid_data['po_number'],
1861
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1862
-                'PAY_details'         => $valid_data,
1863
-                'PAY_ID'              => $PAY_ID,
1864
-            ],
1865
-            '',
1866
-            ['Y-m-d', 'g:i a']
1867
-        );
1868
-
1869
-        if (! $payment->save()) {
1870
-            EE_Error::add_error(
1871
-                sprintf(
1872
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1873
-                    $payment->ID()
1874
-                ),
1875
-                __FILE__,
1876
-                __FUNCTION__,
1877
-                __LINE__
1878
-            );
1879
-        }
1880
-
1881
-        return $payment;
1882
-    }
1883
-
1884
-
1885
-    /**
1886
-     * _process_transaction_payments
1887
-     *
1888
-     * @param EE_Transaction $transaction
1889
-     * @return void
1890
-     * @throws EE_Error
1891
-     * @throws InvalidArgumentException
1892
-     * @throws ReflectionException
1893
-     * @throws InvalidDataTypeException
1894
-     * @throws InvalidInterfaceException
1895
-     */
1896
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1897
-    {
1898
-        /** @type EE_Transaction_Payments $transaction_payments */
1899
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1900
-        // update the transaction with this payment
1901
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1902
-            EE_Error::add_success(
1903
-                esc_html__(
1904
-                    'The payment has been processed successfully.',
1905
-                    'event_espresso'
1906
-                ),
1907
-                __FILE__,
1908
-                __FUNCTION__,
1909
-                __LINE__
1910
-            );
1911
-        } else {
1912
-            EE_Error::add_error(
1913
-                esc_html__(
1914
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1915
-                    'event_espresso'
1916
-                ),
1917
-                __FILE__,
1918
-                __FUNCTION__,
1919
-                __LINE__
1920
-            );
1921
-        }
1922
-    }
1923
-
1924
-
1925
-    /**
1926
-     * _get_REG_IDs_to_apply_payment_to
1927
-     * returns a list of registration IDs that the payment will apply to
1928
-     *
1929
-     * @param EE_Payment $payment
1930
-     * @return array
1931
-     * @throws EE_Error
1932
-     * @throws InvalidArgumentException
1933
-     * @throws InvalidDataTypeException
1934
-     * @throws InvalidInterfaceException
1935
-     * @throws ReflectionException
1936
-     */
1937
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1938
-    {
1939
-        // grab array of IDs for specific registrations to apply changes to
1940
-        $apply_to_all = $this->request->getRequestParam(
1941
-            'txn_admin_payment[apply_to_all_registrations]',
1942
-            false,
1943
-            DataType::BOOL
1944
-        );
1945
-        $REG_IDs = ! $apply_to_all
1946
-            ? $this->request->getRequestParam(
1947
-                'txn_admin_payment[registrations]',
1948
-                [],
1949
-                DataType::INT,
1950
-                true
1951
-            )
1952
-            : [];
1953
-        // nothing specified ? then get all reg IDs
1954
-        if ($apply_to_all || empty($REG_IDs)) {
1955
-            $registrations = $payment->transaction()->registrations();
1956
-            $REG_IDs       = ! empty($registrations)
1957
-                ? array_keys($registrations)
1958
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1959
-        }
1960
-        // ensure that REG_IDs are integers and NOT strings
1961
-        return array_map('absint', $REG_IDs);
1962
-    }
1963
-
1964
-
1965
-    /**
1966
-     * @return array
1967
-     */
1968
-    public function existing_reg_payment_REG_IDs()
1969
-    {
1970
-        return $this->_existing_reg_payment_REG_IDs;
1971
-    }
1972
-
1973
-
1974
-    /**
1975
-     * @param array $existing_reg_payment_REG_IDs
1976
-     */
1977
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1978
-    {
1979
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1980
-    }
1981
-
1982
-
1983
-    /**
1984
-     * _get_existing_reg_payment_REG_IDs
1985
-     * returns a list of registration IDs that the payment is currently related to
1986
-     * as recorded in the database
1987
-     *
1988
-     * @param EE_Payment $payment
1989
-     * @return array
1990
-     * @throws EE_Error
1991
-     * @throws InvalidArgumentException
1992
-     * @throws InvalidDataTypeException
1993
-     * @throws InvalidInterfaceException
1994
-     * @throws ReflectionException
1995
-     */
1996
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
1997
-    {
1998
-        if ($this->existing_reg_payment_REG_IDs() === null) {
1999
-            // let's get any existing reg payment records for this payment
2000
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2001
-            // but we only want the REG IDs, so grab the array keys
2002
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2003
-                ? array_keys($existing_reg_payment_REG_IDs)
2004
-                : [];
2005
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2006
-        }
2007
-
2008
-        return $this->existing_reg_payment_REG_IDs();
2009
-    }
2010
-
2011
-
2012
-    /**
2013
-     * _remove_existing_registration_payments
2014
-     * this calculates the difference between existing relations
2015
-     * to the supplied payment and the new list registration IDs,
2016
-     * removes any related registrations that no longer apply,
2017
-     * and then updates the registration paid fields
2018
-     *
2019
-     * @param EE_Payment $payment
2020
-     * @param int        $PAY_ID
2021
-     * @return bool;
2022
-     * @throws EE_Error
2023
-     * @throws InvalidArgumentException
2024
-     * @throws ReflectionException
2025
-     * @throws InvalidDataTypeException
2026
-     * @throws InvalidInterfaceException
2027
-     */
2028
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2029
-    {
2030
-        // newly created payments will have nothing recorded for $PAY_ID
2031
-        if (absint($PAY_ID) === 0) {
2032
-            return false;
2033
-        }
2034
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2035
-        if (empty($existing_reg_payment_REG_IDs)) {
2036
-            return false;
2037
-        }
2038
-        /** @type EE_Transaction_Payments $transaction_payments */
2039
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2040
-
2041
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2042
-            $payment,
2043
-            [
2044
-                [
2045
-                    'PAY_ID' => $payment->ID(),
2046
-                    'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2047
-                ],
2048
-            ]
2049
-        );
2050
-    }
2051
-
2052
-
2053
-    /**
2054
-     * _update_registration_payments
2055
-     * this applies the payments to the selected registrations
2056
-     * but only if they have not already been paid for
2057
-     *
2058
-     * @param EE_Transaction $transaction
2059
-     * @param EE_Payment     $payment
2060
-     * @param array          $REG_IDs
2061
-     * @return void
2062
-     * @throws EE_Error
2063
-     * @throws InvalidArgumentException
2064
-     * @throws ReflectionException
2065
-     * @throws RuntimeException
2066
-     * @throws InvalidDataTypeException
2067
-     * @throws InvalidInterfaceException
2068
-     */
2069
-    protected function _update_registration_payments(
2070
-        EE_Transaction $transaction,
2071
-        EE_Payment $payment,
2072
-        $REG_IDs = []
2073
-    ) {
2074
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2075
-        // so let's do that using our set of REG_IDs from the form
2076
-        $registration_query_where_params = [
2077
-            'REG_ID' => ['IN', $REG_IDs],
2078
-        ];
2079
-        // but add in some conditions regarding payment,
2080
-        // so that we don't apply payments to registrations that are free or have already been paid for
2081
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2082
-        if (! $payment->is_a_refund()) {
2083
-            $registration_query_where_params['REG_final_price']  = ['!=', 0];
2084
-            $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2085
-        }
2086
-        $registrations = $transaction->registrations([$registration_query_where_params]);
2087
-        if (! empty($registrations)) {
2088
-            /** @type EE_Payment_Processor $payment_processor */
2089
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2090
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2091
-        }
2092
-    }
2093
-
2094
-
2095
-    /**
2096
-     * _process_registration_status_change
2097
-     * This processes requested registration status changes for all the registrations
2098
-     * on a given transaction and (optionally) sends out notifications for the changes.
2099
-     *
2100
-     * @param EE_Transaction $transaction
2101
-     * @param array          $REG_IDs
2102
-     * @return bool
2103
-     * @throws EE_Error
2104
-     * @throws InvalidArgumentException
2105
-     * @throws ReflectionException
2106
-     * @throws InvalidDataTypeException
2107
-     * @throws InvalidInterfaceException
2108
-     */
2109
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2110
-    {
2111
-        // first if there is no change in status then we get out.
2112
-        $reg_status = $reg_status ?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2113
-        if ($reg_status === 'NAN') {
2114
-            // no error message, no change requested, just nothing to do man.
2115
-            return false;
2116
-        }
2117
-        /** @type EE_Transaction_Processor $transaction_processor */
2118
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2119
-
2120
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2121
-        return $transaction_processor->manually_update_registration_statuses(
2122
-            $transaction,
2123
-            $reg_status,
2124
-            [['REG_ID' => ['IN', $REG_IDs]]]
2125
-        );
2126
-    }
2127
-
2128
-
2129
-    /**
2130
-     * _build_payment_json_response
2131
-     *
2132
-     * @access public
2133
-     * @param EE_Payment  $payment
2134
-     * @param array       $REG_IDs
2135
-     * @param bool | null $delete_txn_reg_status_change
2136
-     * @return array
2137
-     * @throws EE_Error
2138
-     * @throws InvalidArgumentException
2139
-     * @throws InvalidDataTypeException
2140
-     * @throws InvalidInterfaceException
2141
-     * @throws ReflectionException
2142
-     */
2143
-    protected function _build_payment_json_response(
2144
-        EE_Payment $payment,
2145
-        $REG_IDs = [],
2146
-        $delete_txn_reg_status_change = null
2147
-    ) {
2148
-        // was the payment deleted ?
2149
-        if (is_bool($delete_txn_reg_status_change)) {
2150
-            return [
2151
-                'PAY_ID'                       => $payment->ID(),
2152
-                'amount'                       => $payment->amount(),
2153
-                'total_paid'                   => $payment->transaction()->paid(),
2154
-                'txn_status'                   => $payment->transaction()->status_ID(),
2155
-                'pay_status'                   => $payment->STS_ID(),
2156
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2157
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2158
-            ];
2159
-        }
2160
-
2161
-        $this->_get_payment_status_array();
2162
-        return [
2163
-            'amount'           => $payment->amount(),
2164
-            'total_paid'       => $payment->transaction()->paid(),
2165
-            'txn_status'       => $payment->transaction()->status_ID(),
2166
-            'pay_status'       => $payment->STS_ID(),
2167
-            'PAY_ID'           => $payment->ID(),
2168
-            'STS_ID'           => $payment->STS_ID(),
2169
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2170
-            'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2171
-            'method'           => strtoupper($payment->source()),
2172
-            'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2173
-            'gateway'          => $payment->payment_method()
2174
-                ? $payment->payment_method()->admin_name()
2175
-                : esc_html__('Unknown', 'event_espresso'),
2176
-            'gateway_response' => $payment->gateway_response(),
2177
-            'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2178
-            'po_number'        => $payment->po_number(),
2179
-            'extra_accntng'    => $payment->extra_accntng(),
2180
-            'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2181
-        ];
2182
-    }
2183
-
2184
-
2185
-    /**
2186
-     * delete_payment
2187
-     *    delete a payment or refund made towards a transaction
2188
-     *
2189
-     * @access public
2190
-     * @return void
2191
-     * @throws EE_Error
2192
-     * @throws InvalidArgumentException
2193
-     * @throws ReflectionException
2194
-     * @throws InvalidDataTypeException
2195
-     * @throws InvalidInterfaceException
2196
-     */
2197
-    public function delete_payment()
2198
-    {
2199
-        $TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2200
-        // $json_response_data = ['return_data' => false];
2201
-        $PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2202
-        $amount = 0;
2203
-        $can_delete         = EE_Registry::instance()->CAP->current_user_can(
2204
-            'ee_delete_payments',
2205
-            'delete_payment_from_registration_details'
2206
-        );
2207
-        if ($PAY_ID && $can_delete) {
2208
-            $delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2209
-            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2210
-            if ($payment instanceof EE_Payment) {
2211
-                $amount = $payment->amount();
2212
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2213
-                /** @type EE_Transaction_Payments $transaction_payments */
2214
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2215
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2216
-                    if ($delete_txn_reg_status_change) {
2217
-                        $this->_maybe_send_notifications();
2218
-                        $this->_process_registration_status_change(
2219
-                            $payment->transaction(),
2220
-                            $REG_IDs,
2221
-                            $delete_txn_reg_status_change
2222
-                        );
2223
-                    }
2224
-                }
2225
-            } else {
2226
-                EE_Error::add_error(
2227
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2228
-                    __FILE__,
2229
-                    __FUNCTION__,
2230
-                    __LINE__
2231
-                );
2232
-            }
2233
-        } elseif ($can_delete) {
2234
-            EE_Error::add_error(
2235
-                esc_html__(
2236
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2237
-                    'event_espresso'
2238
-                ),
2239
-                __FILE__,
2240
-                __FUNCTION__,
2241
-                __LINE__
2242
-            );
2243
-        } else {
2244
-            EE_Error::add_error(
2245
-                esc_html__(
2246
-                    'You do not have access to delete a payment.',
2247
-                    'event_espresso'
2248
-                ),
2249
-                __FILE__,
2250
-                __FUNCTION__,
2251
-                __LINE__
2252
-            );
2253
-        }
2254
-        $query_args = [
2255
-            'page'   => 'espresso_transactions',
2256
-            'action' => 'view_transaction',
2257
-            'TXN_ID' => $TXD_ID
2258
-        ];
2259
-        $this->_redirect_after_action(
2260
-            ! EE_Error::has_error(),
2261
-            $amount > 0
2262
-                ? esc_html__('payment', 'event_espresso')
2263
-                : esc_html__('refund', 'event_espresso'),
2264
-            esc_html__('deleted', 'event_espresso'),
2265
-            $query_args
2266
-        );
2267
-    }
2268
-
2269
-
2270
-    /**
2271
-     * _registration_payment_data_array
2272
-     * adds info for 'owing' and 'paid' for each registration to the json response
2273
-     *
2274
-     * @access protected
2275
-     * @param array $REG_IDs
2276
-     * @return array
2277
-     * @throws EE_Error
2278
-     * @throws InvalidArgumentException
2279
-     * @throws InvalidDataTypeException
2280
-     * @throws InvalidInterfaceException
2281
-     * @throws ReflectionException
2282
-     */
2283
-    protected function _registration_payment_data_array($REG_IDs)
2284
-    {
2285
-        $registration_payment_data = [];
2286
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2287
-        if (! empty($REG_IDs)) {
2288
-            $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2289
-            foreach ($registrations as $registration) {
2290
-                if ($registration instanceof EE_Registration) {
2291
-                    $registration_payment_data[ $registration->ID() ] = [
2292
-                        'paid'  => $registration->pretty_paid(),
2293
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2294
-                    ];
2295
-                }
2296
-            }
2297
-        }
2298
-
2299
-        return $registration_payment_data;
2300
-    }
2301
-
2302
-
2303
-    /**
2304
-     * _maybe_send_notifications
2305
-     * determines whether or not the admin has indicated that notifications should be sent.
2306
-     * If so, will toggle a filter switch for delivering registration notices.
2307
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2308
-     *
2309
-     * @access protected
2310
-     * @param EE_Payment | null $payment
2311
-     */
2312
-    protected function _maybe_send_notifications($payment = null)
2313
-    {
2314
-        switch ($payment instanceof EE_Payment) {
2315
-            // payment notifications
2316
-            case true:
2317
-                if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2318
-                    $this->_process_payment_notification($payment);
2319
-                }
2320
-                break;
2321
-            // registration notifications
2322
-            case false:
2323
-                if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2324
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2325
-                }
2326
-                break;
2327
-        }
2328
-    }
2329
-
2330
-
2331
-    /**
2332
-     * _send_payment_reminder
2333
-     *    generates HTML for the View Transaction Details Admin page
2334
-     *
2335
-     * @access protected
2336
-     * @return void
2337
-     * @throws EE_Error
2338
-     * @throws InvalidArgumentException
2339
-     * @throws InvalidDataTypeException
2340
-     * @throws InvalidInterfaceException
2341
-     */
2342
-    protected function _send_payment_reminder()
2343
-    {
2344
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2345
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2346
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2347
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2348
-        do_action(
2349
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2350
-            $transaction
2351
-        );
2352
-        $this->_redirect_after_action(
2353
-            false,
2354
-            esc_html__('payment reminder', 'event_espresso'),
2355
-            esc_html__('sent', 'event_espresso'),
2356
-            $query_args,
2357
-            true
2358
-        );
2359
-    }
2360
-
2361
-
2362
-    /**
2363
-     *  get_transactions
2364
-     *    get transactions for given parameters (used by list table)
2365
-     *
2366
-     * @param int     $per_page how many transactions displayed per page
2367
-     * @param boolean $count   return the count or objects
2368
-     * @param string  $view
2369
-     * @return EE_Transaction[]|int int = count || array of transaction objects
2370
-     * @throws EE_Error
2371
-     * @throws InvalidArgumentException
2372
-     * @throws InvalidDataTypeException
2373
-     * @throws InvalidInterfaceException
2374
-     */
2375
-    public function get_transactions($per_page, $count = false, $view = '')
2376
-    {
2377
-        $start_date = wp_strip_all_tags(
2378
-            $this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2379
-        );
2380
-        $end_date = wp_strip_all_tags(
2381
-            $this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2382
-        );
2383
-
2384
-        // make sure our timestamps start and end right at the boundaries for each day
2385
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2386
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2387
-
2388
-
2389
-        // convert to timestamps
2390
-        $start_date = strtotime($start_date);
2391
-        $end_date   = strtotime($end_date);
2392
-
2393
-        // makes sure start date is the lowest value and vice versa
2394
-        $start_date = min($start_date, $end_date);
2395
-        $end_date   = max($start_date, $end_date);
2396
-
2397
-        // convert to correct format for query
2398
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2399
-            'TXN_timestamp',
2400
-            date('Y-m-d H:i:s', $start_date),
2401
-            'Y-m-d H:i:s'
2402
-        );
2403
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2404
-            'TXN_timestamp',
2405
-            date('Y-m-d H:i:s', $end_date),
2406
-            'Y-m-d H:i:s'
2407
-        );
2408
-
2409
-
2410
-        // set orderby
2411
-        $orderby = $this->request->getRequestParam('orderby');
2412
-
2413
-        switch ($orderby) {
2414
-            case 'TXN_ID':
2415
-                break;
2416
-            case 'ATT_fname':
2417
-                $orderby = 'Registration.Attendee.ATT_fname';
2418
-                break;
2419
-            case 'event_name':
2420
-                $orderby = 'Registration.Event.EVT_name';
2421
-                break;
2422
-            default: // 'TXN_timestamp'
2423
-                $orderby = 'TXN_timestamp';
2424
-        }
2425
-
2426
-        $sort         = $this->request->getRequestParam('order', 'DESC');
2427
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
2428
-
2429
-        $per_page = absint($per_page) ? $per_page : 10;
2430
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2431
-
2432
-        $offset = ($current_page - 1) * $per_page;
2433
-        $limit  = [$offset, $per_page];
2434
-
2435
-        $_where = [
2436
-            'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2437
-            'Registration.REG_count' => 1,
2438
-        ];
2439
-
2440
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2441
-        if ($EVT_ID) {
2442
-            $_where['Registration.EVT_ID'] = $EVT_ID;
2443
-        }
2444
-
2445
-        $search_term = $this->request->getRequestParam('s');
2446
-        if ($search_term) {
2447
-            $search_term = '%' . $search_term . '%';
2448
-            $_where['OR']  = [
2449
-                'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2450
-                'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2451
-                'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2452
-                'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2453
-                'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2454
-                'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2455
-                'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2456
-                'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2457
-                'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2458
-                'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2459
-                'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2460
-                'Registration.REG_final_price'        => ['LIKE', $search_term],
2461
-                'Registration.REG_code'               => ['LIKE', $search_term],
2462
-                'Registration.REG_count'              => ['LIKE', $search_term],
2463
-                'Registration.REG_group_size'         => ['LIKE', $search_term],
2464
-                'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2465
-                'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2466
-                'Payment.PAY_source'                  => ['LIKE', $search_term],
2467
-                'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2468
-                'TXN_session_data'                    => ['LIKE', $search_term],
2469
-                'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2470
-            ];
2471
-        }
2472
-
2473
-        $status = $this->request->getRequestParam('status');
2474
-        // failed transactions
2475
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2476
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2477
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2478
-
2479
-        if ($failed) {
2480
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2481
-        } elseif ($abandoned) {
2482
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2483
-        } elseif ($incomplete) {
2484
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2485
-        } else {
2486
-            $_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2487
-            $_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2488
-        }
2489
-
2490
-        $query_params = apply_filters(
2491
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2492
-            [
2493
-                $_where,
2494
-                'order_by'                 => [$orderby => $sort],
2495
-                'limit'                    => $limit,
2496
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2497
-            ],
2498
-            $this->request->requestParams(),
2499
-            $view,
2500
-            $count
2501
-        );
2502
-
2503
-        return $count
2504
-            ? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2505
-            : EEM_Transaction::instance()->get_all($query_params);
2506
-    }
2507
-
2508
-
2509
-    /**
2510
-     * @throws EE_Error
2511
-     * @throws InvalidArgumentException
2512
-     * @throws InvalidDataTypeException
2513
-     * @throws InvalidInterfaceException
2514
-     * @throws ReflectionException
2515
-     * @throws RuntimeException
2516
-     * @since 4.9.79.p
2517
-     */
2518
-    public function recalculateLineItems()
2519
-    {
2520
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2521
-        /** @var EE_Transaction $transaction */
2522
-        $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2523
-        $success         = $transaction->recalculateLineItems();
2524
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2525
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2526
-        $this->_redirect_after_action(
2527
-            $success,
2528
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2529
-            esc_html__('recalculated', 'event_espresso'),
2530
-            $query_args,
2531
-            true
2532
-        );
2533
-    }
16
+	/**
17
+	 * @var EE_Transaction
18
+	 */
19
+	private $_transaction;
20
+
21
+	/**
22
+	 * @var EE_Session
23
+	 */
24
+	private $_session;
25
+
26
+	/**
27
+	 * @var array $_txn_status
28
+	 */
29
+	private static $_txn_status;
30
+
31
+	/**
32
+	 * @var array $_pay_status
33
+	 */
34
+	private static $_pay_status;
35
+
36
+	/**
37
+	 * @var array $_existing_reg_payment_REG_IDs
38
+	 */
39
+	protected $_existing_reg_payment_REG_IDs;
40
+
41
+
42
+	/**
43
+	 *    _init_page_props
44
+	 *
45
+	 * @return void
46
+	 */
47
+	protected function _init_page_props()
48
+	{
49
+		$this->page_slug        = TXN_PG_SLUG;
50
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
51
+		$this->_admin_base_url  = TXN_ADMIN_URL;
52
+		$this->_admin_base_path = TXN_ADMIN;
53
+	}
54
+
55
+
56
+	/**
57
+	 *    _ajax_hooks
58
+	 *
59
+	 * @return void
60
+	 */
61
+	protected function _ajax_hooks()
62
+	{
63
+		// add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
64
+		// add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
65
+		// add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
66
+	}
67
+
68
+
69
+	/**
70
+	 *    _define_page_props
71
+	 *
72
+	 * @return void
73
+	 */
74
+	protected function _define_page_props()
75
+	{
76
+		$this->_admin_page_title = $this->page_label;
77
+		$this->_labels           = [
78
+			'buttons' => [
79
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
80
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
81
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
82
+			],
83
+		];
84
+	}
85
+
86
+
87
+	/**
88
+	 *        grab url requests and route them
89
+	 *
90
+	 * @access private
91
+	 * @return void
92
+	 * @throws EE_Error
93
+	 * @throws InvalidArgumentException
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InvalidInterfaceException
96
+	 */
97
+	public function _set_page_routes()
98
+	{
99
+
100
+		$this->_set_transaction_status_array();
101
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
102
+
103
+		$this->_page_routes = [
104
+
105
+			'default' => [
106
+				'func'       => '_transactions_overview_list_table',
107
+				'capability' => 'ee_read_transactions',
108
+			],
109
+
110
+			'view_transaction' => [
111
+				'func'       => '_transaction_details',
112
+				'capability' => 'ee_read_transaction',
113
+				'obj_id'     => $TXN_ID,
114
+			],
115
+
116
+			'send_payment_reminder' => [
117
+				'func'       => '_send_payment_reminder',
118
+				'noheader'   => true,
119
+				'capability' => 'ee_send_message',
120
+			],
121
+
122
+			'espresso_apply_payment' => [
123
+				'func'       => 'apply_payments_or_refunds',
124
+				'noheader'   => true,
125
+				'capability' => 'ee_edit_payments',
126
+			],
127
+
128
+			'espresso_apply_refund' => [
129
+				'func'       => 'apply_payments_or_refunds',
130
+				'noheader'   => true,
131
+				'capability' => 'ee_edit_payments',
132
+			],
133
+
134
+			'espresso_delete_payment' => [
135
+				'func'       => [$this, 'delete_payment'],
136
+				'noheader'   => true,
137
+				'capability' => 'ee_delete_payments',
138
+			],
139
+
140
+			'espresso_recalculate_line_items' => [
141
+				'func'       => 'recalculateLineItems',
142
+				'noheader'   => true,
143
+				'capability' => 'ee_edit_payments',
144
+			],
145
+
146
+		];
147
+	}
148
+
149
+
150
+	protected function _set_page_config()
151
+	{
152
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
153
+		$this->_page_config = [
154
+			'default'          => [
155
+				'nav'           => [
156
+					'label' => esc_html__('Overview', 'event_espresso'),
157
+					'icon' => 'dashicons-list-view',
158
+					'order' => 10,
159
+				],
160
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
161
+				'help_tabs'     => [
162
+					'transactions_overview_help_tab'                       => [
163
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
164
+						'filename' => 'transactions_overview',
165
+					],
166
+					'transactions_overview_table_column_headings_help_tab' => [
167
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
168
+						'filename' => 'transactions_overview_table_column_headings',
169
+					],
170
+					'transactions_overview_views_filters_help_tab'         => [
171
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
172
+						'filename' => 'transactions_overview_views_filters_search',
173
+					],
174
+				],
175
+				'require_nonce' => false,
176
+			],
177
+			'view_transaction' => [
178
+				'nav'       => [
179
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
180
+					'icon' => 'dashicons-cart',
181
+					'order'      => 5,
182
+					'url'        => $TXN_ID
183
+						? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
184
+						: $this->_admin_base_url,
185
+					'persistent' => false,
186
+				],
187
+				'help_tabs' => [
188
+					'transactions_view_transaction_help_tab'                                              => [
189
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
190
+						'filename' => 'transactions_view_transaction',
191
+					],
192
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => [
193
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
194
+						'filename' => 'transactions_view_transaction_transaction_details_table',
195
+					],
196
+					'transactions_view_transaction_attendees_registered_help_tab'                         => [
197
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
198
+						'filename' => 'transactions_view_transaction_attendees_registered',
199
+					],
200
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
201
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
202
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
203
+					],
204
+				],
205
+				'qtips'     => ['Transaction_Details_Tips'],
206
+				'metaboxes' => ['_transaction_details_metaboxes'],
207
+
208
+				'require_nonce' => false,
209
+			],
210
+		];
211
+	}
212
+
213
+
214
+	/**
215
+	 * The below methods aren't used by this class currently
216
+	 */
217
+	protected function _add_screen_options()
218
+	{
219
+		// noop
220
+	}
221
+
222
+
223
+	protected function _add_feature_pointers()
224
+	{
225
+		// noop
226
+	}
227
+
228
+
229
+	public function admin_init()
230
+	{
231
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
232
+		$event_name = $this->request->getRequestParam('event_name');
233
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
234
+		// IF a registration was JUST added via the admin...
235
+		if ($EVT_ID && $event_name && $redirect_from) {
236
+			// then set a cookie so that we can block any attempts to use
237
+			// the back button as a way to enter another registration.
238
+			setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
239
+			// and update the global
240
+			$_COOKIE['ee_registration_added'] = $EVT_ID;
241
+		}
242
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
243
+			'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
244
+			'event_espresso'
245
+		);
246
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
247
+			'An error occurred! Please refresh the page and try again.',
248
+			'event_espresso'
249
+		);
250
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
251
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
252
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
253
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
254
+			'This transaction has been overpaid ! Payments Total',
255
+			'event_espresso'
256
+		);
257
+	}
258
+
259
+
260
+	public function admin_notices()
261
+	{
262
+		// noop
263
+	}
264
+
265
+
266
+	public function admin_footer_scripts()
267
+	{
268
+		// noop
269
+	}
270
+
271
+
272
+	/**
273
+	 * _set_transaction_status_array
274
+	 * sets list of transaction statuses
275
+	 *
276
+	 * @access private
277
+	 * @return void
278
+	 * @throws EE_Error
279
+	 * @throws InvalidArgumentException
280
+	 * @throws InvalidDataTypeException
281
+	 * @throws InvalidInterfaceException
282
+	 */
283
+	private function _set_transaction_status_array()
284
+	{
285
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
286
+	}
287
+
288
+
289
+	/**
290
+	 * get_transaction_status_array
291
+	 * return the transaction status array for wp_list_table
292
+	 *
293
+	 * @access public
294
+	 * @return array
295
+	 */
296
+	public function get_transaction_status_array()
297
+	{
298
+		return self::$_txn_status;
299
+	}
300
+
301
+
302
+	/**
303
+	 *    get list of payment statuses
304
+	 *
305
+	 * @access private
306
+	 * @return void
307
+	 * @throws EE_Error
308
+	 * @throws InvalidArgumentException
309
+	 * @throws InvalidDataTypeException
310
+	 * @throws InvalidInterfaceException
311
+	 */
312
+	private function _get_payment_status_array()
313
+	{
314
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
315
+		$this->_template_args['payment_status'] = self::$_pay_status;
316
+	}
317
+
318
+
319
+	/**
320
+	 *    _add_screen_options_default
321
+	 *
322
+	 * @access protected
323
+	 * @return void
324
+	 * @throws InvalidArgumentException
325
+	 * @throws InvalidDataTypeException
326
+	 * @throws InvalidInterfaceException
327
+	 */
328
+	protected function _add_screen_options_default()
329
+	{
330
+		$this->_per_page_screen_option();
331
+	}
332
+
333
+
334
+	/**
335
+	 * load_scripts_styles
336
+	 *
337
+	 * @access public
338
+	 * @return void
339
+	 */
340
+	public function load_scripts_styles()
341
+	{
342
+		// enqueue style
343
+		wp_register_style(
344
+			'espresso_txn',
345
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
346
+			[],
347
+			EVENT_ESPRESSO_VERSION
348
+		);
349
+		wp_enqueue_style('espresso_txn');
350
+		// scripts
351
+		wp_register_script(
352
+			'espresso_txn',
353
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
354
+			[
355
+				'ee_admin_js',
356
+				'ee-datepicker',
357
+				'jquery-ui-datepicker',
358
+				'jquery-ui-draggable',
359
+				'ee-dialog',
360
+				'ee-accounting',
361
+				'ee-serialize-full-array',
362
+			],
363
+			EVENT_ESPRESSO_VERSION,
364
+			true
365
+		);
366
+		wp_enqueue_script('espresso_txn');
367
+	}
368
+
369
+
370
+	/**
371
+	 *    load_scripts_styles_view_transaction
372
+	 *
373
+	 * @access public
374
+	 * @return void
375
+	 */
376
+	public function load_scripts_styles_view_transaction()
377
+	{
378
+		// styles
379
+		wp_enqueue_style('espresso-ui-theme');
380
+	}
381
+
382
+
383
+	/**
384
+	 *    load_scripts_styles_default
385
+	 *
386
+	 * @access public
387
+	 * @return void
388
+	 */
389
+	public function load_scripts_styles_default()
390
+	{
391
+		// styles
392
+		wp_enqueue_style('espresso-ui-theme');
393
+	}
394
+
395
+
396
+	/**
397
+	 *    _set_list_table_views_default
398
+	 *
399
+	 * @access protected
400
+	 * @return void
401
+	 */
402
+	protected function _set_list_table_views_default()
403
+	{
404
+		$this->_views = [
405
+			'all'        => [
406
+				'slug'  => 'all',
407
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
408
+				'count' => 0,
409
+			],
410
+			'abandoned'  => [
411
+				'slug'  => 'abandoned',
412
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
413
+				'count' => 0,
414
+			],
415
+			'incomplete' => [
416
+				'slug'  => 'incomplete',
417
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
418
+				'count' => 0,
419
+			],
420
+		];
421
+		if (
422
+			/**
423
+			 * Filters whether a link to the "Failed Transactions" list table
424
+			 * appears on the Transactions Admin Page list table.
425
+			 * List display can be turned back on via the following:
426
+			 * add_filter(
427
+			 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
428
+			 *     '__return_true'
429
+			 * );
430
+			 *
431
+			 * @param boolean                 $display_failed_txns_list
432
+			 * @param Transactions_Admin_Page $this
433
+			 * @since 4.9.70.p
434
+			 */
435
+			apply_filters(
436
+				'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
437
+				false,
438
+				$this
439
+			)
440
+		) {
441
+			$this->_views['failed'] = [
442
+				'slug'  => 'failed',
443
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
444
+				'count' => 0,
445
+			];
446
+		}
447
+	}
448
+
449
+
450
+	/**
451
+	 * _set_transaction_object
452
+	 * This sets the _transaction property for the transaction details screen
453
+	 *
454
+	 * @access private
455
+	 * @return void
456
+	 * @throws EE_Error
457
+	 * @throws InvalidArgumentException
458
+	 * @throws RuntimeException
459
+	 * @throws InvalidDataTypeException
460
+	 * @throws InvalidInterfaceException
461
+	 * @throws ReflectionException
462
+	 */
463
+	private function _set_transaction_object()
464
+	{
465
+		if ($this->_transaction instanceof EE_Transaction) {
466
+			return;
467
+		} //get out we've already set the object
468
+
469
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
470
+
471
+		// get transaction object
472
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
473
+		$this->_session     = $this->_transaction instanceof EE_Transaction
474
+			? $this->_transaction->session_data()
475
+			: null;
476
+		if ($this->_transaction instanceof EE_Transaction) {
477
+			$this->_transaction->verify_abandoned_transaction_status();
478
+		}
479
+
480
+		if (! $this->_transaction instanceof EE_Transaction) {
481
+			$error_msg = sprintf(
482
+				esc_html__(
483
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
484
+					'event_espresso'
485
+				),
486
+				$TXN_ID
487
+			);
488
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
489
+		}
490
+	}
491
+
492
+
493
+	/**
494
+	 *    _transaction_legend_items
495
+	 *
496
+	 * @access protected
497
+	 * @return array
498
+	 * @throws EE_Error
499
+	 * @throws InvalidArgumentException
500
+	 * @throws ReflectionException
501
+	 * @throws InvalidDataTypeException
502
+	 * @throws InvalidInterfaceException
503
+	 */
504
+	protected function _transaction_legend_items()
505
+	{
506
+		EE_Registry::instance()->load_helper('MSG_Template');
507
+		$items = [];
508
+
509
+		if (
510
+			EE_Registry::instance()->CAP->current_user_can(
511
+				'ee_read_global_messages',
512
+				'view_filtered_messages'
513
+			)
514
+		) {
515
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
516
+			if (
517
+				is_array($related_for_icon)
518
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
519
+			) {
520
+				$items['view_related_messages'] = [
521
+					'class' => $related_for_icon['css_class'],
522
+					'desc'  => $related_for_icon['label'],
523
+				];
524
+			}
525
+		}
526
+
527
+		$items = apply_filters(
528
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
529
+			array_merge(
530
+				$items,
531
+				[
532
+					'view_details'          => [
533
+						'class' => 'dashicons dashicons-cart',
534
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
535
+					],
536
+					'view_invoice'          => [
537
+						'class' => 'dashicons dashicons-media-spreadsheet',
538
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
539
+					],
540
+					'view_receipt'          => [
541
+						'class' => 'dashicons dashicons-text-page',
542
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
543
+					],
544
+					'view_registration'     => [
545
+						'class' => 'dashicons dashicons-clipboard',
546
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
547
+					],
548
+					'payment_overview_link' => [
549
+						'class' => 'dashicons dashicons-money',
550
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
551
+					],
552
+				]
553
+			)
554
+		);
555
+
556
+		if (
557
+			EEH_MSG_Template::is_mt_active('payment_reminder')
558
+			&& EE_Registry::instance()->CAP->current_user_can(
559
+				'ee_send_message',
560
+				'espresso_transactions_send_payment_reminder'
561
+			)
562
+		) {
563
+			$items['send_payment_reminder'] = [
564
+				'class' => 'dashicons dashicons-email-alt',
565
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
566
+			];
567
+		} else {
568
+			$items['blank*'] = [
569
+				'class' => '',
570
+				'desc'  => '',
571
+			];
572
+		}
573
+		$more_items = apply_filters(
574
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
575
+			[
576
+				'overpaid'   => [
577
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
578
+					'desc'  => EEH_Template::pretty_status(
579
+						EEM_Transaction::overpaid_status_code,
580
+						false,
581
+						'sentence'
582
+					),
583
+				],
584
+				'complete'   => [
585
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
586
+					'desc'  => EEH_Template::pretty_status(
587
+						EEM_Transaction::complete_status_code,
588
+						false,
589
+						'sentence'
590
+					),
591
+				],
592
+				'incomplete' => [
593
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
594
+					'desc'  => EEH_Template::pretty_status(
595
+						EEM_Transaction::incomplete_status_code,
596
+						false,
597
+						'sentence'
598
+					),
599
+				],
600
+				'abandoned'  => [
601
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
602
+					'desc'  => EEH_Template::pretty_status(
603
+						EEM_Transaction::abandoned_status_code,
604
+						false,
605
+						'sentence'
606
+					),
607
+				],
608
+				'failed'     => [
609
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
610
+					'desc'  => EEH_Template::pretty_status(
611
+						EEM_Transaction::failed_status_code,
612
+						false,
613
+						'sentence'
614
+					),
615
+				],
616
+			]
617
+		);
618
+
619
+		return array_merge($items, $more_items);
620
+	}
621
+
622
+
623
+	/**
624
+	 *    _transactions_overview_list_table
625
+	 *
626
+	 * @access protected
627
+	 * @return void
628
+	 * @throws DomainException
629
+	 * @throws EE_Error
630
+	 * @throws InvalidArgumentException
631
+	 * @throws InvalidDataTypeException
632
+	 * @throws InvalidInterfaceException
633
+	 * @throws ReflectionException
634
+	 */
635
+	protected function _transactions_overview_list_table()
636
+	{
637
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
638
+
639
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
640
+		$event = EEM_Event::instance()->get_one_by_ID($EVT_ID);
641
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
642
+			? sprintf(
643
+				esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
644
+				'<h3>',
645
+				'<a href="'
646
+				. EE_Admin_Page::add_query_args_and_nonce(
647
+					['action' => 'edit', 'post' => $event->ID()],
648
+					EVENTS_ADMIN_URL
649
+				)
650
+				. '" aria-label="'
651
+				. esc_attr__('Click to Edit event', 'event_espresso')
652
+				. '">' . $event->name() . '</a>',
653
+				'</h3>'
654
+			)
655
+			: '';
656
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
657
+		$this->display_admin_list_table_page_with_no_sidebar();
658
+	}
659
+
660
+
661
+	/**
662
+	 *    _transaction_details
663
+	 * generates HTML for the View Transaction Details Admin page
664
+	 *
665
+	 * @access protected
666
+	 * @return void
667
+	 * @throws DomainException
668
+	 * @throws EE_Error
669
+	 * @throws InvalidArgumentException
670
+	 * @throws InvalidDataTypeException
671
+	 * @throws InvalidInterfaceException
672
+	 * @throws RuntimeException
673
+	 * @throws ReflectionException
674
+	 */
675
+	protected function _transaction_details()
676
+	{
677
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
678
+
679
+		$this->_set_transaction_status_array();
680
+
681
+		$this->_template_args                      = [];
682
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
683
+
684
+		$this->_set_transaction_object();
685
+
686
+		if (! $this->_transaction instanceof EE_Transaction) {
687
+			return;
688
+		}
689
+
690
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
691
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
692
+
693
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
694
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
695
+
696
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
697
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
698
+		$this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
699
+
700
+		$txn_total  = $this->_transaction->total();
701
+		$total_paid = $this->_transaction->paid();
702
+		$amount_due = $txn_total - $total_paid;
703
+
704
+		$this->_template_args['grand_total'] = $txn_total;
705
+		$this->_template_args['total_paid']  = $total_paid;
706
+
707
+		$this->_template_args['amount_due'] = EEH_Template::format_currency($amount_due, false, false);
708
+
709
+		$this->_template_args['amount_due_class'] = '';
710
+
711
+		if ($txn_total === (float) 0) {
712
+			// free event
713
+			$this->_template_args['amount_due'] = false;
714
+		} elseif ($amount_due < (float) 0) {
715
+			// overpaid
716
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
717
+		} elseif ($amount_due > (float) 0) {
718
+			// monies owing
719
+			$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
720
+		} elseif ($total_paid === (float) 0) {
721
+			// no payments made yet
722
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
723
+		}
724
+
725
+		$payment_method = $this->_transaction->payment_method();
726
+
727
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
728
+			? $payment_method->admin_name()
729
+			: esc_html__('Unknown', 'event_espresso');
730
+
731
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
732
+		// link back to overview
733
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
734
+			'HTTP_REFERER',
735
+			TXN_ADMIN_URL
736
+		);
737
+
738
+
739
+		// next link
740
+		$next_txn                                 = $this->_transaction->next(
741
+			null,
742
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
743
+			'TXN_ID'
744
+		);
745
+		$this->_template_args['next_transaction'] = $next_txn
746
+			? $this->_next_link(
747
+				EE_Admin_Page::add_query_args_and_nonce(
748
+					['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
749
+					TXN_ADMIN_URL
750
+				),
751
+				'dashicons dashicons-arrow-right ee-icon-size-22'
752
+			)
753
+			: '';
754
+		// previous link
755
+		$previous_txn                                 = $this->_transaction->previous(
756
+			null,
757
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
758
+			'TXN_ID'
759
+		);
760
+		$this->_template_args['previous_transaction'] = $previous_txn
761
+			? $this->_previous_link(
762
+				EE_Admin_Page::add_query_args_and_nonce(
763
+					['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
764
+					TXN_ADMIN_URL
765
+				),
766
+				'dashicons dashicons-arrow-left ee-icon-size-22'
767
+			)
768
+			: '';
769
+
770
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
771
+		$event_name    = $this->request->getRequestParam('event_name');
772
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
773
+
774
+		// were we just redirected here after adding a new registration ???
775
+		if ($EVT_ID && $event_name && $redirect_from) {
776
+			if (
777
+				EE_Registry::instance()->CAP->current_user_can(
778
+					'ee_edit_registrations',
779
+					'espresso_registrations_new_registration',
780
+					$EVT_ID
781
+				)
782
+			) {
783
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
784
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
785
+					[
786
+						'page'     => 'espresso_registrations',
787
+						'action'   => 'new_registration',
788
+						'return'   => 'default',
789
+						'TXN_ID'   => $this->_transaction->ID(),
790
+						'event_id' => $EVT_ID,
791
+					],
792
+					REG_ADMIN_URL
793
+				);
794
+				$this->_admin_page_title .= '">';
795
+
796
+				$this->_admin_page_title .= sprintf(
797
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
798
+					htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
799
+				);
800
+				$this->_admin_page_title .= '</a>';
801
+			}
802
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
803
+		}
804
+		// grab messages at the last second
805
+		$this->_template_args['notices'] = EE_Error::get_notices();
806
+		// path to template
807
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
808
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
809
+			$template_path,
810
+			$this->_template_args,
811
+			true
812
+		);
813
+
814
+		// the details template wrapper
815
+		$this->display_admin_page_with_sidebar();
816
+	}
817
+
818
+
819
+	/**
820
+	 *        _transaction_details_metaboxes
821
+	 *
822
+	 * @access protected
823
+	 * @return void
824
+	 * @throws EE_Error
825
+	 * @throws InvalidArgumentException
826
+	 * @throws InvalidDataTypeException
827
+	 * @throws InvalidInterfaceException
828
+	 * @throws RuntimeException
829
+	 * @throws ReflectionException
830
+	 */
831
+	protected function _transaction_details_metaboxes()
832
+	{
833
+
834
+		$this->_set_transaction_object();
835
+
836
+		if (! $this->_transaction instanceof EE_Transaction) {
837
+			return;
838
+		}
839
+		$this->addMetaBox(
840
+			'edit-txn-details-mbox',
841
+			'<span>' . esc_html__('Transaction Details', 'event_espresso')
842
+			. '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
843
+			[$this, 'txn_details_meta_box'],
844
+			$this->_wp_page_slug
845
+		);
846
+		$this->addMetaBox(
847
+			'edit-txn-attendees-mbox',
848
+			'<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
849
+			. '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
850
+			[$this, 'txn_attendees_meta_box'],
851
+			$this->_wp_page_slug,
852
+			'normal',
853
+			'high',
854
+			['TXN_ID' => $this->_transaction->ID()]
855
+		);
856
+		$this->addMetaBox(
857
+			'edit-txn-registrant-mbox',
858
+			esc_html__('Primary Contact', 'event_espresso'),
859
+			[$this, 'txn_registrant_side_meta_box'],
860
+			$this->_wp_page_slug,
861
+			'side'
862
+		);
863
+		$this->addMetaBox(
864
+			'edit-txn-billing-info-mbox',
865
+			esc_html__('Billing Information', 'event_espresso'),
866
+			[$this, 'txn_billing_info_side_meta_box'],
867
+			$this->_wp_page_slug,
868
+			'side'
869
+		);
870
+	}
871
+
872
+
873
+	/**
874
+	 * Callback for transaction actions metabox.
875
+	 *
876
+	 * @param EE_Transaction|null $transaction
877
+	 * @return string
878
+	 * @throws DomainException
879
+	 * @throws EE_Error
880
+	 * @throws InvalidArgumentException
881
+	 * @throws InvalidDataTypeException
882
+	 * @throws InvalidInterfaceException
883
+	 * @throws ReflectionException
884
+	 * @throws RuntimeException
885
+	 */
886
+	public function getActionButtons(EE_Transaction $transaction = null)
887
+	{
888
+		$content = '';
889
+		$actions = [];
890
+		if (! $transaction instanceof EE_Transaction) {
891
+			return $content;
892
+		}
893
+		/** @var EE_Registration $primary_registration */
894
+		$primary_registration = $transaction->primary_registration();
895
+		$attendee             = $primary_registration instanceof EE_Registration
896
+			? $primary_registration->attendee()
897
+			: null;
898
+
899
+		if (
900
+			$attendee instanceof EE_Attendee
901
+			&& EE_Registry::instance()->CAP->current_user_can(
902
+				'ee_send_message',
903
+				'espresso_transactions_send_payment_reminder'
904
+			)
905
+		) {
906
+			$actions['payment_reminder'] =
907
+				EEH_MSG_Template::is_mt_active('payment_reminder')
908
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
909
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
910
+					? EEH_Template::get_button_or_link(
911
+						EE_Admin_Page::add_query_args_and_nonce(
912
+							[
913
+							'action'      => 'send_payment_reminder',
914
+							'TXN_ID'      => $this->_transaction->ID(),
915
+							'redirect_to' => 'view_transaction',
916
+							],
917
+							TXN_ADMIN_URL
918
+						),
919
+						esc_html__(' Send Payment Reminder', 'event_espresso'),
920
+						'button button--secondary',
921
+						'dashicons dashicons-email-alt'
922
+					)
923
+					: '';
924
+		}
925
+
926
+		if (
927
+			EE_Registry::instance()->CAP->current_user_can(
928
+				'ee_edit_payments',
929
+				'espresso_transactions_recalculate_line_items'
930
+			)
931
+		) {
932
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
933
+				EE_Admin_Page::add_query_args_and_nonce(
934
+					[
935
+						'action'      => 'espresso_recalculate_line_items',
936
+						'TXN_ID'      => $this->_transaction->ID(),
937
+						'redirect_to' => 'view_transaction',
938
+					],
939
+					TXN_ADMIN_URL
940
+				),
941
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
942
+				'button button--secondary',
943
+				'dashicons dashicons-update'
944
+			);
945
+		}
946
+
947
+		if (
948
+			$primary_registration instanceof EE_Registration
949
+			&& EEH_MSG_Template::is_mt_active('receipt')
950
+		) {
951
+			$actions['receipt'] = EEH_Template::get_button_or_link(
952
+				$primary_registration->receipt_url(),
953
+				esc_html__('View Receipt', 'event_espresso'),
954
+				'button button--secondary',
955
+				'dashicons dashicons-text-page'
956
+			);
957
+		}
958
+
959
+		if (
960
+			$primary_registration instanceof EE_Registration
961
+			&& EEH_MSG_Template::is_mt_active('invoice')
962
+		) {
963
+			$actions['invoice'] = EEH_Template::get_button_or_link(
964
+				$primary_registration->invoice_url(),
965
+				esc_html__('View Invoice', 'event_espresso'),
966
+				'button button--secondary',
967
+				'dashicons dashicons-media-spreadsheet'
968
+			);
969
+		}
970
+		$actions = array_filter(
971
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
972
+		);
973
+		if ($actions) {
974
+			$content .= implode('', $actions);
975
+		}
976
+		return $content;
977
+	}
978
+
979
+
980
+	/**
981
+	 * txn_details_meta_box
982
+	 * generates HTML for the Transaction main meta box
983
+	 *
984
+	 * @return void
985
+	 * @throws DomainException
986
+	 * @throws EE_Error
987
+	 * @throws InvalidArgumentException
988
+	 * @throws InvalidDataTypeException
989
+	 * @throws InvalidInterfaceException
990
+	 * @throws RuntimeException
991
+	 * @throws ReflectionException
992
+	 */
993
+	public function txn_details_meta_box()
994
+	{
995
+		$this->_set_transaction_object();
996
+		$this->_template_args['TXN_ID']              = $this->_transaction->ID();
997
+		$this->_template_args['attendee']            =
998
+			$this->_transaction->primary_registration() instanceof EE_Registration
999
+				? $this->_transaction->primary_registration()->attendee()
1000
+				: null;
1001
+		$this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1002
+			'ee_edit_payments',
1003
+			'apply_payment_or_refund_from_registration_details'
1004
+		);
1005
+		$this->_template_args['can_delete_payments'] = EE_Registry::instance()->CAP->current_user_can(
1006
+			'ee_delete_payments',
1007
+			'delete_payment_from_registration_details'
1008
+		);
1009
+
1010
+		// get line table
1011
+		EEH_Autoloader::register_line_item_display_autoloaders();
1012
+		$Line_Item_Display                       = new EE_Line_Item_Display(
1013
+			'admin_table',
1014
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1015
+		);
1016
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1017
+			$this->_transaction->total_line_item()
1018
+		);
1019
+		$this->_template_args['REG_code']        =
1020
+			$this->_transaction->primary_registration() instanceof EE_Registration
1021
+				? $this->_transaction->primary_registration()->reg_code()
1022
+				: null;
1023
+		// process taxes
1024
+		$taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1025
+		$this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1026
+
1027
+		$this->_template_args['grand_total']     = EEH_Template::format_currency(
1028
+			$this->_transaction->total(),
1029
+			false,
1030
+			false
1031
+		);
1032
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1033
+		$this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1034
+
1035
+		// process payment details
1036
+		$payments = $this->_transaction->payments();
1037
+		if (! empty($payments)) {
1038
+			$this->_template_args['payments']              = $payments;
1039
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1040
+		} else {
1041
+			$this->_template_args['payments']              = false;
1042
+			$this->_template_args['existing_reg_payments'] = [];
1043
+		}
1044
+
1045
+		$this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1046
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1047
+			['action' => 'espresso_delete_payment'],
1048
+			TXN_ADMIN_URL
1049
+		);
1050
+
1051
+		if (isset($txn_details['invoice_number'])) {
1052
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1053
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1054
+				'Invoice Number',
1055
+				'event_espresso'
1056
+			);
1057
+		}
1058
+
1059
+		$this->_template_args['txn_details']['registration_session']['value'] =
1060
+			$this->_transaction->primary_registration() instanceof EE_Registration
1061
+				? $this->_transaction->primary_registration()->session_ID()
1062
+				: null;
1063
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1064
+			'Registration Session',
1065
+			'event_espresso'
1066
+		);
1067
+
1068
+		$this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1069
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1070
+			'Transaction placed from IP',
1071
+			'event_espresso'
1072
+		);
1073
+
1074
+		$this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1075
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1076
+			'Registrant User Agent',
1077
+			'event_espresso'
1078
+		);
1079
+
1080
+		$reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1081
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1082
+			if ($reg_step_status === true) {
1083
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1084
+							  . sprintf(
1085
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1086
+								  ucwords(str_replace('_', ' ', $reg_step))
1087
+							  )
1088
+							  . '</div>';
1089
+			} elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1090
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1091
+							  . sprintf(
1092
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1093
+								  ucwords(str_replace('_', ' ', $reg_step)),
1094
+								  date(
1095
+									  get_option('date_format') . ' ' . get_option('time_format'),
1096
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1097
+								  )
1098
+							  )
1099
+							  . '</div>';
1100
+			} else {
1101
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1102
+							  . sprintf(
1103
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1104
+								  ucwords(str_replace('_', ' ', $reg_step))
1105
+							  )
1106
+							  . '</div>';
1107
+			}
1108
+		}
1109
+		$reg_steps                                                 .= '</ul>';
1110
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1111
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1112
+			'Registration Step Progress',
1113
+			'event_espresso'
1114
+		);
1115
+
1116
+
1117
+		$this->_get_registrations_to_apply_payment_to();
1118
+		$this->_get_payment_methods($payments);
1119
+		$this->_get_payment_status_array();
1120
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1121
+
1122
+		$this->_template_args['transaction_form_url']    = add_query_arg(
1123
+			[
1124
+				'action'  => 'edit_transaction',
1125
+				'process' => 'transaction',
1126
+			],
1127
+			TXN_ADMIN_URL
1128
+		);
1129
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(
1130
+			[
1131
+				'page'   => 'espresso_transactions',
1132
+				'action' => 'espresso_apply_payment',
1133
+			],
1134
+			TXN_ADMIN_URL
1135
+		);
1136
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1137
+			[
1138
+				'page'   => 'espresso_transactions',
1139
+				'action' => 'espresso_delete_payment',
1140
+			],
1141
+			TXN_ADMIN_URL
1142
+		);
1143
+
1144
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1145
+
1146
+		// 'espresso_delete_payment_nonce'
1147
+
1148
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1149
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1150
+	}
1151
+
1152
+
1153
+	/**
1154
+	 * _get_registration_payment_IDs
1155
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1156
+	 *
1157
+	 * @access protected
1158
+	 * @param EE_Payment[] $payments
1159
+	 * @return array
1160
+	 * @throws EE_Error
1161
+	 * @throws InvalidArgumentException
1162
+	 * @throws InvalidDataTypeException
1163
+	 * @throws InvalidInterfaceException
1164
+	 * @throws ReflectionException
1165
+	 */
1166
+	protected function _get_registration_payment_IDs($payments = [])
1167
+	{
1168
+		$existing_reg_payments = [];
1169
+		// get all reg payments for these payments
1170
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1171
+			[
1172
+				[
1173
+					'PAY_ID' => [
1174
+						'IN',
1175
+						array_keys($payments),
1176
+					],
1177
+				],
1178
+			]
1179
+		);
1180
+		if (! empty($reg_payments)) {
1181
+			foreach ($payments as $payment) {
1182
+				if (! $payment instanceof EE_Payment) {
1183
+					continue;
1184
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1185
+					$existing_reg_payments[ $payment->ID() ] = [];
1186
+				}
1187
+				foreach ($reg_payments as $reg_payment) {
1188
+					if (
1189
+						$reg_payment instanceof EE_Registration_Payment
1190
+						&& $reg_payment->payment_ID() === $payment->ID()
1191
+					) {
1192
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1193
+					}
1194
+				}
1195
+			}
1196
+		}
1197
+
1198
+		return $existing_reg_payments;
1199
+	}
1200
+
1201
+
1202
+	/**
1203
+	 * _get_registrations_to_apply_payment_to
1204
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1205
+	 * which allows the admin to only apply the payment to the specific registrations
1206
+	 *
1207
+	 * @access protected
1208
+	 * @return void
1209
+	 * @throws EE_Error
1210
+	 * @throws InvalidArgumentException
1211
+	 * @throws InvalidDataTypeException
1212
+	 * @throws InvalidInterfaceException
1213
+	 * @throws ReflectionException
1214
+	 */
1215
+	protected function _get_registrations_to_apply_payment_to()
1216
+	{
1217
+		// we want any registration with an active status (ie: not deleted or cancelled)
1218
+		$query_params                      = [
1219
+			[
1220
+				'STS_ID' => [
1221
+					'IN',
1222
+					[
1223
+						EEM_Registration::status_id_approved,
1224
+						EEM_Registration::status_id_pending_payment,
1225
+						EEM_Registration::status_id_not_approved,
1226
+					],
1227
+				],
1228
+			],
1229
+		];
1230
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1231
+			'',
1232
+			'txn-admin-apply-payment-to-registrations-dv',
1233
+			'',
1234
+			'clear: both; margin: 1.5em 0 0; display: none;'
1235
+		);
1236
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1237
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1238
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1239
+			EEH_HTML::tr(
1240
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1241
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1242
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1243
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1244
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1245
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1246
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1247
+			)
1248
+		);
1249
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1250
+		// get registrations for TXN
1251
+		$registrations         = $this->_transaction->registrations($query_params);
1252
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1253
+		foreach ($registrations as $registration) {
1254
+			if ($registration instanceof EE_Registration) {
1255
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
1256
+					? $registration->attendee()->full_name()
1257
+					: esc_html__('Unknown Attendee', 'event_espresso');
1258
+				$owing                             = $registration->final_price() - $registration->paid();
1259
+				$taxable                           = $registration->ticket()->taxable()
1260
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1261
+					: '';
1262
+				$checked                           = empty($existing_reg_payments)
1263
+													 || in_array($registration->ID(), $existing_reg_payments, true)
1264
+					? ' checked'
1265
+					: '';
1266
+				$disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1267
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1268
+					EEH_HTML::td($registration->ID()) .
1269
+					EEH_HTML::td($attendee_name) .
1270
+					EEH_HTML::td(
1271
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1272
+					) .
1273
+					EEH_HTML::td($registration->event_name()) .
1274
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1275
+					EEH_HTML::td(
1276
+						EEH_Template::format_currency($owing),
1277
+						'',
1278
+						'txn-admin-payment-owing-td jst-cntr'
1279
+					) .
1280
+					EEH_HTML::td(
1281
+						'<input type="checkbox" value="' . $registration->ID()
1282
+						. '" name="txn_admin_payment[registrations]"'
1283
+						. $checked . $disabled . '>',
1284
+						'',
1285
+						'jst-cntr'
1286
+					),
1287
+					'apply-payment-registration-row-' . $registration->ID()
1288
+				);
1289
+			}
1290
+		}
1291
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1292
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1293
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1294
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1295
+			esc_html__(
1296
+				'The payment will only be applied to the registrations that have a check mark in their corresponding check box. Checkboxes for free registrations have been disabled.',
1297
+				'event_espresso'
1298
+			),
1299
+			'',
1300
+			'clear description'
1301
+		);
1302
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1303
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1304
+	}
1305
+
1306
+
1307
+	/**
1308
+	 * _get_reg_status_selection
1309
+	 *
1310
+	 * @return void
1311
+	 * @throws EE_Error
1312
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1313
+	 *         instead of events.
1314
+	 * @access protected
1315
+	 */
1316
+	protected function _get_reg_status_selection()
1317
+	{
1318
+		// first get all possible statuses
1319
+		$statuses = EEM_Registration::reg_status_array([], true);
1320
+		// let's add a "don't change" option.
1321
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1322
+		$status_array                                        = array_merge($status_array, $statuses);
1323
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1324
+			'txn_reg_status_change[reg_status]',
1325
+			$status_array,
1326
+			'NAN',
1327
+			'id="txn-admin-payment-reg-status-inp"',
1328
+			'txn-reg-status-change-reg-status'
1329
+		);
1330
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1331
+			'delete_txn_reg_status_change[reg_status]',
1332
+			$status_array,
1333
+			'NAN',
1334
+			'delete-txn-admin-payment-reg-status-inp',
1335
+			'delete-txn-reg-status-change-reg-status'
1336
+		);
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 *    _get_payment_methods
1342
+	 * Gets all the payment methods available generally, or the ones that are already
1343
+	 * selected on these payments (in case their payment methods are no longer active).
1344
+	 * Has the side-effect of updating the template args' payment_methods item
1345
+	 *
1346
+	 * @access private
1347
+	 * @param EE_Payment[] to show on this page
1348
+	 * @return void
1349
+	 * @throws EE_Error
1350
+	 * @throws InvalidArgumentException
1351
+	 * @throws InvalidDataTypeException
1352
+	 * @throws InvalidInterfaceException
1353
+	 * @throws ReflectionException
1354
+	 */
1355
+	private function _get_payment_methods($payments = [])
1356
+	{
1357
+		$payment_methods_of_payments = [];
1358
+		foreach ($payments as $payment) {
1359
+			if ($payment instanceof EE_Payment) {
1360
+				$payment_methods_of_payments[] = $payment->ID();
1361
+			}
1362
+		}
1363
+		if ($payment_methods_of_payments) {
1364
+			$query_args = [
1365
+				[
1366
+					'OR*payment_method_for_payment' => [
1367
+						'PMD_ID'    => ['IN', $payment_methods_of_payments],
1368
+						'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1369
+					],
1370
+				],
1371
+			];
1372
+		} else {
1373
+			$query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1374
+		}
1375
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1376
+	}
1377
+
1378
+
1379
+	/**
1380
+	 * txn_attendees_meta_box
1381
+	 *    generates HTML for the Attendees Transaction main meta box
1382
+	 *
1383
+	 * @access public
1384
+	 * @param WP_Post $post
1385
+	 * @param array   $metabox
1386
+	 * @return void
1387
+	 * @throws DomainException
1388
+	 * @throws EE_Error
1389
+	 * @throws InvalidArgumentException
1390
+	 * @throws InvalidDataTypeException
1391
+	 * @throws InvalidInterfaceException
1392
+	 * @throws ReflectionException
1393
+	 */
1394
+	public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1395
+	{
1396
+
1397
+		/** @noinspection NonSecureExtractUsageInspection */
1398
+		extract($metabox['args']);
1399
+		$this->_template_args['post']            = $post;
1400
+		$this->_template_args['event_attendees'] = [];
1401
+		// process items in cart
1402
+		$line_items = $this->_transaction->get_many_related(
1403
+			'Line_Item',
1404
+			[['LIN_type' => 'line-item']]
1405
+		);
1406
+		if (! empty($line_items)) {
1407
+			foreach ($line_items as $item) {
1408
+				if ($item instanceof EE_Line_Item) {
1409
+					switch ($item->OBJ_type()) {
1410
+						case 'Event':
1411
+							break;
1412
+						case 'Ticket':
1413
+							$ticket = $item->ticket();
1414
+							// right now we're only handling tickets here.
1415
+							// Cause its expected that only tickets will have attendees right?
1416
+							if (! $ticket instanceof EE_Ticket) {
1417
+								break;
1418
+							}
1419
+							try {
1420
+								$event_name = $ticket->get_event_name();
1421
+							} catch (Exception $e) {
1422
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1423
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1424
+							}
1425
+							$event_name   .= ' - ' . $item->name();
1426
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1427
+							// now get all of the registrations for this transaction that use this ticket
1428
+							$registrations = $ticket->registrations(
1429
+								[['TXN_ID' => $this->_transaction->ID()]]
1430
+							);
1431
+							foreach ($registrations as $registration) {
1432
+								if (! $registration instanceof EE_Registration) {
1433
+									break;
1434
+								}
1435
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1436
+									= $registration->status_ID();
1437
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1438
+									= $registration->count();
1439
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1440
+									= $event_name;
1441
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1442
+									= $ticket_price;
1443
+								// attendee info
1444
+								$attendee = $registration->get_first_related('Attendee');
1445
+								if ($attendee instanceof EE_Attendee) {
1446
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1447
+										= $attendee->ID();
1448
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1449
+										= $attendee->full_name();
1450
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1451
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1452
+										  . esc_html__(
1453
+											  ' Event',
1454
+											  'event_espresso'
1455
+										  )
1456
+										  . '">' . $attendee->email() . '</a>';
1457
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1458
+										= EEH_Address::format($attendee, 'inline', false, false);
1459
+								} else {
1460
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1461
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1462
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1463
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1464
+								}
1465
+							}
1466
+							break;
1467
+					}
1468
+				}
1469
+			}
1470
+
1471
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1472
+				[
1473
+					'action'  => 'edit_transaction',
1474
+					'process' => 'attendees',
1475
+				],
1476
+				TXN_ADMIN_URL
1477
+			);
1478
+			echo EEH_Template::display_template(
1479
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1480
+				$this->_template_args,
1481
+				true
1482
+			);
1483
+		} else {
1484
+			printf(
1485
+				esc_html__(
1486
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1487
+					'event_espresso'
1488
+				),
1489
+				'<p class="important-notice">',
1490
+				'</p>'
1491
+			);
1492
+		}
1493
+	}
1494
+
1495
+
1496
+	/**
1497
+	 * txn_registrant_side_meta_box
1498
+	 * generates HTML for the Edit Transaction side meta box
1499
+	 *
1500
+	 * @access public
1501
+	 * @return void
1502
+	 * @throws DomainException
1503
+	 * @throws EE_Error
1504
+	 * @throws InvalidArgumentException
1505
+	 * @throws InvalidDataTypeException
1506
+	 * @throws InvalidInterfaceException
1507
+	 * @throws ReflectionException
1508
+	 */
1509
+	public function txn_registrant_side_meta_box()
1510
+	{
1511
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1512
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1513
+			: null;
1514
+		if (! $primary_att instanceof EE_Attendee) {
1515
+			$this->_template_args['no_attendee_message'] = esc_html__(
1516
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1517
+				'event_espresso'
1518
+			);
1519
+			$primary_att                           = EEM_Attendee::instance()->create_default_object();
1520
+		}
1521
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1522
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1523
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1524
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1525
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1526
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1527
+			[
1528
+				'action' => 'edit_attendee',
1529
+				'post'   => $primary_att->ID(),
1530
+			],
1531
+			REG_ADMIN_URL
1532
+		);
1533
+		// get formatted address for registrant
1534
+		$formatted_address = EEH_Address::format($primary_att);
1535
+		$formatted_address = $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1536
+			? $formatted_address
1537
+			: '';
1538
+		$this->_template_args['formatted_address'] = $formatted_address;
1539
+		echo EEH_Template::display_template(
1540
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1541
+			$this->_template_args,
1542
+			true
1543
+		);
1544
+	}
1545
+
1546
+
1547
+	/**
1548
+	 * txn_billing_info_side_meta_box
1549
+	 *    generates HTML for the Edit Transaction side meta box
1550
+	 *
1551
+	 * @access public
1552
+	 * @return void
1553
+	 * @throws DomainException
1554
+	 * @throws EE_Error
1555
+	 * @throws ReflectionException
1556
+	 */
1557
+	public function txn_billing_info_side_meta_box()
1558
+	{
1559
+
1560
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1561
+		$this->_template_args['billing_form_url'] = add_query_arg(
1562
+			['action' => 'edit_transaction', 'process' => 'billing'],
1563
+			TXN_ADMIN_URL
1564
+		);
1565
+
1566
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1567
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1568
+	}
1569
+
1570
+
1571
+	/**
1572
+	 * apply_payments_or_refunds
1573
+	 *    registers a payment or refund made towards a transaction
1574
+	 *
1575
+	 * @access public
1576
+	 * @return void
1577
+	 * @throws EE_Error
1578
+	 * @throws InvalidArgumentException
1579
+	 * @throws ReflectionException
1580
+	 * @throws RuntimeException
1581
+	 * @throws InvalidDataTypeException
1582
+	 * @throws InvalidInterfaceException
1583
+	 */
1584
+	public function apply_payments_or_refunds()
1585
+	{
1586
+		$valid_data         = $this->_validate_payment_request_data();
1587
+		$has_access         = EE_Registry::instance()->CAP->current_user_can(
1588
+			'ee_edit_payments',
1589
+			'apply_payment_or_refund_from_registration_details'
1590
+		);
1591
+		$TXD_ID = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1592
+		$amount = 0;
1593
+		if (! empty($valid_data) && $has_access) {
1594
+			$PAY_ID = $valid_data['PAY_ID'];
1595
+			// save  the new payment
1596
+			$payment = $this->_create_payment_from_request_data($valid_data);
1597
+			$amount = $payment->amount();
1598
+			// get the TXN for this payment
1599
+			$transaction = $payment->transaction();
1600
+			// verify transaction
1601
+			if ($transaction instanceof EE_Transaction) {
1602
+				// calculate_total_payments_and_update_status
1603
+				$this->_process_transaction_payments($transaction);
1604
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1605
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1606
+				// apply payment to registrations (if applicable)
1607
+				if (! empty($REG_IDs)) {
1608
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1609
+					$this->_maybe_send_notifications();
1610
+					// now process status changes for the same registrations
1611
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1612
+				}
1613
+				$this->_maybe_send_notifications($payment);
1614
+				// prepare to render page
1615
+				do_action(
1616
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1617
+					$transaction,
1618
+					$payment
1619
+				);
1620
+			} else {
1621
+				EE_Error::add_error(
1622
+					esc_html__(
1623
+						'A valid Transaction for this payment could not be retrieved.',
1624
+						'event_espresso'
1625
+					),
1626
+					__FILE__,
1627
+					__FUNCTION__,
1628
+					__LINE__
1629
+				);
1630
+			}
1631
+		} elseif ($has_access) {
1632
+			EE_Error::add_error(
1633
+				esc_html__(
1634
+					'The payment form data could not be processed. Please try again.',
1635
+					'event_espresso'
1636
+				),
1637
+				__FILE__,
1638
+				__FUNCTION__,
1639
+				__LINE__
1640
+			);
1641
+		} else {
1642
+			EE_Error::add_error(
1643
+				esc_html__(
1644
+					'You do not have access to apply payments or refunds to a registration.',
1645
+					'event_espresso'
1646
+				),
1647
+				__FILE__,
1648
+				__FUNCTION__,
1649
+				__LINE__
1650
+			);
1651
+		}
1652
+		$query_args = [
1653
+			'page' => 'espresso_transactions',
1654
+			 'action' => 'view_transaction',
1655
+			 'TXN_ID' => $TXD_ID
1656
+		];
1657
+
1658
+		$this->_redirect_after_action(
1659
+			! EE_Error::has_error(),
1660
+			$amount > 0
1661
+				? esc_html__('payment', 'event_espresso')
1662
+				: esc_html__('refund', 'event_espresso'),
1663
+			esc_html__('processed', 'event_espresso'),
1664
+			$query_args
1665
+		);
1666
+	}
1667
+
1668
+
1669
+	/**
1670
+	 * _validate_payment_request_data
1671
+	 *
1672
+	 * @return array
1673
+	 * @throws EE_Error
1674
+	 * @throws InvalidArgumentException
1675
+	 * @throws InvalidDataTypeException
1676
+	 * @throws InvalidInterfaceException
1677
+	 */
1678
+	protected function _validate_payment_request_data()
1679
+	{
1680
+		if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1681
+			return [];
1682
+		}
1683
+		$payment_form = $this->_generate_payment_form_section();
1684
+		try {
1685
+			if ($payment_form->was_submitted()) {
1686
+				$payment_form->receive_form_submission();
1687
+				if (! $payment_form->is_valid()) {
1688
+					$submission_error_messages = [];
1689
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1690
+						if ($validation_error instanceof EE_Validation_Error) {
1691
+							$form_input = $validation_error->get_form_section();
1692
+							$submission_error_messages[] = sprintf(
1693
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1694
+								$form_input instanceof EE_Form_Input_Base ? $form_input->html_label_text() : '',
1695
+								$validation_error->getMessage()
1696
+							);
1697
+						}
1698
+					}
1699
+					EE_Error::add_error(
1700
+						implode('<br />', $submission_error_messages),
1701
+						__FILE__,
1702
+						__FUNCTION__,
1703
+						__LINE__
1704
+					);
1705
+					return [];
1706
+				}
1707
+			}
1708
+		} catch (EE_Error $e) {
1709
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1710
+			return [];
1711
+		}
1712
+
1713
+		return $payment_form->valid_data();
1714
+	}
1715
+
1716
+
1717
+	/**
1718
+	 * _generate_payment_form_section
1719
+	 *
1720
+	 * @return EE_Form_Section_Proper
1721
+	 * @throws EE_Error
1722
+	 */
1723
+	protected function _generate_payment_form_section()
1724
+	{
1725
+		return new EE_Form_Section_Proper(
1726
+			[
1727
+				'name'        => 'txn_admin_payment',
1728
+				'subsections' => [
1729
+					'PAY_ID'          => new EE_Text_Input(
1730
+						[
1731
+							'default'               => 0,
1732
+							'required'              => false,
1733
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1734
+							'validation_strategies' => [new EE_Int_Normalization()],
1735
+						]
1736
+					),
1737
+					'TXN_ID'          => new EE_Text_Input(
1738
+						[
1739
+							'default'               => 0,
1740
+							'required'              => true,
1741
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1742
+							'validation_strategies' => [new EE_Int_Normalization()],
1743
+						]
1744
+					),
1745
+					'type'            => new EE_Text_Input(
1746
+						[
1747
+							'default'               => 1,
1748
+							'required'              => true,
1749
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1750
+							'validation_strategies' => [new EE_Int_Normalization()],
1751
+						]
1752
+					),
1753
+					'amount'          => new EE_Text_Input(
1754
+						[
1755
+							'default'               => 0,
1756
+							'required'              => true,
1757
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1758
+							'validation_strategies' => [new EE_Float_Normalization()],
1759
+						]
1760
+					),
1761
+					'status'          => new EE_Text_Input(
1762
+						[
1763
+							'default'         => EEM_Payment::status_id_approved,
1764
+							'required'        => true,
1765
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1766
+						]
1767
+					),
1768
+					'PMD_ID'          => new EE_Text_Input(
1769
+						[
1770
+							'default'               => 2,
1771
+							'required'              => true,
1772
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1773
+							'validation_strategies' => [new EE_Int_Normalization()],
1774
+						]
1775
+					),
1776
+					'date'            => new EE_Text_Input(
1777
+						[
1778
+							'default'         => time(),
1779
+							'required'        => true,
1780
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1781
+						]
1782
+					),
1783
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1784
+						[
1785
+							'default'               => '',
1786
+							'required'              => false,
1787
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1788
+							'validation_strategies' => [
1789
+								new EE_Max_Length_Validation_Strategy(
1790
+									esc_html__('Input too long', 'event_espresso'),
1791
+									100
1792
+								),
1793
+							],
1794
+						]
1795
+					),
1796
+					'po_number'       => new EE_Text_Input(
1797
+						[
1798
+							'default'               => '',
1799
+							'required'              => false,
1800
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1801
+							'validation_strategies' => [
1802
+								new EE_Max_Length_Validation_Strategy(
1803
+									esc_html__('Input too long', 'event_espresso'),
1804
+									100
1805
+								),
1806
+							],
1807
+						]
1808
+					),
1809
+					'accounting'      => new EE_Text_Input(
1810
+						[
1811
+							'default'               => '',
1812
+							'required'              => false,
1813
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1814
+							'validation_strategies' => [
1815
+								new EE_Max_Length_Validation_Strategy(
1816
+									esc_html__('Input too long', 'event_espresso'),
1817
+									100
1818
+								),
1819
+							],
1820
+						]
1821
+					),
1822
+				],
1823
+			]
1824
+		);
1825
+	}
1826
+
1827
+
1828
+	/**
1829
+	 * _create_payment_from_request_data
1830
+	 *
1831
+	 * @param array $valid_data
1832
+	 * @return EE_Payment
1833
+	 * @throws EE_Error
1834
+	 * @throws InvalidArgumentException
1835
+	 * @throws InvalidDataTypeException
1836
+	 * @throws InvalidInterfaceException
1837
+	 * @throws ReflectionException
1838
+	 */
1839
+	protected function _create_payment_from_request_data($valid_data)
1840
+	{
1841
+		$PAY_ID = $valid_data['PAY_ID'];
1842
+		// get payment amount
1843
+		$amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0;
1844
+		// payments have a type value of 1 and refunds have a type value of -1
1845
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1846
+		$amount = $valid_data['type'] < 0 ? $amount * -1 : $amount;
1847
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1848
+		$date    = $valid_data['date']
1849
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1850
+			: date('Y-m-d g:i a', current_time('timestamp'));
1851
+		$payment = EE_Payment::new_instance(
1852
+			[
1853
+				'TXN_ID'              => $valid_data['TXN_ID'],
1854
+				'STS_ID'              => $valid_data['status'],
1855
+				'PAY_timestamp'       => $date,
1856
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1857
+				'PMD_ID'              => $valid_data['PMD_ID'],
1858
+				'PAY_amount'          => $amount,
1859
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1860
+				'PAY_po_number'       => $valid_data['po_number'],
1861
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1862
+				'PAY_details'         => $valid_data,
1863
+				'PAY_ID'              => $PAY_ID,
1864
+			],
1865
+			'',
1866
+			['Y-m-d', 'g:i a']
1867
+		);
1868
+
1869
+		if (! $payment->save()) {
1870
+			EE_Error::add_error(
1871
+				sprintf(
1872
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1873
+					$payment->ID()
1874
+				),
1875
+				__FILE__,
1876
+				__FUNCTION__,
1877
+				__LINE__
1878
+			);
1879
+		}
1880
+
1881
+		return $payment;
1882
+	}
1883
+
1884
+
1885
+	/**
1886
+	 * _process_transaction_payments
1887
+	 *
1888
+	 * @param EE_Transaction $transaction
1889
+	 * @return void
1890
+	 * @throws EE_Error
1891
+	 * @throws InvalidArgumentException
1892
+	 * @throws ReflectionException
1893
+	 * @throws InvalidDataTypeException
1894
+	 * @throws InvalidInterfaceException
1895
+	 */
1896
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1897
+	{
1898
+		/** @type EE_Transaction_Payments $transaction_payments */
1899
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1900
+		// update the transaction with this payment
1901
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1902
+			EE_Error::add_success(
1903
+				esc_html__(
1904
+					'The payment has been processed successfully.',
1905
+					'event_espresso'
1906
+				),
1907
+				__FILE__,
1908
+				__FUNCTION__,
1909
+				__LINE__
1910
+			);
1911
+		} else {
1912
+			EE_Error::add_error(
1913
+				esc_html__(
1914
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1915
+					'event_espresso'
1916
+				),
1917
+				__FILE__,
1918
+				__FUNCTION__,
1919
+				__LINE__
1920
+			);
1921
+		}
1922
+	}
1923
+
1924
+
1925
+	/**
1926
+	 * _get_REG_IDs_to_apply_payment_to
1927
+	 * returns a list of registration IDs that the payment will apply to
1928
+	 *
1929
+	 * @param EE_Payment $payment
1930
+	 * @return array
1931
+	 * @throws EE_Error
1932
+	 * @throws InvalidArgumentException
1933
+	 * @throws InvalidDataTypeException
1934
+	 * @throws InvalidInterfaceException
1935
+	 * @throws ReflectionException
1936
+	 */
1937
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1938
+	{
1939
+		// grab array of IDs for specific registrations to apply changes to
1940
+		$apply_to_all = $this->request->getRequestParam(
1941
+			'txn_admin_payment[apply_to_all_registrations]',
1942
+			false,
1943
+			DataType::BOOL
1944
+		);
1945
+		$REG_IDs = ! $apply_to_all
1946
+			? $this->request->getRequestParam(
1947
+				'txn_admin_payment[registrations]',
1948
+				[],
1949
+				DataType::INT,
1950
+				true
1951
+			)
1952
+			: [];
1953
+		// nothing specified ? then get all reg IDs
1954
+		if ($apply_to_all || empty($REG_IDs)) {
1955
+			$registrations = $payment->transaction()->registrations();
1956
+			$REG_IDs       = ! empty($registrations)
1957
+				? array_keys($registrations)
1958
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1959
+		}
1960
+		// ensure that REG_IDs are integers and NOT strings
1961
+		return array_map('absint', $REG_IDs);
1962
+	}
1963
+
1964
+
1965
+	/**
1966
+	 * @return array
1967
+	 */
1968
+	public function existing_reg_payment_REG_IDs()
1969
+	{
1970
+		return $this->_existing_reg_payment_REG_IDs;
1971
+	}
1972
+
1973
+
1974
+	/**
1975
+	 * @param array $existing_reg_payment_REG_IDs
1976
+	 */
1977
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1978
+	{
1979
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
1980
+	}
1981
+
1982
+
1983
+	/**
1984
+	 * _get_existing_reg_payment_REG_IDs
1985
+	 * returns a list of registration IDs that the payment is currently related to
1986
+	 * as recorded in the database
1987
+	 *
1988
+	 * @param EE_Payment $payment
1989
+	 * @return array
1990
+	 * @throws EE_Error
1991
+	 * @throws InvalidArgumentException
1992
+	 * @throws InvalidDataTypeException
1993
+	 * @throws InvalidInterfaceException
1994
+	 * @throws ReflectionException
1995
+	 */
1996
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
1997
+	{
1998
+		if ($this->existing_reg_payment_REG_IDs() === null) {
1999
+			// let's get any existing reg payment records for this payment
2000
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2001
+			// but we only want the REG IDs, so grab the array keys
2002
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2003
+				? array_keys($existing_reg_payment_REG_IDs)
2004
+				: [];
2005
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2006
+		}
2007
+
2008
+		return $this->existing_reg_payment_REG_IDs();
2009
+	}
2010
+
2011
+
2012
+	/**
2013
+	 * _remove_existing_registration_payments
2014
+	 * this calculates the difference between existing relations
2015
+	 * to the supplied payment and the new list registration IDs,
2016
+	 * removes any related registrations that no longer apply,
2017
+	 * and then updates the registration paid fields
2018
+	 *
2019
+	 * @param EE_Payment $payment
2020
+	 * @param int        $PAY_ID
2021
+	 * @return bool;
2022
+	 * @throws EE_Error
2023
+	 * @throws InvalidArgumentException
2024
+	 * @throws ReflectionException
2025
+	 * @throws InvalidDataTypeException
2026
+	 * @throws InvalidInterfaceException
2027
+	 */
2028
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2029
+	{
2030
+		// newly created payments will have nothing recorded for $PAY_ID
2031
+		if (absint($PAY_ID) === 0) {
2032
+			return false;
2033
+		}
2034
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2035
+		if (empty($existing_reg_payment_REG_IDs)) {
2036
+			return false;
2037
+		}
2038
+		/** @type EE_Transaction_Payments $transaction_payments */
2039
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2040
+
2041
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2042
+			$payment,
2043
+			[
2044
+				[
2045
+					'PAY_ID' => $payment->ID(),
2046
+					'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2047
+				],
2048
+			]
2049
+		);
2050
+	}
2051
+
2052
+
2053
+	/**
2054
+	 * _update_registration_payments
2055
+	 * this applies the payments to the selected registrations
2056
+	 * but only if they have not already been paid for
2057
+	 *
2058
+	 * @param EE_Transaction $transaction
2059
+	 * @param EE_Payment     $payment
2060
+	 * @param array          $REG_IDs
2061
+	 * @return void
2062
+	 * @throws EE_Error
2063
+	 * @throws InvalidArgumentException
2064
+	 * @throws ReflectionException
2065
+	 * @throws RuntimeException
2066
+	 * @throws InvalidDataTypeException
2067
+	 * @throws InvalidInterfaceException
2068
+	 */
2069
+	protected function _update_registration_payments(
2070
+		EE_Transaction $transaction,
2071
+		EE_Payment $payment,
2072
+		$REG_IDs = []
2073
+	) {
2074
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2075
+		// so let's do that using our set of REG_IDs from the form
2076
+		$registration_query_where_params = [
2077
+			'REG_ID' => ['IN', $REG_IDs],
2078
+		];
2079
+		// but add in some conditions regarding payment,
2080
+		// so that we don't apply payments to registrations that are free or have already been paid for
2081
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2082
+		if (! $payment->is_a_refund()) {
2083
+			$registration_query_where_params['REG_final_price']  = ['!=', 0];
2084
+			$registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2085
+		}
2086
+		$registrations = $transaction->registrations([$registration_query_where_params]);
2087
+		if (! empty($registrations)) {
2088
+			/** @type EE_Payment_Processor $payment_processor */
2089
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2090
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2091
+		}
2092
+	}
2093
+
2094
+
2095
+	/**
2096
+	 * _process_registration_status_change
2097
+	 * This processes requested registration status changes for all the registrations
2098
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2099
+	 *
2100
+	 * @param EE_Transaction $transaction
2101
+	 * @param array          $REG_IDs
2102
+	 * @return bool
2103
+	 * @throws EE_Error
2104
+	 * @throws InvalidArgumentException
2105
+	 * @throws ReflectionException
2106
+	 * @throws InvalidDataTypeException
2107
+	 * @throws InvalidInterfaceException
2108
+	 */
2109
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2110
+	{
2111
+		// first if there is no change in status then we get out.
2112
+		$reg_status = $reg_status ?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2113
+		if ($reg_status === 'NAN') {
2114
+			// no error message, no change requested, just nothing to do man.
2115
+			return false;
2116
+		}
2117
+		/** @type EE_Transaction_Processor $transaction_processor */
2118
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2119
+
2120
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2121
+		return $transaction_processor->manually_update_registration_statuses(
2122
+			$transaction,
2123
+			$reg_status,
2124
+			[['REG_ID' => ['IN', $REG_IDs]]]
2125
+		);
2126
+	}
2127
+
2128
+
2129
+	/**
2130
+	 * _build_payment_json_response
2131
+	 *
2132
+	 * @access public
2133
+	 * @param EE_Payment  $payment
2134
+	 * @param array       $REG_IDs
2135
+	 * @param bool | null $delete_txn_reg_status_change
2136
+	 * @return array
2137
+	 * @throws EE_Error
2138
+	 * @throws InvalidArgumentException
2139
+	 * @throws InvalidDataTypeException
2140
+	 * @throws InvalidInterfaceException
2141
+	 * @throws ReflectionException
2142
+	 */
2143
+	protected function _build_payment_json_response(
2144
+		EE_Payment $payment,
2145
+		$REG_IDs = [],
2146
+		$delete_txn_reg_status_change = null
2147
+	) {
2148
+		// was the payment deleted ?
2149
+		if (is_bool($delete_txn_reg_status_change)) {
2150
+			return [
2151
+				'PAY_ID'                       => $payment->ID(),
2152
+				'amount'                       => $payment->amount(),
2153
+				'total_paid'                   => $payment->transaction()->paid(),
2154
+				'txn_status'                   => $payment->transaction()->status_ID(),
2155
+				'pay_status'                   => $payment->STS_ID(),
2156
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2157
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2158
+			];
2159
+		}
2160
+
2161
+		$this->_get_payment_status_array();
2162
+		return [
2163
+			'amount'           => $payment->amount(),
2164
+			'total_paid'       => $payment->transaction()->paid(),
2165
+			'txn_status'       => $payment->transaction()->status_ID(),
2166
+			'pay_status'       => $payment->STS_ID(),
2167
+			'PAY_ID'           => $payment->ID(),
2168
+			'STS_ID'           => $payment->STS_ID(),
2169
+			'status'           => self::$_pay_status[ $payment->STS_ID() ],
2170
+			'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2171
+			'method'           => strtoupper($payment->source()),
2172
+			'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
2173
+			'gateway'          => $payment->payment_method()
2174
+				? $payment->payment_method()->admin_name()
2175
+				: esc_html__('Unknown', 'event_espresso'),
2176
+			'gateway_response' => $payment->gateway_response(),
2177
+			'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2178
+			'po_number'        => $payment->po_number(),
2179
+			'extra_accntng'    => $payment->extra_accntng(),
2180
+			'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2181
+		];
2182
+	}
2183
+
2184
+
2185
+	/**
2186
+	 * delete_payment
2187
+	 *    delete a payment or refund made towards a transaction
2188
+	 *
2189
+	 * @access public
2190
+	 * @return void
2191
+	 * @throws EE_Error
2192
+	 * @throws InvalidArgumentException
2193
+	 * @throws ReflectionException
2194
+	 * @throws InvalidDataTypeException
2195
+	 * @throws InvalidInterfaceException
2196
+	 */
2197
+	public function delete_payment()
2198
+	{
2199
+		$TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2200
+		// $json_response_data = ['return_data' => false];
2201
+		$PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2202
+		$amount = 0;
2203
+		$can_delete         = EE_Registry::instance()->CAP->current_user_can(
2204
+			'ee_delete_payments',
2205
+			'delete_payment_from_registration_details'
2206
+		);
2207
+		if ($PAY_ID && $can_delete) {
2208
+			$delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2209
+			$payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2210
+			if ($payment instanceof EE_Payment) {
2211
+				$amount = $payment->amount();
2212
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2213
+				/** @type EE_Transaction_Payments $transaction_payments */
2214
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2215
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2216
+					if ($delete_txn_reg_status_change) {
2217
+						$this->_maybe_send_notifications();
2218
+						$this->_process_registration_status_change(
2219
+							$payment->transaction(),
2220
+							$REG_IDs,
2221
+							$delete_txn_reg_status_change
2222
+						);
2223
+					}
2224
+				}
2225
+			} else {
2226
+				EE_Error::add_error(
2227
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2228
+					__FILE__,
2229
+					__FUNCTION__,
2230
+					__LINE__
2231
+				);
2232
+			}
2233
+		} elseif ($can_delete) {
2234
+			EE_Error::add_error(
2235
+				esc_html__(
2236
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2237
+					'event_espresso'
2238
+				),
2239
+				__FILE__,
2240
+				__FUNCTION__,
2241
+				__LINE__
2242
+			);
2243
+		} else {
2244
+			EE_Error::add_error(
2245
+				esc_html__(
2246
+					'You do not have access to delete a payment.',
2247
+					'event_espresso'
2248
+				),
2249
+				__FILE__,
2250
+				__FUNCTION__,
2251
+				__LINE__
2252
+			);
2253
+		}
2254
+		$query_args = [
2255
+			'page'   => 'espresso_transactions',
2256
+			'action' => 'view_transaction',
2257
+			'TXN_ID' => $TXD_ID
2258
+		];
2259
+		$this->_redirect_after_action(
2260
+			! EE_Error::has_error(),
2261
+			$amount > 0
2262
+				? esc_html__('payment', 'event_espresso')
2263
+				: esc_html__('refund', 'event_espresso'),
2264
+			esc_html__('deleted', 'event_espresso'),
2265
+			$query_args
2266
+		);
2267
+	}
2268
+
2269
+
2270
+	/**
2271
+	 * _registration_payment_data_array
2272
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2273
+	 *
2274
+	 * @access protected
2275
+	 * @param array $REG_IDs
2276
+	 * @return array
2277
+	 * @throws EE_Error
2278
+	 * @throws InvalidArgumentException
2279
+	 * @throws InvalidDataTypeException
2280
+	 * @throws InvalidInterfaceException
2281
+	 * @throws ReflectionException
2282
+	 */
2283
+	protected function _registration_payment_data_array($REG_IDs)
2284
+	{
2285
+		$registration_payment_data = [];
2286
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2287
+		if (! empty($REG_IDs)) {
2288
+			$registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2289
+			foreach ($registrations as $registration) {
2290
+				if ($registration instanceof EE_Registration) {
2291
+					$registration_payment_data[ $registration->ID() ] = [
2292
+						'paid'  => $registration->pretty_paid(),
2293
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2294
+					];
2295
+				}
2296
+			}
2297
+		}
2298
+
2299
+		return $registration_payment_data;
2300
+	}
2301
+
2302
+
2303
+	/**
2304
+	 * _maybe_send_notifications
2305
+	 * determines whether or not the admin has indicated that notifications should be sent.
2306
+	 * If so, will toggle a filter switch for delivering registration notices.
2307
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2308
+	 *
2309
+	 * @access protected
2310
+	 * @param EE_Payment | null $payment
2311
+	 */
2312
+	protected function _maybe_send_notifications($payment = null)
2313
+	{
2314
+		switch ($payment instanceof EE_Payment) {
2315
+			// payment notifications
2316
+			case true:
2317
+				if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2318
+					$this->_process_payment_notification($payment);
2319
+				}
2320
+				break;
2321
+			// registration notifications
2322
+			case false:
2323
+				if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2324
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2325
+				}
2326
+				break;
2327
+		}
2328
+	}
2329
+
2330
+
2331
+	/**
2332
+	 * _send_payment_reminder
2333
+	 *    generates HTML for the View Transaction Details Admin page
2334
+	 *
2335
+	 * @access protected
2336
+	 * @return void
2337
+	 * @throws EE_Error
2338
+	 * @throws InvalidArgumentException
2339
+	 * @throws InvalidDataTypeException
2340
+	 * @throws InvalidInterfaceException
2341
+	 */
2342
+	protected function _send_payment_reminder()
2343
+	{
2344
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2345
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2346
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2347
+		$query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2348
+		do_action(
2349
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2350
+			$transaction
2351
+		);
2352
+		$this->_redirect_after_action(
2353
+			false,
2354
+			esc_html__('payment reminder', 'event_espresso'),
2355
+			esc_html__('sent', 'event_espresso'),
2356
+			$query_args,
2357
+			true
2358
+		);
2359
+	}
2360
+
2361
+
2362
+	/**
2363
+	 *  get_transactions
2364
+	 *    get transactions for given parameters (used by list table)
2365
+	 *
2366
+	 * @param int     $per_page how many transactions displayed per page
2367
+	 * @param boolean $count   return the count or objects
2368
+	 * @param string  $view
2369
+	 * @return EE_Transaction[]|int int = count || array of transaction objects
2370
+	 * @throws EE_Error
2371
+	 * @throws InvalidArgumentException
2372
+	 * @throws InvalidDataTypeException
2373
+	 * @throws InvalidInterfaceException
2374
+	 */
2375
+	public function get_transactions($per_page, $count = false, $view = '')
2376
+	{
2377
+		$start_date = wp_strip_all_tags(
2378
+			$this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2379
+		);
2380
+		$end_date = wp_strip_all_tags(
2381
+			$this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2382
+		);
2383
+
2384
+		// make sure our timestamps start and end right at the boundaries for each day
2385
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2386
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2387
+
2388
+
2389
+		// convert to timestamps
2390
+		$start_date = strtotime($start_date);
2391
+		$end_date   = strtotime($end_date);
2392
+
2393
+		// makes sure start date is the lowest value and vice versa
2394
+		$start_date = min($start_date, $end_date);
2395
+		$end_date   = max($start_date, $end_date);
2396
+
2397
+		// convert to correct format for query
2398
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2399
+			'TXN_timestamp',
2400
+			date('Y-m-d H:i:s', $start_date),
2401
+			'Y-m-d H:i:s'
2402
+		);
2403
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2404
+			'TXN_timestamp',
2405
+			date('Y-m-d H:i:s', $end_date),
2406
+			'Y-m-d H:i:s'
2407
+		);
2408
+
2409
+
2410
+		// set orderby
2411
+		$orderby = $this->request->getRequestParam('orderby');
2412
+
2413
+		switch ($orderby) {
2414
+			case 'TXN_ID':
2415
+				break;
2416
+			case 'ATT_fname':
2417
+				$orderby = 'Registration.Attendee.ATT_fname';
2418
+				break;
2419
+			case 'event_name':
2420
+				$orderby = 'Registration.Event.EVT_name';
2421
+				break;
2422
+			default: // 'TXN_timestamp'
2423
+				$orderby = 'TXN_timestamp';
2424
+		}
2425
+
2426
+		$sort         = $this->request->getRequestParam('order', 'DESC');
2427
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
2428
+
2429
+		$per_page = absint($per_page) ? $per_page : 10;
2430
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2431
+
2432
+		$offset = ($current_page - 1) * $per_page;
2433
+		$limit  = [$offset, $per_page];
2434
+
2435
+		$_where = [
2436
+			'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2437
+			'Registration.REG_count' => 1,
2438
+		];
2439
+
2440
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2441
+		if ($EVT_ID) {
2442
+			$_where['Registration.EVT_ID'] = $EVT_ID;
2443
+		}
2444
+
2445
+		$search_term = $this->request->getRequestParam('s');
2446
+		if ($search_term) {
2447
+			$search_term = '%' . $search_term . '%';
2448
+			$_where['OR']  = [
2449
+				'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2450
+				'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2451
+				'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2452
+				'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2453
+				'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2454
+				'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2455
+				'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2456
+				'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2457
+				'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2458
+				'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2459
+				'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2460
+				'Registration.REG_final_price'        => ['LIKE', $search_term],
2461
+				'Registration.REG_code'               => ['LIKE', $search_term],
2462
+				'Registration.REG_count'              => ['LIKE', $search_term],
2463
+				'Registration.REG_group_size'         => ['LIKE', $search_term],
2464
+				'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2465
+				'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2466
+				'Payment.PAY_source'                  => ['LIKE', $search_term],
2467
+				'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2468
+				'TXN_session_data'                    => ['LIKE', $search_term],
2469
+				'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2470
+			];
2471
+		}
2472
+
2473
+		$status = $this->request->getRequestParam('status');
2474
+		// failed transactions
2475
+		$failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2476
+		$abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2477
+		$incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2478
+
2479
+		if ($failed) {
2480
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2481
+		} elseif ($abandoned) {
2482
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2483
+		} elseif ($incomplete) {
2484
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2485
+		} else {
2486
+			$_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2487
+			$_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2488
+		}
2489
+
2490
+		$query_params = apply_filters(
2491
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2492
+			[
2493
+				$_where,
2494
+				'order_by'                 => [$orderby => $sort],
2495
+				'limit'                    => $limit,
2496
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2497
+			],
2498
+			$this->request->requestParams(),
2499
+			$view,
2500
+			$count
2501
+		);
2502
+
2503
+		return $count
2504
+			? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2505
+			: EEM_Transaction::instance()->get_all($query_params);
2506
+	}
2507
+
2508
+
2509
+	/**
2510
+	 * @throws EE_Error
2511
+	 * @throws InvalidArgumentException
2512
+	 * @throws InvalidDataTypeException
2513
+	 * @throws InvalidInterfaceException
2514
+	 * @throws ReflectionException
2515
+	 * @throws RuntimeException
2516
+	 * @since 4.9.79.p
2517
+	 */
2518
+	public function recalculateLineItems()
2519
+	{
2520
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2521
+		/** @var EE_Transaction $transaction */
2522
+		$transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2523
+		$success         = $transaction->recalculateLineItems();
2524
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2525
+		$query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2526
+		$this->_redirect_after_action(
2527
+			$success,
2528
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2529
+			esc_html__('recalculated', 'event_espresso'),
2530
+			$query_args,
2531
+			true
2532
+		);
2533
+	}
2534 2534
 }
Please login to merge, or discard this patch.
Spacing   +101 added lines, -101 removed lines patch added patch discarded remove patch
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
             'An error occurred! Your request may have been processed, but a valid response from the server was not received. Please refresh the page and try again.',
244 244
             'event_espresso'
245 245
         );
246
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
246
+        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
247 247
             'An error occurred! Please refresh the page and try again.',
248 248
             'event_espresso'
249 249
         );
@@ -342,7 +342,7 @@  discard block
 block discarded – undo
342 342
         // enqueue style
343 343
         wp_register_style(
344 344
             'espresso_txn',
345
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
345
+            TXN_ASSETS_URL.'espresso_transactions_admin.css',
346 346
             [],
347 347
             EVENT_ESPRESSO_VERSION
348 348
         );
@@ -350,7 +350,7 @@  discard block
 block discarded – undo
350 350
         // scripts
351 351
         wp_register_script(
352 352
             'espresso_txn',
353
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
353
+            TXN_ASSETS_URL.'espresso_transactions_admin.js',
354 354
             [
355 355
                 'ee_admin_js',
356 356
                 'ee-datepicker',
@@ -477,7 +477,7 @@  discard block
 block discarded – undo
477 477
             $this->_transaction->verify_abandoned_transaction_status();
478 478
         }
479 479
 
480
-        if (! $this->_transaction instanceof EE_Transaction) {
480
+        if ( ! $this->_transaction instanceof EE_Transaction) {
481 481
             $error_msg = sprintf(
482 482
                 esc_html__(
483 483
                     'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
@@ -574,7 +574,7 @@  discard block
 block discarded – undo
574 574
             'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
575 575
             [
576 576
                 'overpaid'   => [
577
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
577
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::overpaid_status_code,
578 578
                     'desc'  => EEH_Template::pretty_status(
579 579
                         EEM_Transaction::overpaid_status_code,
580 580
                         false,
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
                     ),
583 583
                 ],
584 584
                 'complete'   => [
585
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
585
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::complete_status_code,
586 586
                     'desc'  => EEH_Template::pretty_status(
587 587
                         EEM_Transaction::complete_status_code,
588 588
                         false,
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
                     ),
591 591
                 ],
592 592
                 'incomplete' => [
593
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
593
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::incomplete_status_code,
594 594
                     'desc'  => EEH_Template::pretty_status(
595 595
                         EEM_Transaction::incomplete_status_code,
596 596
                         false,
@@ -598,7 +598,7 @@  discard block
 block discarded – undo
598 598
                     ),
599 599
                 ],
600 600
                 'abandoned'  => [
601
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
601
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::abandoned_status_code,
602 602
                     'desc'  => EEH_Template::pretty_status(
603 603
                         EEM_Transaction::abandoned_status_code,
604 604
                         false,
@@ -606,7 +606,7 @@  discard block
 block discarded – undo
606 606
                     ),
607 607
                 ],
608 608
                 'failed'     => [
609
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
609
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::failed_status_code,
610 610
                     'desc'  => EEH_Template::pretty_status(
611 611
                         EEM_Transaction::failed_status_code,
612 612
                         false,
@@ -649,11 +649,11 @@  discard block
 block discarded – undo
649 649
                 )
650 650
                 . '" aria-label="'
651 651
                 . esc_attr__('Click to Edit event', 'event_espresso')
652
-                . '">' . $event->name() . '</a>',
652
+                . '">'.$event->name().'</a>',
653 653
                 '</h3>'
654 654
             )
655 655
             : '';
656
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
656
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
657 657
         $this->display_admin_list_table_page_with_no_sidebar();
658 658
     }
659 659
 
@@ -683,7 +683,7 @@  discard block
 block discarded – undo
683 683
 
684 684
         $this->_set_transaction_object();
685 685
 
686
-        if (! $this->_transaction instanceof EE_Transaction) {
686
+        if ( ! $this->_transaction instanceof EE_Transaction) {
687 687
             return;
688 688
         }
689 689
 
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
         $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
694 694
         $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
695 695
 
696
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
696
+        $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->status_ID()];
697 697
         $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
698 698
         $this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
699 699
 
@@ -737,7 +737,7 @@  discard block
 block discarded – undo
737 737
 
738 738
 
739 739
         // next link
740
-        $next_txn                                 = $this->_transaction->next(
740
+        $next_txn = $this->_transaction->next(
741 741
             null,
742 742
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
743 743
             'TXN_ID'
@@ -752,7 +752,7 @@  discard block
 block discarded – undo
752 752
             )
753 753
             : '';
754 754
         // previous link
755
-        $previous_txn                                 = $this->_transaction->previous(
755
+        $previous_txn = $this->_transaction->previous(
756 756
             null,
757 757
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
758 758
             'TXN_ID'
@@ -804,7 +804,7 @@  discard block
 block discarded – undo
804 804
         // grab messages at the last second
805 805
         $this->_template_args['notices'] = EE_Error::get_notices();
806 806
         // path to template
807
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
807
+        $template_path                             = TXN_TEMPLATE_PATH.'txn_admin_details_header.template.php';
808 808
         $this->_template_args['admin_page_header'] = EEH_Template::display_template(
809 809
             $template_path,
810 810
             $this->_template_args,
@@ -833,19 +833,19 @@  discard block
 block discarded – undo
833 833
 
834 834
         $this->_set_transaction_object();
835 835
 
836
-        if (! $this->_transaction instanceof EE_Transaction) {
836
+        if ( ! $this->_transaction instanceof EE_Transaction) {
837 837
             return;
838 838
         }
839 839
         $this->addMetaBox(
840 840
             'edit-txn-details-mbox',
841
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
841
+            '<span>'.esc_html__('Transaction Details', 'event_espresso')
842 842
             . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
843 843
             [$this, 'txn_details_meta_box'],
844 844
             $this->_wp_page_slug
845 845
         );
846 846
         $this->addMetaBox(
847 847
             'edit-txn-attendees-mbox',
848
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
848
+            '<span>'.esc_html__('Attendees Registered in this Transaction', 'event_espresso')
849 849
             . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
850 850
             [$this, 'txn_attendees_meta_box'],
851 851
             $this->_wp_page_slug,
@@ -887,7 +887,7 @@  discard block
 block discarded – undo
887 887
     {
888 888
         $content = '';
889 889
         $actions = [];
890
-        if (! $transaction instanceof EE_Transaction) {
890
+        if ( ! $transaction instanceof EE_Transaction) {
891 891
             return $content;
892 892
         }
893 893
         /** @var EE_Registration $primary_registration */
@@ -998,7 +998,7 @@  discard block
 block discarded – undo
998 998
             $this->_transaction->primary_registration() instanceof EE_Registration
999 999
                 ? $this->_transaction->primary_registration()->attendee()
1000 1000
                 : null;
1001
-        $this->_template_args['can_edit_payments']   = EE_Registry::instance()->CAP->current_user_can(
1001
+        $this->_template_args['can_edit_payments'] = EE_Registry::instance()->CAP->current_user_can(
1002 1002
             'ee_edit_payments',
1003 1003
             'apply_payment_or_refund_from_registration_details'
1004 1004
         );
@@ -1009,7 +1009,7 @@  discard block
 block discarded – undo
1009 1009
 
1010 1010
         // get line table
1011 1011
         EEH_Autoloader::register_line_item_display_autoloaders();
1012
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1012
+        $Line_Item_Display = new EE_Line_Item_Display(
1013 1013
             'admin_table',
1014 1014
             'EE_Admin_Table_Line_Item_Display_Strategy'
1015 1015
         );
@@ -1024,7 +1024,7 @@  discard block
 block discarded – undo
1024 1024
         $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1025 1025
         $this->_template_args['taxes'] = ! empty($taxes) ? $taxes : false;
1026 1026
 
1027
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1027
+        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1028 1028
             $this->_transaction->total(),
1029 1029
             false,
1030 1030
             false
@@ -1034,7 +1034,7 @@  discard block
 block discarded – undo
1034 1034
 
1035 1035
         // process payment details
1036 1036
         $payments = $this->_transaction->payments();
1037
-        if (! empty($payments)) {
1037
+        if ( ! empty($payments)) {
1038 1038
             $this->_template_args['payments']              = $payments;
1039 1039
             $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1040 1040
         } else {
@@ -1092,7 +1092,7 @@  discard block
 block discarded – undo
1092 1092
                                   esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1093 1093
                                   ucwords(str_replace('_', ' ', $reg_step)),
1094 1094
                                   date(
1095
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1095
+                                      get_option('date_format').' '.get_option('time_format'),
1096 1096
                                       $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1097 1097
                                   )
1098 1098
                               )
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
                               . '</div>';
1107 1107
             }
1108 1108
         }
1109
-        $reg_steps                                                 .= '</ul>';
1109
+        $reg_steps .= '</ul>';
1110 1110
         $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1111 1111
         $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1112 1112
             'Registration Step Progress',
@@ -1119,14 +1119,14 @@  discard block
 block discarded – undo
1119 1119
         $this->_get_payment_status_array();
1120 1120
         $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1121 1121
 
1122
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1122
+        $this->_template_args['transaction_form_url'] = add_query_arg(
1123 1123
             [
1124 1124
                 'action'  => 'edit_transaction',
1125 1125
                 'process' => 'transaction',
1126 1126
             ],
1127 1127
             TXN_ADMIN_URL
1128 1128
         );
1129
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1129
+        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1130 1130
             [
1131 1131
                 'page'   => 'espresso_transactions',
1132 1132
                 'action' => 'espresso_apply_payment',
@@ -1145,7 +1145,7 @@  discard block
 block discarded – undo
1145 1145
 
1146 1146
         // 'espresso_delete_payment_nonce'
1147 1147
 
1148
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1148
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_txn_details.template.php';
1149 1149
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1150 1150
     }
1151 1151
 
@@ -1177,19 +1177,19 @@  discard block
 block discarded – undo
1177 1177
                 ],
1178 1178
             ]
1179 1179
         );
1180
-        if (! empty($reg_payments)) {
1180
+        if ( ! empty($reg_payments)) {
1181 1181
             foreach ($payments as $payment) {
1182
-                if (! $payment instanceof EE_Payment) {
1182
+                if ( ! $payment instanceof EE_Payment) {
1183 1183
                     continue;
1184
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1185
-                    $existing_reg_payments[ $payment->ID() ] = [];
1184
+                } elseif ( ! isset($existing_reg_payments[$payment->ID()])) {
1185
+                    $existing_reg_payments[$payment->ID()] = [];
1186 1186
                 }
1187 1187
                 foreach ($reg_payments as $reg_payment) {
1188 1188
                     if (
1189 1189
                         $reg_payment instanceof EE_Registration_Payment
1190 1190
                         && $reg_payment->payment_ID() === $payment->ID()
1191 1191
                     ) {
1192
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1192
+                        $existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
1193 1193
                     }
1194 1194
                 }
1195 1195
             }
@@ -1215,7 +1215,7 @@  discard block
 block discarded – undo
1215 1215
     protected function _get_registrations_to_apply_payment_to()
1216 1216
     {
1217 1217
         // we want any registration with an active status (ie: not deleted or cancelled)
1218
-        $query_params                      = [
1218
+        $query_params = [
1219 1219
             [
1220 1220
                 'STS_ID' => [
1221 1221
                     'IN',
@@ -1227,22 +1227,22 @@  discard block
 block discarded – undo
1227 1227
                 ],
1228 1228
             ],
1229 1229
         ];
1230
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1230
+        $registrations_to_apply_payment_to = EEH_HTML::br().EEH_HTML::div(
1231 1231
             '',
1232 1232
             'txn-admin-apply-payment-to-registrations-dv',
1233 1233
             '',
1234 1234
             'clear: both; margin: 1.5em 0 0; display: none;'
1235 1235
         );
1236
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1236
+        $registrations_to_apply_payment_to .= EEH_HTML::br().EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1237 1237
         $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1238 1238
         $registrations_to_apply_payment_to .= EEH_HTML::thead(
1239 1239
             EEH_HTML::tr(
1240
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1241
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1242
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1243
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1244
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1245
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1240
+                EEH_HTML::th(esc_html__('ID', 'event_espresso')).
1241
+                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')).
1242
+                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')).
1243
+                EEH_HTML::th(esc_html__('Event', 'event_espresso')).
1244
+                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr').
1245
+                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr').
1246 1246
                 EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1247 1247
             )
1248 1248
         );
@@ -1257,34 +1257,34 @@  discard block
 block discarded – undo
1257 1257
                     : esc_html__('Unknown Attendee', 'event_espresso');
1258 1258
                 $owing                             = $registration->final_price() - $registration->paid();
1259 1259
                 $taxable                           = $registration->ticket()->taxable()
1260
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1260
+                    ? ' <span class="smaller-text lt-grey-text"> '.esc_html__('+ tax', 'event_espresso').'</span>'
1261 1261
                     : '';
1262 1262
                 $checked                           = empty($existing_reg_payments)
1263 1263
                                                      || in_array($registration->ID(), $existing_reg_payments, true)
1264 1264
                     ? ' checked'
1265 1265
                     : '';
1266
-                $disabled                          = $registration->final_price() > 0 ? '' : ' disabled';
1266
+                $disabled = $registration->final_price() > 0 ? '' : ' disabled';
1267 1267
                 $registrations_to_apply_payment_to .= EEH_HTML::tr(
1268
-                    EEH_HTML::td($registration->ID()) .
1269
-                    EEH_HTML::td($attendee_name) .
1268
+                    EEH_HTML::td($registration->ID()).
1269
+                    EEH_HTML::td($attendee_name).
1270 1270
                     EEH_HTML::td(
1271
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1272
-                    ) .
1273
-                    EEH_HTML::td($registration->event_name()) .
1274
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1271
+                        $registration->ticket()->name().' : '.$registration->ticket()->pretty_price().$taxable
1272
+                    ).
1273
+                    EEH_HTML::td($registration->event_name()).
1274
+                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr').
1275 1275
                     EEH_HTML::td(
1276 1276
                         EEH_Template::format_currency($owing),
1277 1277
                         '',
1278 1278
                         'txn-admin-payment-owing-td jst-cntr'
1279
-                    ) .
1279
+                    ).
1280 1280
                     EEH_HTML::td(
1281
-                        '<input type="checkbox" value="' . $registration->ID()
1281
+                        '<input type="checkbox" value="'.$registration->ID()
1282 1282
                         . '" name="txn_admin_payment[registrations]"'
1283
-                        . $checked . $disabled . '>',
1283
+                        . $checked.$disabled.'>',
1284 1284
                         '',
1285 1285
                         'jst-cntr'
1286 1286
                     ),
1287
-                    'apply-payment-registration-row-' . $registration->ID()
1287
+                    'apply-payment-registration-row-'.$registration->ID()
1288 1288
                 );
1289 1289
             }
1290 1290
         }
@@ -1299,7 +1299,7 @@  discard block
 block discarded – undo
1299 1299
             '',
1300 1300
             'clear description'
1301 1301
         );
1302
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1302
+        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1303 1303
         $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1304 1304
     }
1305 1305
 
@@ -1365,12 +1365,12 @@  discard block
 block discarded – undo
1365 1365
                 [
1366 1366
                     'OR*payment_method_for_payment' => [
1367 1367
                         'PMD_ID'    => ['IN', $payment_methods_of_payments],
1368
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1368
+                        'PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%'],
1369 1369
                     ],
1370 1370
                 ],
1371 1371
             ];
1372 1372
         } else {
1373
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1373
+            $query_args = [['PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%']]];
1374 1374
         }
1375 1375
         $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1376 1376
     }
@@ -1403,7 +1403,7 @@  discard block
 block discarded – undo
1403 1403
             'Line_Item',
1404 1404
             [['LIN_type' => 'line-item']]
1405 1405
         );
1406
-        if (! empty($line_items)) {
1406
+        if ( ! empty($line_items)) {
1407 1407
             foreach ($line_items as $item) {
1408 1408
                 if ($item instanceof EE_Line_Item) {
1409 1409
                     switch ($item->OBJ_type()) {
@@ -1413,7 +1413,7 @@  discard block
 block discarded – undo
1413 1413
                             $ticket = $item->ticket();
1414 1414
                             // right now we're only handling tickets here.
1415 1415
                             // Cause its expected that only tickets will have attendees right?
1416
-                            if (! $ticket instanceof EE_Ticket) {
1416
+                            if ( ! $ticket instanceof EE_Ticket) {
1417 1417
                                 break;
1418 1418
                             }
1419 1419
                             try {
@@ -1422,45 +1422,45 @@  discard block
 block discarded – undo
1422 1422
                                 EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1423 1423
                                 $event_name = esc_html__('Unknown Event', 'event_espresso');
1424 1424
                             }
1425
-                            $event_name   .= ' - ' . $item->name();
1425
+                            $event_name   .= ' - '.$item->name();
1426 1426
                             $ticket_price = EEH_Template::format_currency($item->unit_price());
1427 1427
                             // now get all of the registrations for this transaction that use this ticket
1428 1428
                             $registrations = $ticket->registrations(
1429 1429
                                 [['TXN_ID' => $this->_transaction->ID()]]
1430 1430
                             );
1431 1431
                             foreach ($registrations as $registration) {
1432
-                                if (! $registration instanceof EE_Registration) {
1432
+                                if ( ! $registration instanceof EE_Registration) {
1433 1433
                                     break;
1434 1434
                                 }
1435
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1435
+                                $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']
1436 1436
                                     = $registration->status_ID();
1437
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1437
+                                $this->_template_args['event_attendees'][$registration->ID()]['att_num']
1438 1438
                                     = $registration->count();
1439
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1439
+                                $this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name']
1440 1440
                                     = $event_name;
1441
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1441
+                                $this->_template_args['event_attendees'][$registration->ID()]['ticket_price']
1442 1442
                                     = $ticket_price;
1443 1443
                                 // attendee info
1444 1444
                                 $attendee = $registration->get_first_related('Attendee');
1445 1445
                                 if ($attendee instanceof EE_Attendee) {
1446
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1446
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']
1447 1447
                                         = $attendee->ID();
1448
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1448
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee']
1449 1449
                                         = $attendee->full_name();
1450
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1451
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1450
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']
1451
+                                        = '<a href="mailto:'.$attendee->email().'?subject='.$event_name
1452 1452
                                           . esc_html__(
1453 1453
                                               ' Event',
1454 1454
                                               'event_espresso'
1455 1455
                                           )
1456
-                                          . '">' . $attendee->email() . '</a>';
1457
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1456
+                                          . '">'.$attendee->email().'</a>';
1457
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']
1458 1458
                                         = EEH_Address::format($attendee, 'inline', false, false);
1459 1459
                                 } else {
1460
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1461
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1462
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1463
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1460
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1461
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1462
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1463
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1464 1464
                                 }
1465 1465
                             }
1466 1466
                             break;
@@ -1476,7 +1476,7 @@  discard block
 block discarded – undo
1476 1476
                 TXN_ADMIN_URL
1477 1477
             );
1478 1478
             echo EEH_Template::display_template(
1479
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1479
+                TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_attendees.template.php',
1480 1480
                 $this->_template_args,
1481 1481
                 true
1482 1482
             );
@@ -1511,7 +1511,7 @@  discard block
 block discarded – undo
1511 1511
         $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1512 1512
             ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1513 1513
             : null;
1514
-        if (! $primary_att instanceof EE_Attendee) {
1514
+        if ( ! $primary_att instanceof EE_Attendee) {
1515 1515
             $this->_template_args['no_attendee_message'] = esc_html__(
1516 1516
                 'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1517 1517
                 'event_espresso'
@@ -1537,7 +1537,7 @@  discard block
 block discarded – undo
1537 1537
             : '';
1538 1538
         $this->_template_args['formatted_address'] = $formatted_address;
1539 1539
         echo EEH_Template::display_template(
1540
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1540
+            TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_registrant.template.php',
1541 1541
             $this->_template_args,
1542 1542
             true
1543 1543
         );
@@ -1563,7 +1563,7 @@  discard block
 block discarded – undo
1563 1563
             TXN_ADMIN_URL
1564 1564
         );
1565 1565
 
1566
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1566
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_billing_info.template.php';
1567 1567
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1568 1568
     }
1569 1569
 
@@ -1590,7 +1590,7 @@  discard block
 block discarded – undo
1590 1590
         );
1591 1591
         $TXD_ID = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1592 1592
         $amount = 0;
1593
-        if (! empty($valid_data) && $has_access) {
1593
+        if ( ! empty($valid_data) && $has_access) {
1594 1594
             $PAY_ID = $valid_data['PAY_ID'];
1595 1595
             // save  the new payment
1596 1596
             $payment = $this->_create_payment_from_request_data($valid_data);
@@ -1604,7 +1604,7 @@  discard block
 block discarded – undo
1604 1604
                 $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1605 1605
                 $this->_remove_existing_registration_payments($payment, $PAY_ID);
1606 1606
                 // apply payment to registrations (if applicable)
1607
-                if (! empty($REG_IDs)) {
1607
+                if ( ! empty($REG_IDs)) {
1608 1608
                     $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1609 1609
                     $this->_maybe_send_notifications();
1610 1610
                     // now process status changes for the same registrations
@@ -1677,14 +1677,14 @@  discard block
 block discarded – undo
1677 1677
      */
1678 1678
     protected function _validate_payment_request_data()
1679 1679
     {
1680
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1680
+        if ( ! $this->request->requestParamIsSet('txn_admin_payment')) {
1681 1681
             return [];
1682 1682
         }
1683 1683
         $payment_form = $this->_generate_payment_form_section();
1684 1684
         try {
1685 1685
             if ($payment_form->was_submitted()) {
1686 1686
                 $payment_form->receive_form_submission();
1687
-                if (! $payment_form->is_valid()) {
1687
+                if ( ! $payment_form->is_valid()) {
1688 1688
                     $submission_error_messages = [];
1689 1689
                     foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1690 1690
                         if ($validation_error instanceof EE_Validation_Error) {
@@ -1866,7 +1866,7 @@  discard block
 block discarded – undo
1866 1866
             ['Y-m-d', 'g:i a']
1867 1867
         );
1868 1868
 
1869
-        if (! $payment->save()) {
1869
+        if ( ! $payment->save()) {
1870 1870
             EE_Error::add_error(
1871 1871
                 sprintf(
1872 1872
                     esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
@@ -2079,12 +2079,12 @@  discard block
 block discarded – undo
2079 2079
         // but add in some conditions regarding payment,
2080 2080
         // so that we don't apply payments to registrations that are free or have already been paid for
2081 2081
         // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2082
-        if (! $payment->is_a_refund()) {
2082
+        if ( ! $payment->is_a_refund()) {
2083 2083
             $registration_query_where_params['REG_final_price']  = ['!=', 0];
2084 2084
             $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2085 2085
         }
2086 2086
         $registrations = $transaction->registrations([$registration_query_where_params]);
2087
-        if (! empty($registrations)) {
2087
+        if ( ! empty($registrations)) {
2088 2088
             /** @type EE_Payment_Processor $payment_processor */
2089 2089
             $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2090 2090
             $payment_processor->process_registration_payments($transaction, $payment, $registrations);
@@ -2166,7 +2166,7 @@  discard block
 block discarded – undo
2166 2166
             'pay_status'       => $payment->STS_ID(),
2167 2167
             'PAY_ID'           => $payment->ID(),
2168 2168
             'STS_ID'           => $payment->STS_ID(),
2169
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2169
+            'status'           => self::$_pay_status[$payment->STS_ID()],
2170 2170
             'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2171 2171
             'method'           => strtoupper($payment->source()),
2172 2172
             'PM_ID'            => $payment->payment_method() ? $payment->payment_method()->ID() : 1,
@@ -2200,7 +2200,7 @@  discard block
 block discarded – undo
2200 2200
         // $json_response_data = ['return_data' => false];
2201 2201
         $PAY_ID = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2202 2202
         $amount = 0;
2203
-        $can_delete         = EE_Registry::instance()->CAP->current_user_can(
2203
+        $can_delete = EE_Registry::instance()->CAP->current_user_can(
2204 2204
             'ee_delete_payments',
2205 2205
             'delete_payment_from_registration_details'
2206 2206
         );
@@ -2284,11 +2284,11 @@  discard block
 block discarded – undo
2284 2284
     {
2285 2285
         $registration_payment_data = [];
2286 2286
         // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2287
-        if (! empty($REG_IDs)) {
2287
+        if ( ! empty($REG_IDs)) {
2288 2288
             $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2289 2289
             foreach ($registrations as $registration) {
2290 2290
                 if ($registration instanceof EE_Registration) {
2291
-                    $registration_payment_data[ $registration->ID() ] = [
2291
+                    $registration_payment_data[$registration->ID()] = [
2292 2292
                         'paid'  => $registration->pretty_paid(),
2293 2293
                         'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2294 2294
                     ];
@@ -2344,7 +2344,7 @@  discard block
 block discarded – undo
2344 2344
         $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2345 2345
         $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2346 2346
         $redirect_to = $this->request->getRequestParam('redirect_to');
2347
-        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2347
+        $query_args  = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2348 2348
         do_action(
2349 2349
             'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2350 2350
             $transaction
@@ -2382,8 +2382,8 @@  discard block
 block discarded – undo
2382 2382
         );
2383 2383
 
2384 2384
         // make sure our timestamps start and end right at the boundaries for each day
2385
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2386
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2385
+        $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
2386
+        $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
2387 2387
 
2388 2388
 
2389 2389
         // convert to timestamps
@@ -2400,7 +2400,7 @@  discard block
 block discarded – undo
2400 2400
             date('Y-m-d H:i:s', $start_date),
2401 2401
             'Y-m-d H:i:s'
2402 2402
         );
2403
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2403
+        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2404 2404
             'TXN_timestamp',
2405 2405
             date('Y-m-d H:i:s', $end_date),
2406 2406
             'Y-m-d H:i:s'
@@ -2444,8 +2444,8 @@  discard block
 block discarded – undo
2444 2444
 
2445 2445
         $search_term = $this->request->getRequestParam('s');
2446 2446
         if ($search_term) {
2447
-            $search_term = '%' . $search_term . '%';
2448
-            $_where['OR']  = [
2447
+            $search_term = '%'.$search_term.'%';
2448
+            $_where['OR'] = [
2449 2449
                 'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2450 2450
                 'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2451 2451
                 'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
@@ -2472,9 +2472,9 @@  discard block
 block discarded – undo
2472 2472
 
2473 2473
         $status = $this->request->getRequestParam('status');
2474 2474
         // failed transactions
2475
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2476
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2477
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2475
+        $failed     = ( ! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2476
+        $abandoned  = ( ! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2477
+        $incomplete = ( ! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2478 2478
 
2479 2479
         if ($failed) {
2480 2480
             $_where['STS_ID'] = EEM_Transaction::failed_status_code;
@@ -2522,7 +2522,7 @@  discard block
 block discarded – undo
2522 2522
         $transaction     = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2523 2523
         $success         = $transaction->recalculateLineItems();
2524 2524
         $redirect_to = $this->request->getRequestParam('redirect_to');
2525
-        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,] : [];
2525
+        $query_args = $redirect_to ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ] : [];
2526 2526
         $this->_redirect_after_action(
2527 2527
             $success,
2528 2528
             esc_html__('Transaction taxes and totals', 'event_espresso'),
Please login to merge, or discard this patch.
admin_pages/about/templates/credits.template.php 2 patches
Indentation   +89 added lines, -89 removed lines patch added patch discarded remove patch
@@ -3,67 +3,67 @@  discard block
 block discarded – undo
3 3
 use EventEspresso\core\services\request\sanitizers\AllowedTags;
4 4
 
5 5
 $tEEm_members = [
6
-    __('Founders', 'event_espresso') => [
7
-        'garth-koyle' => [
8
-            'email' => '[email protected]',
9
-            'name'  => 'Garth Koyle',
10
-            'desc'  => __('Co-Founder', 'event_espresso'),
11
-        ],
12
-    ],
13
-    __('Core Developers', 'event_espresso') => [
14
-        'brent-christensen' => [
15
-            'email' => '[email protected]',
16
-            'name'  => 'Brent Christensen',
17
-            'desc'  => __('Lead Developer', 'event_espresso'),
18
-        ],
19
-        'nazar-kolivoshka' => [
20
-            'email' => '[email protected]',
21
-            'name'  => 'Nazar Kolivoshka',
22
-            'desc'  => __('Core Developer', 'event_espresso'),
23
-        ],
24
-        'hossein-rafiei' => [
25
-            'email' => '[email protected]',
26
-            'name'  => 'Hossein Rafiei',
27
-            'desc'  => __('Core Developer', 'event_espresso'),
28
-        ],
29
-        'majid-abbasi' => [
30
-            'email' => '[email protected]',
31
-            'name'  => 'Majid Abbasi',
32
-            'desc'  => __('Core Developer', 'event_espresso'),
33
-        ],
34
-    ],
35
-    __('Support Staff', 'event_espresso') => [
36
-        'tony-warwick' => [
37
-            'email' => '[email protected]',
38
-            'name'  => 'Tony Warwick',
39
-            'desc'  => __('Support', 'event_espresso'),
40
-        ],
41
-        'lorenzo-caum' => [
42
-            'email' => '[email protected]',
43
-            'name'  => 'Lorenzo Caum',
44
-            'desc'  => __('Sales & Support', 'event_espresso'),
45
-        ],
46
-        'janice-gutierrez' => [
47
-            'email' => '[email protected]',
48
-            'name'  => 'Janice Gutierrez',
49
-            'desc'  => __('Support', 'event_espresso'),
50
-        ],
51
-        'chinny-love-verana' => [
52
-            'email' => '[email protected]',
53
-            'name'  => 'Chinny Love Verana',
54
-            'desc'  => __('Sales & Support', 'event_espresso'),
55
-        ],
56
-        'sam' => [
57
-            'email' => '[email protected]',
58
-            'name'  => 'Sam',
59
-            'desc'  => __('Sales & Support', 'event_espresso'),
60
-        ],
61
-    ],
6
+	__('Founders', 'event_espresso') => [
7
+		'garth-koyle' => [
8
+			'email' => '[email protected]',
9
+			'name'  => 'Garth Koyle',
10
+			'desc'  => __('Co-Founder', 'event_espresso'),
11
+		],
12
+	],
13
+	__('Core Developers', 'event_espresso') => [
14
+		'brent-christensen' => [
15
+			'email' => '[email protected]',
16
+			'name'  => 'Brent Christensen',
17
+			'desc'  => __('Lead Developer', 'event_espresso'),
18
+		],
19
+		'nazar-kolivoshka' => [
20
+			'email' => '[email protected]',
21
+			'name'  => 'Nazar Kolivoshka',
22
+			'desc'  => __('Core Developer', 'event_espresso'),
23
+		],
24
+		'hossein-rafiei' => [
25
+			'email' => '[email protected]',
26
+			'name'  => 'Hossein Rafiei',
27
+			'desc'  => __('Core Developer', 'event_espresso'),
28
+		],
29
+		'majid-abbasi' => [
30
+			'email' => '[email protected]',
31
+			'name'  => 'Majid Abbasi',
32
+			'desc'  => __('Core Developer', 'event_espresso'),
33
+		],
34
+	],
35
+	__('Support Staff', 'event_espresso') => [
36
+		'tony-warwick' => [
37
+			'email' => '[email protected]',
38
+			'name'  => 'Tony Warwick',
39
+			'desc'  => __('Support', 'event_espresso'),
40
+		],
41
+		'lorenzo-caum' => [
42
+			'email' => '[email protected]',
43
+			'name'  => 'Lorenzo Caum',
44
+			'desc'  => __('Sales & Support', 'event_espresso'),
45
+		],
46
+		'janice-gutierrez' => [
47
+			'email' => '[email protected]',
48
+			'name'  => 'Janice Gutierrez',
49
+			'desc'  => __('Support', 'event_espresso'),
50
+		],
51
+		'chinny-love-verana' => [
52
+			'email' => '[email protected]',
53
+			'name'  => 'Chinny Love Verana',
54
+			'desc'  => __('Sales & Support', 'event_espresso'),
55
+		],
56
+		'sam' => [
57
+			'email' => '[email protected]',
58
+			'name'  => 'Sam',
59
+			'desc'  => __('Sales & Support', 'event_espresso'),
60
+		],
61
+	],
62 62
 ];
63 63
 
64 64
 function espressoPerson(string $id, string $email, string $name, string $desc): string
65 65
 {
66
-    return '
66
+	return '
67 67
     <li class="ee-card ee-credits-person" id="ee-person-' . $id . '">
68 68
         <a href="' . esp_gravatar_profile($email) . '" target="_blank">
69 69
             ' . esp_gravatar_image($email, $name) . '
@@ -77,15 +77,15 @@  discard block
 block discarded – undo
77 77
 
78 78
 function esp_gravatar_profile(string $email): string
79 79
 {
80
-    return esc_url_raw('https://www.gravatar.com/' . md5($email));
80
+	return esc_url_raw('https://www.gravatar.com/' . md5($email));
81 81
 }
82 82
 
83 83
 function esp_gravatar_image(string $email, string $name): string
84 84
 {
85
-    $email = md5($email);
86
-    $name  = esc_attr($name);
87
-    $url   = esc_url_raw("https://0.gravatar.com/avatar/{$email}?s=60");
88
-    return "<img src='{$url}' class='gravatar' alt='{$name}'/>";
85
+	$email = md5($email);
86
+	$name  = esc_attr($name);
87
+	$url   = esc_url_raw("https://0.gravatar.com/avatar/{$email}?s=60");
88
+	return "<img src='{$url}' class='gravatar' alt='{$name}'/>";
89 89
 }
90 90
 
91 91
 
@@ -102,9 +102,9 @@  discard block
 block discarded – undo
102 102
 
103 103
         <h4>
104 104
             <?php esc_html_e(
105
-                'Event Espresso is created by an international team of passionate individuals with a drive to empower your events!',
106
-                'event_espresso'
107
-            ); ?>
105
+				'Event Espresso is created by an international team of passionate individuals with a drive to empower your events!',
106
+				'event_espresso'
107
+			); ?>
108 108
         </h4>
109 109
 
110 110
         <div class='ee-credits-tEEm'>
@@ -112,12 +112,12 @@  discard block
 block discarded – undo
112 112
             <h3 class="wp-people-group"><?php echo esc_html($tEEm); ?></h3>
113 113
             <ul class="ee-card-grid ee-card-grid-4-cols" id="' . sanitize_key($tEEm) . '">
114 114
                 <?php foreach ($members as $id => $person) {
115
-                    echo wp_kses(
116
-                        espressoPerson($id, $person['email'], $person['name'], $person['desc']),
117
-                        AllowedTags::getAllowedTags()
118
-                    );
119
-                }
120
-                ?>
115
+					echo wp_kses(
116
+						espressoPerson($id, $person['email'], $person['name'], $person['desc']),
117
+						AllowedTags::getAllowedTags()
118
+					);
119
+				}
120
+				?>
121 121
             </ul>
122 122
             <?php } ?>
123 123
         </div>
@@ -125,15 +125,15 @@  discard block
 block discarded – undo
125 125
         <h3 class="wp-people-group"><?php esc_html_e('Contributor Recognition', 'event_espresso'); ?></h3>
126 126
         <p class="description">
127 127
             <?php
128
-            printf(
129
-                esc_html__(
130
-                    'For every major release we want to recognize the people who contributed to the release via a GitHub pull request. Want to see your name listed here? %sWhen you submit a pull request that gets included in a major release%s, we\'ll add your name here linked to your GitHub profile.',
131
-                    'event_espresso'
132
-                ),
133
-                '<a href="https://github.com/eventespresso/event-espresso-core" aria-label="Contribute to Event Espresso by making a pull request via GitHub" target="_blank">',
134
-                '</a>'
135
-            );
136
-            ?>
128
+			printf(
129
+				esc_html__(
130
+					'For every major release we want to recognize the people who contributed to the release via a GitHub pull request. Want to see your name listed here? %sWhen you submit a pull request that gets included in a major release%s, we\'ll add your name here linked to your GitHub profile.',
131
+					'event_espresso'
132
+				),
133
+				'<a href="https://github.com/eventespresso/event-espresso-core" aria-label="Contribute to Event Espresso by making a pull request via GitHub" target="_blank">',
134
+				'</a>'
135
+			);
136
+			?>
137 137
         </p>
138 138
 
139 139
         <ul class='wp-credits-list'>
@@ -147,15 +147,15 @@  discard block
 block discarded – undo
147 147
         <h3 class="wp-people-group"><?php esc_html_e('External Libraries', 'event_espresso'); ?></h3>
148 148
         <p class="description">
149 149
             <?php
150
-            printf(
151
-                esc_html__(
152
-                    'Along with the libraries %sincluded with WordPress%s, Event Espresso utilizes the following third party libraries:',
153
-                    'event_espresso'
154
-                ),
155
-                '<a href="' . admin_url('credits.php') . '">',
156
-                '</a>'
157
-            );
158
-            ?>
150
+			printf(
151
+				esc_html__(
152
+					'Along with the libraries %sincluded with WordPress%s, Event Espresso utilizes the following third party libraries:',
153
+					'event_espresso'
154
+				),
155
+				'<a href="' . admin_url('credits.php') . '">',
156
+				'</a>'
157
+			);
158
+			?>
159 159
         </p>
160 160
 <p class="wp-credits-list">
161 161
     <a href="https://openexchangerates.github.io/accounting.js/" target='_blank'>accounting.js</a>,
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -64,20 +64,20 @@  discard block
 block discarded – undo
64 64
 function espressoPerson(string $id, string $email, string $name, string $desc): string
65 65
 {
66 66
     return '
67
-    <li class="ee-card ee-credits-person" id="ee-person-' . $id . '">
68
-        <a href="' . esp_gravatar_profile($email) . '" target="_blank">
69
-            ' . esp_gravatar_image($email, $name) . '
67
+    <li class="ee-card ee-credits-person" id="ee-person-' . $id.'">
68
+        <a href="' . esp_gravatar_profile($email).'" target="_blank">
69
+            ' . esp_gravatar_image($email, $name).'
70 70
         </a>
71 71
         <p>
72
-            <a class="web" href="' . esp_gravatar_profile($email) . '" target="_blank">' . $name . '</a>
73
-            <span class="title">' . $desc . '</span>
72
+            <a class="web" href="' . esp_gravatar_profile($email).'" target="_blank">'.$name.'</a>
73
+            <span class="title">' . $desc.'</span>
74 74
         </p>
75 75
     </li>';
76 76
 }
77 77
 
78 78
 function esp_gravatar_profile(string $email): string
79 79
 {
80
-    return esc_url_raw('https://www.gravatar.com/' . md5($email));
80
+    return esc_url_raw('https://www.gravatar.com/'.md5($email));
81 81
 }
82 82
 
83 83
 function esp_gravatar_image(string $email, string $name): string
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
                     'Along with the libraries %sincluded with WordPress%s, Event Espresso utilizes the following third party libraries:',
153 153
                     'event_espresso'
154 154
                 ),
155
-                '<a href="' . admin_url('credits.php') . '">',
155
+                '<a href="'.admin_url('credits.php').'">',
156 156
                 '</a>'
157 157
             );
158 158
             ?>
Please login to merge, or discard this patch.
admin_pages/about/templates/reviews.template.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -1,19 +1,19 @@  discard block
 block discarded – undo
1 1
 <h2 style="text-align: left;"><?php esc_html_e('Who uses Event Espresso?', 'event_espresso'); ?></h2>
2 2
 <p>
3 3
     <?php printf(
4
-        esc_html__(
5
-            'Event Espresso is used by over 40,000 event organizers across the world. They host %sconferences%s, %sart classes%s, training courses, concerts, fundraisers, workshops, %sfilm festivals%s, %spaint and wine%s, and more.',
6
-            'event_espresso'
7
-        ),
8
-        '<a href="https://eventespresso.com/use-cases/conferences/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
9
-        '</a>',
10
-        '<a href="https://eventespresso.com/use-cases/art-classes/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
11
-        '</a>',
12
-        '<a href="https://eventespresso.com/use-cases/film-festival-ticketing-software/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
13
-        '</a>',
14
-        '<a href="https://eventespresso.com/use-cases/paint-wine-party-ticketing-software/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
15
-        '</a>'
16
-    ); ?>
4
+		esc_html__(
5
+			'Event Espresso is used by over 40,000 event organizers across the world. They host %sconferences%s, %sart classes%s, training courses, concerts, fundraisers, workshops, %sfilm festivals%s, %spaint and wine%s, and more.',
6
+			'event_espresso'
7
+		),
8
+		'<a href="https://eventespresso.com/use-cases/conferences/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
9
+		'</a>',
10
+		'<a href="https://eventespresso.com/use-cases/art-classes/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
11
+		'</a>',
12
+		'<a href="https://eventespresso.com/use-cases/film-festival-ticketing-software/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
13
+		'</a>',
14
+		'<a href="https://eventespresso.com/use-cases/paint-wine-party-ticketing-software/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=Decaf+vs+Regular">',
15
+		'</a>'
16
+	); ?>
17 17
 </p>
18 18
 
19 19
 <h2 class="about-headline-callout">
@@ -451,8 +451,8 @@  discard block
 block discarded – undo
451 451
 
452 452
 function espressoUpgradeNow()
453 453
 {
454
-    if (! defined('EE_CAF_URL')) {
455
-        return '
454
+	if (! defined('EE_CAF_URL')) {
455
+		return '
456 456
     <div class="ee-card ee-card__buy-now ee-grid-col-span-3 ee-card--blank">
457 457
         <a href="https://eventespresso.com/pricing/?utm_source=wordpress_org&amp;utm_medium=link&amp;utm_campaign=decaf_about_page&amp;utm_content=reviews+tab"
458 458
            target="_blank"
@@ -462,13 +462,13 @@  discard block
 block discarded – undo
462 462
             ' . esc_html__('Upgrade Now!', 'event_espresso') . '
463 463
         </a>
464 464
     </div>';
465
-    }
465
+	}
466 466
 }
467 467
 
468 468
 
469 469
 function espressoFiveStars()
470 470
 {
471
-    return '
471
+	return '
472 472
         <div class="wporg-ratings" aria-label="5 out of 5 stars">
473 473
             <span class="dashicons dashicons-star-filled"></span>
474 474
             <span class="dashicons dashicons-star-filled"></span>
Please login to merge, or discard this patch.
admin_pages/maintenance/templates/migration_options_from_ee3.template.php 1 patch
Indentation   +99 added lines, -99 removed lines patch added patch discarded remove patch
@@ -36,24 +36,24 @@  discard block
 block discarded – undo
36 36
                     <td><h3><?php esc_html_e('1', 'event_espresso'); ?></h3></td>
37 37
                     <td>
38 38
                         <?php echo apply_filters(
39
-                            'FHEE__ee_migration_page__option_1_main',
40
-                            sprintf(
41
-                                __(
42
-                                    '%1$sYes. I have backed up my database%2$s, %3$sunderstand the risks involved%4$s, and am ready to migrate my existing %5$s data to %6$s.',
43
-                                    "event_espresso"
44
-                                ),
45
-                                '<strong>',
46
-                                '</strong>',
47
-                                '<a id="migration-risks" class="" aria-label="'
48
-                                . esc_attr__('click for more details', "event_espresso")
49
-                                . '">',
50
-                                '</a>',
51
-                                $current_db_state,
52
-                                $next_db_state
53
-                            ),
54
-                            $current_db_state,
55
-                            $next_db_state
56
-                        ); ?>
39
+							'FHEE__ee_migration_page__option_1_main',
40
+							sprintf(
41
+								__(
42
+									'%1$sYes. I have backed up my database%2$s, %3$sunderstand the risks involved%4$s, and am ready to migrate my existing %5$s data to %6$s.',
43
+									"event_espresso"
44
+								),
45
+								'<strong>',
46
+								'</strong>',
47
+								'<a id="migration-risks" class="" aria-label="'
48
+								. esc_attr__('click for more details', "event_espresso")
49
+								. '">',
50
+								'</a>',
51
+								$current_db_state,
52
+								$next_db_state
53
+							),
54
+							$current_db_state,
55
+							$next_db_state
56
+						); ?>
57 57
                         <a id="display-migration-details"
58 58
                            class="display-the-hidden lt-grey-text smaller-text hide-if-no-js"
59 59
                            rel="migration-details"
@@ -66,9 +66,9 @@  discard block
 block discarded – undo
66 66
                            style="display:none;"
67 67
                         >
68 68
                             <?php printf(
69
-                                esc_html__('hide%1$sdetails%1$s-', 'event_espresso'),
70
-                                '&nbsp;'
71
-                            ); ?>
69
+								esc_html__('hide%1$sdetails%1$s-', 'event_espresso'),
70
+								'&nbsp;'
71
+							); ?>
72 72
                         </a>
73 73
                     </td>
74 74
                     <td>
@@ -76,17 +76,17 @@  discard block
 block discarded – undo
76 76
                            class="toggle-migration-monitor button--primary"
77 77
                         >
78 78
                             <?php echo esc_html(
79
-                                apply_filters(
80
-                                    'FHEE__ee_migration_page__option_1_button_text',
81
-                                    sprintf(
82
-                                        __("Migrate My %s Data to %s", "event_espresso"),
83
-                                        $current_db_state,
84
-                                        $next_db_state
85
-                                    ),
86
-                                    $current_db_state,
87
-                                    $next_db_state
88
-                                )
89
-                            ); ?>
79
+								apply_filters(
80
+									'FHEE__ee_migration_page__option_1_button_text',
81
+									sprintf(
82
+										__("Migrate My %s Data to %s", "event_espresso"),
83
+										$current_db_state,
84
+										$next_db_state
85
+									),
86
+									$current_db_state,
87
+									$next_db_state
88
+								)
89
+							); ?>
90 90
                         </a>
91 91
                     </td>
92 92
                 </tr>
@@ -95,33 +95,33 @@  discard block
 block discarded – undo
95 95
                         <div id="migration-details-dv" style="display: none; padding: 1em;">
96 96
                             <span class="reminder-spn">
97 97
                             <?php printf(
98
-                                esc_html__(
99
-                                    "%s Important: %s Before migrating, please back up your database and files.",
100
-                                    "event_espresso"
101
-                                ),
102
-                                "<b>",
103
-                                "</b>"
104
-                            ); ?>
98
+								esc_html__(
99
+									"%s Important: %s Before migrating, please back up your database and files.",
100
+									"event_espresso"
101
+								),
102
+								"<b>",
103
+								"</b>"
104
+							); ?>
105 105
                             </span>
106 106
                             <p>
107 107
                                 <?php printf(
108
-                                    esc_html__(
109
-                                        '%1$sNot sure how to backup your existing data?%2$s Here is %3$sWordPress\'s explanation%7$s, and here\'s %6$sour explanation%7$s.%8$sYou can also search the WordPress plugin database for %4$s database backup plugins %7$s,%8$sor have one of our dedicated support technicians help you by purchasing a %5$sPriority Support Token%7$s.',
110
-                                        "event_espresso"
111
-                                    ),
112
-                                    '<b>',
113
-                                    '</b>',
114
-                                    "<a href='https://codex.wordpress.org/Backing_Up_Your_Database'>",
115
-                                    "<a href='"
116
-                                    . admin_url(
117
-                                        'plugin-install.php?tab=search&type=term&s=database+backup&plugin-search-input=Search+Plugins'
118
-                                    )
119
-                                    . "'>",
120
-                                    "<a href='https://eventespresso.com/product/priority-support-tokens/'>",
121
-                                    '<a href="https://eventespresso.com/wiki/how-to-back-up-your-site/">',
122
-                                    "</a>",
123
-                                    '<br/>'
124
-                                ); ?>
108
+									esc_html__(
109
+										'%1$sNot sure how to backup your existing data?%2$s Here is %3$sWordPress\'s explanation%7$s, and here\'s %6$sour explanation%7$s.%8$sYou can also search the WordPress plugin database for %4$s database backup plugins %7$s,%8$sor have one of our dedicated support technicians help you by purchasing a %5$sPriority Support Token%7$s.',
110
+										"event_espresso"
111
+									),
112
+									'<b>',
113
+									'</b>',
114
+									"<a href='https://codex.wordpress.org/Backing_Up_Your_Database'>",
115
+									"<a href='"
116
+									. admin_url(
117
+										'plugin-install.php?tab=search&type=term&s=database+backup&plugin-search-input=Search+Plugins'
118
+									)
119
+									. "'>",
120
+									"<a href='https://eventespresso.com/product/priority-support-tokens/'>",
121
+									'<a href="https://eventespresso.com/wiki/how-to-back-up-your-site/">',
122
+									"</a>",
123
+									'<br/>'
124
+								); ?>
125 125
                             </p>
126 126
                             <?php do_action('AHEE__ee_migration_page__option_1_extra_details'); ?>
127 127
                         </div>
@@ -133,28 +133,28 @@  discard block
 block discarded – undo
133 133
                     </td>
134 134
                     <td>
135 135
                         <?php echo esc_html(
136
-                            apply_filters(
137
-                                'FHEE__ee_migration_page__option_2_main',
138
-                                sprintf(
139
-                                    __(
140
-                                        'I do NOT want to migrate my %1$s data to %2$s at this time and just want to use %3$s without migrating data.',
141
-                                        "event_espresso"
142
-                                    ),
143
-                                    $current_db_state,
144
-                                    $next_db_state,
145
-                                    $ultimate_db_state
146
-                                ),
147
-                                $current_db_state,
148
-                                $next_db_state,
149
-                                $ultimate_db_state
150
-                            )
151
-                        ); ?>
136
+							apply_filters(
137
+								'FHEE__ee_migration_page__option_2_main',
138
+								sprintf(
139
+									__(
140
+										'I do NOT want to migrate my %1$s data to %2$s at this time and just want to use %3$s without migrating data.',
141
+										"event_espresso"
142
+									),
143
+									$current_db_state,
144
+									$next_db_state,
145
+									$ultimate_db_state
146
+								),
147
+								$current_db_state,
148
+								$next_db_state,
149
+								$ultimate_db_state
150
+							)
151
+						); ?>
152 152
                         <br />
153 153
                         <span class="reminder-spn">
154 154
                             <?php esc_html_e(
155
-                                'Please Note: In order to avoid errors, any existing Event Espresso data (events, ticket, registrations, etc) in your db will be erased! Regular WP data will NOT be affected.',
156
-                                'event_espresso'
157
-                            ); ?>
155
+								'Please Note: In order to avoid errors, any existing Event Espresso data (events, ticket, registrations, etc) in your db will be erased! Regular WP data will NOT be affected.',
156
+								'event_espresso'
157
+							); ?>
158 158
                         </span>
159 159
                         <a id="display-no-migration-details"
160 160
                            class="display-the-hidden lt-grey-text smaller-text hide-if-no-js"
@@ -168,9 +168,9 @@  discard block
 block discarded – undo
168 168
                            style="display:none;"
169 169
                         >
170 170
                             <?php printf(
171
-                                esc_html__('hide%1$sdetails%1$s-', 'event_espresso'),
172
-                                '&nbsp;'
173
-                            ); ?>
171
+								esc_html__('hide%1$sdetails%1$s-', 'event_espresso'),
172
+								'&nbsp;'
173
+							); ?>
174 174
                         </a>
175 175
                     </td>
176 176
                     <td>
@@ -179,15 +179,15 @@  discard block
 block discarded – undo
179 179
                            href="<?php echo esc_url_raw($reset_db_page_link); ?>"
180 180
                         >
181 181
                             <?php echo esc_html(
182
-                                apply_filters(
183
-                                    'FHEE__ee_migration_page__option_2_button_text',
184
-                                    sprintf(
185
-                                        __("Just Start %s and Delete Existing Data", "event_espresso"),
186
-                                        $ultimate_db_state
187
-                                    ),
188
-                                    $ultimate_db_state
189
-                                )
190
-                            ); ?>
182
+								apply_filters(
183
+									'FHEE__ee_migration_page__option_2_button_text',
184
+									sprintf(
185
+										__("Just Start %s and Delete Existing Data", "event_espresso"),
186
+										$ultimate_db_state
187
+									),
188
+									$ultimate_db_state
189
+								)
190
+							); ?>
191 191
                         </a>
192 192
                     </td>
193 193
                 </tr>
@@ -196,18 +196,18 @@  discard block
 block discarded – undo
196 196
                         <div id="no-migration-details-dv" style="display: none; padding: 1em;">
197 197
                             <p>
198 198
                                 <?php echo esc_html(
199
-                                    apply_filters(
200
-                                        'FHEE__ee_migration_page__option_2_details',
201
-                                        sprintf(
202
-                                            __(
203
-                                                "If your existing Event and Registration Data is no longer relevant nor required, you can just start up %s without performing a data migration.",
204
-                                                "event_espresso"
205
-                                            ),
206
-                                            $ultimate_db_state
207
-                                        ),
208
-                                        $ultimate_db_state
209
-                                    )
210
-                                ); ?>
199
+									apply_filters(
200
+										'FHEE__ee_migration_page__option_2_details',
201
+										sprintf(
202
+											__(
203
+												"If your existing Event and Registration Data is no longer relevant nor required, you can just start up %s without performing a data migration.",
204
+												"event_espresso"
205
+											),
206
+											$ultimate_db_state
207
+										),
208
+										$ultimate_db_state
209
+									)
210
+								); ?>
211 211
                             </p>
212 212
                         </div>
213 213
                     </td>
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 1 patch
Indentation   +2939 added lines, -2939 removed lines patch added patch discarded remove patch
@@ -16,2946 +16,2946 @@
 block discarded – undo
16 16
  */
17 17
 class Events_Admin_Page extends EE_Admin_Page_CPT
18 18
 {
19
-    /**
20
-     * This will hold the event object for event_details screen.
19
+	/**
20
+	 * This will hold the event object for event_details screen.
21
+	 *
22
+	 * @var EE_Event $_event
23
+	 */
24
+	protected $_event;
25
+
26
+
27
+	/**
28
+	 * This will hold the category object for category_details screen.
29
+	 *
30
+	 * @var stdClass $_category
31
+	 */
32
+	protected $_category;
33
+
34
+
35
+	/**
36
+	 * This will hold the event model instance
37
+	 *
38
+	 * @var EEM_Event $_event_model
39
+	 */
40
+	protected $_event_model;
41
+
42
+
43
+	/**
44
+	 * @var EE_Event
45
+	 */
46
+	protected $_cpt_model_obj = false;
47
+
48
+
49
+	/**
50
+	 * @var NodeGroupDao
51
+	 */
52
+	protected $model_obj_node_group_persister;
53
+
54
+	/**
55
+	 * @var AdvancedEditorAdminFormSection
56
+	 */
57
+	protected $advanced_editor_admin_form;
58
+
59
+
60
+	/**
61
+	 * Initialize page props for this admin page group.
62
+	 */
63
+	protected function _init_page_props()
64
+	{
65
+		$this->page_slug        = EVENTS_PG_SLUG;
66
+		$this->page_label       = EVENTS_LABEL;
67
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
68
+		$this->_admin_base_path = EVENTS_ADMIN;
69
+		$this->_cpt_model_names = [
70
+			'create_new' => 'EEM_Event',
71
+			'edit'       => 'EEM_Event',
72
+		];
73
+		$this->_cpt_edit_routes = [
74
+			'espresso_events' => 'edit',
75
+		];
76
+		add_action(
77
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
78
+			[$this, 'verify_event_edit'],
79
+			10,
80
+			2
81
+		);
82
+	}
83
+
84
+
85
+	/**
86
+	 * Sets the ajax hooks used for this admin page group.
87
+	 */
88
+	protected function _ajax_hooks()
89
+	{
90
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
91
+	}
92
+
93
+
94
+	/**
95
+	 * Sets the page properties for this admin page group.
96
+	 */
97
+	protected function _define_page_props()
98
+	{
99
+		$this->_admin_page_title = EVENTS_LABEL;
100
+		$this->_labels           = [
101
+			'buttons'      => [
102
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
103
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
104
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
105
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
106
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
107
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
108
+			],
109
+			'editor_title' => [
110
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
111
+			],
112
+			'publishbox'   => [
113
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
114
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
115
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
116
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
117
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
118
+			],
119
+		];
120
+	}
121
+
122
+
123
+	/**
124
+	 * Sets the page routes property for this admin page group.
125
+	 */
126
+	protected function _set_page_routes()
127
+	{
128
+		// load formatter helper
129
+		// load field generator helper
130
+		// is there a evt_id in the request?
131
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
132
+		$EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
133
+
134
+		$this->_page_routes = [
135
+			'default'                       => [
136
+				'func'       => [$this, '_events_overview_list_table'],
137
+				'capability' => 'ee_read_events',
138
+			],
139
+			'create_new'                    => [
140
+				'func'       => [$this, '_create_new_cpt_item'],
141
+				'capability' => 'ee_edit_events',
142
+			],
143
+			'edit'                          => [
144
+				'func'       => [$this, '_edit_cpt_item'],
145
+				'capability' => 'ee_edit_event',
146
+				'obj_id'     => $EVT_ID,
147
+			],
148
+			'copy_event'                    => [
149
+				'func'       => [$this, '_copy_events'],
150
+				'capability' => 'ee_edit_event',
151
+				'obj_id'     => $EVT_ID,
152
+				'noheader'   => true,
153
+			],
154
+			'trash_event'                   => [
155
+				'func'       => [$this, '_trash_or_restore_event'],
156
+				'args'       => ['event_status' => 'trash'],
157
+				'capability' => 'ee_delete_event',
158
+				'obj_id'     => $EVT_ID,
159
+				'noheader'   => true,
160
+			],
161
+			'trash_events'                  => [
162
+				'func'       => [$this, '_trash_or_restore_events'],
163
+				'args'       => ['event_status' => 'trash'],
164
+				'capability' => 'ee_delete_events',
165
+				'noheader'   => true,
166
+			],
167
+			'restore_event'                 => [
168
+				'func'       => [$this, '_trash_or_restore_event'],
169
+				'args'       => ['event_status' => 'draft'],
170
+				'capability' => 'ee_delete_event',
171
+				'obj_id'     => $EVT_ID,
172
+				'noheader'   => true,
173
+			],
174
+			'restore_events'                => [
175
+				'func'       => [$this, '_trash_or_restore_events'],
176
+				'args'       => ['event_status' => 'draft'],
177
+				'capability' => 'ee_delete_events',
178
+				'noheader'   => true,
179
+			],
180
+			'delete_event'                  => [
181
+				'func'       => [$this, '_delete_event'],
182
+				'capability' => 'ee_delete_event',
183
+				'obj_id'     => $EVT_ID,
184
+				'noheader'   => true,
185
+			],
186
+			'delete_events'                 => [
187
+				'func'       => [$this, '_delete_events'],
188
+				'capability' => 'ee_delete_events',
189
+				'noheader'   => true,
190
+			],
191
+			'view_report'                   => [
192
+				'func'       => [$this, '_view_report'],
193
+				'capability' => 'ee_edit_events',
194
+			],
195
+			'default_event_settings'        => [
196
+				'func'       => [$this, '_default_event_settings'],
197
+				'capability' => 'manage_options',
198
+			],
199
+			'update_default_event_settings' => [
200
+				'func'       => [$this, '_update_default_event_settings'],
201
+				'capability' => 'manage_options',
202
+				'noheader'   => true,
203
+			],
204
+			'template_settings'             => [
205
+				'func'       => [$this, '_template_settings'],
206
+				'capability' => 'manage_options',
207
+			],
208
+			// event category tab related
209
+			'add_category'                  => [
210
+				'func'       => [$this, '_category_details'],
211
+				'capability' => 'ee_edit_event_category',
212
+				'args'       => ['add'],
213
+			],
214
+			'edit_category'                 => [
215
+				'func'       => [$this, '_category_details'],
216
+				'capability' => 'ee_edit_event_category',
217
+				'args'       => ['edit'],
218
+			],
219
+			'delete_categories'             => [
220
+				'func'       => [$this, '_delete_categories'],
221
+				'capability' => 'ee_delete_event_category',
222
+				'noheader'   => true,
223
+			],
224
+			'delete_category'               => [
225
+				'func'       => [$this, '_delete_categories'],
226
+				'capability' => 'ee_delete_event_category',
227
+				'noheader'   => true,
228
+			],
229
+			'insert_category'               => [
230
+				'func'       => [$this, '_insert_or_update_category'],
231
+				'args'       => ['new_category' => true],
232
+				'capability' => 'ee_edit_event_category',
233
+				'noheader'   => true,
234
+			],
235
+			'update_category'               => [
236
+				'func'       => [$this, '_insert_or_update_category'],
237
+				'args'       => ['new_category' => false],
238
+				'capability' => 'ee_edit_event_category',
239
+				'noheader'   => true,
240
+			],
241
+			'category_list'                 => [
242
+				'func'       => [$this, '_category_list_table'],
243
+				'capability' => 'ee_manage_event_categories',
244
+			],
245
+			'preview_deletion'              => [
246
+				'func'       => [$this, 'previewDeletion'],
247
+				'capability' => 'ee_delete_events',
248
+			],
249
+			'confirm_deletion'              => [
250
+				'func'       => [$this, 'confirmDeletion'],
251
+				'capability' => 'ee_delete_events',
252
+				'noheader'   => true,
253
+			],
254
+		];
255
+	}
256
+
257
+
258
+	/**
259
+	 * Set the _page_config property for this admin page group.
260
+	 */
261
+	protected function _set_page_config()
262
+	{
263
+		$post_id            = $this->request->getRequestParam('post', 0, 'int');
264
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
265
+		$this->_page_config = [
266
+			'default'                => [
267
+				'nav'           => [
268
+					'label' => esc_html__('Overview', 'event_espresso'),
269
+					'icon' => 'dashicons-list-view',
270
+					'order' => 10,
271
+				],
272
+				'list_table'    => 'Events_Admin_List_Table',
273
+				'help_tabs'     => [
274
+					'events_overview_help_tab'                       => [
275
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
276
+						'filename' => 'events_overview',
277
+					],
278
+					'events_overview_table_column_headings_help_tab' => [
279
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
280
+						'filename' => 'events_overview_table_column_headings',
281
+					],
282
+					'events_overview_filters_help_tab'               => [
283
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
284
+						'filename' => 'events_overview_filters',
285
+					],
286
+					'events_overview_view_help_tab'                  => [
287
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
288
+						'filename' => 'events_overview_views',
289
+					],
290
+					'events_overview_other_help_tab'                 => [
291
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
292
+						'filename' => 'events_overview_other',
293
+					],
294
+				],
295
+				'require_nonce' => false,
296
+			],
297
+			'create_new'             => [
298
+				'nav'           => [
299
+					'label'      => esc_html__('Add New Event', 'event_espresso'),
300
+					'icon' => 'dashicons-plus-alt',
301
+					'order'      => 15,
302
+					'persistent' => false,
303
+				],
304
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
305
+				'help_tabs'     => [
306
+					'event_editor_help_tab'                            => [
307
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
308
+						'filename' => 'event_editor',
309
+					],
310
+					'event_editor_title_richtexteditor_help_tab'       => [
311
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
312
+						'filename' => 'event_editor_title_richtexteditor',
313
+					],
314
+					'event_editor_venue_details_help_tab'              => [
315
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
316
+						'filename' => 'event_editor_venue_details',
317
+					],
318
+					'event_editor_event_datetimes_help_tab'            => [
319
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
320
+						'filename' => 'event_editor_event_datetimes',
321
+					],
322
+					'event_editor_event_tickets_help_tab'              => [
323
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
324
+						'filename' => 'event_editor_event_tickets',
325
+					],
326
+					'event_editor_event_registration_options_help_tab' => [
327
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
328
+						'filename' => 'event_editor_event_registration_options',
329
+					],
330
+					'event_editor_tags_categories_help_tab'            => [
331
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
332
+						'filename' => 'event_editor_tags_categories',
333
+					],
334
+					'event_editor_questions_registrants_help_tab'      => [
335
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
336
+						'filename' => 'event_editor_questions_registrants',
337
+					],
338
+					'event_editor_save_new_event_help_tab'             => [
339
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
340
+						'filename' => 'event_editor_save_new_event',
341
+					],
342
+					'event_editor_other_help_tab'                      => [
343
+						'title'    => esc_html__('Event Other', 'event_espresso'),
344
+						'filename' => 'event_editor_other',
345
+					],
346
+				],
347
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
348
+				'require_nonce' => false,
349
+			],
350
+			'edit'                   => [
351
+				'nav'           => [
352
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
353
+					'icon' => 'dashicons-edit',
354
+					'order'      => 15,
355
+					'persistent' => false,
356
+					'url'        => $post_id
357
+						? EE_Admin_Page::add_query_args_and_nonce(
358
+							['post' => $post_id, 'action' => 'edit'],
359
+							$this->_current_page_view_url
360
+						)
361
+						: $this->_admin_base_url,
362
+				],
363
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
364
+				'help_tabs'     => [
365
+					'event_editor_help_tab'                            => [
366
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
367
+						'filename' => 'event_editor',
368
+					],
369
+					'event_editor_title_richtexteditor_help_tab'       => [
370
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
371
+						'filename' => 'event_editor_title_richtexteditor',
372
+					],
373
+					'event_editor_venue_details_help_tab'              => [
374
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
375
+						'filename' => 'event_editor_venue_details',
376
+					],
377
+					'event_editor_event_datetimes_help_tab'            => [
378
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
379
+						'filename' => 'event_editor_event_datetimes',
380
+					],
381
+					'event_editor_event_tickets_help_tab'              => [
382
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
383
+						'filename' => 'event_editor_event_tickets',
384
+					],
385
+					'event_editor_event_registration_options_help_tab' => [
386
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
387
+						'filename' => 'event_editor_event_registration_options',
388
+					],
389
+					'event_editor_tags_categories_help_tab'            => [
390
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
391
+						'filename' => 'event_editor_tags_categories',
392
+					],
393
+					'event_editor_questions_registrants_help_tab'      => [
394
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
395
+						'filename' => 'event_editor_questions_registrants',
396
+					],
397
+					'event_editor_save_new_event_help_tab'             => [
398
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
399
+						'filename' => 'event_editor_save_new_event',
400
+					],
401
+					'event_editor_other_help_tab'                      => [
402
+						'title'    => esc_html__('Event Other', 'event_espresso'),
403
+						'filename' => 'event_editor_other',
404
+					],
405
+				],
406
+				'require_nonce' => false,
407
+			],
408
+			'default_event_settings' => [
409
+				'nav'           => [
410
+					'label' => esc_html__('Default Settings', 'event_espresso'),
411
+					'icon' => 'dashicons-admin-generic',
412
+					'order' => 40,
413
+				],
414
+				'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
415
+				'labels'        => [
416
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
417
+				],
418
+				'help_tabs'     => [
419
+					'default_settings_help_tab'        => [
420
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
421
+						'filename' => 'events_default_settings',
422
+					],
423
+					'default_settings_status_help_tab' => [
424
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
425
+						'filename' => 'events_default_settings_status',
426
+					],
427
+					'default_maximum_tickets_help_tab' => [
428
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
429
+						'filename' => 'events_default_settings_max_tickets',
430
+					],
431
+				],
432
+				'require_nonce' => false,
433
+			],
434
+			// template settings
435
+			'template_settings'      => [
436
+				'nav'           => [
437
+					'label' => esc_html__('Templates', 'event_espresso'),
438
+					'icon' => 'dashicons-layout',
439
+					'order' => 30,
440
+				],
441
+				'metaboxes'     => $this->_default_espresso_metaboxes,
442
+				'help_tabs'     => [
443
+					'general_settings_templates_help_tab' => [
444
+						'title'    => esc_html__('Templates', 'event_espresso'),
445
+						'filename' => 'general_settings_templates',
446
+					],
447
+				],
448
+				'require_nonce' => false,
449
+			],
450
+			// event category stuff
451
+			'add_category'           => [
452
+				'nav'           => [
453
+					'label'      => esc_html__('Add Category', 'event_espresso'),
454
+					'icon' => 'dashicons-plus-alt',
455
+					'order'      => 25,
456
+					'persistent' => false,
457
+				],
458
+				'help_tabs'     => [
459
+					'add_category_help_tab' => [
460
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
461
+						'filename' => 'events_add_category',
462
+					],
463
+				],
464
+				'metaboxes'     => ['_publish_post_box'],
465
+				'require_nonce' => false,
466
+			],
467
+			'edit_category'          => [
468
+				'nav'           => [
469
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
470
+					'icon' => 'dashicons-edit',
471
+					'order'      => 25,
472
+					'persistent' => false,
473
+					'url'        => $EVT_CAT_ID
474
+						? add_query_arg(
475
+							['EVT_CAT_ID' => $EVT_CAT_ID],
476
+							$this->_current_page_view_url
477
+						)
478
+						: $this->_admin_base_url,
479
+				],
480
+				'help_tabs'     => [
481
+					'edit_category_help_tab' => [
482
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
483
+						'filename' => 'events_edit_category',
484
+					],
485
+				],
486
+				'metaboxes'     => ['_publish_post_box'],
487
+				'require_nonce' => false,
488
+			],
489
+			'category_list'          => [
490
+				'nav'           => [
491
+					'label' => esc_html__('Categories', 'event_espresso'),
492
+					'icon' => 'dashicons-networking',
493
+					'order' => 20,
494
+				],
495
+				'list_table'    => 'Event_Categories_Admin_List_Table',
496
+				'help_tabs'     => [
497
+					'events_categories_help_tab'                       => [
498
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
499
+						'filename' => 'events_categories',
500
+					],
501
+					'events_categories_table_column_headings_help_tab' => [
502
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
503
+						'filename' => 'events_categories_table_column_headings',
504
+					],
505
+					'events_categories_view_help_tab'                  => [
506
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
507
+						'filename' => 'events_categories_views',
508
+					],
509
+					'events_categories_other_help_tab'                 => [
510
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
511
+						'filename' => 'events_categories_other',
512
+					],
513
+				],
514
+				'metaboxes'     => $this->_default_espresso_metaboxes,
515
+				'require_nonce' => false,
516
+			],
517
+			'preview_deletion'       => [
518
+				'nav'           => [
519
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
520
+					'icon' => 'dashicons-remove',
521
+					'order'      => 15,
522
+					'persistent' => false,
523
+					'url'        => '',
524
+				],
525
+				'require_nonce' => false,
526
+			],
527
+		];
528
+	}
529
+
530
+
531
+	/**
532
+	 * Used to register any global screen options if necessary for every route in this admin page group.
533
+	 */
534
+	protected function _add_screen_options()
535
+	{
536
+	}
537
+
538
+
539
+	/**
540
+	 * Implementing the screen options for the 'default' route.
541
+	 *
542
+	 * @throws InvalidArgumentException
543
+	 * @throws InvalidDataTypeException
544
+	 * @throws InvalidInterfaceException
545
+	 */
546
+	protected function _add_screen_options_default()
547
+	{
548
+		$this->_per_page_screen_option();
549
+	}
550
+
551
+
552
+	/**
553
+	 * Implementing screen options for the category list route.
554
+	 *
555
+	 * @throws InvalidArgumentException
556
+	 * @throws InvalidDataTypeException
557
+	 * @throws InvalidInterfaceException
558
+	 */
559
+	protected function _add_screen_options_category_list()
560
+	{
561
+		$page_title              = $this->_admin_page_title;
562
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
563
+		$this->_per_page_screen_option();
564
+		$this->_admin_page_title = $page_title;
565
+	}
566
+
567
+
568
+	/**
569
+	 * Used to register any global feature pointers for the admin page group.
570
+	 */
571
+	protected function _add_feature_pointers()
572
+	{
573
+	}
574
+
575
+
576
+	/**
577
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
578
+	 */
579
+	public function load_scripts_styles()
580
+	{
581
+		wp_register_style(
582
+			'events-admin-css',
583
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
584
+			[],
585
+			EVENT_ESPRESSO_VERSION
586
+		);
587
+		wp_register_style(
588
+			'ee-cat-admin',
589
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
590
+			[],
591
+			EVENT_ESPRESSO_VERSION
592
+		);
593
+		wp_enqueue_style('events-admin-css');
594
+		wp_enqueue_style('ee-cat-admin');
595
+		// scripts
596
+		wp_register_script(
597
+			'event_editor_js',
598
+			EVENTS_ASSETS_URL . 'event_editor.js',
599
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
600
+			EVENT_ESPRESSO_VERSION,
601
+			true
602
+		);
603
+	}
604
+
605
+
606
+	/**
607
+	 * Enqueuing scripts and styles specific to this view
608
+	 */
609
+	public function load_scripts_styles_create_new()
610
+	{
611
+		$this->load_scripts_styles_edit();
612
+	}
613
+
614
+
615
+	/**
616
+	 * Enqueuing scripts and styles specific to this view
617
+	 */
618
+	public function load_scripts_styles_edit()
619
+	{
620
+		// styles
621
+		wp_enqueue_style('espresso-ui-theme');
622
+		wp_register_style(
623
+			'event-editor-css',
624
+			EVENTS_ASSETS_URL . 'event-editor.css',
625
+			['ee-admin-css'],
626
+			EVENT_ESPRESSO_VERSION
627
+		);
628
+		wp_enqueue_style('event-editor-css');
629
+		// scripts
630
+		if (! $this->admin_config->useAdvancedEditor()) {
631
+			wp_register_script(
632
+				'event-datetime-metabox',
633
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
634
+				['event_editor_js', 'ee-datepicker'],
635
+				EVENT_ESPRESSO_VERSION
636
+			);
637
+			wp_enqueue_script('event-datetime-metabox');
638
+		}
639
+	}
640
+
641
+
642
+	/**
643
+	 * Populating the _views property for the category list table view.
644
+	 */
645
+	protected function _set_list_table_views_category_list()
646
+	{
647
+		$this->_views = [
648
+			'all' => [
649
+				'slug'        => 'all',
650
+				'label'       => esc_html__('All', 'event_espresso'),
651
+				'count'       => 0,
652
+				'bulk_action' => [
653
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
654
+				],
655
+			],
656
+		];
657
+	}
658
+
659
+
660
+	/**
661
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
662
+	 */
663
+	public function admin_init()
664
+	{
665
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
666
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
667
+			'event_espresso'
668
+		);
669
+	}
670
+
671
+
672
+	/**
673
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
674
+	 * group.
675
+	 */
676
+	public function admin_notices()
677
+	{
678
+	}
679
+
680
+
681
+	/**
682
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
683
+	 * this admin page group.
684
+	 */
685
+	public function admin_footer_scripts()
686
+	{
687
+	}
688
+
689
+
690
+	/**
691
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
692
+	 * warning (via EE_Error::add_error());
693
+	 *
694
+	 * @param EE_Event $event Event object
695
+	 * @param string   $req_type
696
+	 * @return void
697
+	 * @throws EE_Error
698
+	 * @throws ReflectionException
699
+	 */
700
+	public function verify_event_edit($event = null, $req_type = '')
701
+	{
702
+		// don't need to do this when processing
703
+		if (! empty($req_type)) {
704
+			return;
705
+		}
706
+		// no event?
707
+		if (! $event instanceof EE_Event) {
708
+			$event = $this->_cpt_model_obj;
709
+		}
710
+		// STILL no event?
711
+		if (! $event instanceof EE_Event) {
712
+			return;
713
+		}
714
+		$orig_status = $event->status();
715
+		// first check if event is active.
716
+		if (
717
+			$orig_status === EEM_Event::cancelled
718
+			|| $orig_status === EEM_Event::postponed
719
+			|| $event->is_expired()
720
+			|| $event->is_inactive()
721
+		) {
722
+			return;
723
+		}
724
+		// made it here so it IS active... next check that any of the tickets are sold.
725
+		if ($event->is_sold_out(true)) {
726
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
727
+				EE_Error::add_attention(
728
+					sprintf(
729
+						esc_html__(
730
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
731
+							'event_espresso'
732
+						),
733
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
734
+					)
735
+				);
736
+			}
737
+			return;
738
+		}
739
+		if ($orig_status === EEM_Event::sold_out) {
740
+			EE_Error::add_attention(
741
+				sprintf(
742
+					esc_html__(
743
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
744
+						'event_espresso'
745
+					),
746
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
747
+				)
748
+			);
749
+		}
750
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
751
+		if (! $event->tickets_on_sale()) {
752
+			return;
753
+		}
754
+		// made it here so show warning
755
+		$this->_edit_event_warning();
756
+	}
757
+
758
+
759
+	/**
760
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
761
+	 * When needed, hook this into a EE_Error::add_error() notice.
762
+	 *
763
+	 * @access protected
764
+	 * @return void
765
+	 */
766
+	protected function _edit_event_warning()
767
+	{
768
+		// we don't want to add warnings during these requests
769
+		if ($this->request->getRequestParam('action') === 'editpost') {
770
+			return;
771
+		}
772
+		EE_Error::add_attention(
773
+			sprintf(
774
+				esc_html__(
775
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
776
+					'event_espresso'
777
+				),
778
+				'<a class="espresso-help-tab-lnk ee-help-tab-link">',
779
+				'</a>'
780
+			)
781
+		);
782
+	}
783
+
784
+
785
+	/**
786
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
787
+	 * Otherwise, do the normal logic
788
+	 *
789
+	 * @return void
790
+	 * @throws EE_Error
791
+	 * @throws InvalidArgumentException
792
+	 * @throws InvalidDataTypeException
793
+	 * @throws InvalidInterfaceException
794
+	 */
795
+	protected function _create_new_cpt_item()
796
+	{
797
+		$has_timezone_string = get_option('timezone_string');
798
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
799
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
800
+			EE_Error::add_attention(
801
+				sprintf(
802
+					esc_html__(
803
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
804
+						'event_espresso'
805
+					),
806
+					'<br>',
807
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
808
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
809
+					. '</select>',
810
+					'<button class="button button--secondary timezone-submit">',
811
+					'</button><span class="spinner"></span>'
812
+				),
813
+				__FILE__,
814
+				__FUNCTION__,
815
+				__LINE__
816
+			);
817
+		}
818
+		parent::_create_new_cpt_item();
819
+	}
820
+
821
+
822
+	/**
823
+	 * Sets the _views property for the default route in this admin page group.
824
+	 */
825
+	protected function _set_list_table_views_default()
826
+	{
827
+		$this->_views = [
828
+			'all'   => [
829
+				'slug'        => 'all',
830
+				'label'       => esc_html__('View All Events', 'event_espresso'),
831
+				'count'       => 0,
832
+				'bulk_action' => [
833
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
834
+				],
835
+			],
836
+			'draft' => [
837
+				'slug'        => 'draft',
838
+				'label'       => esc_html__('Draft', 'event_espresso'),
839
+				'count'       => 0,
840
+				'bulk_action' => [
841
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
842
+				],
843
+			],
844
+		];
845
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
846
+			$this->_views['trash'] = [
847
+				'slug'        => 'trash',
848
+				'label'       => esc_html__('Trash', 'event_espresso'),
849
+				'count'       => 0,
850
+				'bulk_action' => [
851
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
852
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
853
+				],
854
+			];
855
+		}
856
+	}
857
+
858
+
859
+	/**
860
+	 * Provides the legend item array for the default list table view.
861
+	 *
862
+	 * @return array
863
+	 * @throws EE_Error
864
+	 * @throws EE_Error
865
+	 */
866
+	protected function _event_legend_items()
867
+	{
868
+		$items    = [
869
+			'view_details'   => [
870
+				'class' => 'dashicons dashicons-visibility',
871
+				'desc'  => esc_html__('View Event', 'event_espresso'),
872
+			],
873
+			'edit_event'     => [
874
+				'class' => 'dashicons dashicons-calendar-alt',
875
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
876
+			],
877
+			'view_attendees' => [
878
+				'class' => 'dashicons dashicons-groups',
879
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
880
+			],
881
+		];
882
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
883
+		$statuses = [
884
+			'sold_out_status'  => [
885
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
886
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
887
+			],
888
+			'active_status'    => [
889
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
890
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
891
+			],
892
+			'upcoming_status'  => [
893
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
894
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
895
+			],
896
+			'postponed_status' => [
897
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
898
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
899
+			],
900
+			'cancelled_status' => [
901
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
902
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
903
+			],
904
+			'expired_status'   => [
905
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
906
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
907
+			],
908
+			'inactive_status'  => [
909
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
910
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
911
+			],
912
+		];
913
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
914
+		return array_merge($items, $statuses);
915
+	}
916
+
917
+
918
+	/**
919
+	 * @return EEM_Event
920
+	 * @throws EE_Error
921
+	 * @throws InvalidArgumentException
922
+	 * @throws InvalidDataTypeException
923
+	 * @throws InvalidInterfaceException
924
+	 * @throws ReflectionException
925
+	 */
926
+	private function _event_model()
927
+	{
928
+		if (! $this->_event_model instanceof EEM_Event) {
929
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
930
+		}
931
+		return $this->_event_model;
932
+	}
933
+
934
+
935
+	/**
936
+	 * Adds extra buttons to the WP CPT permalink field row.
937
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
938
+	 *
939
+	 * @param string $return    the current html
940
+	 * @param int    $id        the post id for the page
941
+	 * @param string $new_title What the title is
942
+	 * @param string $new_slug  what the slug is
943
+	 * @return string            The new html string for the permalink area
944
+	 */
945
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
946
+	{
947
+		// make sure this is only when editing
948
+		if (! empty($id)) {
949
+			$post = get_post($id);
950
+			$return .= '<a class="button button--small button--secondary" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
951
+					   . esc_html__('Shortcode', 'event_espresso')
952
+					   . '</a> ';
953
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
954
+					   . $post->ID
955
+					   . ']">';
956
+		}
957
+		return $return;
958
+	}
959
+
960
+
961
+	/**
962
+	 * _events_overview_list_table
963
+	 * This contains the logic for showing the events_overview list
964
+	 *
965
+	 * @access protected
966
+	 * @return void
967
+	 * @throws DomainException
968
+	 * @throws EE_Error
969
+	 * @throws InvalidArgumentException
970
+	 * @throws InvalidDataTypeException
971
+	 * @throws InvalidInterfaceException
972
+	 */
973
+	protected function _events_overview_list_table()
974
+	{
975
+		$after_list_table                           = [];
976
+		$links_html = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
977
+		$links_html .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
978
+		$links_html .= EEH_HTML::div(
979
+			EEH_Template::get_button_or_link(
980
+				get_post_type_archive_link('espresso_events'),
981
+				esc_html__('View Event Archive Page', 'event_espresso'),
982
+				'button button--small button--secondary'
983
+			),
984
+			'',
985
+			'ee-admin-button-row ee-admin-button-row--align-start'
986
+		);
987
+		$links_html .= EEH_HTML::divx();
988
+
989
+		$after_list_table['view_event_list_button'] = $links_html;
990
+
991
+		$after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
992
+		$this->_admin_page_title                    .= ' ' . $this->get_action_link_or_button(
993
+			'create_new',
994
+			'add',
995
+			[],
996
+			'add-new-h2'
997
+		);
998
+
999
+		$this->_template_args['after_list_table']   = array_merge(
1000
+			(array) $this->_template_args['after_list_table'],
1001
+			$after_list_table
1002
+		);
1003
+		$this->display_admin_list_table_page_with_no_sidebar();
1004
+	}
1005
+
1006
+
1007
+	/**
1008
+	 * this allows for extra misc actions in the default WP publish box
1009
+	 *
1010
+	 * @return void
1011
+	 * @throws DomainException
1012
+	 * @throws EE_Error
1013
+	 * @throws InvalidArgumentException
1014
+	 * @throws InvalidDataTypeException
1015
+	 * @throws InvalidInterfaceException
1016
+	 * @throws ReflectionException
1017
+	 */
1018
+	public function extra_misc_actions_publish_box()
1019
+	{
1020
+		$this->_generate_publish_box_extra_content();
1021
+	}
1022
+
1023
+
1024
+	/**
1025
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1026
+	 * saved.
1027
+	 * Typically you would use this to save any additional data.
1028
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1029
+	 * ALSO very important.  When a post transitions from scheduled to published,
1030
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1031
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1032
+	 *
1033
+	 * @access protected
1034
+	 * @abstract
1035
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1036
+	 * @param WP_Post $post    The post object of the cpt that was saved.
1037
+	 * @return void
1038
+	 * @throws EE_Error
1039
+	 * @throws InvalidArgumentException
1040
+	 * @throws InvalidDataTypeException
1041
+	 * @throws InvalidInterfaceException
1042
+	 * @throws ReflectionException
1043
+	 */
1044
+	protected function _insert_update_cpt_item($post_id, $post)
1045
+	{
1046
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1047
+			// get out we're not processing an event save.
1048
+			return;
1049
+		}
1050
+		$event_values = [
1051
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1052
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1053
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1054
+		];
1055
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1056
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1057
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1058
+				'display_ticket_selector',
1059
+				false,
1060
+				'bool'
1061
+			);
1062
+			$event_values['EVT_additional_limit']            = min(
1063
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1064
+				$this->request->getRequestParam(
1065
+					'additional_limit',
1066
+					EEM_Event::get_default_additional_limit(),
1067
+					'int'
1068
+				)
1069
+			);
1070
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1071
+				'EVT_default_registration_status',
1072
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1073
+			);
1074
+
1075
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1076
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1077
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, 'bool');
1078
+		} elseif ($post instanceof WP_Post) {
1079
+			$event_values['EVT_name'] = $post->post_title;
1080
+			$event_values['EVT_desc'] = $post->post_content;
1081
+		}
1082
+		// update event
1083
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1084
+		// get event_object for other metaboxes...
1085
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1086
+		// i have to setup where conditions to override the filters in the model
1087
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1088
+		/** @var EE_Event $event */
1089
+		$event = $this->_event_model()->get_one(
1090
+			[
1091
+				[
1092
+					$this->_event_model()->primary_key_name() => $post_id,
1093
+					'OR'                                      => [
1094
+						'status'   => $post->post_status,
1095
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1096
+						// but the returned object here has a status of "publish", so use the original post status as well
1097
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1098
+					],
1099
+				],
1100
+			]
1101
+		);
1102
+
1103
+		// the following are default callbacks for event attachment updates
1104
+		// that can be overridden by caffeinated functionality and/or addons.
1105
+		$event_update_callbacks = [];
1106
+		if (! $this->admin_config->useAdvancedEditor()) {
1107
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1108
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1109
+		}
1110
+		$event_update_callbacks = apply_filters(
1111
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1112
+			$event_update_callbacks
1113
+		);
1114
+
1115
+		$att_success = true;
1116
+		foreach ($event_update_callbacks as $e_callback) {
1117
+			$_success = is_callable($e_callback)
1118
+				? $e_callback($event, $this->request->requestParams())
1119
+				: false;
1120
+			// if ANY of these updates fail then we want the appropriate global error message
1121
+			$att_success = $_success !== false ? $att_success : false;
1122
+		}
1123
+		// any errors?
1124
+		if ($success && $att_success === false) {
1125
+			EE_Error::add_error(
1126
+				esc_html__(
1127
+					'Event Details saved successfully but something went wrong with saving attachments.',
1128
+					'event_espresso'
1129
+				),
1130
+				__FILE__,
1131
+				__FUNCTION__,
1132
+				__LINE__
1133
+			);
1134
+		} elseif ($success === false) {
1135
+			EE_Error::add_error(
1136
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1137
+				__FILE__,
1138
+				__FUNCTION__,
1139
+				__LINE__
1140
+			);
1141
+		}
1142
+	}
1143
+
1144
+
1145
+	/**
1146
+	 * @param int $post_id
1147
+	 * @param int $revision_id
1148
+	 * @throws EE_Error
1149
+	 * @throws EE_Error
1150
+	 * @throws ReflectionException
1151
+	 * @see parent::restore_item()
1152
+	 */
1153
+	protected function _restore_cpt_item($post_id, $revision_id)
1154
+	{
1155
+		// copy existing event meta to new post
1156
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1157
+		if ($post_evt instanceof EE_Event) {
1158
+			// meta revision restore
1159
+			$post_evt->restore_revision($revision_id);
1160
+			// related objs restore
1161
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1162
+		}
1163
+	}
1164
+
1165
+
1166
+	/**
1167
+	 * Attach the venue to the Event
1168
+	 *
1169
+	 * @param EE_Event $event Event Object to add the venue to
1170
+	 * @param array    $data  The request data from the form
1171
+	 * @return bool           Success or fail.
1172
+	 * @throws EE_Error
1173
+	 * @throws ReflectionException
1174
+	 */
1175
+	protected function _default_venue_update(EE_Event $event, $data)
1176
+	{
1177
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1178
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1179
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1180
+		// very important.  If we don't have a venue name...
1181
+		// then we'll get out because not necessary to create empty venue
1182
+		if (empty($data['venue_title'])) {
1183
+			return false;
1184
+		}
1185
+		$venue_array = [
1186
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1187
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1188
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1189
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1190
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1191
+				? $data['venue_short_description']
1192
+				: null,
1193
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1194
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1195
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1196
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1197
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1198
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1199
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1200
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1201
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1202
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1203
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1204
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1205
+			'status'              => 'publish',
1206
+		];
1207
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1208
+		if (! empty($venue_id)) {
1209
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1210
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1211
+			// we've gotta make sure that the venue is always attached to a revision..
1212
+			// add_relation_to should take care of making sure that the relation is already present.
1213
+			$event->_add_relation_to($venue_id, 'Venue');
1214
+			return $rows_affected > 0;
1215
+		}
1216
+		// we insert the venue
1217
+		$venue_id = $venue_model->insert($venue_array);
1218
+		$event->_add_relation_to($venue_id, 'Venue');
1219
+		return ! empty($venue_id);
1220
+		// when we have the ancestor come in it's already been handled by the revision save.
1221
+	}
1222
+
1223
+
1224
+	/**
1225
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1226
+	 *
1227
+	 * @param EE_Event $event The Event object we're attaching data to
1228
+	 * @param array    $data  The request data from the form
1229
+	 * @return array
1230
+	 * @throws EE_Error
1231
+	 * @throws ReflectionException
1232
+	 * @throws Exception
1233
+	 */
1234
+	protected function _default_tickets_update(EE_Event $event, $data)
1235
+	{
1236
+		if ($this->admin_config->useAdvancedEditor()) {
1237
+			return [];
1238
+		}
1239
+		$datetime       = null;
1240
+		$saved_tickets  = [];
1241
+		$event_timezone = $event->get_timezone();
1242
+		$date_formats   = ['Y-m-d', 'h:i a'];
1243
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1244
+			// trim all values to ensure any excess whitespace is removed.
1245
+			$datetime_data                = array_map('trim', $datetime_data);
1246
+			$datetime_data['DTT_EVT_end'] =
1247
+				isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1248
+					? $datetime_data['DTT_EVT_end']
1249
+					: $datetime_data['DTT_EVT_start'];
1250
+			$datetime_values              = [
1251
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1252
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1253
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1254
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1255
+				'DTT_order'     => $row,
1256
+			];
1257
+			// if we have an id then let's get existing object first and then set the new values.
1258
+			//  Otherwise we instantiate a new object for save.
1259
+			if (! empty($datetime_data['DTT_ID'])) {
1260
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1261
+				if (! $datetime instanceof EE_Datetime) {
1262
+					throw new RuntimeException(
1263
+						sprintf(
1264
+							esc_html__(
1265
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1266
+								'event_espresso'
1267
+							),
1268
+							$datetime_data['DTT_ID']
1269
+						)
1270
+					);
1271
+				}
1272
+				$datetime->set_date_format($date_formats[0]);
1273
+				$datetime->set_time_format($date_formats[1]);
1274
+				foreach ($datetime_values as $field => $value) {
1275
+					$datetime->set($field, $value);
1276
+				}
1277
+			} else {
1278
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1279
+			}
1280
+			if (! $datetime instanceof EE_Datetime) {
1281
+				throw new RuntimeException(
1282
+					sprintf(
1283
+						esc_html__(
1284
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1285
+							'event_espresso'
1286
+						),
1287
+						print_r($datetime_values, true)
1288
+					)
1289
+				);
1290
+			}
1291
+			// before going any further make sure our dates are setup correctly
1292
+			// so that the end date is always equal or greater than the start date.
1293
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1294
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1295
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1296
+			}
1297
+			$datetime->save();
1298
+			$event->_add_relation_to($datetime, 'Datetime');
1299
+		}
1300
+		// no datetimes get deleted so we don't do any of that logic here.
1301
+		// update tickets next
1302
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1303
+
1304
+		// set up some default start and end dates in case those are not present in the incoming data
1305
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1306
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1307
+		// use the start date of the first datetime for the end date
1308
+		$first_datetime   = $event->first_datetime();
1309
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1310
+
1311
+		// now process the incoming data
1312
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1313
+			$update_prices = false;
1314
+			$ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1315
+				? $data['edit_prices'][ $row ][1]['PRC_amount']
1316
+				: 0;
1317
+			// trim inputs to ensure any excess whitespace is removed.
1318
+			$ticket_data   = array_map('trim', $ticket_data);
1319
+			$ticket_values = [
1320
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1321
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1322
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1323
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1324
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1325
+					? $ticket_data['TKT_start_date']
1326
+					: $default_start_date,
1327
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1328
+					? $ticket_data['TKT_end_date']
1329
+					: $default_end_date,
1330
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1331
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1332
+					? $ticket_data['TKT_qty']
1333
+					: EE_INF,
1334
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1335
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1336
+					? $ticket_data['TKT_uses']
1337
+					: EE_INF,
1338
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1339
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1340
+				'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1341
+				'TKT_price'       => $ticket_price,
1342
+				'TKT_row'         => $row,
1343
+			];
1344
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1345
+			// which means in turn that the prices will become new prices as well.
1346
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1347
+				$ticket_values['TKT_ID']         = 0;
1348
+				$ticket_values['TKT_is_default'] = 0;
1349
+				$update_prices                   = true;
1350
+			}
1351
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1352
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1353
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1354
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1355
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1356
+			if (! empty($ticket_data['TKT_ID'])) {
1357
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1358
+				if (! $existing_ticket instanceof EE_Ticket) {
1359
+					throw new RuntimeException(
1360
+						sprintf(
1361
+							esc_html__(
1362
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1363
+								'event_espresso'
1364
+							),
1365
+							$ticket_data['TKT_ID']
1366
+						)
1367
+					);
1368
+				}
1369
+				$ticket_sold = $existing_ticket->count_related(
1370
+					'Registration',
1371
+					[
1372
+							[
1373
+								'STS_ID' => [
1374
+									'NOT IN',
1375
+									[EEM_Registration::status_id_incomplete],
1376
+								],
1377
+							],
1378
+						]
1379
+				) > 0;
1380
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1381
+				// if they are different then we create a new ticket (if $ticket_sold)
1382
+				// if they aren't different then we go ahead and modify existing ticket.
1383
+				$create_new_ticket = $ticket_sold
1384
+									 && $ticket_price !== $existing_ticket->price()
1385
+									 && ! $existing_ticket->deleted();
1386
+				$existing_ticket->set_date_format($date_formats[0]);
1387
+				$existing_ticket->set_time_format($date_formats[1]);
1388
+				// set new values
1389
+				foreach ($ticket_values as $field => $value) {
1390
+					if ($field == 'TKT_qty') {
1391
+						$existing_ticket->set_qty($value);
1392
+					} elseif ($field == 'TKT_price') {
1393
+						$existing_ticket->set('TKT_price', $ticket_price);
1394
+					} else {
1395
+						$existing_ticket->set($field, $value);
1396
+					}
1397
+				}
1398
+				$ticket = $existing_ticket;
1399
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1400
+				//  Otherwise we have to create a new ticket.
1401
+				if ($create_new_ticket) {
1402
+					// archive the old ticket first
1403
+					$existing_ticket->set('TKT_deleted', 1);
1404
+					$existing_ticket->save();
1405
+					// make sure this ticket is still recorded in our $saved_tickets
1406
+					// so we don't run it through the regular trash routine.
1407
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1408
+					// create new ticket that's a copy of the existing except,
1409
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1410
+					$new_ticket = clone $existing_ticket;
1411
+					$new_ticket->set('TKT_ID', 0);
1412
+					$new_ticket->set('TKT_deleted', 0);
1413
+					$new_ticket->set('TKT_sold', 0);
1414
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1415
+					$update_prices = true;
1416
+					$ticket        = $new_ticket;
1417
+				}
1418
+			} else {
1419
+				// no TKT_id so a new ticket
1420
+				$ticket_values['TKT_price'] = $ticket_price;
1421
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1422
+				$update_prices              = true;
1423
+			}
1424
+			if (! $ticket instanceof EE_Ticket) {
1425
+				throw new RuntimeException(
1426
+					sprintf(
1427
+						esc_html__(
1428
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1429
+							'event_espresso'
1430
+						),
1431
+						print_r($ticket_values, true)
1432
+					)
1433
+				);
1434
+			}
1435
+			// cap ticket qty by datetime reg limits
1436
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1437
+			// update ticket.
1438
+			$ticket->save();
1439
+			// before going any further make sure our dates are setup correctly
1440
+			// so that the end date is always equal or greater than the start date.
1441
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1442
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1443
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1444
+				$ticket->save();
1445
+			}
1446
+			// initially let's add the ticket to the datetime
1447
+			$datetime->_add_relation_to($ticket, 'Ticket');
1448
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1449
+			// add prices to ticket
1450
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1451
+				? $data['edit_prices'][ $row ]
1452
+				: [];
1453
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1454
+		}
1455
+		// however now we need to handle permanently deleting tickets via the ui.
1456
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1457
+		// However, it does allow for deleting tickets that have no tickets sold,
1458
+		// in which case we want to get rid of permanently because there is no need to save in db.
1459
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1460
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1461
+		foreach ($tickets_removed as $id) {
1462
+			$id = absint($id);
1463
+			// get the ticket for this id
1464
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1465
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1466
+				continue;
1467
+			}
1468
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1469
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1470
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1471
+			foreach ($related_datetimes as $related_datetime) {
1472
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1473
+			}
1474
+			// need to do the same for prices (except these prices can also be deleted because again,
1475
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1476
+			$ticket_to_remove->delete_related_permanently('Price');
1477
+			// finally let's delete this ticket
1478
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1479
+			$ticket_to_remove->delete_permanently();
1480
+		}
1481
+		return [$datetime, $saved_tickets];
1482
+	}
1483
+
1484
+
1485
+	/**
1486
+	 * This attaches a list of given prices to a ticket.
1487
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1488
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1489
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1490
+	 *
1491
+	 * @access  private
1492
+	 * @param array     $prices_data Array of prices from the form.
1493
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1494
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1495
+	 * @return  void
1496
+	 * @throws EE_Error
1497
+	 * @throws ReflectionException
1498
+	 */
1499
+	private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1500
+	{
1501
+		$timezone = $ticket->get_timezone();
1502
+		foreach ($prices_data as $row => $price_data) {
1503
+			$price_values = [
1504
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1505
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1506
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1507
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1508
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1509
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1510
+				'PRC_order'      => $row,
1511
+			];
1512
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1513
+				$price_values['PRC_ID'] = 0;
1514
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1515
+			} else {
1516
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1517
+				// update this price with new values
1518
+				foreach ($price_values as $field => $new_price) {
1519
+					$price->set($field, $new_price);
1520
+				}
1521
+			}
1522
+			if (! $price instanceof EE_Price) {
1523
+				throw new RuntimeException(
1524
+					sprintf(
1525
+						esc_html__(
1526
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1527
+							'event_espresso'
1528
+						),
1529
+						print_r($price_values, true)
1530
+					)
1531
+				);
1532
+			}
1533
+			$price->save();
1534
+			$ticket->_add_relation_to($price, 'Price');
1535
+		}
1536
+	}
1537
+
1538
+
1539
+	/**
1540
+	 * Add in our autosave ajax handlers
1541
+	 *
1542
+	 */
1543
+	protected function _ee_autosave_create_new()
1544
+	{
1545
+	}
1546
+
1547
+
1548
+	/**
1549
+	 * More autosave handlers.
1550
+	 */
1551
+	protected function _ee_autosave_edit()
1552
+	{
1553
+	}
1554
+
1555
+
1556
+	/**
1557
+	 * @throws EE_Error
1558
+	 * @throws ReflectionException
1559
+	 */
1560
+	private function _generate_publish_box_extra_content()
1561
+	{
1562
+		// load formatter helper
1563
+		// args for getting related registrations
1564
+		$approved_query_args        = [
1565
+			[
1566
+				'REG_deleted' => 0,
1567
+				'STS_ID'      => EEM_Registration::status_id_approved,
1568
+			],
1569
+		];
1570
+		$not_approved_query_args    = [
1571
+			[
1572
+				'REG_deleted' => 0,
1573
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1574
+			],
1575
+		];
1576
+		$pending_payment_query_args = [
1577
+			[
1578
+				'REG_deleted' => 0,
1579
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1580
+			],
1581
+		];
1582
+		// publish box
1583
+		$publish_box_extra_args = [
1584
+			'view_approved_reg_url'        => add_query_arg(
1585
+				[
1586
+					'action'      => 'default',
1587
+					'event_id'    => $this->_cpt_model_obj->ID(),
1588
+					'_reg_status' => EEM_Registration::status_id_approved,
1589
+					'use_filters' => true,
1590
+				],
1591
+				REG_ADMIN_URL
1592
+			),
1593
+			'view_not_approved_reg_url'    => add_query_arg(
1594
+				[
1595
+					'action'      => 'default',
1596
+					'event_id'    => $this->_cpt_model_obj->ID(),
1597
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1598
+					'use_filters' => true,
1599
+				],
1600
+				REG_ADMIN_URL
1601
+			),
1602
+			'view_pending_payment_reg_url' => add_query_arg(
1603
+				[
1604
+					'action'      => 'default',
1605
+					'event_id'    => $this->_cpt_model_obj->ID(),
1606
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1607
+					'use_filters' => true,
1608
+				],
1609
+				REG_ADMIN_URL
1610
+			),
1611
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1612
+				'Registration',
1613
+				$approved_query_args
1614
+			),
1615
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1616
+				'Registration',
1617
+				$not_approved_query_args
1618
+			),
1619
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1620
+				'Registration',
1621
+				$pending_payment_query_args
1622
+			),
1623
+			'misc_pub_section_class'       => apply_filters(
1624
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1625
+				'misc-pub-section'
1626
+			),
1627
+		];
1628
+		ob_start();
1629
+		do_action(
1630
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1631
+			$this->_cpt_model_obj
1632
+		);
1633
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1634
+		// load template
1635
+		EEH_Template::display_template(
1636
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1637
+			$publish_box_extra_args
1638
+		);
1639
+	}
1640
+
1641
+
1642
+	/**
1643
+	 * @return EE_Event
1644
+	 */
1645
+	public function get_event_object()
1646
+	{
1647
+		return $this->_cpt_model_obj;
1648
+	}
1649
+
1650
+
1651
+
1652
+
1653
+	/** METABOXES * */
1654
+	/**
1655
+	 * _register_event_editor_meta_boxes
1656
+	 * add all metaboxes related to the event_editor
1657
+	 *
1658
+	 * @return void
1659
+	 * @throws EE_Error
1660
+	 * @throws ReflectionException
1661
+	 */
1662
+	protected function _register_event_editor_meta_boxes()
1663
+	{
1664
+		$this->verify_cpt_object();
1665
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1666
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1667
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1668
+			$this->addMetaBox(
1669
+				'espresso_event_editor_event_options',
1670
+				esc_html__('Event Registration Options', 'event_espresso'),
1671
+				[$this, 'registration_options_meta_box'],
1672
+				$this->page_slug,
1673
+				'side'
1674
+			);
1675
+		}
1676
+		if (! $use_advanced_editor) {
1677
+			$this->addMetaBox(
1678
+				'espresso_event_editor_tickets',
1679
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1680
+				[$this, 'ticket_metabox'],
1681
+				$this->page_slug,
1682
+				'normal',
1683
+				'high'
1684
+			);
1685
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1686
+			add_action(
1687
+				'add_meta_boxes_espresso_events',
1688
+				function () {
1689
+					global $current_screen;
1690
+					remove_meta_box('authordiv', $current_screen, 'normal');
1691
+				},
1692
+				99
1693
+			);
1694
+		}
1695
+		// NOTE: if you're looking for other metaboxes in here,
1696
+		// where a metabox has a related management page in the admin
1697
+		// you will find it setup in the related management page's "_Hooks" file.
1698
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1699
+	}
1700
+
1701
+
1702
+	/**
1703
+	 * @throws DomainException
1704
+	 * @throws EE_Error
1705
+	 * @throws ReflectionException
1706
+	 */
1707
+	public function ticket_metabox()
1708
+	{
1709
+		$existing_datetime_ids = $existing_ticket_ids = [];
1710
+		// defaults for template args
1711
+		$template_args = [
1712
+			'ticket_rows'              => '',
1713
+			'total_ticket_rows'        => 1,
1714
+			'ticket_js_structure'      => '',
1715
+			'trash_icon'               => 'dashicons dashicons-lock',
1716
+			'disabled'                 => '',
1717
+		];
1718
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1719
+		/**
1720
+		 * 1. Start with retrieving Datetimes
1721
+		 * 2. Fore each datetime get related tickets
1722
+		 * 3. For each ticket get related prices
1723
+		 */
1724
+		/** @var EEM_Datetime $datetime_model */
1725
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1726
+		/** @var EEM_Ticket $datetime_model */
1727
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1728
+		$times        = $datetime_model->get_all_event_dates($event_id);
1729
+		/** @type EE_Datetime $first_datetime */
1730
+		$first_datetime = reset($times);
1731
+		// do we get related tickets?
1732
+		if (
1733
+			$first_datetime instanceof EE_Datetime
1734
+			&& $first_datetime->ID() !== 0
1735
+		) {
1736
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1737
+			$template_args['time']   = $first_datetime;
1738
+			$related_tickets         = $first_datetime->tickets(
1739
+				[
1740
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1741
+					'default_where_conditions' => 'none',
1742
+				]
1743
+			);
1744
+			if (! empty($related_tickets)) {
1745
+				$template_args['total_ticket_rows'] = count($related_tickets);
1746
+				$row                                = 0;
1747
+				foreach ($related_tickets as $ticket) {
1748
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1749
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1750
+					$row++;
1751
+				}
1752
+			} else {
1753
+				$template_args['total_ticket_rows'] = 1;
1754
+				/** @type EE_Ticket $ticket */
1755
+				$ticket                       = $ticket_model->create_default_object();
1756
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1757
+			}
1758
+		} else {
1759
+			$template_args['time'] = $times[0];
1760
+			/** @type EE_Ticket[] $tickets */
1761
+			$tickets                      = $ticket_model->get_all_default_tickets();
1762
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1763
+			// NOTE: we're just sending the first default row
1764
+			// (decaf can't manage default tickets so this should be sufficient);
1765
+		}
1766
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1767
+			'event_editor_event_datetimes_help_tab'
1768
+		);
1769
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1770
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1771
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1772
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1773
+			$ticket_model->create_default_object(),
1774
+			true
1775
+		);
1776
+		$template                                  = apply_filters(
1777
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1778
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1779
+		);
1780
+		EEH_Template::display_template($template, $template_args);
1781
+	}
1782
+
1783
+
1784
+	/**
1785
+	 * Setup an individual ticket form for the decaf event editor page
1786
+	 *
1787
+	 * @access private
1788
+	 * @param EE_Ticket $ticket   the ticket object
1789
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1790
+	 * @param int       $row
1791
+	 * @return string generated html for the ticket row.
1792
+	 * @throws EE_Error
1793
+	 * @throws ReflectionException
1794
+	 */
1795
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1796
+	{
1797
+		$template_args = [
1798
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1799
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1800
+				: '',
1801
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1802
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1803
+			'TKT_name'            => $ticket->get('TKT_name'),
1804
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1805
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1806
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1807
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1808
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1809
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1810
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1811
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1812
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'dashicons dashicons-lock',
1813
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1814
+				: ' disabled=disabled',
1815
+		];
1816
+		$price         = $ticket->ID() !== 0
1817
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1818
+			: null;
1819
+		$price         = $price instanceof EE_Price
1820
+			? $price
1821
+			: EEM_Price::instance()->create_default_object();
1822
+		$price_args    = [
1823
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1824
+			'PRC_amount'            => $price->get('PRC_amount'),
1825
+			'PRT_ID'                => $price->get('PRT_ID'),
1826
+			'PRC_ID'                => $price->get('PRC_ID'),
1827
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1828
+		];
1829
+		// make sure we have default start and end dates if skeleton
1830
+		// handle rows that should NOT be empty
1831
+		if (empty($template_args['TKT_start_date'])) {
1832
+			// if empty then the start date will be now.
1833
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1834
+		}
1835
+		if (empty($template_args['TKT_end_date'])) {
1836
+			// get the earliest datetime (if present);
1837
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1838
+				? $this->_cpt_model_obj->get_first_related(
1839
+					'Datetime',
1840
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1841
+				)
1842
+				: null;
1843
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1844
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1845
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1846
+		}
1847
+		$template_args = array_merge($template_args, $price_args);
1848
+		$template      = apply_filters(
1849
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1850
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1851
+			$ticket
1852
+		);
1853
+		return EEH_Template::display_template($template, $template_args, true);
1854
+	}
1855
+
1856
+
1857
+	/**
1858
+	 * @throws EE_Error
1859
+	 * @throws ReflectionException
1860
+	 */
1861
+	public function registration_options_meta_box()
1862
+	{
1863
+		$yes_no_values             = [
1864
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1865
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1866
+		];
1867
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1868
+			[
1869
+				EEM_Registration::status_id_cancelled,
1870
+				EEM_Registration::status_id_declined,
1871
+				EEM_Registration::status_id_incomplete,
1872
+			],
1873
+			true
1874
+		);
1875
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1876
+		$template_args['_event']                          = $this->_cpt_model_obj;
1877
+		$template_args['event']                           = $this->_cpt_model_obj;
1878
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1879
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1880
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1881
+			'default_reg_status',
1882
+			$default_reg_status_values,
1883
+			$this->_cpt_model_obj->default_registration_status()
1884
+		);
1885
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1886
+			'display_desc',
1887
+			$yes_no_values,
1888
+			$this->_cpt_model_obj->display_description()
1889
+		);
1890
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1891
+			'display_ticket_selector',
1892
+			$yes_no_values,
1893
+			$this->_cpt_model_obj->display_ticket_selector(),
1894
+			'',
1895
+			'',
1896
+			false
1897
+		);
1898
+		$template_args['additional_registration_options'] = apply_filters(
1899
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1900
+			'',
1901
+			$template_args,
1902
+			$yes_no_values,
1903
+			$default_reg_status_values
1904
+		);
1905
+		EEH_Template::display_template(
1906
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1907
+			$template_args
1908
+		);
1909
+	}
1910
+
1911
+
1912
+	/**
1913
+	 * _get_events()
1914
+	 * This method simply returns all the events (for the given _view and paging)
1915
+	 *
1916
+	 * @access public
1917
+	 * @param int  $per_page     count of items per page (20 default);
1918
+	 * @param int  $current_page what is the current page being viewed.
1919
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1920
+	 *                           If FALSE then we return an array of event objects
1921
+	 *                           that match the given _view and paging parameters.
1922
+	 * @return array|int         an array of event objects or a count of them.
1923
+	 * @throws Exception
1924
+	 */
1925
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1926
+	{
1927
+		$EEM_Event   = $this->_event_model();
1928
+		$offset      = ($current_page - 1) * $per_page;
1929
+		$limit       = $count ? null : $offset . ',' . $per_page;
1930
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1931
+		$order       = $this->request->getRequestParam('order', 'DESC');
1932
+		$month_range = $this->request->getRequestParam('month_range');
1933
+		if ($month_range) {
1934
+			$pieces = explode(' ', $month_range, 3);
1935
+			// simulate the FIRST day of the month, that fixes issues for months like February
1936
+			// where PHP doesn't know what to assume for date.
1937
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1938
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1939
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1940
+		}
1941
+		$where  = [];
1942
+		$status = $this->request->getRequestParam('status');
1943
+		// determine what post_status our condition will have for the query.
1944
+		switch ($status) {
1945
+			case 'month':
1946
+			case 'today':
1947
+			case null:
1948
+			case 'all':
1949
+				break;
1950
+			case 'draft':
1951
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1952
+				break;
1953
+			default:
1954
+				$where['status'] = $status;
1955
+		}
1956
+		// categories? The default for all categories is -1
1957
+		$category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1958
+		if ($category !== -1) {
1959
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1960
+			$where['Term_Taxonomy.term_id']  = $category;
1961
+		}
1962
+		// date where conditions
1963
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1964
+		if ($month_range) {
1965
+			$DateTime = new DateTime(
1966
+				$year_r . '-' . $month_r . '-01 00:00:00',
1967
+				new DateTimeZone('UTC')
1968
+			);
1969
+			$start    = $DateTime->getTimestamp();
1970
+			// set the datetime to be the end of the month
1971
+			$DateTime->setDate(
1972
+				$year_r,
1973
+				$month_r,
1974
+				$DateTime->format('t')
1975
+			)->setTime(23, 59, 59);
1976
+			$end                             = $DateTime->getTimestamp();
1977
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1978
+		} elseif ($status === 'today') {
1979
+			$DateTime                        =
1980
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1981
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1982
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1983
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1984
+		} elseif ($status === 'month') {
1985
+			$now                             = date('Y-m-01');
1986
+			$DateTime                        =
1987
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1988
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1989
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1990
+														->setTime(23, 59, 59)
1991
+														->format(implode(' ', $start_formats));
1992
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1993
+		}
1994
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1995
+			$where['EVT_wp_user'] = get_current_user_id();
1996
+		} else {
1997
+			if (! isset($where['status'])) {
1998
+				if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1999
+					$where['OR'] = [
2000
+						'status*restrict_private' => ['!=', 'private'],
2001
+						'AND'                     => [
2002
+							'status*inclusive' => ['=', 'private'],
2003
+							'EVT_wp_user'      => get_current_user_id(),
2004
+						],
2005
+					];
2006
+				}
2007
+			}
2008
+		}
2009
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
2010
+		if (
2011
+			$wp_user
2012
+			&& $wp_user !== get_current_user_id()
2013
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2014
+		) {
2015
+			$where['EVT_wp_user'] = $wp_user;
2016
+		}
2017
+		// search query handling
2018
+		$search_term = $this->request->getRequestParam('s');
2019
+		if ($search_term) {
2020
+			$search_term = '%' . $search_term . '%';
2021
+			$where['OR'] = [
2022
+				'EVT_name'       => ['LIKE', $search_term],
2023
+				'EVT_desc'       => ['LIKE', $search_term],
2024
+				'EVT_short_desc' => ['LIKE', $search_term],
2025
+			];
2026
+		}
2027
+		// filter events by venue.
2028
+		$venue = $this->request->getRequestParam('venue', 0, 'int');
2029
+		if ($venue) {
2030
+			$where['Venue.VNU_ID'] = $venue;
2031
+		}
2032
+		$request_params = $this->request->requestParams();
2033
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2034
+		$query_params   = apply_filters(
2035
+			'FHEE__Events_Admin_Page__get_events__query_params',
2036
+			[
2037
+				$where,
2038
+				'limit'    => $limit,
2039
+				'order_by' => $orderby,
2040
+				'order'    => $order,
2041
+				'group_by' => 'EVT_ID',
2042
+			],
2043
+			$request_params
2044
+		);
2045
+
2046
+		// let's first check if we have special requests coming in.
2047
+		$active_status = $this->request->getRequestParam('active_status');
2048
+		if ($active_status) {
2049
+			switch ($active_status) {
2050
+				case 'upcoming':
2051
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2052
+				case 'expired':
2053
+					return $EEM_Event->get_expired_events($query_params, $count);
2054
+				case 'active':
2055
+					return $EEM_Event->get_active_events($query_params, $count);
2056
+				case 'inactive':
2057
+					return $EEM_Event->get_inactive_events($query_params, $count);
2058
+			}
2059
+		}
2060
+
2061
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2062
+	}
2063
+
2064
+
2065
+	/**
2066
+	 * handling for WordPress CPT actions (trash, restore, delete)
2067
+	 *
2068
+	 * @param string $post_id
2069
+	 * @throws EE_Error
2070
+	 * @throws ReflectionException
2071
+	 */
2072
+	public function trash_cpt_item($post_id)
2073
+	{
2074
+		$this->request->setRequestParam('EVT_ID', $post_id);
2075
+		$this->_trash_or_restore_event('trash', false);
2076
+	}
2077
+
2078
+
2079
+	/**
2080
+	 * @param string $post_id
2081
+	 * @throws EE_Error
2082
+	 * @throws ReflectionException
2083
+	 */
2084
+	public function restore_cpt_item($post_id)
2085
+	{
2086
+		$this->request->setRequestParam('EVT_ID', $post_id);
2087
+		$this->_trash_or_restore_event('draft', false);
2088
+	}
2089
+
2090
+
2091
+	/**
2092
+	 * @param string $post_id
2093
+	 * @throws EE_Error
2094
+	 * @throws EE_Error
2095
+	 */
2096
+	public function delete_cpt_item($post_id)
2097
+	{
2098
+		throw new EE_Error(
2099
+			esc_html__(
2100
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2101
+				'event_espresso'
2102
+			)
2103
+		);
2104
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2105
+		// $this->_delete_event();
2106
+	}
2107
+
2108
+
2109
+	/**
2110
+	 * _trash_or_restore_event
2111
+	 *
2112
+	 * @access protected
2113
+	 * @param string $event_status
2114
+	 * @param bool   $redirect_after
2115
+	 * @throws EE_Error
2116
+	 * @throws EE_Error
2117
+	 * @throws ReflectionException
2118
+	 */
2119
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2120
+	{
2121
+		// determine the event id and set to array.
2122
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2123
+		// loop thru events
2124
+		if ($EVT_ID) {
2125
+			// clean status
2126
+			$event_status = sanitize_key($event_status);
2127
+			// grab status
2128
+			if (! empty($event_status)) {
2129
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2130
+			} else {
2131
+				$success = false;
2132
+				$msg     = esc_html__(
2133
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2134
+					'event_espresso'
2135
+				);
2136
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2137
+			}
2138
+		} else {
2139
+			$success = false;
2140
+			$msg     = esc_html__(
2141
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2142
+				'event_espresso'
2143
+			);
2144
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2145
+		}
2146
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2147
+		if ($redirect_after) {
2148
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2149
+		}
2150
+	}
2151
+
2152
+
2153
+	/**
2154
+	 * _trash_or_restore_events
2155
+	 *
2156
+	 * @access protected
2157
+	 * @param string $event_status
2158
+	 * @return void
2159
+	 * @throws EE_Error
2160
+	 * @throws EE_Error
2161
+	 * @throws ReflectionException
2162
+	 */
2163
+	protected function _trash_or_restore_events($event_status = 'trash')
2164
+	{
2165
+		// clean status
2166
+		$event_status = sanitize_key($event_status);
2167
+		// grab status
2168
+		if (! empty($event_status)) {
2169
+			$success = true;
2170
+			// determine the event id and set to array.
2171
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2172
+			// loop thru events
2173
+			foreach ($EVT_IDs as $EVT_ID) {
2174
+				if ($EVT_ID = absint($EVT_ID)) {
2175
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2176
+					$success = $results !== false ? $success : false;
2177
+				} else {
2178
+					$msg = sprintf(
2179
+						esc_html__(
2180
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2181
+							'event_espresso'
2182
+						),
2183
+						$EVT_ID
2184
+					);
2185
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2186
+					$success = false;
2187
+				}
2188
+			}
2189
+		} else {
2190
+			$success = false;
2191
+			$msg     = esc_html__(
2192
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2193
+				'event_espresso'
2194
+			);
2195
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2196
+		}
2197
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2198
+		$success = $success ? 2 : false;
2199
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2200
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2201
+	}
2202
+
2203
+
2204
+	/**
2205
+	 * @param int    $EVT_ID
2206
+	 * @param string $event_status
2207
+	 * @return bool
2208
+	 * @throws EE_Error
2209
+	 * @throws ReflectionException
2210
+	 */
2211
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2212
+	{
2213
+		// grab event id
2214
+		if (! $EVT_ID) {
2215
+			$msg = esc_html__(
2216
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2217
+				'event_espresso'
2218
+			);
2219
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
+			return false;
2221
+		}
2222
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2223
+		// clean status
2224
+		$event_status = sanitize_key($event_status);
2225
+		// grab status
2226
+		if (empty($event_status)) {
2227
+			$msg = esc_html__(
2228
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2229
+				'event_espresso'
2230
+			);
2231
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2232
+			return false;
2233
+		}
2234
+		// was event trashed or restored ?
2235
+		switch ($event_status) {
2236
+			case 'draft':
2237
+				$action = 'restored from the trash';
2238
+				$hook   = 'AHEE_event_restored_from_trash';
2239
+				break;
2240
+			case 'trash':
2241
+				$action = 'moved to the trash';
2242
+				$hook   = 'AHEE_event_moved_to_trash';
2243
+				break;
2244
+			default:
2245
+				$action = 'updated';
2246
+				$hook   = false;
2247
+		}
2248
+		// use class to change status
2249
+		$this->_cpt_model_obj->set_status($event_status);
2250
+		$success = $this->_cpt_model_obj->save();
2251
+		if (! $success) {
2252
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2253
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2254
+			return false;
2255
+		}
2256
+		if ($hook) {
2257
+			do_action($hook);
2258
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2259
+			// because events side step that and it otherwise won't get called
2260
+			do_action(
2261
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2262
+				$this->_cpt_model_obj,
2263
+				$hook === 'AHEE_event_moved_to_trash',
2264
+				$success
2265
+			);
2266
+		}
2267
+		return true;
2268
+	}
2269
+
2270
+
2271
+	/**
2272
+	 * @param array $event_ids
2273
+	 * @return array
2274
+	 * @since   4.10.23.p
2275
+	 */
2276
+	private function cleanEventIds(array $event_ids)
2277
+	{
2278
+		return array_map('absint', $event_ids);
2279
+	}
2280
+
2281
+
2282
+	/**
2283
+	 * @return array
2284
+	 * @since   4.10.23.p
2285
+	 */
2286
+	private function getEventIdsFromRequest()
2287
+	{
2288
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2289
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2290
+		} else {
2291
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2292
+		}
2293
+	}
2294
+
2295
+
2296
+	/**
2297
+	 * @param bool $preview_delete
2298
+	 * @throws EE_Error
2299
+	 * @throws ReflectionException
2300
+	 */
2301
+	protected function _delete_event($preview_delete = true)
2302
+	{
2303
+		$this->_delete_events($preview_delete);
2304
+	}
2305
+
2306
+
2307
+	/**
2308
+	 * Gets the tree traversal batch persister.
2309
+	 *
2310
+	 * @return NodeGroupDao
2311
+	 * @throws InvalidArgumentException
2312
+	 * @throws InvalidDataTypeException
2313
+	 * @throws InvalidInterfaceException
2314
+	 * @since 4.10.12.p
2315
+	 */
2316
+	protected function getModelObjNodeGroupPersister()
2317
+	{
2318
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2319
+			$this->model_obj_node_group_persister =
2320
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2321
+		}
2322
+		return $this->model_obj_node_group_persister;
2323
+	}
2324
+
2325
+
2326
+	/**
2327
+	 * @param bool $preview_delete
2328
+	 * @return void
2329
+	 * @throws EE_Error
2330
+	 * @throws ReflectionException
2331
+	 */
2332
+	protected function _delete_events($preview_delete = true)
2333
+	{
2334
+		$event_ids = $this->getEventIdsFromRequest();
2335
+		if ($preview_delete) {
2336
+			$this->generateDeletionPreview($event_ids);
2337
+		} else {
2338
+			foreach ($event_ids as $event_id) {
2339
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2340
+				if ($event instanceof EE_Event) {
2341
+					$event->delete_permanently();
2342
+				}
2343
+			}
2344
+		}
2345
+	}
2346
+
2347
+
2348
+	/**
2349
+	 * @param array $event_ids
2350
+	 */
2351
+	protected function generateDeletionPreview(array $event_ids)
2352
+	{
2353
+		$event_ids = $this->cleanEventIds($event_ids);
2354
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2355
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2356
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2357
+			[
2358
+				'action'            => 'preview_deletion',
2359
+				'deletion_job_code' => $deletion_job_code,
2360
+			],
2361
+			$this->_admin_base_url
2362
+		);
2363
+		EEH_URL::safeRedirectAndExit(
2364
+			EE_Admin_Page::add_query_args_and_nonce(
2365
+				[
2366
+					'page'              => EED_Batch::PAGE_SLUG,
2367
+					'batch'             => EED_Batch::batch_job,
2368
+					'EVT_IDs'           => $event_ids,
2369
+					'deletion_job_code' => $deletion_job_code,
2370
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2371
+					'return_url'        => urlencode($return_url),
2372
+				],
2373
+				admin_url()
2374
+			)
2375
+		);
2376
+	}
2377
+
2378
+
2379
+	/**
2380
+	 * Checks for a POST submission
2381
+	 *
2382
+	 * @since 4.10.12.p
2383
+	 */
2384
+	protected function confirmDeletion()
2385
+	{
2386
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2387
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2388
+		);
2389
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2390
+	}
2391
+
2392
+
2393
+	/**
2394
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2395
+	 *
2396
+	 * @throws EE_Error
2397
+	 * @since 4.10.12.p
2398
+	 */
2399
+	protected function previewDeletion()
2400
+	{
2401
+		$preview_deletion_logic = $this->getLoader()->getShared(
2402
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2403
+		);
2404
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2405
+		$this->display_admin_page_with_no_sidebar();
2406
+	}
2407
+
2408
+
2409
+	/**
2410
+	 * get total number of events
2411
+	 *
2412
+	 * @access public
2413
+	 * @return int
2414
+	 * @throws EE_Error
2415
+	 * @throws EE_Error
2416
+	 */
2417
+	public function total_events()
2418
+	{
2419
+		return EEM_Event::instance()->count(
2420
+			['caps' => 'read_admin'],
2421
+			'EVT_ID',
2422
+			true
2423
+		);
2424
+	}
2425
+
2426
+
2427
+	/**
2428
+	 * get total number of draft events
2429
+	 *
2430
+	 * @access public
2431
+	 * @return int
2432
+	 * @throws EE_Error
2433
+	 * @throws EE_Error
2434
+	 */
2435
+	public function total_events_draft()
2436
+	{
2437
+		return EEM_Event::instance()->count(
2438
+			[
2439
+				['status' => ['IN', ['draft', 'auto-draft']]],
2440
+				'caps' => 'read_admin',
2441
+			],
2442
+			'EVT_ID',
2443
+			true
2444
+		);
2445
+	}
2446
+
2447
+
2448
+	/**
2449
+	 * get total number of trashed events
2450
+	 *
2451
+	 * @access public
2452
+	 * @return int
2453
+	 * @throws EE_Error
2454
+	 * @throws EE_Error
2455
+	 */
2456
+	public function total_trashed_events()
2457
+	{
2458
+		return EEM_Event::instance()->count(
2459
+			[
2460
+				['status' => 'trash'],
2461
+				'caps' => 'read_admin',
2462
+			],
2463
+			'EVT_ID',
2464
+			true
2465
+		);
2466
+	}
2467
+
2468
+
2469
+	/**
2470
+	 *    _default_event_settings
2471
+	 *    This generates the Default Settings Tab
2472
+	 *
2473
+	 * @return void
2474
+	 * @throws DomainException
2475
+	 * @throws EE_Error
2476
+	 * @throws InvalidArgumentException
2477
+	 * @throws InvalidDataTypeException
2478
+	 * @throws InvalidInterfaceException
2479
+	 */
2480
+	protected function _default_event_settings()
2481
+	{
2482
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2483
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2484
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
2485
+			$this->_default_event_settings_form()->get_html(),
2486
+			'',
2487
+			'padding'
2488
+		);
2489
+		$this->display_admin_page_with_sidebar();
2490
+	}
2491
+
2492
+
2493
+	/**
2494
+	 * Return the form for event settings.
2495
+	 *
2496
+	 * @return EE_Form_Section_Proper
2497
+	 * @throws EE_Error
2498
+	 */
2499
+	protected function _default_event_settings_form()
2500
+	{
2501
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2502
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2503
+		// exclude
2504
+			[
2505
+				EEM_Registration::status_id_cancelled,
2506
+				EEM_Registration::status_id_declined,
2507
+				EEM_Registration::status_id_incomplete,
2508
+				EEM_Registration::status_id_wait_list,
2509
+			],
2510
+			true
2511
+		);
2512
+		// setup Advanced Editor ???
2513
+		if (
2514
+			$this->raw_req_action === 'default_event_settings'
2515
+			|| $this->raw_req_action === 'update_default_event_settings'
2516
+		) {
2517
+			$this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2518
+		}
2519
+		return new EE_Form_Section_Proper(
2520
+			[
2521
+				'name'            => 'update_default_event_settings',
2522
+				'html_id'         => 'update_default_event_settings',
2523
+				'html_class'      => 'form-table',
2524
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2525
+				'subsections'     => apply_filters(
2526
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2527
+					[
2528
+						'defaults_section_header' => new EE_Form_Section_HTML(
2529
+							EEH_HTML::h2(
2530
+								esc_html__('Default Settings', 'event_espresso'),
2531
+								'',
2532
+								'ee-admin-settings-hdr'
2533
+							)
2534
+						),
2535
+						'default_reg_status'  => new EE_Select_Input(
2536
+							$registration_stati_for_selection,
2537
+							[
2538
+								'default'         => isset($registration_config->default_STS_ID)
2539
+													 && array_key_exists(
2540
+														 $registration_config->default_STS_ID,
2541
+														 $registration_stati_for_selection
2542
+													 )
2543
+									? sanitize_text_field($registration_config->default_STS_ID)
2544
+									: EEM_Registration::status_id_pending_payment,
2545
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2546
+													 . EEH_Template::get_help_tab_link(
2547
+														 'default_settings_status_help_tab'
2548
+													 ),
2549
+								'html_help_text'  => esc_html__(
2550
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2551
+									'event_espresso'
2552
+								),
2553
+							]
2554
+						),
2555
+						'default_max_tickets' => new EE_Integer_Input(
2556
+							[
2557
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2558
+									? $registration_config->default_maximum_number_of_tickets
2559
+									: EEM_Event::get_default_additional_limit(),
2560
+								'html_label_text' => esc_html__(
2561
+									'Default Maximum Tickets Allowed Per Order:',
2562
+									'event_espresso'
2563
+								)
2564
+													 . EEH_Template::get_help_tab_link(
2565
+														 'default_maximum_tickets_help_tab"'
2566
+													 ),
2567
+								'html_help_text'  => esc_html__(
2568
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2569
+									'event_espresso'
2570
+								),
2571
+							]
2572
+						),
2573
+					]
2574
+				),
2575
+			]
2576
+		);
2577
+	}
2578
+
2579
+
2580
+	/**
2581
+	 * @return void
2582
+	 * @throws EE_Error
2583
+	 * @throws InvalidArgumentException
2584
+	 * @throws InvalidDataTypeException
2585
+	 * @throws InvalidInterfaceException
2586
+	 */
2587
+	protected function _update_default_event_settings()
2588
+	{
2589
+		$form = $this->_default_event_settings_form();
2590
+		if ($form->was_submitted()) {
2591
+			$form->receive_form_submission();
2592
+			if ($form->is_valid()) {
2593
+				$registration_config = EE_Registry::instance()->CFG->registration;
2594
+				$valid_data          = $form->valid_data();
2595
+				if (isset($valid_data['default_reg_status'])) {
2596
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2597
+				}
2598
+				if (isset($valid_data['default_max_tickets'])) {
2599
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2600
+				}
2601
+				do_action(
2602
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2603
+					$valid_data,
2604
+					EE_Registry::instance()->CFG,
2605
+					$this
2606
+				);
2607
+				// update because data was valid!
2608
+				EE_Registry::instance()->CFG->update_espresso_config();
2609
+				EE_Error::overwrite_success();
2610
+				EE_Error::add_success(
2611
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2612
+				);
2613
+			}
2614
+		}
2615
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2616
+	}
2617
+
2618
+
2619
+	/*************        Templates        *************
21 2620
      *
22
-     * @var EE_Event $_event
23
-     */
24
-    protected $_event;
25
-
26
-
27
-    /**
28
-     * This will hold the category object for category_details screen.
29
-     *
30
-     * @var stdClass $_category
31
-     */
32
-    protected $_category;
33
-
34
-
35
-    /**
36
-     * This will hold the event model instance
37
-     *
38
-     * @var EEM_Event $_event_model
39
-     */
40
-    protected $_event_model;
41
-
42
-
43
-    /**
44
-     * @var EE_Event
45
-     */
46
-    protected $_cpt_model_obj = false;
47
-
48
-
49
-    /**
50
-     * @var NodeGroupDao
51
-     */
52
-    protected $model_obj_node_group_persister;
53
-
54
-    /**
55
-     * @var AdvancedEditorAdminFormSection
56
-     */
57
-    protected $advanced_editor_admin_form;
58
-
59
-
60
-    /**
61
-     * Initialize page props for this admin page group.
62
-     */
63
-    protected function _init_page_props()
64
-    {
65
-        $this->page_slug        = EVENTS_PG_SLUG;
66
-        $this->page_label       = EVENTS_LABEL;
67
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
68
-        $this->_admin_base_path = EVENTS_ADMIN;
69
-        $this->_cpt_model_names = [
70
-            'create_new' => 'EEM_Event',
71
-            'edit'       => 'EEM_Event',
72
-        ];
73
-        $this->_cpt_edit_routes = [
74
-            'espresso_events' => 'edit',
75
-        ];
76
-        add_action(
77
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
78
-            [$this, 'verify_event_edit'],
79
-            10,
80
-            2
81
-        );
82
-    }
83
-
84
-
85
-    /**
86
-     * Sets the ajax hooks used for this admin page group.
87
-     */
88
-    protected function _ajax_hooks()
89
-    {
90
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
91
-    }
92
-
93
-
94
-    /**
95
-     * Sets the page properties for this admin page group.
96
-     */
97
-    protected function _define_page_props()
98
-    {
99
-        $this->_admin_page_title = EVENTS_LABEL;
100
-        $this->_labels           = [
101
-            'buttons'      => [
102
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
103
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
104
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
105
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
106
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
107
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
108
-            ],
109
-            'editor_title' => [
110
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
111
-            ],
112
-            'publishbox'   => [
113
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
114
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
115
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
116
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
117
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
118
-            ],
119
-        ];
120
-    }
121
-
122
-
123
-    /**
124
-     * Sets the page routes property for this admin page group.
125
-     */
126
-    protected function _set_page_routes()
127
-    {
128
-        // load formatter helper
129
-        // load field generator helper
130
-        // is there a evt_id in the request?
131
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
132
-        $EVT_ID = $this->request->getRequestParam('post', $EVT_ID, 'int');
133
-
134
-        $this->_page_routes = [
135
-            'default'                       => [
136
-                'func'       => [$this, '_events_overview_list_table'],
137
-                'capability' => 'ee_read_events',
138
-            ],
139
-            'create_new'                    => [
140
-                'func'       => [$this, '_create_new_cpt_item'],
141
-                'capability' => 'ee_edit_events',
142
-            ],
143
-            'edit'                          => [
144
-                'func'       => [$this, '_edit_cpt_item'],
145
-                'capability' => 'ee_edit_event',
146
-                'obj_id'     => $EVT_ID,
147
-            ],
148
-            'copy_event'                    => [
149
-                'func'       => [$this, '_copy_events'],
150
-                'capability' => 'ee_edit_event',
151
-                'obj_id'     => $EVT_ID,
152
-                'noheader'   => true,
153
-            ],
154
-            'trash_event'                   => [
155
-                'func'       => [$this, '_trash_or_restore_event'],
156
-                'args'       => ['event_status' => 'trash'],
157
-                'capability' => 'ee_delete_event',
158
-                'obj_id'     => $EVT_ID,
159
-                'noheader'   => true,
160
-            ],
161
-            'trash_events'                  => [
162
-                'func'       => [$this, '_trash_or_restore_events'],
163
-                'args'       => ['event_status' => 'trash'],
164
-                'capability' => 'ee_delete_events',
165
-                'noheader'   => true,
166
-            ],
167
-            'restore_event'                 => [
168
-                'func'       => [$this, '_trash_or_restore_event'],
169
-                'args'       => ['event_status' => 'draft'],
170
-                'capability' => 'ee_delete_event',
171
-                'obj_id'     => $EVT_ID,
172
-                'noheader'   => true,
173
-            ],
174
-            'restore_events'                => [
175
-                'func'       => [$this, '_trash_or_restore_events'],
176
-                'args'       => ['event_status' => 'draft'],
177
-                'capability' => 'ee_delete_events',
178
-                'noheader'   => true,
179
-            ],
180
-            'delete_event'                  => [
181
-                'func'       => [$this, '_delete_event'],
182
-                'capability' => 'ee_delete_event',
183
-                'obj_id'     => $EVT_ID,
184
-                'noheader'   => true,
185
-            ],
186
-            'delete_events'                 => [
187
-                'func'       => [$this, '_delete_events'],
188
-                'capability' => 'ee_delete_events',
189
-                'noheader'   => true,
190
-            ],
191
-            'view_report'                   => [
192
-                'func'       => [$this, '_view_report'],
193
-                'capability' => 'ee_edit_events',
194
-            ],
195
-            'default_event_settings'        => [
196
-                'func'       => [$this, '_default_event_settings'],
197
-                'capability' => 'manage_options',
198
-            ],
199
-            'update_default_event_settings' => [
200
-                'func'       => [$this, '_update_default_event_settings'],
201
-                'capability' => 'manage_options',
202
-                'noheader'   => true,
203
-            ],
204
-            'template_settings'             => [
205
-                'func'       => [$this, '_template_settings'],
206
-                'capability' => 'manage_options',
207
-            ],
208
-            // event category tab related
209
-            'add_category'                  => [
210
-                'func'       => [$this, '_category_details'],
211
-                'capability' => 'ee_edit_event_category',
212
-                'args'       => ['add'],
213
-            ],
214
-            'edit_category'                 => [
215
-                'func'       => [$this, '_category_details'],
216
-                'capability' => 'ee_edit_event_category',
217
-                'args'       => ['edit'],
218
-            ],
219
-            'delete_categories'             => [
220
-                'func'       => [$this, '_delete_categories'],
221
-                'capability' => 'ee_delete_event_category',
222
-                'noheader'   => true,
223
-            ],
224
-            'delete_category'               => [
225
-                'func'       => [$this, '_delete_categories'],
226
-                'capability' => 'ee_delete_event_category',
227
-                'noheader'   => true,
228
-            ],
229
-            'insert_category'               => [
230
-                'func'       => [$this, '_insert_or_update_category'],
231
-                'args'       => ['new_category' => true],
232
-                'capability' => 'ee_edit_event_category',
233
-                'noheader'   => true,
234
-            ],
235
-            'update_category'               => [
236
-                'func'       => [$this, '_insert_or_update_category'],
237
-                'args'       => ['new_category' => false],
238
-                'capability' => 'ee_edit_event_category',
239
-                'noheader'   => true,
240
-            ],
241
-            'category_list'                 => [
242
-                'func'       => [$this, '_category_list_table'],
243
-                'capability' => 'ee_manage_event_categories',
244
-            ],
245
-            'preview_deletion'              => [
246
-                'func'       => [$this, 'previewDeletion'],
247
-                'capability' => 'ee_delete_events',
248
-            ],
249
-            'confirm_deletion'              => [
250
-                'func'       => [$this, 'confirmDeletion'],
251
-                'capability' => 'ee_delete_events',
252
-                'noheader'   => true,
253
-            ],
254
-        ];
255
-    }
256
-
257
-
258
-    /**
259
-     * Set the _page_config property for this admin page group.
260
-     */
261
-    protected function _set_page_config()
262
-    {
263
-        $post_id            = $this->request->getRequestParam('post', 0, 'int');
264
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
265
-        $this->_page_config = [
266
-            'default'                => [
267
-                'nav'           => [
268
-                    'label' => esc_html__('Overview', 'event_espresso'),
269
-                    'icon' => 'dashicons-list-view',
270
-                    'order' => 10,
271
-                ],
272
-                'list_table'    => 'Events_Admin_List_Table',
273
-                'help_tabs'     => [
274
-                    'events_overview_help_tab'                       => [
275
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
276
-                        'filename' => 'events_overview',
277
-                    ],
278
-                    'events_overview_table_column_headings_help_tab' => [
279
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
280
-                        'filename' => 'events_overview_table_column_headings',
281
-                    ],
282
-                    'events_overview_filters_help_tab'               => [
283
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
284
-                        'filename' => 'events_overview_filters',
285
-                    ],
286
-                    'events_overview_view_help_tab'                  => [
287
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
288
-                        'filename' => 'events_overview_views',
289
-                    ],
290
-                    'events_overview_other_help_tab'                 => [
291
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
292
-                        'filename' => 'events_overview_other',
293
-                    ],
294
-                ],
295
-                'require_nonce' => false,
296
-            ],
297
-            'create_new'             => [
298
-                'nav'           => [
299
-                    'label'      => esc_html__('Add New Event', 'event_espresso'),
300
-                    'icon' => 'dashicons-plus-alt',
301
-                    'order'      => 15,
302
-                    'persistent' => false,
303
-                ],
304
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
305
-                'help_tabs'     => [
306
-                    'event_editor_help_tab'                            => [
307
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
308
-                        'filename' => 'event_editor',
309
-                    ],
310
-                    'event_editor_title_richtexteditor_help_tab'       => [
311
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
312
-                        'filename' => 'event_editor_title_richtexteditor',
313
-                    ],
314
-                    'event_editor_venue_details_help_tab'              => [
315
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
316
-                        'filename' => 'event_editor_venue_details',
317
-                    ],
318
-                    'event_editor_event_datetimes_help_tab'            => [
319
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
320
-                        'filename' => 'event_editor_event_datetimes',
321
-                    ],
322
-                    'event_editor_event_tickets_help_tab'              => [
323
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
324
-                        'filename' => 'event_editor_event_tickets',
325
-                    ],
326
-                    'event_editor_event_registration_options_help_tab' => [
327
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
328
-                        'filename' => 'event_editor_event_registration_options',
329
-                    ],
330
-                    'event_editor_tags_categories_help_tab'            => [
331
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
332
-                        'filename' => 'event_editor_tags_categories',
333
-                    ],
334
-                    'event_editor_questions_registrants_help_tab'      => [
335
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
336
-                        'filename' => 'event_editor_questions_registrants',
337
-                    ],
338
-                    'event_editor_save_new_event_help_tab'             => [
339
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
340
-                        'filename' => 'event_editor_save_new_event',
341
-                    ],
342
-                    'event_editor_other_help_tab'                      => [
343
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
344
-                        'filename' => 'event_editor_other',
345
-                    ],
346
-                ],
347
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
348
-                'require_nonce' => false,
349
-            ],
350
-            'edit'                   => [
351
-                'nav'           => [
352
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
353
-                    'icon' => 'dashicons-edit',
354
-                    'order'      => 15,
355
-                    'persistent' => false,
356
-                    'url'        => $post_id
357
-                        ? EE_Admin_Page::add_query_args_and_nonce(
358
-                            ['post' => $post_id, 'action' => 'edit'],
359
-                            $this->_current_page_view_url
360
-                        )
361
-                        : $this->_admin_base_url,
362
-                ],
363
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
364
-                'help_tabs'     => [
365
-                    'event_editor_help_tab'                            => [
366
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
367
-                        'filename' => 'event_editor',
368
-                    ],
369
-                    'event_editor_title_richtexteditor_help_tab'       => [
370
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
371
-                        'filename' => 'event_editor_title_richtexteditor',
372
-                    ],
373
-                    'event_editor_venue_details_help_tab'              => [
374
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
375
-                        'filename' => 'event_editor_venue_details',
376
-                    ],
377
-                    'event_editor_event_datetimes_help_tab'            => [
378
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
379
-                        'filename' => 'event_editor_event_datetimes',
380
-                    ],
381
-                    'event_editor_event_tickets_help_tab'              => [
382
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
383
-                        'filename' => 'event_editor_event_tickets',
384
-                    ],
385
-                    'event_editor_event_registration_options_help_tab' => [
386
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
387
-                        'filename' => 'event_editor_event_registration_options',
388
-                    ],
389
-                    'event_editor_tags_categories_help_tab'            => [
390
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
391
-                        'filename' => 'event_editor_tags_categories',
392
-                    ],
393
-                    'event_editor_questions_registrants_help_tab'      => [
394
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
395
-                        'filename' => 'event_editor_questions_registrants',
396
-                    ],
397
-                    'event_editor_save_new_event_help_tab'             => [
398
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
399
-                        'filename' => 'event_editor_save_new_event',
400
-                    ],
401
-                    'event_editor_other_help_tab'                      => [
402
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
403
-                        'filename' => 'event_editor_other',
404
-                    ],
405
-                ],
406
-                'require_nonce' => false,
407
-            ],
408
-            'default_event_settings' => [
409
-                'nav'           => [
410
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
411
-                    'icon' => 'dashicons-admin-generic',
412
-                    'order' => 40,
413
-                ],
414
-                'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
415
-                'labels'        => [
416
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
417
-                ],
418
-                'help_tabs'     => [
419
-                    'default_settings_help_tab'        => [
420
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
421
-                        'filename' => 'events_default_settings',
422
-                    ],
423
-                    'default_settings_status_help_tab' => [
424
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
425
-                        'filename' => 'events_default_settings_status',
426
-                    ],
427
-                    'default_maximum_tickets_help_tab' => [
428
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
429
-                        'filename' => 'events_default_settings_max_tickets',
430
-                    ],
431
-                ],
432
-                'require_nonce' => false,
433
-            ],
434
-            // template settings
435
-            'template_settings'      => [
436
-                'nav'           => [
437
-                    'label' => esc_html__('Templates', 'event_espresso'),
438
-                    'icon' => 'dashicons-layout',
439
-                    'order' => 30,
440
-                ],
441
-                'metaboxes'     => $this->_default_espresso_metaboxes,
442
-                'help_tabs'     => [
443
-                    'general_settings_templates_help_tab' => [
444
-                        'title'    => esc_html__('Templates', 'event_espresso'),
445
-                        'filename' => 'general_settings_templates',
446
-                    ],
447
-                ],
448
-                'require_nonce' => false,
449
-            ],
450
-            // event category stuff
451
-            'add_category'           => [
452
-                'nav'           => [
453
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
454
-                    'icon' => 'dashicons-plus-alt',
455
-                    'order'      => 25,
456
-                    'persistent' => false,
457
-                ],
458
-                'help_tabs'     => [
459
-                    'add_category_help_tab' => [
460
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
461
-                        'filename' => 'events_add_category',
462
-                    ],
463
-                ],
464
-                'metaboxes'     => ['_publish_post_box'],
465
-                'require_nonce' => false,
466
-            ],
467
-            'edit_category'          => [
468
-                'nav'           => [
469
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
470
-                    'icon' => 'dashicons-edit',
471
-                    'order'      => 25,
472
-                    'persistent' => false,
473
-                    'url'        => $EVT_CAT_ID
474
-                        ? add_query_arg(
475
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
476
-                            $this->_current_page_view_url
477
-                        )
478
-                        : $this->_admin_base_url,
479
-                ],
480
-                'help_tabs'     => [
481
-                    'edit_category_help_tab' => [
482
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
483
-                        'filename' => 'events_edit_category',
484
-                    ],
485
-                ],
486
-                'metaboxes'     => ['_publish_post_box'],
487
-                'require_nonce' => false,
488
-            ],
489
-            'category_list'          => [
490
-                'nav'           => [
491
-                    'label' => esc_html__('Categories', 'event_espresso'),
492
-                    'icon' => 'dashicons-networking',
493
-                    'order' => 20,
494
-                ],
495
-                'list_table'    => 'Event_Categories_Admin_List_Table',
496
-                'help_tabs'     => [
497
-                    'events_categories_help_tab'                       => [
498
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
499
-                        'filename' => 'events_categories',
500
-                    ],
501
-                    'events_categories_table_column_headings_help_tab' => [
502
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
503
-                        'filename' => 'events_categories_table_column_headings',
504
-                    ],
505
-                    'events_categories_view_help_tab'                  => [
506
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
507
-                        'filename' => 'events_categories_views',
508
-                    ],
509
-                    'events_categories_other_help_tab'                 => [
510
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
511
-                        'filename' => 'events_categories_other',
512
-                    ],
513
-                ],
514
-                'metaboxes'     => $this->_default_espresso_metaboxes,
515
-                'require_nonce' => false,
516
-            ],
517
-            'preview_deletion'       => [
518
-                'nav'           => [
519
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
520
-                    'icon' => 'dashicons-remove',
521
-                    'order'      => 15,
522
-                    'persistent' => false,
523
-                    'url'        => '',
524
-                ],
525
-                'require_nonce' => false,
526
-            ],
527
-        ];
528
-    }
529
-
530
-
531
-    /**
532
-     * Used to register any global screen options if necessary for every route in this admin page group.
533
-     */
534
-    protected function _add_screen_options()
535
-    {
536
-    }
537
-
538
-
539
-    /**
540
-     * Implementing the screen options for the 'default' route.
541
-     *
542
-     * @throws InvalidArgumentException
543
-     * @throws InvalidDataTypeException
544
-     * @throws InvalidInterfaceException
545
-     */
546
-    protected function _add_screen_options_default()
547
-    {
548
-        $this->_per_page_screen_option();
549
-    }
550
-
551
-
552
-    /**
553
-     * Implementing screen options for the category list route.
554
-     *
555
-     * @throws InvalidArgumentException
556
-     * @throws InvalidDataTypeException
557
-     * @throws InvalidInterfaceException
558
-     */
559
-    protected function _add_screen_options_category_list()
560
-    {
561
-        $page_title              = $this->_admin_page_title;
562
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
563
-        $this->_per_page_screen_option();
564
-        $this->_admin_page_title = $page_title;
565
-    }
566
-
567
-
568
-    /**
569
-     * Used to register any global feature pointers for the admin page group.
570
-     */
571
-    protected function _add_feature_pointers()
572
-    {
573
-    }
574
-
575
-
576
-    /**
577
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
578
-     */
579
-    public function load_scripts_styles()
580
-    {
581
-        wp_register_style(
582
-            'events-admin-css',
583
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
584
-            [],
585
-            EVENT_ESPRESSO_VERSION
586
-        );
587
-        wp_register_style(
588
-            'ee-cat-admin',
589
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
590
-            [],
591
-            EVENT_ESPRESSO_VERSION
592
-        );
593
-        wp_enqueue_style('events-admin-css');
594
-        wp_enqueue_style('ee-cat-admin');
595
-        // scripts
596
-        wp_register_script(
597
-            'event_editor_js',
598
-            EVENTS_ASSETS_URL . 'event_editor.js',
599
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
600
-            EVENT_ESPRESSO_VERSION,
601
-            true
602
-        );
603
-    }
604
-
605
-
606
-    /**
607
-     * Enqueuing scripts and styles specific to this view
608
-     */
609
-    public function load_scripts_styles_create_new()
610
-    {
611
-        $this->load_scripts_styles_edit();
612
-    }
613
-
614
-
615
-    /**
616
-     * Enqueuing scripts and styles specific to this view
617
-     */
618
-    public function load_scripts_styles_edit()
619
-    {
620
-        // styles
621
-        wp_enqueue_style('espresso-ui-theme');
622
-        wp_register_style(
623
-            'event-editor-css',
624
-            EVENTS_ASSETS_URL . 'event-editor.css',
625
-            ['ee-admin-css'],
626
-            EVENT_ESPRESSO_VERSION
627
-        );
628
-        wp_enqueue_style('event-editor-css');
629
-        // scripts
630
-        if (! $this->admin_config->useAdvancedEditor()) {
631
-            wp_register_script(
632
-                'event-datetime-metabox',
633
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
634
-                ['event_editor_js', 'ee-datepicker'],
635
-                EVENT_ESPRESSO_VERSION
636
-            );
637
-            wp_enqueue_script('event-datetime-metabox');
638
-        }
639
-    }
640
-
641
-
642
-    /**
643
-     * Populating the _views property for the category list table view.
644
-     */
645
-    protected function _set_list_table_views_category_list()
646
-    {
647
-        $this->_views = [
648
-            'all' => [
649
-                'slug'        => 'all',
650
-                'label'       => esc_html__('All', 'event_espresso'),
651
-                'count'       => 0,
652
-                'bulk_action' => [
653
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
654
-                ],
655
-            ],
656
-        ];
657
-    }
658
-
659
-
660
-    /**
661
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
662
-     */
663
-    public function admin_init()
664
-    {
665
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
666
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
667
-            'event_espresso'
668
-        );
669
-    }
670
-
671
-
672
-    /**
673
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
674
-     * group.
675
-     */
676
-    public function admin_notices()
677
-    {
678
-    }
679
-
680
-
681
-    /**
682
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
683
-     * this admin page group.
684
-     */
685
-    public function admin_footer_scripts()
686
-    {
687
-    }
688
-
689
-
690
-    /**
691
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
692
-     * warning (via EE_Error::add_error());
693
-     *
694
-     * @param EE_Event $event Event object
695
-     * @param string   $req_type
696
-     * @return void
697
-     * @throws EE_Error
698
-     * @throws ReflectionException
699
-     */
700
-    public function verify_event_edit($event = null, $req_type = '')
701
-    {
702
-        // don't need to do this when processing
703
-        if (! empty($req_type)) {
704
-            return;
705
-        }
706
-        // no event?
707
-        if (! $event instanceof EE_Event) {
708
-            $event = $this->_cpt_model_obj;
709
-        }
710
-        // STILL no event?
711
-        if (! $event instanceof EE_Event) {
712
-            return;
713
-        }
714
-        $orig_status = $event->status();
715
-        // first check if event is active.
716
-        if (
717
-            $orig_status === EEM_Event::cancelled
718
-            || $orig_status === EEM_Event::postponed
719
-            || $event->is_expired()
720
-            || $event->is_inactive()
721
-        ) {
722
-            return;
723
-        }
724
-        // made it here so it IS active... next check that any of the tickets are sold.
725
-        if ($event->is_sold_out(true)) {
726
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
727
-                EE_Error::add_attention(
728
-                    sprintf(
729
-                        esc_html__(
730
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
731
-                            'event_espresso'
732
-                        ),
733
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
734
-                    )
735
-                );
736
-            }
737
-            return;
738
-        }
739
-        if ($orig_status === EEM_Event::sold_out) {
740
-            EE_Error::add_attention(
741
-                sprintf(
742
-                    esc_html__(
743
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
744
-                        'event_espresso'
745
-                    ),
746
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
747
-                )
748
-            );
749
-        }
750
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
751
-        if (! $event->tickets_on_sale()) {
752
-            return;
753
-        }
754
-        // made it here so show warning
755
-        $this->_edit_event_warning();
756
-    }
757
-
758
-
759
-    /**
760
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
761
-     * When needed, hook this into a EE_Error::add_error() notice.
762
-     *
763
-     * @access protected
764
-     * @return void
765
-     */
766
-    protected function _edit_event_warning()
767
-    {
768
-        // we don't want to add warnings during these requests
769
-        if ($this->request->getRequestParam('action') === 'editpost') {
770
-            return;
771
-        }
772
-        EE_Error::add_attention(
773
-            sprintf(
774
-                esc_html__(
775
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
776
-                    'event_espresso'
777
-                ),
778
-                '<a class="espresso-help-tab-lnk ee-help-tab-link">',
779
-                '</a>'
780
-            )
781
-        );
782
-    }
783
-
784
-
785
-    /**
786
-     * When a user is creating a new event, notify them if they haven't set their timezone.
787
-     * Otherwise, do the normal logic
788
-     *
789
-     * @return void
790
-     * @throws EE_Error
791
-     * @throws InvalidArgumentException
792
-     * @throws InvalidDataTypeException
793
-     * @throws InvalidInterfaceException
794
-     */
795
-    protected function _create_new_cpt_item()
796
-    {
797
-        $has_timezone_string = get_option('timezone_string');
798
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
799
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
800
-            EE_Error::add_attention(
801
-                sprintf(
802
-                    esc_html__(
803
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
804
-                        'event_espresso'
805
-                    ),
806
-                    '<br>',
807
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
808
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
809
-                    . '</select>',
810
-                    '<button class="button button--secondary timezone-submit">',
811
-                    '</button><span class="spinner"></span>'
812
-                ),
813
-                __FILE__,
814
-                __FUNCTION__,
815
-                __LINE__
816
-            );
817
-        }
818
-        parent::_create_new_cpt_item();
819
-    }
820
-
821
-
822
-    /**
823
-     * Sets the _views property for the default route in this admin page group.
824
-     */
825
-    protected function _set_list_table_views_default()
826
-    {
827
-        $this->_views = [
828
-            'all'   => [
829
-                'slug'        => 'all',
830
-                'label'       => esc_html__('View All Events', 'event_espresso'),
831
-                'count'       => 0,
832
-                'bulk_action' => [
833
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
834
-                ],
835
-            ],
836
-            'draft' => [
837
-                'slug'        => 'draft',
838
-                'label'       => esc_html__('Draft', 'event_espresso'),
839
-                'count'       => 0,
840
-                'bulk_action' => [
841
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
842
-                ],
843
-            ],
844
-        ];
845
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
846
-            $this->_views['trash'] = [
847
-                'slug'        => 'trash',
848
-                'label'       => esc_html__('Trash', 'event_espresso'),
849
-                'count'       => 0,
850
-                'bulk_action' => [
851
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
852
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
853
-                ],
854
-            ];
855
-        }
856
-    }
857
-
858
-
859
-    /**
860
-     * Provides the legend item array for the default list table view.
861
-     *
862
-     * @return array
863
-     * @throws EE_Error
864
-     * @throws EE_Error
865
-     */
866
-    protected function _event_legend_items()
867
-    {
868
-        $items    = [
869
-            'view_details'   => [
870
-                'class' => 'dashicons dashicons-visibility',
871
-                'desc'  => esc_html__('View Event', 'event_espresso'),
872
-            ],
873
-            'edit_event'     => [
874
-                'class' => 'dashicons dashicons-calendar-alt',
875
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
876
-            ],
877
-            'view_attendees' => [
878
-                'class' => 'dashicons dashicons-groups',
879
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
880
-            ],
881
-        ];
882
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
883
-        $statuses = [
884
-            'sold_out_status'  => [
885
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
886
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
887
-            ],
888
-            'active_status'    => [
889
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
890
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
891
-            ],
892
-            'upcoming_status'  => [
893
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
894
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
895
-            ],
896
-            'postponed_status' => [
897
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
898
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
899
-            ],
900
-            'cancelled_status' => [
901
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
902
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
903
-            ],
904
-            'expired_status'   => [
905
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
906
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
907
-            ],
908
-            'inactive_status'  => [
909
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
910
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
911
-            ],
912
-        ];
913
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
914
-        return array_merge($items, $statuses);
915
-    }
916
-
917
-
918
-    /**
919
-     * @return EEM_Event
920
-     * @throws EE_Error
921
-     * @throws InvalidArgumentException
922
-     * @throws InvalidDataTypeException
923
-     * @throws InvalidInterfaceException
924
-     * @throws ReflectionException
925
-     */
926
-    private function _event_model()
927
-    {
928
-        if (! $this->_event_model instanceof EEM_Event) {
929
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
930
-        }
931
-        return $this->_event_model;
932
-    }
933
-
934
-
935
-    /**
936
-     * Adds extra buttons to the WP CPT permalink field row.
937
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
938
-     *
939
-     * @param string $return    the current html
940
-     * @param int    $id        the post id for the page
941
-     * @param string $new_title What the title is
942
-     * @param string $new_slug  what the slug is
943
-     * @return string            The new html string for the permalink area
944
-     */
945
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
946
-    {
947
-        // make sure this is only when editing
948
-        if (! empty($id)) {
949
-            $post = get_post($id);
950
-            $return .= '<a class="button button--small button--secondary" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
951
-                       . esc_html__('Shortcode', 'event_espresso')
952
-                       . '</a> ';
953
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
954
-                       . $post->ID
955
-                       . ']">';
956
-        }
957
-        return $return;
958
-    }
959
-
960
-
961
-    /**
962
-     * _events_overview_list_table
963
-     * This contains the logic for showing the events_overview list
964
-     *
965
-     * @access protected
966
-     * @return void
967
-     * @throws DomainException
968
-     * @throws EE_Error
969
-     * @throws InvalidArgumentException
970
-     * @throws InvalidDataTypeException
971
-     * @throws InvalidInterfaceException
972
-     */
973
-    protected function _events_overview_list_table()
974
-    {
975
-        $after_list_table                           = [];
976
-        $links_html = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
977
-        $links_html .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
978
-        $links_html .= EEH_HTML::div(
979
-            EEH_Template::get_button_or_link(
980
-                get_post_type_archive_link('espresso_events'),
981
-                esc_html__('View Event Archive Page', 'event_espresso'),
982
-                'button button--small button--secondary'
983
-            ),
984
-            '',
985
-            'ee-admin-button-row ee-admin-button-row--align-start'
986
-        );
987
-        $links_html .= EEH_HTML::divx();
988
-
989
-        $after_list_table['view_event_list_button'] = $links_html;
990
-
991
-        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
992
-        $this->_admin_page_title                    .= ' ' . $this->get_action_link_or_button(
993
-            'create_new',
994
-            'add',
995
-            [],
996
-            'add-new-h2'
997
-        );
998
-
999
-        $this->_template_args['after_list_table']   = array_merge(
1000
-            (array) $this->_template_args['after_list_table'],
1001
-            $after_list_table
1002
-        );
1003
-        $this->display_admin_list_table_page_with_no_sidebar();
1004
-    }
1005
-
1006
-
1007
-    /**
1008
-     * this allows for extra misc actions in the default WP publish box
1009
-     *
1010
-     * @return void
1011
-     * @throws DomainException
1012
-     * @throws EE_Error
1013
-     * @throws InvalidArgumentException
1014
-     * @throws InvalidDataTypeException
1015
-     * @throws InvalidInterfaceException
1016
-     * @throws ReflectionException
1017
-     */
1018
-    public function extra_misc_actions_publish_box()
1019
-    {
1020
-        $this->_generate_publish_box_extra_content();
1021
-    }
1022
-
1023
-
1024
-    /**
1025
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1026
-     * saved.
1027
-     * Typically you would use this to save any additional data.
1028
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1029
-     * ALSO very important.  When a post transitions from scheduled to published,
1030
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1031
-     * other meta saves. So MAKE sure that you handle this accordingly.
1032
-     *
1033
-     * @access protected
1034
-     * @abstract
1035
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
1036
-     * @param WP_Post $post    The post object of the cpt that was saved.
1037
-     * @return void
1038
-     * @throws EE_Error
1039
-     * @throws InvalidArgumentException
1040
-     * @throws InvalidDataTypeException
1041
-     * @throws InvalidInterfaceException
1042
-     * @throws ReflectionException
1043
-     */
1044
-    protected function _insert_update_cpt_item($post_id, $post)
1045
-    {
1046
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1047
-            // get out we're not processing an event save.
1048
-            return;
1049
-        }
1050
-        $event_values = [
1051
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, 'bool'),
1052
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, 'bool'),
1053
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1054
-        ];
1055
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1056
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1057
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1058
-                'display_ticket_selector',
1059
-                false,
1060
-                'bool'
1061
-            );
1062
-            $event_values['EVT_additional_limit']            = min(
1063
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1064
-                $this->request->getRequestParam(
1065
-                    'additional_limit',
1066
-                    EEM_Event::get_default_additional_limit(),
1067
-                    'int'
1068
-                )
1069
-            );
1070
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1071
-                'EVT_default_registration_status',
1072
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1073
-            );
1074
-
1075
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1076
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1077
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, 'bool');
1078
-        } elseif ($post instanceof WP_Post) {
1079
-            $event_values['EVT_name'] = $post->post_title;
1080
-            $event_values['EVT_desc'] = $post->post_content;
1081
-        }
1082
-        // update event
1083
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1084
-        // get event_object for other metaboxes...
1085
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1086
-        // i have to setup where conditions to override the filters in the model
1087
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1088
-        /** @var EE_Event $event */
1089
-        $event = $this->_event_model()->get_one(
1090
-            [
1091
-                [
1092
-                    $this->_event_model()->primary_key_name() => $post_id,
1093
-                    'OR'                                      => [
1094
-                        'status'   => $post->post_status,
1095
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1096
-                        // but the returned object here has a status of "publish", so use the original post status as well
1097
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1098
-                    ],
1099
-                ],
1100
-            ]
1101
-        );
1102
-
1103
-        // the following are default callbacks for event attachment updates
1104
-        // that can be overridden by caffeinated functionality and/or addons.
1105
-        $event_update_callbacks = [];
1106
-        if (! $this->admin_config->useAdvancedEditor()) {
1107
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1108
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1109
-        }
1110
-        $event_update_callbacks = apply_filters(
1111
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1112
-            $event_update_callbacks
1113
-        );
1114
-
1115
-        $att_success = true;
1116
-        foreach ($event_update_callbacks as $e_callback) {
1117
-            $_success = is_callable($e_callback)
1118
-                ? $e_callback($event, $this->request->requestParams())
1119
-                : false;
1120
-            // if ANY of these updates fail then we want the appropriate global error message
1121
-            $att_success = $_success !== false ? $att_success : false;
1122
-        }
1123
-        // any errors?
1124
-        if ($success && $att_success === false) {
1125
-            EE_Error::add_error(
1126
-                esc_html__(
1127
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1128
-                    'event_espresso'
1129
-                ),
1130
-                __FILE__,
1131
-                __FUNCTION__,
1132
-                __LINE__
1133
-            );
1134
-        } elseif ($success === false) {
1135
-            EE_Error::add_error(
1136
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1137
-                __FILE__,
1138
-                __FUNCTION__,
1139
-                __LINE__
1140
-            );
1141
-        }
1142
-    }
1143
-
1144
-
1145
-    /**
1146
-     * @param int $post_id
1147
-     * @param int $revision_id
1148
-     * @throws EE_Error
1149
-     * @throws EE_Error
1150
-     * @throws ReflectionException
1151
-     * @see parent::restore_item()
1152
-     */
1153
-    protected function _restore_cpt_item($post_id, $revision_id)
1154
-    {
1155
-        // copy existing event meta to new post
1156
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1157
-        if ($post_evt instanceof EE_Event) {
1158
-            // meta revision restore
1159
-            $post_evt->restore_revision($revision_id);
1160
-            // related objs restore
1161
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1162
-        }
1163
-    }
1164
-
1165
-
1166
-    /**
1167
-     * Attach the venue to the Event
1168
-     *
1169
-     * @param EE_Event $event Event Object to add the venue to
1170
-     * @param array    $data  The request data from the form
1171
-     * @return bool           Success or fail.
1172
-     * @throws EE_Error
1173
-     * @throws ReflectionException
1174
-     */
1175
-    protected function _default_venue_update(EE_Event $event, $data)
1176
-    {
1177
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1178
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1179
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1180
-        // very important.  If we don't have a venue name...
1181
-        // then we'll get out because not necessary to create empty venue
1182
-        if (empty($data['venue_title'])) {
1183
-            return false;
1184
-        }
1185
-        $venue_array = [
1186
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1187
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1188
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1189
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1190
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1191
-                ? $data['venue_short_description']
1192
-                : null,
1193
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1194
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1195
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1196
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1197
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1198
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1199
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1200
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1201
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1202
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1203
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1204
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1205
-            'status'              => 'publish',
1206
-        ];
1207
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1208
-        if (! empty($venue_id)) {
1209
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1210
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1211
-            // we've gotta make sure that the venue is always attached to a revision..
1212
-            // add_relation_to should take care of making sure that the relation is already present.
1213
-            $event->_add_relation_to($venue_id, 'Venue');
1214
-            return $rows_affected > 0;
1215
-        }
1216
-        // we insert the venue
1217
-        $venue_id = $venue_model->insert($venue_array);
1218
-        $event->_add_relation_to($venue_id, 'Venue');
1219
-        return ! empty($venue_id);
1220
-        // when we have the ancestor come in it's already been handled by the revision save.
1221
-    }
1222
-
1223
-
1224
-    /**
1225
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1226
-     *
1227
-     * @param EE_Event $event The Event object we're attaching data to
1228
-     * @param array    $data  The request data from the form
1229
-     * @return array
1230
-     * @throws EE_Error
1231
-     * @throws ReflectionException
1232
-     * @throws Exception
1233
-     */
1234
-    protected function _default_tickets_update(EE_Event $event, $data)
1235
-    {
1236
-        if ($this->admin_config->useAdvancedEditor()) {
1237
-            return [];
1238
-        }
1239
-        $datetime       = null;
1240
-        $saved_tickets  = [];
1241
-        $event_timezone = $event->get_timezone();
1242
-        $date_formats   = ['Y-m-d', 'h:i a'];
1243
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1244
-            // trim all values to ensure any excess whitespace is removed.
1245
-            $datetime_data                = array_map('trim', $datetime_data);
1246
-            $datetime_data['DTT_EVT_end'] =
1247
-                isset($datetime_data['DTT_EVT_end']) && ! empty($datetime_data['DTT_EVT_end'])
1248
-                    ? $datetime_data['DTT_EVT_end']
1249
-                    : $datetime_data['DTT_EVT_start'];
1250
-            $datetime_values              = [
1251
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1252
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1253
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1254
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1255
-                'DTT_order'     => $row,
1256
-            ];
1257
-            // if we have an id then let's get existing object first and then set the new values.
1258
-            //  Otherwise we instantiate a new object for save.
1259
-            if (! empty($datetime_data['DTT_ID'])) {
1260
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1261
-                if (! $datetime instanceof EE_Datetime) {
1262
-                    throw new RuntimeException(
1263
-                        sprintf(
1264
-                            esc_html__(
1265
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1266
-                                'event_espresso'
1267
-                            ),
1268
-                            $datetime_data['DTT_ID']
1269
-                        )
1270
-                    );
1271
-                }
1272
-                $datetime->set_date_format($date_formats[0]);
1273
-                $datetime->set_time_format($date_formats[1]);
1274
-                foreach ($datetime_values as $field => $value) {
1275
-                    $datetime->set($field, $value);
1276
-                }
1277
-            } else {
1278
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1279
-            }
1280
-            if (! $datetime instanceof EE_Datetime) {
1281
-                throw new RuntimeException(
1282
-                    sprintf(
1283
-                        esc_html__(
1284
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1285
-                            'event_espresso'
1286
-                        ),
1287
-                        print_r($datetime_values, true)
1288
-                    )
1289
-                );
1290
-            }
1291
-            // before going any further make sure our dates are setup correctly
1292
-            // so that the end date is always equal or greater than the start date.
1293
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1294
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1295
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1296
-            }
1297
-            $datetime->save();
1298
-            $event->_add_relation_to($datetime, 'Datetime');
1299
-        }
1300
-        // no datetimes get deleted so we don't do any of that logic here.
1301
-        // update tickets next
1302
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1303
-
1304
-        // set up some default start and end dates in case those are not present in the incoming data
1305
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1306
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1307
-        // use the start date of the first datetime for the end date
1308
-        $first_datetime   = $event->first_datetime();
1309
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1310
-
1311
-        // now process the incoming data
1312
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1313
-            $update_prices = false;
1314
-            $ticket_price  = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1315
-                ? $data['edit_prices'][ $row ][1]['PRC_amount']
1316
-                : 0;
1317
-            // trim inputs to ensure any excess whitespace is removed.
1318
-            $ticket_data   = array_map('trim', $ticket_data);
1319
-            $ticket_values = [
1320
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1321
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1322
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1323
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1324
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1325
-                    ? $ticket_data['TKT_start_date']
1326
-                    : $default_start_date,
1327
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1328
-                    ? $ticket_data['TKT_end_date']
1329
-                    : $default_end_date,
1330
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1331
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1332
-                    ? $ticket_data['TKT_qty']
1333
-                    : EE_INF,
1334
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1335
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1336
-                    ? $ticket_data['TKT_uses']
1337
-                    : EE_INF,
1338
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1339
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1340
-                'TKT_order'       => isset($ticket_data['TKT_order']) ? $ticket_data['TKT_order'] : $row,
1341
-                'TKT_price'       => $ticket_price,
1342
-                'TKT_row'         => $row,
1343
-            ];
1344
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1345
-            // which means in turn that the prices will become new prices as well.
1346
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1347
-                $ticket_values['TKT_ID']         = 0;
1348
-                $ticket_values['TKT_is_default'] = 0;
1349
-                $update_prices                   = true;
1350
-            }
1351
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1352
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1353
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1354
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1355
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1356
-            if (! empty($ticket_data['TKT_ID'])) {
1357
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1358
-                if (! $existing_ticket instanceof EE_Ticket) {
1359
-                    throw new RuntimeException(
1360
-                        sprintf(
1361
-                            esc_html__(
1362
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1363
-                                'event_espresso'
1364
-                            ),
1365
-                            $ticket_data['TKT_ID']
1366
-                        )
1367
-                    );
1368
-                }
1369
-                $ticket_sold = $existing_ticket->count_related(
1370
-                    'Registration',
1371
-                    [
1372
-                            [
1373
-                                'STS_ID' => [
1374
-                                    'NOT IN',
1375
-                                    [EEM_Registration::status_id_incomplete],
1376
-                                ],
1377
-                            ],
1378
-                        ]
1379
-                ) > 0;
1380
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1381
-                // if they are different then we create a new ticket (if $ticket_sold)
1382
-                // if they aren't different then we go ahead and modify existing ticket.
1383
-                $create_new_ticket = $ticket_sold
1384
-                                     && $ticket_price !== $existing_ticket->price()
1385
-                                     && ! $existing_ticket->deleted();
1386
-                $existing_ticket->set_date_format($date_formats[0]);
1387
-                $existing_ticket->set_time_format($date_formats[1]);
1388
-                // set new values
1389
-                foreach ($ticket_values as $field => $value) {
1390
-                    if ($field == 'TKT_qty') {
1391
-                        $existing_ticket->set_qty($value);
1392
-                    } elseif ($field == 'TKT_price') {
1393
-                        $existing_ticket->set('TKT_price', $ticket_price);
1394
-                    } else {
1395
-                        $existing_ticket->set($field, $value);
1396
-                    }
1397
-                }
1398
-                $ticket = $existing_ticket;
1399
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1400
-                //  Otherwise we have to create a new ticket.
1401
-                if ($create_new_ticket) {
1402
-                    // archive the old ticket first
1403
-                    $existing_ticket->set('TKT_deleted', 1);
1404
-                    $existing_ticket->save();
1405
-                    // make sure this ticket is still recorded in our $saved_tickets
1406
-                    // so we don't run it through the regular trash routine.
1407
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1408
-                    // create new ticket that's a copy of the existing except,
1409
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1410
-                    $new_ticket = clone $existing_ticket;
1411
-                    $new_ticket->set('TKT_ID', 0);
1412
-                    $new_ticket->set('TKT_deleted', 0);
1413
-                    $new_ticket->set('TKT_sold', 0);
1414
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1415
-                    $update_prices = true;
1416
-                    $ticket        = $new_ticket;
1417
-                }
1418
-            } else {
1419
-                // no TKT_id so a new ticket
1420
-                $ticket_values['TKT_price'] = $ticket_price;
1421
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1422
-                $update_prices              = true;
1423
-            }
1424
-            if (! $ticket instanceof EE_Ticket) {
1425
-                throw new RuntimeException(
1426
-                    sprintf(
1427
-                        esc_html__(
1428
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1429
-                            'event_espresso'
1430
-                        ),
1431
-                        print_r($ticket_values, true)
1432
-                    )
1433
-                );
1434
-            }
1435
-            // cap ticket qty by datetime reg limits
1436
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1437
-            // update ticket.
1438
-            $ticket->save();
1439
-            // before going any further make sure our dates are setup correctly
1440
-            // so that the end date is always equal or greater than the start date.
1441
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1442
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1443
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1444
-                $ticket->save();
1445
-            }
1446
-            // initially let's add the ticket to the datetime
1447
-            $datetime->_add_relation_to($ticket, 'Ticket');
1448
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1449
-            // add prices to ticket
1450
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1451
-                ? $data['edit_prices'][ $row ]
1452
-                : [];
1453
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1454
-        }
1455
-        // however now we need to handle permanently deleting tickets via the ui.
1456
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1457
-        // However, it does allow for deleting tickets that have no tickets sold,
1458
-        // in which case we want to get rid of permanently because there is no need to save in db.
1459
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1460
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1461
-        foreach ($tickets_removed as $id) {
1462
-            $id = absint($id);
1463
-            // get the ticket for this id
1464
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1465
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1466
-                continue;
1467
-            }
1468
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1469
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1470
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1471
-            foreach ($related_datetimes as $related_datetime) {
1472
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1473
-            }
1474
-            // need to do the same for prices (except these prices can also be deleted because again,
1475
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1476
-            $ticket_to_remove->delete_related_permanently('Price');
1477
-            // finally let's delete this ticket
1478
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1479
-            $ticket_to_remove->delete_permanently();
1480
-        }
1481
-        return [$datetime, $saved_tickets];
1482
-    }
1483
-
1484
-
1485
-    /**
1486
-     * This attaches a list of given prices to a ticket.
1487
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1488
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1489
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1490
-     *
1491
-     * @access  private
1492
-     * @param array     $prices_data Array of prices from the form.
1493
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1494
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1495
-     * @return  void
1496
-     * @throws EE_Error
1497
-     * @throws ReflectionException
1498
-     */
1499
-    private function _add_prices_to_ticket($prices_data, EE_Ticket $ticket, $new_prices = false)
1500
-    {
1501
-        $timezone = $ticket->get_timezone();
1502
-        foreach ($prices_data as $row => $price_data) {
1503
-            $price_values = [
1504
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1505
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1506
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1507
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1508
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1509
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1510
-                'PRC_order'      => $row,
1511
-            ];
1512
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1513
-                $price_values['PRC_ID'] = 0;
1514
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1515
-            } else {
1516
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1517
-                // update this price with new values
1518
-                foreach ($price_values as $field => $new_price) {
1519
-                    $price->set($field, $new_price);
1520
-                }
1521
-            }
1522
-            if (! $price instanceof EE_Price) {
1523
-                throw new RuntimeException(
1524
-                    sprintf(
1525
-                        esc_html__(
1526
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1527
-                            'event_espresso'
1528
-                        ),
1529
-                        print_r($price_values, true)
1530
-                    )
1531
-                );
1532
-            }
1533
-            $price->save();
1534
-            $ticket->_add_relation_to($price, 'Price');
1535
-        }
1536
-    }
1537
-
1538
-
1539
-    /**
1540
-     * Add in our autosave ajax handlers
1541
-     *
1542
-     */
1543
-    protected function _ee_autosave_create_new()
1544
-    {
1545
-    }
1546
-
1547
-
1548
-    /**
1549
-     * More autosave handlers.
1550
-     */
1551
-    protected function _ee_autosave_edit()
1552
-    {
1553
-    }
1554
-
1555
-
1556
-    /**
1557
-     * @throws EE_Error
1558
-     * @throws ReflectionException
1559
-     */
1560
-    private function _generate_publish_box_extra_content()
1561
-    {
1562
-        // load formatter helper
1563
-        // args for getting related registrations
1564
-        $approved_query_args        = [
1565
-            [
1566
-                'REG_deleted' => 0,
1567
-                'STS_ID'      => EEM_Registration::status_id_approved,
1568
-            ],
1569
-        ];
1570
-        $not_approved_query_args    = [
1571
-            [
1572
-                'REG_deleted' => 0,
1573
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1574
-            ],
1575
-        ];
1576
-        $pending_payment_query_args = [
1577
-            [
1578
-                'REG_deleted' => 0,
1579
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1580
-            ],
1581
-        ];
1582
-        // publish box
1583
-        $publish_box_extra_args = [
1584
-            'view_approved_reg_url'        => add_query_arg(
1585
-                [
1586
-                    'action'      => 'default',
1587
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1588
-                    '_reg_status' => EEM_Registration::status_id_approved,
1589
-                    'use_filters' => true,
1590
-                ],
1591
-                REG_ADMIN_URL
1592
-            ),
1593
-            'view_not_approved_reg_url'    => add_query_arg(
1594
-                [
1595
-                    'action'      => 'default',
1596
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1597
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1598
-                    'use_filters' => true,
1599
-                ],
1600
-                REG_ADMIN_URL
1601
-            ),
1602
-            'view_pending_payment_reg_url' => add_query_arg(
1603
-                [
1604
-                    'action'      => 'default',
1605
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1606
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1607
-                    'use_filters' => true,
1608
-                ],
1609
-                REG_ADMIN_URL
1610
-            ),
1611
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1612
-                'Registration',
1613
-                $approved_query_args
1614
-            ),
1615
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1616
-                'Registration',
1617
-                $not_approved_query_args
1618
-            ),
1619
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1620
-                'Registration',
1621
-                $pending_payment_query_args
1622
-            ),
1623
-            'misc_pub_section_class'       => apply_filters(
1624
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1625
-                'misc-pub-section'
1626
-            ),
1627
-        ];
1628
-        ob_start();
1629
-        do_action(
1630
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1631
-            $this->_cpt_model_obj
1632
-        );
1633
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1634
-        // load template
1635
-        EEH_Template::display_template(
1636
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1637
-            $publish_box_extra_args
1638
-        );
1639
-    }
1640
-
1641
-
1642
-    /**
1643
-     * @return EE_Event
1644
-     */
1645
-    public function get_event_object()
1646
-    {
1647
-        return $this->_cpt_model_obj;
1648
-    }
1649
-
1650
-
1651
-
1652
-
1653
-    /** METABOXES * */
1654
-    /**
1655
-     * _register_event_editor_meta_boxes
1656
-     * add all metaboxes related to the event_editor
1657
-     *
1658
-     * @return void
1659
-     * @throws EE_Error
1660
-     * @throws ReflectionException
1661
-     */
1662
-    protected function _register_event_editor_meta_boxes()
1663
-    {
1664
-        $this->verify_cpt_object();
1665
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1666
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1667
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1668
-            $this->addMetaBox(
1669
-                'espresso_event_editor_event_options',
1670
-                esc_html__('Event Registration Options', 'event_espresso'),
1671
-                [$this, 'registration_options_meta_box'],
1672
-                $this->page_slug,
1673
-                'side'
1674
-            );
1675
-        }
1676
-        if (! $use_advanced_editor) {
1677
-            $this->addMetaBox(
1678
-                'espresso_event_editor_tickets',
1679
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1680
-                [$this, 'ticket_metabox'],
1681
-                $this->page_slug,
1682
-                'normal',
1683
-                'high'
1684
-            );
1685
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1686
-            add_action(
1687
-                'add_meta_boxes_espresso_events',
1688
-                function () {
1689
-                    global $current_screen;
1690
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1691
-                },
1692
-                99
1693
-            );
1694
-        }
1695
-        // NOTE: if you're looking for other metaboxes in here,
1696
-        // where a metabox has a related management page in the admin
1697
-        // you will find it setup in the related management page's "_Hooks" file.
1698
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1699
-    }
1700
-
1701
-
1702
-    /**
1703
-     * @throws DomainException
1704
-     * @throws EE_Error
1705
-     * @throws ReflectionException
1706
-     */
1707
-    public function ticket_metabox()
1708
-    {
1709
-        $existing_datetime_ids = $existing_ticket_ids = [];
1710
-        // defaults for template args
1711
-        $template_args = [
1712
-            'ticket_rows'              => '',
1713
-            'total_ticket_rows'        => 1,
1714
-            'ticket_js_structure'      => '',
1715
-            'trash_icon'               => 'dashicons dashicons-lock',
1716
-            'disabled'                 => '',
1717
-        ];
1718
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1719
-        /**
1720
-         * 1. Start with retrieving Datetimes
1721
-         * 2. Fore each datetime get related tickets
1722
-         * 3. For each ticket get related prices
1723
-         */
1724
-        /** @var EEM_Datetime $datetime_model */
1725
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1726
-        /** @var EEM_Ticket $datetime_model */
1727
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1728
-        $times        = $datetime_model->get_all_event_dates($event_id);
1729
-        /** @type EE_Datetime $first_datetime */
1730
-        $first_datetime = reset($times);
1731
-        // do we get related tickets?
1732
-        if (
1733
-            $first_datetime instanceof EE_Datetime
1734
-            && $first_datetime->ID() !== 0
1735
-        ) {
1736
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1737
-            $template_args['time']   = $first_datetime;
1738
-            $related_tickets         = $first_datetime->tickets(
1739
-                [
1740
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1741
-                    'default_where_conditions' => 'none',
1742
-                ]
1743
-            );
1744
-            if (! empty($related_tickets)) {
1745
-                $template_args['total_ticket_rows'] = count($related_tickets);
1746
-                $row                                = 0;
1747
-                foreach ($related_tickets as $ticket) {
1748
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1749
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1750
-                    $row++;
1751
-                }
1752
-            } else {
1753
-                $template_args['total_ticket_rows'] = 1;
1754
-                /** @type EE_Ticket $ticket */
1755
-                $ticket                       = $ticket_model->create_default_object();
1756
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1757
-            }
1758
-        } else {
1759
-            $template_args['time'] = $times[0];
1760
-            /** @type EE_Ticket[] $tickets */
1761
-            $tickets                      = $ticket_model->get_all_default_tickets();
1762
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1763
-            // NOTE: we're just sending the first default row
1764
-            // (decaf can't manage default tickets so this should be sufficient);
1765
-        }
1766
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1767
-            'event_editor_event_datetimes_help_tab'
1768
-        );
1769
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1770
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1771
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1772
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1773
-            $ticket_model->create_default_object(),
1774
-            true
1775
-        );
1776
-        $template                                  = apply_filters(
1777
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1778
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1779
-        );
1780
-        EEH_Template::display_template($template, $template_args);
1781
-    }
1782
-
1783
-
1784
-    /**
1785
-     * Setup an individual ticket form for the decaf event editor page
1786
-     *
1787
-     * @access private
1788
-     * @param EE_Ticket $ticket   the ticket object
1789
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1790
-     * @param int       $row
1791
-     * @return string generated html for the ticket row.
1792
-     * @throws EE_Error
1793
-     * @throws ReflectionException
1794
-     */
1795
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1796
-    {
1797
-        $template_args = [
1798
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1799
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1800
-                : '',
1801
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1802
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1803
-            'TKT_name'            => $ticket->get('TKT_name'),
1804
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1805
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1806
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1807
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1808
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1809
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1810
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1811
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1812
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'dashicons dashicons-lock',
1813
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1814
-                : ' disabled=disabled',
1815
-        ];
1816
-        $price         = $ticket->ID() !== 0
1817
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1818
-            : null;
1819
-        $price         = $price instanceof EE_Price
1820
-            ? $price
1821
-            : EEM_Price::instance()->create_default_object();
1822
-        $price_args    = [
1823
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1824
-            'PRC_amount'            => $price->get('PRC_amount'),
1825
-            'PRT_ID'                => $price->get('PRT_ID'),
1826
-            'PRC_ID'                => $price->get('PRC_ID'),
1827
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1828
-        ];
1829
-        // make sure we have default start and end dates if skeleton
1830
-        // handle rows that should NOT be empty
1831
-        if (empty($template_args['TKT_start_date'])) {
1832
-            // if empty then the start date will be now.
1833
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1834
-        }
1835
-        if (empty($template_args['TKT_end_date'])) {
1836
-            // get the earliest datetime (if present);
1837
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1838
-                ? $this->_cpt_model_obj->get_first_related(
1839
-                    'Datetime',
1840
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1841
-                )
1842
-                : null;
1843
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1844
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1845
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1846
-        }
1847
-        $template_args = array_merge($template_args, $price_args);
1848
-        $template      = apply_filters(
1849
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1850
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1851
-            $ticket
1852
-        );
1853
-        return EEH_Template::display_template($template, $template_args, true);
1854
-    }
1855
-
1856
-
1857
-    /**
1858
-     * @throws EE_Error
1859
-     * @throws ReflectionException
1860
-     */
1861
-    public function registration_options_meta_box()
1862
-    {
1863
-        $yes_no_values             = [
1864
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1865
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1866
-        ];
1867
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1868
-            [
1869
-                EEM_Registration::status_id_cancelled,
1870
-                EEM_Registration::status_id_declined,
1871
-                EEM_Registration::status_id_incomplete,
1872
-            ],
1873
-            true
1874
-        );
1875
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1876
-        $template_args['_event']                          = $this->_cpt_model_obj;
1877
-        $template_args['event']                           = $this->_cpt_model_obj;
1878
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1879
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1880
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1881
-            'default_reg_status',
1882
-            $default_reg_status_values,
1883
-            $this->_cpt_model_obj->default_registration_status()
1884
-        );
1885
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1886
-            'display_desc',
1887
-            $yes_no_values,
1888
-            $this->_cpt_model_obj->display_description()
1889
-        );
1890
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1891
-            'display_ticket_selector',
1892
-            $yes_no_values,
1893
-            $this->_cpt_model_obj->display_ticket_selector(),
1894
-            '',
1895
-            '',
1896
-            false
1897
-        );
1898
-        $template_args['additional_registration_options'] = apply_filters(
1899
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1900
-            '',
1901
-            $template_args,
1902
-            $yes_no_values,
1903
-            $default_reg_status_values
1904
-        );
1905
-        EEH_Template::display_template(
1906
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1907
-            $template_args
1908
-        );
1909
-    }
1910
-
1911
-
1912
-    /**
1913
-     * _get_events()
1914
-     * This method simply returns all the events (for the given _view and paging)
1915
-     *
1916
-     * @access public
1917
-     * @param int  $per_page     count of items per page (20 default);
1918
-     * @param int  $current_page what is the current page being viewed.
1919
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1920
-     *                           If FALSE then we return an array of event objects
1921
-     *                           that match the given _view and paging parameters.
1922
-     * @return array|int         an array of event objects or a count of them.
1923
-     * @throws Exception
1924
-     */
1925
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1926
-    {
1927
-        $EEM_Event   = $this->_event_model();
1928
-        $offset      = ($current_page - 1) * $per_page;
1929
-        $limit       = $count ? null : $offset . ',' . $per_page;
1930
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1931
-        $order       = $this->request->getRequestParam('order', 'DESC');
1932
-        $month_range = $this->request->getRequestParam('month_range');
1933
-        if ($month_range) {
1934
-            $pieces = explode(' ', $month_range, 3);
1935
-            // simulate the FIRST day of the month, that fixes issues for months like February
1936
-            // where PHP doesn't know what to assume for date.
1937
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1938
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1939
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1940
-        }
1941
-        $where  = [];
1942
-        $status = $this->request->getRequestParam('status');
1943
-        // determine what post_status our condition will have for the query.
1944
-        switch ($status) {
1945
-            case 'month':
1946
-            case 'today':
1947
-            case null:
1948
-            case 'all':
1949
-                break;
1950
-            case 'draft':
1951
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1952
-                break;
1953
-            default:
1954
-                $where['status'] = $status;
1955
-        }
1956
-        // categories? The default for all categories is -1
1957
-        $category = $this->request->getRequestParam('EVT_CAT', -1, 'int');
1958
-        if ($category !== -1) {
1959
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1960
-            $where['Term_Taxonomy.term_id']  = $category;
1961
-        }
1962
-        // date where conditions
1963
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1964
-        if ($month_range) {
1965
-            $DateTime = new DateTime(
1966
-                $year_r . '-' . $month_r . '-01 00:00:00',
1967
-                new DateTimeZone('UTC')
1968
-            );
1969
-            $start    = $DateTime->getTimestamp();
1970
-            // set the datetime to be the end of the month
1971
-            $DateTime->setDate(
1972
-                $year_r,
1973
-                $month_r,
1974
-                $DateTime->format('t')
1975
-            )->setTime(23, 59, 59);
1976
-            $end                             = $DateTime->getTimestamp();
1977
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1978
-        } elseif ($status === 'today') {
1979
-            $DateTime                        =
1980
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1981
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1982
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1983
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1984
-        } elseif ($status === 'month') {
1985
-            $now                             = date('Y-m-01');
1986
-            $DateTime                        =
1987
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1988
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1989
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1990
-                                                        ->setTime(23, 59, 59)
1991
-                                                        ->format(implode(' ', $start_formats));
1992
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1993
-        }
1994
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1995
-            $where['EVT_wp_user'] = get_current_user_id();
1996
-        } else {
1997
-            if (! isset($where['status'])) {
1998
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1999
-                    $where['OR'] = [
2000
-                        'status*restrict_private' => ['!=', 'private'],
2001
-                        'AND'                     => [
2002
-                            'status*inclusive' => ['=', 'private'],
2003
-                            'EVT_wp_user'      => get_current_user_id(),
2004
-                        ],
2005
-                    ];
2006
-                }
2007
-            }
2008
-        }
2009
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, 'int');
2010
-        if (
2011
-            $wp_user
2012
-            && $wp_user !== get_current_user_id()
2013
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
2014
-        ) {
2015
-            $where['EVT_wp_user'] = $wp_user;
2016
-        }
2017
-        // search query handling
2018
-        $search_term = $this->request->getRequestParam('s');
2019
-        if ($search_term) {
2020
-            $search_term = '%' . $search_term . '%';
2021
-            $where['OR'] = [
2022
-                'EVT_name'       => ['LIKE', $search_term],
2023
-                'EVT_desc'       => ['LIKE', $search_term],
2024
-                'EVT_short_desc' => ['LIKE', $search_term],
2025
-            ];
2026
-        }
2027
-        // filter events by venue.
2028
-        $venue = $this->request->getRequestParam('venue', 0, 'int');
2029
-        if ($venue) {
2030
-            $where['Venue.VNU_ID'] = $venue;
2031
-        }
2032
-        $request_params = $this->request->requestParams();
2033
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2034
-        $query_params   = apply_filters(
2035
-            'FHEE__Events_Admin_Page__get_events__query_params',
2036
-            [
2037
-                $where,
2038
-                'limit'    => $limit,
2039
-                'order_by' => $orderby,
2040
-                'order'    => $order,
2041
-                'group_by' => 'EVT_ID',
2042
-            ],
2043
-            $request_params
2044
-        );
2045
-
2046
-        // let's first check if we have special requests coming in.
2047
-        $active_status = $this->request->getRequestParam('active_status');
2048
-        if ($active_status) {
2049
-            switch ($active_status) {
2050
-                case 'upcoming':
2051
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2052
-                case 'expired':
2053
-                    return $EEM_Event->get_expired_events($query_params, $count);
2054
-                case 'active':
2055
-                    return $EEM_Event->get_active_events($query_params, $count);
2056
-                case 'inactive':
2057
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2058
-            }
2059
-        }
2060
-
2061
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2062
-    }
2063
-
2064
-
2065
-    /**
2066
-     * handling for WordPress CPT actions (trash, restore, delete)
2067
-     *
2068
-     * @param string $post_id
2069
-     * @throws EE_Error
2070
-     * @throws ReflectionException
2071
-     */
2072
-    public function trash_cpt_item($post_id)
2073
-    {
2074
-        $this->request->setRequestParam('EVT_ID', $post_id);
2075
-        $this->_trash_or_restore_event('trash', false);
2076
-    }
2077
-
2078
-
2079
-    /**
2080
-     * @param string $post_id
2081
-     * @throws EE_Error
2082
-     * @throws ReflectionException
2083
-     */
2084
-    public function restore_cpt_item($post_id)
2085
-    {
2086
-        $this->request->setRequestParam('EVT_ID', $post_id);
2087
-        $this->_trash_or_restore_event('draft', false);
2088
-    }
2089
-
2090
-
2091
-    /**
2092
-     * @param string $post_id
2093
-     * @throws EE_Error
2094
-     * @throws EE_Error
2095
-     */
2096
-    public function delete_cpt_item($post_id)
2097
-    {
2098
-        throw new EE_Error(
2099
-            esc_html__(
2100
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2101
-                'event_espresso'
2102
-            )
2103
-        );
2104
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2105
-        // $this->_delete_event();
2106
-    }
2107
-
2108
-
2109
-    /**
2110
-     * _trash_or_restore_event
2111
-     *
2112
-     * @access protected
2113
-     * @param string $event_status
2114
-     * @param bool   $redirect_after
2115
-     * @throws EE_Error
2116
-     * @throws EE_Error
2117
-     * @throws ReflectionException
2118
-     */
2119
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2120
-    {
2121
-        // determine the event id and set to array.
2122
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2123
-        // loop thru events
2124
-        if ($EVT_ID) {
2125
-            // clean status
2126
-            $event_status = sanitize_key($event_status);
2127
-            // grab status
2128
-            if (! empty($event_status)) {
2129
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2130
-            } else {
2131
-                $success = false;
2132
-                $msg     = esc_html__(
2133
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2134
-                    'event_espresso'
2135
-                );
2136
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2137
-            }
2138
-        } else {
2139
-            $success = false;
2140
-            $msg     = esc_html__(
2141
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2142
-                'event_espresso'
2143
-            );
2144
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2145
-        }
2146
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2147
-        if ($redirect_after) {
2148
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2149
-        }
2150
-    }
2151
-
2152
-
2153
-    /**
2154
-     * _trash_or_restore_events
2155
-     *
2156
-     * @access protected
2157
-     * @param string $event_status
2158
-     * @return void
2159
-     * @throws EE_Error
2160
-     * @throws EE_Error
2161
-     * @throws ReflectionException
2162
-     */
2163
-    protected function _trash_or_restore_events($event_status = 'trash')
2164
-    {
2165
-        // clean status
2166
-        $event_status = sanitize_key($event_status);
2167
-        // grab status
2168
-        if (! empty($event_status)) {
2169
-            $success = true;
2170
-            // determine the event id and set to array.
2171
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2172
-            // loop thru events
2173
-            foreach ($EVT_IDs as $EVT_ID) {
2174
-                if ($EVT_ID = absint($EVT_ID)) {
2175
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2176
-                    $success = $results !== false ? $success : false;
2177
-                } else {
2178
-                    $msg = sprintf(
2179
-                        esc_html__(
2180
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2181
-                            'event_espresso'
2182
-                        ),
2183
-                        $EVT_ID
2184
-                    );
2185
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2186
-                    $success = false;
2187
-                }
2188
-            }
2189
-        } else {
2190
-            $success = false;
2191
-            $msg     = esc_html__(
2192
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2193
-                'event_espresso'
2194
-            );
2195
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2196
-        }
2197
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2198
-        $success = $success ? 2 : false;
2199
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2200
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2201
-    }
2202
-
2203
-
2204
-    /**
2205
-     * @param int    $EVT_ID
2206
-     * @param string $event_status
2207
-     * @return bool
2208
-     * @throws EE_Error
2209
-     * @throws ReflectionException
2210
-     */
2211
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2212
-    {
2213
-        // grab event id
2214
-        if (! $EVT_ID) {
2215
-            $msg = esc_html__(
2216
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2217
-                'event_espresso'
2218
-            );
2219
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
-            return false;
2221
-        }
2222
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2223
-        // clean status
2224
-        $event_status = sanitize_key($event_status);
2225
-        // grab status
2226
-        if (empty($event_status)) {
2227
-            $msg = esc_html__(
2228
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2229
-                'event_espresso'
2230
-            );
2231
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2232
-            return false;
2233
-        }
2234
-        // was event trashed or restored ?
2235
-        switch ($event_status) {
2236
-            case 'draft':
2237
-                $action = 'restored from the trash';
2238
-                $hook   = 'AHEE_event_restored_from_trash';
2239
-                break;
2240
-            case 'trash':
2241
-                $action = 'moved to the trash';
2242
-                $hook   = 'AHEE_event_moved_to_trash';
2243
-                break;
2244
-            default:
2245
-                $action = 'updated';
2246
-                $hook   = false;
2247
-        }
2248
-        // use class to change status
2249
-        $this->_cpt_model_obj->set_status($event_status);
2250
-        $success = $this->_cpt_model_obj->save();
2251
-        if (! $success) {
2252
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2253
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2254
-            return false;
2255
-        }
2256
-        if ($hook) {
2257
-            do_action($hook);
2258
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2259
-            // because events side step that and it otherwise won't get called
2260
-            do_action(
2261
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2262
-                $this->_cpt_model_obj,
2263
-                $hook === 'AHEE_event_moved_to_trash',
2264
-                $success
2265
-            );
2266
-        }
2267
-        return true;
2268
-    }
2269
-
2270
-
2271
-    /**
2272
-     * @param array $event_ids
2273
-     * @return array
2274
-     * @since   4.10.23.p
2275
-     */
2276
-    private function cleanEventIds(array $event_ids)
2277
-    {
2278
-        return array_map('absint', $event_ids);
2279
-    }
2280
-
2281
-
2282
-    /**
2283
-     * @return array
2284
-     * @since   4.10.23.p
2285
-     */
2286
-    private function getEventIdsFromRequest()
2287
-    {
2288
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2289
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2290
-        } else {
2291
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2292
-        }
2293
-    }
2294
-
2295
-
2296
-    /**
2297
-     * @param bool $preview_delete
2298
-     * @throws EE_Error
2299
-     * @throws ReflectionException
2300
-     */
2301
-    protected function _delete_event($preview_delete = true)
2302
-    {
2303
-        $this->_delete_events($preview_delete);
2304
-    }
2305
-
2306
-
2307
-    /**
2308
-     * Gets the tree traversal batch persister.
2309
-     *
2310
-     * @return NodeGroupDao
2311
-     * @throws InvalidArgumentException
2312
-     * @throws InvalidDataTypeException
2313
-     * @throws InvalidInterfaceException
2314
-     * @since 4.10.12.p
2315
-     */
2316
-    protected function getModelObjNodeGroupPersister()
2317
-    {
2318
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2319
-            $this->model_obj_node_group_persister =
2320
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2321
-        }
2322
-        return $this->model_obj_node_group_persister;
2323
-    }
2324
-
2325
-
2326
-    /**
2327
-     * @param bool $preview_delete
2328
-     * @return void
2329
-     * @throws EE_Error
2330
-     * @throws ReflectionException
2331
-     */
2332
-    protected function _delete_events($preview_delete = true)
2333
-    {
2334
-        $event_ids = $this->getEventIdsFromRequest();
2335
-        if ($preview_delete) {
2336
-            $this->generateDeletionPreview($event_ids);
2337
-        } else {
2338
-            foreach ($event_ids as $event_id) {
2339
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2340
-                if ($event instanceof EE_Event) {
2341
-                    $event->delete_permanently();
2342
-                }
2343
-            }
2344
-        }
2345
-    }
2346
-
2347
-
2348
-    /**
2349
-     * @param array $event_ids
2350
-     */
2351
-    protected function generateDeletionPreview(array $event_ids)
2352
-    {
2353
-        $event_ids = $this->cleanEventIds($event_ids);
2354
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2355
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2356
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2357
-            [
2358
-                'action'            => 'preview_deletion',
2359
-                'deletion_job_code' => $deletion_job_code,
2360
-            ],
2361
-            $this->_admin_base_url
2362
-        );
2363
-        EEH_URL::safeRedirectAndExit(
2364
-            EE_Admin_Page::add_query_args_and_nonce(
2365
-                [
2366
-                    'page'              => EED_Batch::PAGE_SLUG,
2367
-                    'batch'             => EED_Batch::batch_job,
2368
-                    'EVT_IDs'           => $event_ids,
2369
-                    'deletion_job_code' => $deletion_job_code,
2370
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2371
-                    'return_url'        => urlencode($return_url),
2372
-                ],
2373
-                admin_url()
2374
-            )
2375
-        );
2376
-    }
2377
-
2378
-
2379
-    /**
2380
-     * Checks for a POST submission
2381
-     *
2382
-     * @since 4.10.12.p
2383
-     */
2384
-    protected function confirmDeletion()
2385
-    {
2386
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2387
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2388
-        );
2389
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2390
-    }
2391
-
2392
-
2393
-    /**
2394
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2395
-     *
2396
-     * @throws EE_Error
2397
-     * @since 4.10.12.p
2398
-     */
2399
-    protected function previewDeletion()
2400
-    {
2401
-        $preview_deletion_logic = $this->getLoader()->getShared(
2402
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2403
-        );
2404
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2405
-        $this->display_admin_page_with_no_sidebar();
2406
-    }
2407
-
2408
-
2409
-    /**
2410
-     * get total number of events
2411
-     *
2412
-     * @access public
2413
-     * @return int
2414
-     * @throws EE_Error
2415
-     * @throws EE_Error
2416
-     */
2417
-    public function total_events()
2418
-    {
2419
-        return EEM_Event::instance()->count(
2420
-            ['caps' => 'read_admin'],
2421
-            'EVT_ID',
2422
-            true
2423
-        );
2424
-    }
2425
-
2426
-
2427
-    /**
2428
-     * get total number of draft events
2429
-     *
2430
-     * @access public
2431
-     * @return int
2432
-     * @throws EE_Error
2433
-     * @throws EE_Error
2434
-     */
2435
-    public function total_events_draft()
2436
-    {
2437
-        return EEM_Event::instance()->count(
2438
-            [
2439
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2440
-                'caps' => 'read_admin',
2441
-            ],
2442
-            'EVT_ID',
2443
-            true
2444
-        );
2445
-    }
2446
-
2447
-
2448
-    /**
2449
-     * get total number of trashed events
2450
-     *
2451
-     * @access public
2452
-     * @return int
2453
-     * @throws EE_Error
2454
-     * @throws EE_Error
2455
-     */
2456
-    public function total_trashed_events()
2457
-    {
2458
-        return EEM_Event::instance()->count(
2459
-            [
2460
-                ['status' => 'trash'],
2461
-                'caps' => 'read_admin',
2462
-            ],
2463
-            'EVT_ID',
2464
-            true
2465
-        );
2466
-    }
2467
-
2468
-
2469
-    /**
2470
-     *    _default_event_settings
2471
-     *    This generates the Default Settings Tab
2472
-     *
2473
-     * @return void
2474
-     * @throws DomainException
2475
-     * @throws EE_Error
2476
-     * @throws InvalidArgumentException
2477
-     * @throws InvalidDataTypeException
2478
-     * @throws InvalidInterfaceException
2479
-     */
2480
-    protected function _default_event_settings()
2481
-    {
2482
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2483
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2484
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
2485
-            $this->_default_event_settings_form()->get_html(),
2486
-            '',
2487
-            'padding'
2488
-        );
2489
-        $this->display_admin_page_with_sidebar();
2490
-    }
2491
-
2492
-
2493
-    /**
2494
-     * Return the form for event settings.
2495
-     *
2496
-     * @return EE_Form_Section_Proper
2497
-     * @throws EE_Error
2498
-     */
2499
-    protected function _default_event_settings_form()
2500
-    {
2501
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2502
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2503
-        // exclude
2504
-            [
2505
-                EEM_Registration::status_id_cancelled,
2506
-                EEM_Registration::status_id_declined,
2507
-                EEM_Registration::status_id_incomplete,
2508
-                EEM_Registration::status_id_wait_list,
2509
-            ],
2510
-            true
2511
-        );
2512
-        // setup Advanced Editor ???
2513
-        if (
2514
-            $this->raw_req_action === 'default_event_settings'
2515
-            || $this->raw_req_action === 'update_default_event_settings'
2516
-        ) {
2517
-            $this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2518
-        }
2519
-        return new EE_Form_Section_Proper(
2520
-            [
2521
-                'name'            => 'update_default_event_settings',
2522
-                'html_id'         => 'update_default_event_settings',
2523
-                'html_class'      => 'form-table',
2524
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2525
-                'subsections'     => apply_filters(
2526
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2527
-                    [
2528
-                        'defaults_section_header' => new EE_Form_Section_HTML(
2529
-                            EEH_HTML::h2(
2530
-                                esc_html__('Default Settings', 'event_espresso'),
2531
-                                '',
2532
-                                'ee-admin-settings-hdr'
2533
-                            )
2534
-                        ),
2535
-                        'default_reg_status'  => new EE_Select_Input(
2536
-                            $registration_stati_for_selection,
2537
-                            [
2538
-                                'default'         => isset($registration_config->default_STS_ID)
2539
-                                                     && array_key_exists(
2540
-                                                         $registration_config->default_STS_ID,
2541
-                                                         $registration_stati_for_selection
2542
-                                                     )
2543
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2544
-                                    : EEM_Registration::status_id_pending_payment,
2545
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2546
-                                                     . EEH_Template::get_help_tab_link(
2547
-                                                         'default_settings_status_help_tab'
2548
-                                                     ),
2549
-                                'html_help_text'  => esc_html__(
2550
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2551
-                                    'event_espresso'
2552
-                                ),
2553
-                            ]
2554
-                        ),
2555
-                        'default_max_tickets' => new EE_Integer_Input(
2556
-                            [
2557
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2558
-                                    ? $registration_config->default_maximum_number_of_tickets
2559
-                                    : EEM_Event::get_default_additional_limit(),
2560
-                                'html_label_text' => esc_html__(
2561
-                                    'Default Maximum Tickets Allowed Per Order:',
2562
-                                    'event_espresso'
2563
-                                )
2564
-                                                     . EEH_Template::get_help_tab_link(
2565
-                                                         'default_maximum_tickets_help_tab"'
2566
-                                                     ),
2567
-                                'html_help_text'  => esc_html__(
2568
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2569
-                                    'event_espresso'
2570
-                                ),
2571
-                            ]
2572
-                        ),
2573
-                    ]
2574
-                ),
2575
-            ]
2576
-        );
2577
-    }
2578
-
2579
-
2580
-    /**
2581
-     * @return void
2582
-     * @throws EE_Error
2583
-     * @throws InvalidArgumentException
2584
-     * @throws InvalidDataTypeException
2585
-     * @throws InvalidInterfaceException
2586
-     */
2587
-    protected function _update_default_event_settings()
2588
-    {
2589
-        $form = $this->_default_event_settings_form();
2590
-        if ($form->was_submitted()) {
2591
-            $form->receive_form_submission();
2592
-            if ($form->is_valid()) {
2593
-                $registration_config = EE_Registry::instance()->CFG->registration;
2594
-                $valid_data          = $form->valid_data();
2595
-                if (isset($valid_data['default_reg_status'])) {
2596
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2597
-                }
2598
-                if (isset($valid_data['default_max_tickets'])) {
2599
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2600
-                }
2601
-                do_action(
2602
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2603
-                    $valid_data,
2604
-                    EE_Registry::instance()->CFG,
2605
-                    $this
2606
-                );
2607
-                // update because data was valid!
2608
-                EE_Registry::instance()->CFG->update_espresso_config();
2609
-                EE_Error::overwrite_success();
2610
-                EE_Error::add_success(
2611
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2612
-                );
2613
-            }
2614
-        }
2615
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2616
-    }
2617
-
2618
-
2619
-    /*************        Templates        *************
2620
-     *
2621
-     * @throws EE_Error
2622
-     */
2623
-    protected function _template_settings()
2624
-    {
2625
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2626
-        $this->_template_args['preview_img']  = '<img src="'
2627
-                                                . EVENTS_ASSETS_URL
2628
-                                                . '/images/'
2629
-                                                . 'caffeinated_template_features.jpg" alt="'
2630
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2631
-                                                . '" />';
2632
-        $this->_template_args['preview_text'] = '<strong>'
2633
-                                                . esc_html__(
2634
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2635
-                                                    'event_espresso'
2636
-                                                ) . '</strong>';
2637
-        $this->display_admin_caf_preview_page('template_settings_tab');
2638
-    }
2639
-
2640
-
2641
-    /** Event Category Stuff **/
2642
-    /**
2643
-     * set the _category property with the category object for the loaded page.
2644
-     *
2645
-     * @access private
2646
-     * @return void
2647
-     */
2648
-    private function _set_category_object()
2649
-    {
2650
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2651
-            return;
2652
-        } //already have the category object so get out.
2653
-        // set default category object
2654
-        $this->_set_empty_category_object();
2655
-        // only set if we've got an id
2656
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2657
-        if (! $category_ID) {
2658
-            return;
2659
-        }
2660
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2661
-        if (! empty($term)) {
2662
-            $this->_category->category_name       = $term->name;
2663
-            $this->_category->category_identifier = $term->slug;
2664
-            $this->_category->category_desc       = $term->description;
2665
-            $this->_category->id                  = $term->term_id;
2666
-            $this->_category->parent              = $term->parent;
2667
-        }
2668
-    }
2669
-
2670
-
2671
-    /**
2672
-     * Clears out category properties.
2673
-     */
2674
-    private function _set_empty_category_object()
2675
-    {
2676
-        $this->_category                = new stdClass();
2677
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2678
-        $this->_category->id            = $this->_category->parent = 0;
2679
-    }
2680
-
2681
-
2682
-    /**
2683
-     * @throws DomainException
2684
-     * @throws EE_Error
2685
-     * @throws InvalidArgumentException
2686
-     * @throws InvalidDataTypeException
2687
-     * @throws InvalidInterfaceException
2688
-     */
2689
-    protected function _category_list_table()
2690
-    {
2691
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2692
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2693
-        $this->_admin_page_title .= ' ';
2694
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2695
-            'add_category',
2696
-            'add_category',
2697
-            [],
2698
-            'add-new-h2'
2699
-        );
2700
-        $this->display_admin_list_table_page_with_sidebar();
2701
-    }
2702
-
2703
-
2704
-    /**
2705
-     * Output category details view.
2706
-     *
2707
-     * @throws EE_Error
2708
-     * @throws EE_Error
2709
-     */
2710
-    protected function _category_details($view)
2711
-    {
2712
-        // load formatter helper
2713
-        // load field generator helper
2714
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2715
-        $this->_set_add_edit_form_tags($route);
2716
-        $this->_set_category_object();
2717
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2718
-        $delete_action = 'delete_category';
2719
-        // custom redirect
2720
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2721
-            ['action' => 'category_list'],
2722
-            $this->_admin_base_url
2723
-        );
2724
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2725
-        // take care of contents
2726
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2727
-        $this->display_admin_page_with_sidebar();
2728
-    }
2729
-
2730
-
2731
-    /**
2732
-     * Output category details content.
2733
-     *
2734
-     * @throws DomainException
2735
-     */
2736
-    protected function _category_details_content()
2737
-    {
2738
-        $editor_args['category_desc'] = [
2739
-            'type'          => 'wp_editor',
2740
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2741
-            'class'         => 'my_editor_custom',
2742
-            'wpeditor_args' => ['media_buttons' => false],
2743
-        ];
2744
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2745
-        $all_terms                    = get_terms(
2746
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2747
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2748
-        );
2749
-        // setup category select for term parents.
2750
-        $category_select_values[] = [
2751
-            'text' => esc_html__('No Parent', 'event_espresso'),
2752
-            'id'   => 0,
2753
-        ];
2754
-        foreach ($all_terms as $term) {
2755
-            $category_select_values[] = [
2756
-                'text' => $term->name,
2757
-                'id'   => $term->term_id,
2758
-            ];
2759
-        }
2760
-        $category_select = EEH_Form_Fields::select_input(
2761
-            'category_parent',
2762
-            $category_select_values,
2763
-            $this->_category->parent
2764
-        );
2765
-        $template_args   = [
2766
-            'category'                 => $this->_category,
2767
-            'category_select'          => $category_select,
2768
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2769
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2770
-            'disable'                  => '',
2771
-            'disabled_message'         => false,
2772
-        ];
2773
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2774
-        return EEH_Template::display_template($template, $template_args, true);
2775
-    }
2776
-
2777
-
2778
-    /**
2779
-     * Handles deleting categories.
2780
-     *
2781
-     * @throws EE_Error
2782
-     */
2783
-    protected function _delete_categories()
2784
-    {
2785
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2786
-        foreach ($category_IDs as $category_ID) {
2787
-            $this->_delete_category($category_ID);
2788
-        }
2789
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2790
-        $query_args = [
2791
-            'action' => 'category_list',
2792
-        ];
2793
-        $this->_redirect_after_action(0, '', '', $query_args);
2794
-    }
2795
-
2796
-
2797
-    /**
2798
-     * Handles deleting specific category.
2799
-     *
2800
-     * @param int $cat_id
2801
-     */
2802
-    protected function _delete_category($cat_id)
2803
-    {
2804
-        $cat_id = absint($cat_id);
2805
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2806
-    }
2807
-
2808
-
2809
-    /**
2810
-     * Handles triggering the update or insertion of a new category.
2811
-     *
2812
-     * @param bool $new_category true means we're triggering the insert of a new category.
2813
-     * @throws EE_Error
2814
-     * @throws EE_Error
2815
-     */
2816
-    protected function _insert_or_update_category($new_category)
2817
-    {
2818
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2819
-        $success = 0; // we already have a success message so lets not send another.
2820
-        if ($cat_id) {
2821
-            $query_args = [
2822
-                'action'     => 'edit_category',
2823
-                'EVT_CAT_ID' => $cat_id,
2824
-            ];
2825
-        } else {
2826
-            $query_args = ['action' => 'add_category'];
2827
-        }
2828
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2829
-    }
2830
-
2831
-
2832
-    /**
2833
-     * Inserts or updates category
2834
-     *
2835
-     * @param bool $update (true indicates we're updating a category).
2836
-     * @return bool|mixed|string
2837
-     */
2838
-    private function _insert_category($update = false)
2839
-    {
2840
-        $category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2841
-        $category_name       = $this->request->getRequestParam('category_name', '');
2842
-        $category_desc       = $this->request->getRequestParam('category_desc', '');
2843
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2844
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2845
-
2846
-        if (empty($category_name)) {
2847
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2848
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2849
-            return false;
2850
-        }
2851
-        $term_args = [
2852
-            'name'        => $category_name,
2853
-            'description' => $category_desc,
2854
-            'parent'      => $category_parent,
2855
-        ];
2856
-        // was the category_identifier input disabled?
2857
-        if ($category_identifier) {
2858
-            $term_args['slug'] = $category_identifier;
2859
-        }
2860
-        $insert_ids = $update
2861
-            ? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2862
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2863
-        if (! is_array($insert_ids)) {
2864
-            $msg = esc_html__(
2865
-                'An error occurred and the category has not been saved to the database.',
2866
-                'event_espresso'
2867
-            );
2868
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2869
-        } else {
2870
-            $category_ID = $insert_ids['term_id'];
2871
-            $msg         = sprintf(
2872
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2873
-                $category_name
2874
-            );
2875
-            EE_Error::add_success($msg);
2876
-        }
2877
-        return $category_ID;
2878
-    }
2879
-
2880
-
2881
-    /**
2882
-     * Gets categories or count of categories matching the arguments in the request.
2883
-     *
2884
-     * @param int  $per_page
2885
-     * @param int  $current_page
2886
-     * @param bool $count
2887
-     * @return EE_Term_Taxonomy[]|int
2888
-     * @throws EE_Error
2889
-     */
2890
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2891
-    {
2892
-        // testing term stuff
2893
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2894
-        $order       = $this->request->getRequestParam('order', 'DESC');
2895
-        $limit       = ($current_page - 1) * $per_page;
2896
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2897
-        $search_term = $this->request->getRequestParam('s');
2898
-        if ($search_term) {
2899
-            $search_term = '%' . $search_term . '%';
2900
-            $where['OR'] = [
2901
-                'Term.name'   => ['LIKE', $search_term],
2902
-                'description' => ['LIKE', $search_term],
2903
-            ];
2904
-        }
2905
-        $query_params = [
2906
-            $where,
2907
-            'order_by'   => [$orderby => $order],
2908
-            'limit'      => $limit . ',' . $per_page,
2909
-            'force_join' => ['Term'],
2910
-        ];
2911
-        return $count
2912
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2913
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2914
-    }
2915
-
2916
-    /* end category stuff */
2917
-
2918
-
2919
-    /**************/
2920
-
2921
-
2922
-    /**
2923
-     * Callback for the `ee_save_timezone_setting` ajax action.
2924
-     *
2925
-     * @throws EE_Error
2926
-     * @throws InvalidArgumentException
2927
-     * @throws InvalidDataTypeException
2928
-     * @throws InvalidInterfaceException
2929
-     */
2930
-    public function saveTimezoneString()
2931
-    {
2932
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2933
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2934
-            EE_Error::add_error(
2935
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2936
-                __FILE__,
2937
-                __FUNCTION__,
2938
-                __LINE__
2939
-            );
2940
-            $this->_template_args['error'] = true;
2941
-            $this->_return_json();
2942
-        }
2943
-
2944
-        update_option('timezone_string', $timezone_string);
2945
-        EE_Error::add_success(
2946
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2947
-        );
2948
-        $this->_template_args['success'] = true;
2949
-        $this->_return_json(true, ['action' => 'create_new']);
2950
-    }
2951
-
2952
-
2953
-    /**
2954 2621
      * @throws EE_Error
2955
-     * @deprecated 4.10.25.p
2956 2622
      */
2957
-    public function save_timezonestring_setting()
2958
-    {
2959
-        $this->saveTimezoneString();
2960
-    }
2623
+	protected function _template_settings()
2624
+	{
2625
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2626
+		$this->_template_args['preview_img']  = '<img src="'
2627
+												. EVENTS_ASSETS_URL
2628
+												. '/images/'
2629
+												. 'caffeinated_template_features.jpg" alt="'
2630
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2631
+												. '" />';
2632
+		$this->_template_args['preview_text'] = '<strong>'
2633
+												. esc_html__(
2634
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2635
+													'event_espresso'
2636
+												) . '</strong>';
2637
+		$this->display_admin_caf_preview_page('template_settings_tab');
2638
+	}
2639
+
2640
+
2641
+	/** Event Category Stuff **/
2642
+	/**
2643
+	 * set the _category property with the category object for the loaded page.
2644
+	 *
2645
+	 * @access private
2646
+	 * @return void
2647
+	 */
2648
+	private function _set_category_object()
2649
+	{
2650
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2651
+			return;
2652
+		} //already have the category object so get out.
2653
+		// set default category object
2654
+		$this->_set_empty_category_object();
2655
+		// only set if we've got an id
2656
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
2657
+		if (! $category_ID) {
2658
+			return;
2659
+		}
2660
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2661
+		if (! empty($term)) {
2662
+			$this->_category->category_name       = $term->name;
2663
+			$this->_category->category_identifier = $term->slug;
2664
+			$this->_category->category_desc       = $term->description;
2665
+			$this->_category->id                  = $term->term_id;
2666
+			$this->_category->parent              = $term->parent;
2667
+		}
2668
+	}
2669
+
2670
+
2671
+	/**
2672
+	 * Clears out category properties.
2673
+	 */
2674
+	private function _set_empty_category_object()
2675
+	{
2676
+		$this->_category                = new stdClass();
2677
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2678
+		$this->_category->id            = $this->_category->parent = 0;
2679
+	}
2680
+
2681
+
2682
+	/**
2683
+	 * @throws DomainException
2684
+	 * @throws EE_Error
2685
+	 * @throws InvalidArgumentException
2686
+	 * @throws InvalidDataTypeException
2687
+	 * @throws InvalidInterfaceException
2688
+	 */
2689
+	protected function _category_list_table()
2690
+	{
2691
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2692
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2693
+		$this->_admin_page_title .= ' ';
2694
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2695
+			'add_category',
2696
+			'add_category',
2697
+			[],
2698
+			'add-new-h2'
2699
+		);
2700
+		$this->display_admin_list_table_page_with_sidebar();
2701
+	}
2702
+
2703
+
2704
+	/**
2705
+	 * Output category details view.
2706
+	 *
2707
+	 * @throws EE_Error
2708
+	 * @throws EE_Error
2709
+	 */
2710
+	protected function _category_details($view)
2711
+	{
2712
+		// load formatter helper
2713
+		// load field generator helper
2714
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2715
+		$this->_set_add_edit_form_tags($route);
2716
+		$this->_set_category_object();
2717
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2718
+		$delete_action = 'delete_category';
2719
+		// custom redirect
2720
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2721
+			['action' => 'category_list'],
2722
+			$this->_admin_base_url
2723
+		);
2724
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2725
+		// take care of contents
2726
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2727
+		$this->display_admin_page_with_sidebar();
2728
+	}
2729
+
2730
+
2731
+	/**
2732
+	 * Output category details content.
2733
+	 *
2734
+	 * @throws DomainException
2735
+	 */
2736
+	protected function _category_details_content()
2737
+	{
2738
+		$editor_args['category_desc'] = [
2739
+			'type'          => 'wp_editor',
2740
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2741
+			'class'         => 'my_editor_custom',
2742
+			'wpeditor_args' => ['media_buttons' => false],
2743
+		];
2744
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2745
+		$all_terms                    = get_terms(
2746
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2747
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2748
+		);
2749
+		// setup category select for term parents.
2750
+		$category_select_values[] = [
2751
+			'text' => esc_html__('No Parent', 'event_espresso'),
2752
+			'id'   => 0,
2753
+		];
2754
+		foreach ($all_terms as $term) {
2755
+			$category_select_values[] = [
2756
+				'text' => $term->name,
2757
+				'id'   => $term->term_id,
2758
+			];
2759
+		}
2760
+		$category_select = EEH_Form_Fields::select_input(
2761
+			'category_parent',
2762
+			$category_select_values,
2763
+			$this->_category->parent
2764
+		);
2765
+		$template_args   = [
2766
+			'category'                 => $this->_category,
2767
+			'category_select'          => $category_select,
2768
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2769
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2770
+			'disable'                  => '',
2771
+			'disabled_message'         => false,
2772
+		];
2773
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2774
+		return EEH_Template::display_template($template, $template_args, true);
2775
+	}
2776
+
2777
+
2778
+	/**
2779
+	 * Handles deleting categories.
2780
+	 *
2781
+	 * @throws EE_Error
2782
+	 */
2783
+	protected function _delete_categories()
2784
+	{
2785
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2786
+		foreach ($category_IDs as $category_ID) {
2787
+			$this->_delete_category($category_ID);
2788
+		}
2789
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2790
+		$query_args = [
2791
+			'action' => 'category_list',
2792
+		];
2793
+		$this->_redirect_after_action(0, '', '', $query_args);
2794
+	}
2795
+
2796
+
2797
+	/**
2798
+	 * Handles deleting specific category.
2799
+	 *
2800
+	 * @param int $cat_id
2801
+	 */
2802
+	protected function _delete_category($cat_id)
2803
+	{
2804
+		$cat_id = absint($cat_id);
2805
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2806
+	}
2807
+
2808
+
2809
+	/**
2810
+	 * Handles triggering the update or insertion of a new category.
2811
+	 *
2812
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2813
+	 * @throws EE_Error
2814
+	 * @throws EE_Error
2815
+	 */
2816
+	protected function _insert_or_update_category($new_category)
2817
+	{
2818
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2819
+		$success = 0; // we already have a success message so lets not send another.
2820
+		if ($cat_id) {
2821
+			$query_args = [
2822
+				'action'     => 'edit_category',
2823
+				'EVT_CAT_ID' => $cat_id,
2824
+			];
2825
+		} else {
2826
+			$query_args = ['action' => 'add_category'];
2827
+		}
2828
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2829
+	}
2830
+
2831
+
2832
+	/**
2833
+	 * Inserts or updates category
2834
+	 *
2835
+	 * @param bool $update (true indicates we're updating a category).
2836
+	 * @return bool|mixed|string
2837
+	 */
2838
+	private function _insert_category($update = false)
2839
+	{
2840
+		$category_ID         = $update ? $this->request->getRequestParam('EVT_CAT_ID', 0, 'int') : 0;
2841
+		$category_name       = $this->request->getRequestParam('category_name', '');
2842
+		$category_desc       = $this->request->getRequestParam('category_desc', '');
2843
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, 'int');
2844
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2845
+
2846
+		if (empty($category_name)) {
2847
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2848
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2849
+			return false;
2850
+		}
2851
+		$term_args = [
2852
+			'name'        => $category_name,
2853
+			'description' => $category_desc,
2854
+			'parent'      => $category_parent,
2855
+		];
2856
+		// was the category_identifier input disabled?
2857
+		if ($category_identifier) {
2858
+			$term_args['slug'] = $category_identifier;
2859
+		}
2860
+		$insert_ids = $update
2861
+			? wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2862
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2863
+		if (! is_array($insert_ids)) {
2864
+			$msg = esc_html__(
2865
+				'An error occurred and the category has not been saved to the database.',
2866
+				'event_espresso'
2867
+			);
2868
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2869
+		} else {
2870
+			$category_ID = $insert_ids['term_id'];
2871
+			$msg         = sprintf(
2872
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2873
+				$category_name
2874
+			);
2875
+			EE_Error::add_success($msg);
2876
+		}
2877
+		return $category_ID;
2878
+	}
2879
+
2880
+
2881
+	/**
2882
+	 * Gets categories or count of categories matching the arguments in the request.
2883
+	 *
2884
+	 * @param int  $per_page
2885
+	 * @param int  $current_page
2886
+	 * @param bool $count
2887
+	 * @return EE_Term_Taxonomy[]|int
2888
+	 * @throws EE_Error
2889
+	 */
2890
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2891
+	{
2892
+		// testing term stuff
2893
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2894
+		$order       = $this->request->getRequestParam('order', 'DESC');
2895
+		$limit       = ($current_page - 1) * $per_page;
2896
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2897
+		$search_term = $this->request->getRequestParam('s');
2898
+		if ($search_term) {
2899
+			$search_term = '%' . $search_term . '%';
2900
+			$where['OR'] = [
2901
+				'Term.name'   => ['LIKE', $search_term],
2902
+				'description' => ['LIKE', $search_term],
2903
+			];
2904
+		}
2905
+		$query_params = [
2906
+			$where,
2907
+			'order_by'   => [$orderby => $order],
2908
+			'limit'      => $limit . ',' . $per_page,
2909
+			'force_join' => ['Term'],
2910
+		];
2911
+		return $count
2912
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2913
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2914
+	}
2915
+
2916
+	/* end category stuff */
2917
+
2918
+
2919
+	/**************/
2920
+
2921
+
2922
+	/**
2923
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2924
+	 *
2925
+	 * @throws EE_Error
2926
+	 * @throws InvalidArgumentException
2927
+	 * @throws InvalidDataTypeException
2928
+	 * @throws InvalidInterfaceException
2929
+	 */
2930
+	public function saveTimezoneString()
2931
+	{
2932
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2933
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2934
+			EE_Error::add_error(
2935
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2936
+				__FILE__,
2937
+				__FUNCTION__,
2938
+				__LINE__
2939
+			);
2940
+			$this->_template_args['error'] = true;
2941
+			$this->_return_json();
2942
+		}
2943
+
2944
+		update_option('timezone_string', $timezone_string);
2945
+		EE_Error::add_success(
2946
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2947
+		);
2948
+		$this->_template_args['success'] = true;
2949
+		$this->_return_json(true, ['action' => 'create_new']);
2950
+	}
2951
+
2952
+
2953
+	/**
2954
+	 * @throws EE_Error
2955
+	 * @deprecated 4.10.25.p
2956
+	 */
2957
+	public function save_timezonestring_setting()
2958
+	{
2959
+		$this->saveTimezoneString();
2960
+	}
2961 2961
 }
Please login to merge, or discard this patch.
admin_pages/events/Event_Categories_Admin_List_Table.class.php 2 patches
Indentation   +160 added lines, -160 removed lines patch added patch discarded remove patch
@@ -11,176 +11,176 @@
 block discarded – undo
11 11
  */
12 12
 class Event_Categories_Admin_List_Table extends EE_Admin_List_Table
13 13
 {
14
-    /**
15
-     * @var Events_Admin_Page $_admin_page
16
-     */
17
-    protected $_admin_page;
18
-
19
-
20
-    /**
21
-     * @throws EE_Error
22
-     * @throws ReflectionException
23
-     */
24
-    protected function _setup_data()
25
-    {
26
-        $this->_data           = $this->_admin_page->get_categories($this->_per_page, $this->_current_page);
27
-        $this->_all_data_count = EEM_Term_Taxonomy::instance()->count(
28
-            [['taxonomy' => 'espresso_event_categories']]
29
-        );
30
-    }
31
-
32
-
33
-    protected function _set_properties()
34
-    {
35
-        $this->_wp_list_args = [
36
-            'singular' => esc_html__('event category', 'event_espresso'),
37
-            'plural'   => esc_html__('event categories', 'event_espresso'),
38
-            'ajax'     => true, // for now,
39
-            'screen'   => $this->_admin_page->get_current_screen()->id,
40
-        ];
41
-
42
-        $this->_columns = [
43
-            'cb'        => '<input type="checkbox" />',
44
-            'id'        => esc_html__('ID', 'event_espresso'),
45
-            'name'      => esc_html__('Name', 'event_espresso'),
46
-            'shortcode' => esc_html__('Shortcode', 'event_espresso'),
47
-            'count'     => esc_html__('Events', 'event_espresso'),
48
-        ];
49
-
50
-        $this->_sortable_columns = [
51
-            'id'    => ['Term.term_id' => true],
52
-            'name'  => ['Term.slug' => false],
53
-            'count' => ['term_count' => false],
54
-        ];
55
-
56
-        $this->_primary_column = 'id';
57
-
58
-        $this->_hidden_columns = [];
59
-    }
60
-
61
-
62
-    protected function _get_table_filters(): array
63
-    {
64
-        return [];
65
-    }
66
-
67
-
68
-    protected function _add_view_counts()
69
-    {
70
-        $this->_views['all']['count'] = $this->_all_data_count;
71
-    }
72
-
73
-
74
-    public function column_cb($item): string
75
-    {
76
-        return sprintf('<input type="checkbox" name="EVT_CAT_ID[]" value="%s" />', $item->get('term_id'));
77
-    }
78
-
79
-
80
-    /**
81
-     * @param EE_Term_Taxonomy $item
82
-     * @return string
83
-     * @throws EE_Error
84
-     * @throws ReflectionException
85
-     */
86
-    public function column_id(EE_Term_Taxonomy $item): string
87
-    {
88
-        $content = '
14
+	/**
15
+	 * @var Events_Admin_Page $_admin_page
16
+	 */
17
+	protected $_admin_page;
18
+
19
+
20
+	/**
21
+	 * @throws EE_Error
22
+	 * @throws ReflectionException
23
+	 */
24
+	protected function _setup_data()
25
+	{
26
+		$this->_data           = $this->_admin_page->get_categories($this->_per_page, $this->_current_page);
27
+		$this->_all_data_count = EEM_Term_Taxonomy::instance()->count(
28
+			[['taxonomy' => 'espresso_event_categories']]
29
+		);
30
+	}
31
+
32
+
33
+	protected function _set_properties()
34
+	{
35
+		$this->_wp_list_args = [
36
+			'singular' => esc_html__('event category', 'event_espresso'),
37
+			'plural'   => esc_html__('event categories', 'event_espresso'),
38
+			'ajax'     => true, // for now,
39
+			'screen'   => $this->_admin_page->get_current_screen()->id,
40
+		];
41
+
42
+		$this->_columns = [
43
+			'cb'        => '<input type="checkbox" />',
44
+			'id'        => esc_html__('ID', 'event_espresso'),
45
+			'name'      => esc_html__('Name', 'event_espresso'),
46
+			'shortcode' => esc_html__('Shortcode', 'event_espresso'),
47
+			'count'     => esc_html__('Events', 'event_espresso'),
48
+		];
49
+
50
+		$this->_sortable_columns = [
51
+			'id'    => ['Term.term_id' => true],
52
+			'name'  => ['Term.slug' => false],
53
+			'count' => ['term_count' => false],
54
+		];
55
+
56
+		$this->_primary_column = 'id';
57
+
58
+		$this->_hidden_columns = [];
59
+	}
60
+
61
+
62
+	protected function _get_table_filters(): array
63
+	{
64
+		return [];
65
+	}
66
+
67
+
68
+	protected function _add_view_counts()
69
+	{
70
+		$this->_views['all']['count'] = $this->_all_data_count;
71
+	}
72
+
73
+
74
+	public function column_cb($item): string
75
+	{
76
+		return sprintf('<input type="checkbox" name="EVT_CAT_ID[]" value="%s" />', $item->get('term_id'));
77
+	}
78
+
79
+
80
+	/**
81
+	 * @param EE_Term_Taxonomy $item
82
+	 * @return string
83
+	 * @throws EE_Error
84
+	 * @throws ReflectionException
85
+	 */
86
+	public function column_id(EE_Term_Taxonomy $item): string
87
+	{
88
+		$content = '
89 89
         <span class="ee-entity-id">' . $item->get('term_id') . '</span>
90 90
         <span class="show-on-mobile-view-only">
91 91
             ' . $item->get_first_related('Term')->get('name') . '
92 92
         </span>';
93
-        return $this->columnContent('id', $content, 'end');
94
-    }
95
-
96
-
97
-    /**
98
-     * @param EE_Term_Taxonomy $item
99
-     * @return string
100
-     * @throws EE_Error
101
-     * @throws ReflectionException
102
-     */
103
-    public function column_name(EE_Term_Taxonomy $item): string
104
-    {
105
-        $edit_query_args = [
106
-            'action'     => 'edit_category',
107
-            'EVT_CAT_ID' => $item->get('term_id'),
108
-        ];
109
-
110
-        $delete_query_args = [
111
-            'action'     => 'delete_category',
112
-            'EVT_CAT_ID' => $item->get('term_id'),
113
-        ];
114
-
115
-        $edit_link   = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
116
-        $delete_link = EE_Admin_Page::add_query_args_and_nonce($delete_query_args, EVENTS_ADMIN_URL);
117
-        $view_link   = get_term_link($item->get('term_id'));
118
-
119
-        $term_name = $item->get_first_related('Term')->get('name');
120
-
121
-        $edit_category_label = sprintf(
122
-        /* translators: The name of the event category */
123
-            esc_attr__(
124
-                'Edit Category (%s)',
125
-                'event_espresso'
126
-            ),
127
-            $term_name
128
-        );
129
-        $actions['edit']     = '
93
+		return $this->columnContent('id', $content, 'end');
94
+	}
95
+
96
+
97
+	/**
98
+	 * @param EE_Term_Taxonomy $item
99
+	 * @return string
100
+	 * @throws EE_Error
101
+	 * @throws ReflectionException
102
+	 */
103
+	public function column_name(EE_Term_Taxonomy $item): string
104
+	{
105
+		$edit_query_args = [
106
+			'action'     => 'edit_category',
107
+			'EVT_CAT_ID' => $item->get('term_id'),
108
+		];
109
+
110
+		$delete_query_args = [
111
+			'action'     => 'delete_category',
112
+			'EVT_CAT_ID' => $item->get('term_id'),
113
+		];
114
+
115
+		$edit_link   = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
116
+		$delete_link = EE_Admin_Page::add_query_args_and_nonce($delete_query_args, EVENTS_ADMIN_URL);
117
+		$view_link   = get_term_link($item->get('term_id'));
118
+
119
+		$term_name = $item->get_first_related('Term')->get('name');
120
+
121
+		$edit_category_label = sprintf(
122
+		/* translators: The name of the event category */
123
+			esc_attr__(
124
+				'Edit Category (%s)',
125
+				'event_espresso'
126
+			),
127
+			$term_name
128
+		);
129
+		$actions['edit']     = '
130 130
             <a href="' . $edit_link . '" aria-label="' . $edit_category_label . '">
131 131
                 ' . esc_html__('Edit', 'event_espresso') . '
132 132
             </a>';
133 133
 
134
-        $actions['delete'] = '<a href="' . $delete_link . '" aria-label="' . esc_attr__(
135
-                'Delete Category',
136
-                'event_espresso'
137
-            ) . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
138
-
139
-        $view_category_label = sprintf(
140
-        /* translators: %s: event category name */
141
-            esc_html__('View &#8220;%s&#8221; archive', 'event_espresso'),
142
-            $item->get_first_related('Term')->get('name')
143
-        );
144
-        $actions['view']     = '
134
+		$actions['delete'] = '<a href="' . $delete_link . '" aria-label="' . esc_attr__(
135
+				'Delete Category',
136
+				'event_espresso'
137
+			) . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
138
+
139
+		$view_category_label = sprintf(
140
+		/* translators: %s: event category name */
141
+			esc_html__('View &#8220;%s&#8221; archive', 'event_espresso'),
142
+			$item->get_first_related('Term')->get('name')
143
+		);
144
+		$actions['view']     = '
145 145
             <a href="' . $view_link . '" aria-label="' . $view_category_label . '">
146 146
                 ' . esc_html__('View', 'event_espresso') . '
147 147
             </a>';
148 148
 
149
-        $content = '<strong><a class="row-title" href="' . $edit_link . '">' . $term_name . '</a></strong>';
150
-        $content .= $this->row_actions($actions);
151
-        return $this->columnContent('name', $content);
152
-    }
153
-
154
-
155
-    /**
156
-     * @param EE_Term_Taxonomy $item
157
-     * @return string
158
-     * @throws EE_Error
159
-     * @throws ReflectionException
160
-     */
161
-    public function column_shortcode(EE_Term_Taxonomy $item): string
162
-    {
163
-        $content = '[ESPRESSO_EVENTS category_slug=' . $item->get_first_related('Term')->get('slug') . ']';
164
-        return $this->columnContent('shortcode', $content);
165
-    }
166
-
167
-
168
-    /**
169
-     * @param EE_Term_Taxonomy $item
170
-     * @return string
171
-     * @throws EE_Error
172
-     * @throws ReflectionException
173
-     */
174
-    public function column_count(EE_Term_Taxonomy $item): string
175
-    {
176
-        $category_url = EE_Admin_Page::add_query_args_and_nonce(
177
-            [
178
-                'action'  => 'default',
179
-                'EVT_CAT' => $item->get_first_related('Term')->ID(),
180
-            ],
181
-            EVENTS_ADMIN_URL
182
-        );
183
-        $content      = '<a href="' . $category_url . '">' . $item->get('term_count') . '</a>';
184
-        return $this->columnContent('count', $content);
185
-    }
149
+		$content = '<strong><a class="row-title" href="' . $edit_link . '">' . $term_name . '</a></strong>';
150
+		$content .= $this->row_actions($actions);
151
+		return $this->columnContent('name', $content);
152
+	}
153
+
154
+
155
+	/**
156
+	 * @param EE_Term_Taxonomy $item
157
+	 * @return string
158
+	 * @throws EE_Error
159
+	 * @throws ReflectionException
160
+	 */
161
+	public function column_shortcode(EE_Term_Taxonomy $item): string
162
+	{
163
+		$content = '[ESPRESSO_EVENTS category_slug=' . $item->get_first_related('Term')->get('slug') . ']';
164
+		return $this->columnContent('shortcode', $content);
165
+	}
166
+
167
+
168
+	/**
169
+	 * @param EE_Term_Taxonomy $item
170
+	 * @return string
171
+	 * @throws EE_Error
172
+	 * @throws ReflectionException
173
+	 */
174
+	public function column_count(EE_Term_Taxonomy $item): string
175
+	{
176
+		$category_url = EE_Admin_Page::add_query_args_and_nonce(
177
+			[
178
+				'action'  => 'default',
179
+				'EVT_CAT' => $item->get_first_related('Term')->ID(),
180
+			],
181
+			EVENTS_ADMIN_URL
182
+		);
183
+		$content      = '<a href="' . $category_url . '">' . $item->get('term_count') . '</a>';
184
+		return $this->columnContent('count', $content);
185
+	}
186 186
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -86,9 +86,9 @@  discard block
 block discarded – undo
86 86
     public function column_id(EE_Term_Taxonomy $item): string
87 87
     {
88 88
         $content = '
89
-        <span class="ee-entity-id">' . $item->get('term_id') . '</span>
89
+        <span class="ee-entity-id">' . $item->get('term_id').'</span>
90 90
         <span class="show-on-mobile-view-only">
91
-            ' . $item->get_first_related('Term')->get('name') . '
91
+            ' . $item->get_first_related('Term')->get('name').'
92 92
         </span>';
93 93
         return $this->columnContent('id', $content, 'end');
94 94
     }
@@ -126,27 +126,27 @@  discard block
 block discarded – undo
126 126
             ),
127 127
             $term_name
128 128
         );
129
-        $actions['edit']     = '
130
-            <a href="' . $edit_link . '" aria-label="' . $edit_category_label . '">
131
-                ' . esc_html__('Edit', 'event_espresso') . '
129
+        $actions['edit'] = '
130
+            <a href="' . $edit_link.'" aria-label="'.$edit_category_label.'">
131
+                ' . esc_html__('Edit', 'event_espresso').'
132 132
             </a>';
133 133
 
134
-        $actions['delete'] = '<a href="' . $delete_link . '" aria-label="' . esc_attr__(
134
+        $actions['delete'] = '<a href="'.$delete_link.'" aria-label="'.esc_attr__(
135 135
                 'Delete Category',
136 136
                 'event_espresso'
137
-            ) . '">' . esc_html__('Delete', 'event_espresso') . '</a>';
137
+            ).'">'.esc_html__('Delete', 'event_espresso').'</a>';
138 138
 
139 139
         $view_category_label = sprintf(
140 140
         /* translators: %s: event category name */
141 141
             esc_html__('View &#8220;%s&#8221; archive', 'event_espresso'),
142 142
             $item->get_first_related('Term')->get('name')
143 143
         );
144
-        $actions['view']     = '
145
-            <a href="' . $view_link . '" aria-label="' . $view_category_label . '">
146
-                ' . esc_html__('View', 'event_espresso') . '
144
+        $actions['view'] = '
145
+            <a href="' . $view_link.'" aria-label="'.$view_category_label.'">
146
+                ' . esc_html__('View', 'event_espresso').'
147 147
             </a>';
148 148
 
149
-        $content = '<strong><a class="row-title" href="' . $edit_link . '">' . $term_name . '</a></strong>';
149
+        $content = '<strong><a class="row-title" href="'.$edit_link.'">'.$term_name.'</a></strong>';
150 150
         $content .= $this->row_actions($actions);
151 151
         return $this->columnContent('name', $content);
152 152
     }
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
      */
161 161
     public function column_shortcode(EE_Term_Taxonomy $item): string
162 162
     {
163
-        $content = '[ESPRESSO_EVENTS category_slug=' . $item->get_first_related('Term')->get('slug') . ']';
163
+        $content = '[ESPRESSO_EVENTS category_slug='.$item->get_first_related('Term')->get('slug').']';
164 164
         return $this->columnContent('shortcode', $content);
165 165
     }
166 166
 
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
             ],
181 181
             EVENTS_ADMIN_URL
182 182
         );
183
-        $content      = '<a href="' . $category_url . '">' . $item->get('term_count') . '</a>';
183
+        $content = '<a href="'.$category_url.'">'.$item->get('term_count').'</a>';
184 184
         return $this->columnContent('count', $content);
185 185
     }
186 186
 }
Please login to merge, or discard this patch.
templates/reg_admin_details_side_meta_box_registrant.template.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -59,11 +59,11 @@  discard block
 block discarded – undo
59 59
 <?php
60 60
 // only show if logged-in user has access
61 61
 if (
62
-    EE_Registry::instance()->CAP->current_user_can(
63
-        'ee_edit_contact',
64
-        'view_or_edit_contact_button',
65
-        $ATT_ID
66
-    )
62
+	EE_Registry::instance()->CAP->current_user_can(
63
+		'ee_edit_contact',
64
+		'view_or_edit_contact_button',
65
+		$ATT_ID
66
+	)
67 67
 ) : ?>
68 68
     <div class='ee-admin-button-row'>
69 69
         <a class="ee-aria-tooltip button button--small button--secondary" href="<?php echo esc_url_raw($att_edit_link); ?>"
@@ -76,9 +76,9 @@  discard block
 block discarded – undo
76 76
     <?php if (! empty($create_link)) : ?>
77 77
         <a class="ee-aria-tooltip button button--small button--secondary" href="<?php echo esc_url_raw($create_link); ?>"
78 78
            aria-label="<?php esc_attr_e(
79
-               'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
80
-               'event_espresso'
81
-           ); ?>"
79
+			   'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
80
+			   'event_espresso'
81
+		   ); ?>"
82 82
         >
83 83
             <span class="ee-icon ee-icon-user-add-new"></span>
84 84
             <?php echo esc_html($create_label); ?>
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -18,11 +18,11 @@  discard block
 block discarded – undo
18 18
 
19 19
 $attendee_full_name = "$fname $lname";
20 20
 $email = sanitize_email($email);
21
-$avatar  = get_avatar_url($email);
21
+$avatar = get_avatar_url($email);
22 22
 ?>
23 23
 
24 24
 <div id='admin-side-mbox-primary-registrant-dv' class='admin-side-mbox-dv'>
25
-    <?php if (! empty($avatar)) : ?>
25
+    <?php if ( ! empty($avatar)) : ?>
26 26
     <div class="ee-admin-attendee-avatar">
27 27
         <img alt="profile pic for <?php echo esc_html($attendee_full_name); ?>" src="<?php echo $avatar; ?>" />
28 28
     </div>
@@ -37,7 +37,7 @@  discard block
 block discarded – undo
37 37
                 <a href="mailto:<?php echo esc_attr($email); ?>"><?php echo esc_html($email); ?></a>
38 38
             </div>
39 39
         </div>
40
-        <?php if (! empty($phone)) : ?>
40
+        <?php if ( ! empty($phone)) : ?>
41 41
             <div class='ee-admin-attendee-phone'>
42 42
                 <div class='ee-admin-contact-details-with-dashicon'>
43 43
                     <span class='dashicons dashicons-phone'></span>
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
                 </div>
46 46
             </div>
47 47
         <?php endif; ?>
48
-        <?php if (! empty($formatted_address)) : ?>
48
+        <?php if ( ! empty($formatted_address)) : ?>
49 49
         <div class='ee-admin-attendee-address'>
50 50
             <div class='ee-admin-contact-details-with-dashicon'>
51 51
                 <span class='dashicons dashicons-location'></span>
@@ -73,7 +73,7 @@  discard block
 block discarded – undo
73 73
             <?php echo esc_html($att_edit_label); ?>
74 74
         </a>
75 75
 
76
-    <?php if (! empty($create_link)) : ?>
76
+    <?php if ( ! empty($create_link)) : ?>
77 77
         <a class="ee-aria-tooltip button button--small button--secondary" href="<?php echo esc_url_raw($create_link); ?>"
78 78
            aria-label="<?php esc_attr_e(
79 79
                'This registration shares the contact details for the primary registration in this group.  If you\'d like this registration to have its own details, you can do so by clicking this button',
@@ -86,4 +86,4 @@  discard block
 block discarded – undo
86 86
     <?php endif; ?>
87 87
 
88 88
     </div>
89
-<?php endif;?>
89
+<?php endif; ?>
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Indentation   +3655 added lines, -3655 removed lines patch added patch discarded remove patch
@@ -21,2206 +21,2206 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
23 23
 {
24
-    /**
25
-     * @var EE_Registration
26
-     */
27
-    private $_registration;
28
-
29
-    /**
30
-     * @var EE_Event
31
-     */
32
-    private $_reg_event;
33
-
34
-    /**
35
-     * @var EE_Session
36
-     */
37
-    private $_session;
38
-
39
-    /**
40
-     * @var array
41
-     */
42
-    private static $_reg_status;
43
-
44
-    /**
45
-     * Form for displaying the custom questions for this registration.
46
-     * This gets used a few times throughout the request so its best to cache it
47
-     *
48
-     * @var EE_Registration_Custom_Questions_Form
49
-     */
50
-    protected $_reg_custom_questions_form;
51
-
52
-    /**
53
-     * @var EEM_Registration $registration_model
54
-     */
55
-    private $registration_model;
56
-
57
-    /**
58
-     * @var EEM_Attendee $attendee_model
59
-     */
60
-    private $attendee_model;
61
-
62
-    /**
63
-     * @var EEM_Event $event_model
64
-     */
65
-    private $event_model;
66
-
67
-    /**
68
-     * @var EEM_Status $status_model
69
-     */
70
-    private $status_model;
71
-
72
-
73
-    /**
74
-     * @param bool $routing
75
-     * @throws EE_Error
76
-     * @throws InvalidArgumentException
77
-     * @throws InvalidDataTypeException
78
-     * @throws InvalidInterfaceException
79
-     * @throws ReflectionException
80
-     */
81
-    public function __construct($routing = true)
82
-    {
83
-        parent::__construct($routing);
84
-        add_action('wp_loaded', [$this, 'wp_loaded']);
85
-    }
86
-
87
-
88
-    /**
89
-     * @return EEM_Registration
90
-     * @throws InvalidArgumentException
91
-     * @throws InvalidDataTypeException
92
-     * @throws InvalidInterfaceException
93
-     * @since 4.10.2.p
94
-     */
95
-    protected function getRegistrationModel()
96
-    {
97
-        if (! $this->registration_model instanceof EEM_Registration) {
98
-            $this->registration_model = $this->loader->getShared('EEM_Registration');
99
-        }
100
-        return $this->registration_model;
101
-    }
102
-
103
-
104
-    /**
105
-     * @return EEM_Attendee
106
-     * @throws InvalidArgumentException
107
-     * @throws InvalidDataTypeException
108
-     * @throws InvalidInterfaceException
109
-     * @since 4.10.2.p
110
-     */
111
-    protected function getAttendeeModel()
112
-    {
113
-        if (! $this->attendee_model instanceof EEM_Attendee) {
114
-            $this->attendee_model = $this->loader->getShared('EEM_Attendee');
115
-        }
116
-        return $this->attendee_model;
117
-    }
118
-
119
-
120
-    /**
121
-     * @return EEM_Event
122
-     * @throws InvalidArgumentException
123
-     * @throws InvalidDataTypeException
124
-     * @throws InvalidInterfaceException
125
-     * @since 4.10.2.p
126
-     */
127
-    protected function getEventModel()
128
-    {
129
-        if (! $this->event_model instanceof EEM_Event) {
130
-            $this->event_model = $this->loader->getShared('EEM_Event');
131
-        }
132
-        return $this->event_model;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EEM_Status
138
-     * @throws InvalidArgumentException
139
-     * @throws InvalidDataTypeException
140
-     * @throws InvalidInterfaceException
141
-     * @since 4.10.2.p
142
-     */
143
-    protected function getStatusModel()
144
-    {
145
-        if (! $this->status_model instanceof EEM_Status) {
146
-            $this->status_model = $this->loader->getShared('EEM_Status');
147
-        }
148
-        return $this->status_model;
149
-    }
150
-
151
-
152
-    public function wp_loaded()
153
-    {
154
-        // when adding a new registration...
155
-        $action = $this->request->getRequestParam('action');
156
-        if ($action === 'new_registration') {
157
-            EE_System::do_not_cache();
158
-            if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
159
-                // and it's NOT the attendee information reg step
160
-                // force cookie expiration by setting time to last week
161
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
162
-                // and update the global
163
-                $_COOKIE['ee_registration_added'] = 0;
164
-            }
165
-        }
166
-    }
167
-
168
-
169
-    protected function _init_page_props()
170
-    {
171
-        $this->page_slug        = REG_PG_SLUG;
172
-        $this->_admin_base_url  = REG_ADMIN_URL;
173
-        $this->_admin_base_path = REG_ADMIN;
174
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
175
-        $this->_cpt_routes      = [
176
-            'add_new_attendee' => 'espresso_attendees',
177
-            'edit_attendee'    => 'espresso_attendees',
178
-            'insert_attendee'  => 'espresso_attendees',
179
-            'update_attendee'  => 'espresso_attendees',
180
-        ];
181
-        $this->_cpt_model_names = [
182
-            'add_new_attendee' => 'EEM_Attendee',
183
-            'edit_attendee'    => 'EEM_Attendee',
184
-        ];
185
-        $this->_cpt_edit_routes = [
186
-            'espresso_attendees' => 'edit_attendee',
187
-        ];
188
-        $this->_pagenow_map     = [
189
-            'add_new_attendee' => 'post-new.php',
190
-            'edit_attendee'    => 'post.php',
191
-            'trash'            => 'post.php',
192
-        ];
193
-        add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
194
-        // add filters so that the comment urls don't take users to a confusing 404 page
195
-        add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
196
-    }
197
-
198
-
199
-    /**
200
-     * @param string     $link    The comment permalink with '#comment-$id' appended.
201
-     * @param WP_Comment $comment The current comment object.
202
-     * @return string
203
-     */
204
-    public function clear_comment_link($link, WP_Comment $comment)
205
-    {
206
-        // gotta make sure this only happens on this route
207
-        $post_type = get_post_type($comment->comment_post_ID);
208
-        if ($post_type === 'espresso_attendees') {
209
-            return '#commentsdiv';
210
-        }
211
-        return $link;
212
-    }
213
-
214
-
215
-    protected function _ajax_hooks()
216
-    {
217
-        // todo: all hooks for registrations ajax goes in here
218
-        add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
219
-    }
220
-
221
-
222
-    protected function _define_page_props()
223
-    {
224
-        $this->_admin_page_title = $this->page_label;
225
-        $this->_labels           = [
226
-            'buttons'                      => [
227
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
228
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
229
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
230
-                'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
231
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
-            ],
234
-            'publishbox'                   => [
235
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
-            ],
238
-            'hide_add_button_on_cpt_route' => [
239
-                'edit_attendee' => true,
240
-            ],
241
-        ];
242
-    }
243
-
244
-
245
-    /**
246
-     * grab url requests and route them
247
-     *
248
-     * @return void
249
-     * @throws EE_Error
250
-     */
251
-    public function _set_page_routes()
252
-    {
253
-        $this->_get_registration_status_array();
254
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
-        $REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
-        $ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
-        $this->_page_routes = [
259
-            'default'                             => [
260
-                'func'       => [$this, '_registrations_overview_list_table'],
261
-                'capability' => 'ee_read_registrations',
262
-            ],
263
-            'view_registration'                   => [
264
-                'func'       => '_registration_details',
265
-                'capability' => 'ee_read_registration',
266
-                'obj_id'     => $REG_ID,
267
-            ],
268
-            'edit_registration'                   => [
269
-                'func'               => '_update_attendee_registration_form',
270
-                'noheader'           => true,
271
-                'headers_sent_route' => 'view_registration',
272
-                'capability'         => 'ee_edit_registration',
273
-                'obj_id'             => $REG_ID,
274
-                '_REG_ID'            => $REG_ID,
275
-            ],
276
-            'trash_registrations'                 => [
277
-                'func'       => '_trash_or_restore_registrations',
278
-                'args'       => ['trash' => true],
279
-                'noheader'   => true,
280
-                'capability' => 'ee_delete_registrations',
281
-            ],
282
-            'restore_registrations'               => [
283
-                'func'       => '_trash_or_restore_registrations',
284
-                'args'       => ['trash' => false],
285
-                'noheader'   => true,
286
-                'capability' => 'ee_delete_registrations',
287
-            ],
288
-            'delete_registrations'                => [
289
-                'func'       => '_delete_registrations',
290
-                'noheader'   => true,
291
-                'capability' => 'ee_delete_registrations',
292
-            ],
293
-            'new_registration'                    => [
294
-                'func'       => 'new_registration',
295
-                'capability' => 'ee_edit_registrations',
296
-            ],
297
-            'process_reg_step'                    => [
298
-                'func'       => 'process_reg_step',
299
-                'noheader'   => true,
300
-                'capability' => 'ee_edit_registrations',
301
-            ],
302
-            'redirect_to_txn'                     => [
303
-                'func'       => 'redirect_to_txn',
304
-                'noheader'   => true,
305
-                'capability' => 'ee_edit_registrations',
306
-            ],
307
-            'change_reg_status'                   => [
308
-                'func'       => '_change_reg_status',
309
-                'noheader'   => true,
310
-                'capability' => 'ee_edit_registration',
311
-                'obj_id'     => $REG_ID,
312
-            ],
313
-            'approve_registration'                => [
314
-                'func'       => 'approve_registration',
315
-                'noheader'   => true,
316
-                'capability' => 'ee_edit_registration',
317
-                'obj_id'     => $REG_ID,
318
-            ],
319
-            'approve_and_notify_registration'     => [
320
-                'func'       => 'approve_registration',
321
-                'noheader'   => true,
322
-                'args'       => [true],
323
-                'capability' => 'ee_edit_registration',
324
-                'obj_id'     => $REG_ID,
325
-            ],
326
-            'approve_registrations'               => [
327
-                'func'       => 'bulk_action_on_registrations',
328
-                'noheader'   => true,
329
-                'capability' => 'ee_edit_registrations',
330
-                'args'       => ['approve'],
331
-            ],
332
-            'approve_and_notify_registrations'    => [
333
-                'func'       => 'bulk_action_on_registrations',
334
-                'noheader'   => true,
335
-                'capability' => 'ee_edit_registrations',
336
-                'args'       => ['approve', true],
337
-            ],
338
-            'decline_registration'                => [
339
-                'func'       => 'decline_registration',
340
-                'noheader'   => true,
341
-                'capability' => 'ee_edit_registration',
342
-                'obj_id'     => $REG_ID,
343
-            ],
344
-            'decline_and_notify_registration'     => [
345
-                'func'       => 'decline_registration',
346
-                'noheader'   => true,
347
-                'args'       => [true],
348
-                'capability' => 'ee_edit_registration',
349
-                'obj_id'     => $REG_ID,
350
-            ],
351
-            'decline_registrations'               => [
352
-                'func'       => 'bulk_action_on_registrations',
353
-                'noheader'   => true,
354
-                'capability' => 'ee_edit_registrations',
355
-                'args'       => ['decline'],
356
-            ],
357
-            'decline_and_notify_registrations'    => [
358
-                'func'       => 'bulk_action_on_registrations',
359
-                'noheader'   => true,
360
-                'capability' => 'ee_edit_registrations',
361
-                'args'       => ['decline', true],
362
-            ],
363
-            'pending_registration'                => [
364
-                'func'       => 'pending_registration',
365
-                'noheader'   => true,
366
-                'capability' => 'ee_edit_registration',
367
-                'obj_id'     => $REG_ID,
368
-            ],
369
-            'pending_and_notify_registration'     => [
370
-                'func'       => 'pending_registration',
371
-                'noheader'   => true,
372
-                'args'       => [true],
373
-                'capability' => 'ee_edit_registration',
374
-                'obj_id'     => $REG_ID,
375
-            ],
376
-            'pending_registrations'               => [
377
-                'func'       => 'bulk_action_on_registrations',
378
-                'noheader'   => true,
379
-                'capability' => 'ee_edit_registrations',
380
-                'args'       => ['pending'],
381
-            ],
382
-            'pending_and_notify_registrations'    => [
383
-                'func'       => 'bulk_action_on_registrations',
384
-                'noheader'   => true,
385
-                'capability' => 'ee_edit_registrations',
386
-                'args'       => ['pending', true],
387
-            ],
388
-            'no_approve_registration'             => [
389
-                'func'       => 'not_approve_registration',
390
-                'noheader'   => true,
391
-                'capability' => 'ee_edit_registration',
392
-                'obj_id'     => $REG_ID,
393
-            ],
394
-            'no_approve_and_notify_registration'  => [
395
-                'func'       => 'not_approve_registration',
396
-                'noheader'   => true,
397
-                'args'       => [true],
398
-                'capability' => 'ee_edit_registration',
399
-                'obj_id'     => $REG_ID,
400
-            ],
401
-            'no_approve_registrations'            => [
402
-                'func'       => 'bulk_action_on_registrations',
403
-                'noheader'   => true,
404
-                'capability' => 'ee_edit_registrations',
405
-                'args'       => ['not_approve'],
406
-            ],
407
-            'no_approve_and_notify_registrations' => [
408
-                'func'       => 'bulk_action_on_registrations',
409
-                'noheader'   => true,
410
-                'capability' => 'ee_edit_registrations',
411
-                'args'       => ['not_approve', true],
412
-            ],
413
-            'cancel_registration'                 => [
414
-                'func'       => 'cancel_registration',
415
-                'noheader'   => true,
416
-                'capability' => 'ee_edit_registration',
417
-                'obj_id'     => $REG_ID,
418
-            ],
419
-            'cancel_and_notify_registration'      => [
420
-                'func'       => 'cancel_registration',
421
-                'noheader'   => true,
422
-                'args'       => [true],
423
-                'capability' => 'ee_edit_registration',
424
-                'obj_id'     => $REG_ID,
425
-            ],
426
-            'cancel_registrations'                => [
427
-                'func'       => 'bulk_action_on_registrations',
428
-                'noheader'   => true,
429
-                'capability' => 'ee_edit_registrations',
430
-                'args'       => ['cancel'],
431
-            ],
432
-            'cancel_and_notify_registrations'     => [
433
-                'func'       => 'bulk_action_on_registrations',
434
-                'noheader'   => true,
435
-                'capability' => 'ee_edit_registrations',
436
-                'args'       => ['cancel', true],
437
-            ],
438
-            'wait_list_registration'              => [
439
-                'func'       => 'wait_list_registration',
440
-                'noheader'   => true,
441
-                'capability' => 'ee_edit_registration',
442
-                'obj_id'     => $REG_ID,
443
-            ],
444
-            'wait_list_and_notify_registration'   => [
445
-                'func'       => 'wait_list_registration',
446
-                'noheader'   => true,
447
-                'args'       => [true],
448
-                'capability' => 'ee_edit_registration',
449
-                'obj_id'     => $REG_ID,
450
-            ],
451
-            'contact_list'                        => [
452
-                'func'       => '_attendee_contact_list_table',
453
-                'capability' => 'ee_read_contacts',
454
-            ],
455
-            'add_new_attendee'                    => [
456
-                'func' => '_create_new_cpt_item',
457
-                'args' => [
458
-                    'new_attendee' => true,
459
-                    'capability'   => 'ee_edit_contacts',
460
-                ],
461
-            ],
462
-            'edit_attendee'                       => [
463
-                'func'       => '_edit_cpt_item',
464
-                'capability' => 'ee_edit_contacts',
465
-                'obj_id'     => $ATT_ID,
466
-            ],
467
-            'duplicate_attendee'                  => [
468
-                'func'       => '_duplicate_attendee',
469
-                'noheader'   => true,
470
-                'capability' => 'ee_edit_contacts',
471
-                'obj_id'     => $ATT_ID,
472
-            ],
473
-            'insert_attendee'                     => [
474
-                'func'       => '_insert_or_update_attendee',
475
-                'args'       => [
476
-                    'new_attendee' => true,
477
-                ],
478
-                'noheader'   => true,
479
-                'capability' => 'ee_edit_contacts',
480
-            ],
481
-            'update_attendee'                     => [
482
-                'func'       => '_insert_or_update_attendee',
483
-                'args'       => [
484
-                    'new_attendee' => false,
485
-                ],
486
-                'noheader'   => true,
487
-                'capability' => 'ee_edit_contacts',
488
-                'obj_id'     => $ATT_ID,
489
-            ],
490
-            'trash_attendees'                     => [
491
-                'func'       => '_trash_or_restore_attendees',
492
-                'args'       => [
493
-                    'trash' => 'true',
494
-                ],
495
-                'noheader'   => true,
496
-                'capability' => 'ee_delete_contacts',
497
-            ],
498
-            'trash_attendee'                      => [
499
-                'func'       => '_trash_or_restore_attendees',
500
-                'args'       => [
501
-                    'trash' => true,
502
-                ],
503
-                'noheader'   => true,
504
-                'capability' => 'ee_delete_contacts',
505
-                'obj_id'     => $ATT_ID,
506
-            ],
507
-            'restore_attendees'                   => [
508
-                'func'       => '_trash_or_restore_attendees',
509
-                'args'       => [
510
-                    'trash' => false,
511
-                ],
512
-                'noheader'   => true,
513
-                'capability' => 'ee_delete_contacts',
514
-                'obj_id'     => $ATT_ID,
515
-            ],
516
-            'resend_registration'                 => [
517
-                'func'       => '_resend_registration',
518
-                'noheader'   => true,
519
-                'capability' => 'ee_send_message',
520
-            ],
521
-            'registrations_report'                => [
522
-                'func'       => [$this, '_registrations_report'],
523
-                'noheader'   => true,
524
-                'capability' => 'ee_read_registrations',
525
-            ],
526
-            'contact_list_export'                 => [
527
-                'func'       => '_contact_list_export',
528
-                'noheader'   => true,
529
-                'capability' => 'export',
530
-            ],
531
-            'contact_list_report'                 => [
532
-                'func'       => '_contact_list_report',
533
-                'noheader'   => true,
534
-                'capability' => 'ee_read_contacts',
535
-            ],
536
-        ];
537
-    }
538
-
539
-
540
-    protected function _set_page_config()
541
-    {
542
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
-        $this->_page_config = [
545
-            'default'           => [
546
-                'nav'           => [
547
-                    'label' => esc_html__('Overview', 'event_espresso'),
548
-                    'icon' => 'dashicons-list-view',
549
-                    'order' => 5,
550
-                ],
551
-                'help_tabs'     => [
552
-                    'registrations_overview_help_tab'                       => [
553
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
554
-                        'filename' => 'registrations_overview',
555
-                    ],
556
-                    'registrations_overview_table_column_headings_help_tab' => [
557
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
558
-                        'filename' => 'registrations_overview_table_column_headings',
559
-                    ],
560
-                    'registrations_overview_filters_help_tab'               => [
561
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
562
-                        'filename' => 'registrations_overview_filters',
563
-                    ],
564
-                    'registrations_overview_views_help_tab'                 => [
565
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
566
-                        'filename' => 'registrations_overview_views',
567
-                    ],
568
-                    'registrations_regoverview_other_help_tab'              => [
569
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
570
-                        'filename' => 'registrations_overview_other',
571
-                    ],
572
-                ],
573
-                'list_table'    => 'EE_Registrations_List_Table',
574
-                'require_nonce' => false,
575
-            ],
576
-            'view_registration' => [
577
-                'nav'           => [
578
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
579
-                    'icon' => 'dashicons-clipboard',
580
-                    'order'      => 15,
581
-                    'url'        => $REG_ID
582
-                        ? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
583
-                        : $this->_admin_base_url,
584
-                    'persistent' => false,
585
-                ],
586
-                'help_tabs'     => [
587
-                    'registrations_details_help_tab'                    => [
588
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
589
-                        'filename' => 'registrations_details',
590
-                    ],
591
-                    'registrations_details_table_help_tab'              => [
592
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
593
-                        'filename' => 'registrations_details_table',
594
-                    ],
595
-                    'registrations_details_form_answers_help_tab'       => [
596
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
597
-                        'filename' => 'registrations_details_form_answers',
598
-                    ],
599
-                    'registrations_details_registrant_details_help_tab' => [
600
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
601
-                        'filename' => 'registrations_details_registrant_details',
602
-                    ],
603
-                ],
604
-                'metaboxes'     => array_merge(
605
-                    $this->_default_espresso_metaboxes,
606
-                    ['_registration_details_metaboxes']
607
-                ),
608
-                'require_nonce' => false,
609
-            ],
610
-            'new_registration'  => [
611
-                'nav'           => [
612
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
613
-                    'icon' => 'dashicons-plus-alt',
614
-                    'url'        => '#',
615
-                    'order'      => 15,
616
-                    'persistent' => false,
617
-                ],
618
-                'metaboxes'     => $this->_default_espresso_metaboxes,
619
-                'labels'        => [
620
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
621
-                ],
622
-                'require_nonce' => false,
623
-            ],
624
-            'add_new_attendee'  => [
625
-                'nav'           => [
626
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
627
-                    'icon' => 'dashicons-plus-alt',
628
-                    'order'      => 15,
629
-                    'persistent' => false,
630
-                ],
631
-                'metaboxes'     => array_merge(
632
-                    $this->_default_espresso_metaboxes,
633
-                    ['_publish_post_box', 'attendee_editor_metaboxes']
634
-                ),
635
-                'require_nonce' => false,
636
-            ],
637
-            'edit_attendee'     => [
638
-                'nav'           => [
639
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
640
-                    'icon' => 'dashicons-edit-large',
641
-                    'order'      => 15,
642
-                    'persistent' => false,
643
-                    'url'        => $ATT_ID
644
-                        ? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
-                        : $this->_admin_base_url,
646
-                ],
647
-                'metaboxes'     => array_merge(
648
-                    $this->_default_espresso_metaboxes,
649
-                    ['attendee_editor_metaboxes']
650
-                ),
651
-                'require_nonce' => false,
652
-            ],
653
-            'contact_list'      => [
654
-                'nav'           => [
655
-                    'label' => esc_html__('Contact List', 'event_espresso'),
656
-                    'icon' => 'dashicons-id-alt',
657
-                    'order' => 20,
658
-                ],
659
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
660
-                'help_tabs'     => [
661
-                    'registrations_contact_list_help_tab'                       => [
662
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
663
-                        'filename' => 'registrations_contact_list',
664
-                    ],
665
-                    'registrations_contact-list_table_column_headings_help_tab' => [
666
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
667
-                        'filename' => 'registrations_contact_list_table_column_headings',
668
-                    ],
669
-                    'registrations_contact_list_views_help_tab'                 => [
670
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
671
-                        'filename' => 'registrations_contact_list_views',
672
-                    ],
673
-                    'registrations_contact_list_other_help_tab'                 => [
674
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
675
-                        'filename' => 'registrations_contact_list_other',
676
-                    ],
677
-                ],
678
-                'metaboxes'     => [],
679
-                'require_nonce' => false,
680
-            ],
681
-            // override default cpt routes
682
-            'create_new'        => '',
683
-            'edit'              => '',
684
-        ];
685
-    }
686
-
687
-
688
-    /**
689
-     * The below methods aren't used by this class currently
690
-     */
691
-    protected function _add_screen_options()
692
-    {
693
-    }
694
-
695
-
696
-    protected function _add_feature_pointers()
697
-    {
698
-    }
699
-
700
-
701
-    public function admin_init()
702
-    {
703
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
704
-            'click "Update Registration Questions" to save your changes',
705
-            'event_espresso'
706
-        );
707
-    }
708
-
709
-
710
-    public function admin_notices()
711
-    {
712
-    }
713
-
714
-
715
-    public function admin_footer_scripts()
716
-    {
717
-    }
718
-
719
-
720
-    /**
721
-     * get list of registration statuses
722
-     *
723
-     * @return void
724
-     * @throws EE_Error
725
-     */
726
-    private function _get_registration_status_array()
727
-    {
728
-        self::$_reg_status = EEM_Registration::reg_status_array([], true);
729
-    }
730
-
731
-
732
-    /**
733
-     * @throws InvalidArgumentException
734
-     * @throws InvalidDataTypeException
735
-     * @throws InvalidInterfaceException
736
-     * @since 4.10.2.p
737
-     */
738
-    protected function _add_screen_options_default()
739
-    {
740
-        $this->_per_page_screen_option();
741
-    }
742
-
743
-
744
-    /**
745
-     * @throws InvalidArgumentException
746
-     * @throws InvalidDataTypeException
747
-     * @throws InvalidInterfaceException
748
-     * @since 4.10.2.p
749
-     */
750
-    protected function _add_screen_options_contact_list()
751
-    {
752
-        $page_title              = $this->_admin_page_title;
753
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
754
-        $this->_per_page_screen_option();
755
-        $this->_admin_page_title = $page_title;
756
-    }
757
-
758
-
759
-    public function load_scripts_styles()
760
-    {
761
-        // style
762
-        wp_register_style(
763
-            'espresso_reg',
764
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
765
-            ['ee-admin-css'],
766
-            EVENT_ESPRESSO_VERSION
767
-        );
768
-        wp_enqueue_style('espresso_reg');
769
-        // script
770
-        wp_register_script(
771
-            'espresso_reg',
772
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
773
-            ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774
-            EVENT_ESPRESSO_VERSION,
775
-            true
776
-        );
777
-        wp_enqueue_script('espresso_reg');
778
-    }
779
-
780
-
781
-    /**
782
-     * @throws EE_Error
783
-     * @throws InvalidArgumentException
784
-     * @throws InvalidDataTypeException
785
-     * @throws InvalidInterfaceException
786
-     * @throws ReflectionException
787
-     * @since 4.10.2.p
788
-     */
789
-    public function load_scripts_styles_edit_attendee()
790
-    {
791
-        // stuff to only show up on our attendee edit details page.
792
-        $attendee_details_translations = [
793
-            'att_publish_text' => sprintf(
794
-            /* translators: The date and time */
795
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
797
-            ),
798
-        ];
799
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
800
-        wp_enqueue_script('jquery-validate');
801
-    }
802
-
803
-
804
-    /**
805
-     * @throws EE_Error
806
-     * @throws InvalidArgumentException
807
-     * @throws InvalidDataTypeException
808
-     * @throws InvalidInterfaceException
809
-     * @throws ReflectionException
810
-     * @since 4.10.2.p
811
-     */
812
-    public function load_scripts_styles_view_registration()
813
-    {
814
-        // styles
815
-        wp_enqueue_style('espresso-ui-theme');
816
-        // scripts
817
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
818
-        $this->_reg_custom_questions_form->wp_enqueue_scripts();
819
-    }
820
-
821
-
822
-    public function load_scripts_styles_contact_list()
823
-    {
824
-        wp_dequeue_style('espresso_reg');
825
-        wp_register_style(
826
-            'espresso_att',
827
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
828
-            ['ee-admin-css'],
829
-            EVENT_ESPRESSO_VERSION
830
-        );
831
-        wp_enqueue_style('espresso_att');
832
-    }
833
-
834
-
835
-    public function load_scripts_styles_new_registration()
836
-    {
837
-        wp_register_script(
838
-            'ee-spco-for-admin',
839
-            REG_ASSETS_URL . 'spco_for_admin.js',
840
-            ['underscore', 'jquery'],
841
-            EVENT_ESPRESSO_VERSION,
842
-            true
843
-        );
844
-        wp_enqueue_script('ee-spco-for-admin');
845
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
846
-        EE_Form_Section_Proper::wp_enqueue_scripts();
847
-        EED_Ticket_Selector::load_tckt_slctr_assets();
848
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
849
-    }
850
-
851
-
852
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
853
-    {
854
-        add_filter('FHEE_load_EE_messages', '__return_true');
855
-    }
856
-
857
-
858
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
859
-    {
860
-        add_filter('FHEE_load_EE_messages', '__return_true');
861
-    }
862
-
863
-
864
-    /**
865
-     * @throws EE_Error
866
-     * @throws InvalidArgumentException
867
-     * @throws InvalidDataTypeException
868
-     * @throws InvalidInterfaceException
869
-     * @throws ReflectionException
870
-     * @since 4.10.2.p
871
-     */
872
-    protected function _set_list_table_views_default()
873
-    {
874
-        // for notification related bulk actions we need to make sure only active messengers have an option.
875
-        EED_Messages::set_autoloaders();
876
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
877
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
878
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
879
-        // key= bulk_action_slug, value= message type.
880
-        $match_array = [
881
-            'approve_registrations'    => 'registration',
882
-            'decline_registrations'    => 'declined_registration',
883
-            'pending_registrations'    => 'pending_approval',
884
-            'no_approve_registrations' => 'not_approved_registration',
885
-            'cancel_registrations'     => 'cancelled_registration',
886
-        ];
887
-        $can_send    = EE_Registry::instance()->CAP->current_user_can(
888
-            'ee_send_message',
889
-            'batch_send_messages'
890
-        );
891
-        /** setup reg status bulk actions **/
892
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
893
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
894
-            $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
895
-                'Approve and Notify Registrations',
896
-                'event_espresso'
897
-            );
898
-        }
899
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
900
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
901
-            $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
902
-                'Decline and Notify Registrations',
903
-                'event_espresso'
904
-            );
905
-        }
906
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
907
-            'Set Registrations to Pending Payment',
908
-            'event_espresso'
909
-        );
910
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
911
-            $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
912
-                'Set Registrations to Pending Payment and Notify',
913
-                'event_espresso'
914
-            );
915
-        }
916
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
917
-            'Set Registrations to Not Approved',
918
-            'event_espresso'
919
-        );
920
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
921
-            $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
922
-                'Set Registrations to Not Approved and Notify',
923
-                'event_espresso'
924
-            );
925
-        }
926
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
927
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
928
-            $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
929
-                'Cancel Registrations and Notify',
930
-                'event_espresso'
931
-            );
932
-        }
933
-        $def_reg_status_actions = apply_filters(
934
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
935
-            $def_reg_status_actions,
936
-            $active_mts,
937
-            $can_send
938
-        );
939
-
940
-        $this->_views = [
941
-            'all'   => [
942
-                'slug'        => 'all',
943
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
944
-                'count'       => 0,
945
-                'bulk_action' => array_merge(
946
-                    $def_reg_status_actions,
947
-                    [
948
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
949
-                    ]
950
-                ),
951
-            ],
952
-            'month' => [
953
-                'slug'        => 'month',
954
-                'label'       => esc_html__('This Month', 'event_espresso'),
955
-                'count'       => 0,
956
-                'bulk_action' => array_merge(
957
-                    $def_reg_status_actions,
958
-                    [
959
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
960
-                    ]
961
-                ),
962
-            ],
963
-            'today' => [
964
-                'slug'        => 'today',
965
-                'label'       => sprintf(
966
-                    esc_html__('Today - %s', 'event_espresso'),
967
-                    date('M d, Y', current_time('timestamp'))
968
-                ),
969
-                'count'       => 0,
970
-                'bulk_action' => array_merge(
971
-                    $def_reg_status_actions,
972
-                    [
973
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
974
-                    ]
975
-                ),
976
-            ],
977
-        ];
978
-        if (
979
-            EE_Registry::instance()->CAP->current_user_can(
980
-                'ee_delete_registrations',
981
-                'espresso_registrations_delete_registration'
982
-            )
983
-        ) {
984
-            $this->_views['incomplete'] = [
985
-                'slug'        => 'incomplete',
986
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
987
-                'count'       => 0,
988
-                'bulk_action' => [
989
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
990
-                ],
991
-            ];
992
-            $this->_views['trash']      = [
993
-                'slug'        => 'trash',
994
-                'label'       => esc_html__('Trash', 'event_espresso'),
995
-                'count'       => 0,
996
-                'bulk_action' => [
997
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
998
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
999
-                ],
1000
-            ];
1001
-        }
1002
-    }
1003
-
1004
-
1005
-    protected function _set_list_table_views_contact_list()
1006
-    {
1007
-        $this->_views = [
1008
-            'in_use' => [
1009
-                'slug'        => 'in_use',
1010
-                'label'       => esc_html__('In Use', 'event_espresso'),
1011
-                'count'       => 0,
1012
-                'bulk_action' => [
1013
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1014
-                ],
1015
-            ],
1016
-        ];
1017
-        if (
1018
-            EE_Registry::instance()->CAP->current_user_can(
1019
-                'ee_delete_contacts',
1020
-                'espresso_registrations_trash_attendees'
1021
-            )
1022
-        ) {
1023
-            $this->_views['trash'] = [
1024
-                'slug'        => 'trash',
1025
-                'label'       => esc_html__('Trash', 'event_espresso'),
1026
-                'count'       => 0,
1027
-                'bulk_action' => [
1028
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1029
-                ],
1030
-            ];
1031
-        }
1032
-    }
1033
-
1034
-
1035
-    /**
1036
-     * @return array
1037
-     * @throws EE_Error
1038
-     */
1039
-    protected function _registration_legend_items()
1040
-    {
1041
-        $fc_items = [
1042
-            'star-icon'        => [
1043
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1044
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1045
-            ],
1046
-            'view_details'     => [
1047
-                'class' => 'dashicons dashicons-clipboard',
1048
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1049
-            ],
1050
-            'edit_attendee'    => [
1051
-                'class' => 'dashicons dashicons-admin-users',
1052
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1053
-            ],
1054
-            'view_transaction' => [
1055
-                'class' => 'dashicons dashicons-cart',
1056
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1057
-            ],
1058
-            'view_invoice'     => [
1059
-                'class' => 'dashicons dashicons-media-spreadsheet',
1060
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1061
-            ],
1062
-        ];
1063
-        if (
1064
-            EE_Registry::instance()->CAP->current_user_can(
1065
-                'ee_send_message',
1066
-                'espresso_registrations_resend_registration'
1067
-            )
1068
-        ) {
1069
-            $fc_items['resend_registration'] = [
1070
-                'class' => 'dashicons dashicons-email-alt',
1071
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1072
-            ];
1073
-        } else {
1074
-            $fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1075
-        }
1076
-        if (
1077
-            EE_Registry::instance()->CAP->current_user_can(
1078
-                'ee_read_global_messages',
1079
-                'view_filtered_messages'
1080
-            )
1081
-        ) {
1082
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1083
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1084
-                $fc_items['view_related_messages'] = [
1085
-                    'class' => $related_for_icon['css_class'],
1086
-                    'desc'  => $related_for_icon['label'],
1087
-                ];
1088
-            }
1089
-        }
1090
-        $sc_items = [
1091
-            'approved_status'   => [
1092
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1093
-                'desc'  => EEH_Template::pretty_status(
1094
-                    EEM_Registration::status_id_approved,
1095
-                    false,
1096
-                    'sentence'
1097
-                ),
1098
-            ],
1099
-            'pending_status'    => [
1100
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1101
-                'desc'  => EEH_Template::pretty_status(
1102
-                    EEM_Registration::status_id_pending_payment,
1103
-                    false,
1104
-                    'sentence'
1105
-                ),
1106
-            ],
1107
-            'wait_list'         => [
1108
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1109
-                'desc'  => EEH_Template::pretty_status(
1110
-                    EEM_Registration::status_id_wait_list,
1111
-                    false,
1112
-                    'sentence'
1113
-                ),
1114
-            ],
1115
-            'incomplete_status' => [
1116
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1117
-                'desc'  => EEH_Template::pretty_status(
1118
-                    EEM_Registration::status_id_incomplete,
1119
-                    false,
1120
-                    'sentence'
1121
-                ),
1122
-            ],
1123
-            'not_approved'      => [
1124
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1125
-                'desc'  => EEH_Template::pretty_status(
1126
-                    EEM_Registration::status_id_not_approved,
1127
-                    false,
1128
-                    'sentence'
1129
-                ),
1130
-            ],
1131
-            'declined_status'   => [
1132
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1133
-                'desc'  => EEH_Template::pretty_status(
1134
-                    EEM_Registration::status_id_declined,
1135
-                    false,
1136
-                    'sentence'
1137
-                ),
1138
-            ],
1139
-            'cancelled_status'  => [
1140
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1141
-                'desc'  => EEH_Template::pretty_status(
1142
-                    EEM_Registration::status_id_cancelled,
1143
-                    false,
1144
-                    'sentence'
1145
-                ),
1146
-            ],
1147
-        ];
1148
-        return array_merge($fc_items, $sc_items);
1149
-    }
1150
-
1151
-
1152
-
1153
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1154
-
1155
-
1156
-    /**
1157
-     * @throws DomainException
1158
-     * @throws EE_Error
1159
-     * @throws InvalidArgumentException
1160
-     * @throws InvalidDataTypeException
1161
-     * @throws InvalidInterfaceException
1162
-     */
1163
-    protected function _registrations_overview_list_table()
1164
-    {
1165
-        $this->appendAddNewRegistrationButtonToPageTitle();
1166
-        $header_text                  = '';
1167
-        $admin_page_header_decorators = [
1168
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1169
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1170
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1171
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1172
-        ];
1173
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1174
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1175
-            $header_text = $filter_header_decorator->getHeaderText($header_text);
1176
-        }
1177
-        $this->_template_args['before_list_table']  = $header_text;
1178
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1179
-        $this->display_admin_list_table_page_with_no_sidebar();
1180
-    }
1181
-
1182
-
1183
-    /**
1184
-     * @throws EE_Error
1185
-     * @throws InvalidArgumentException
1186
-     * @throws InvalidDataTypeException
1187
-     * @throws InvalidInterfaceException
1188
-     */
1189
-    private function appendAddNewRegistrationButtonToPageTitle()
1190
-    {
1191
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1192
-        if (
1193
-            $EVT_ID
1194
-            && EE_Registry::instance()->CAP->current_user_can(
1195
-                'ee_edit_registrations',
1196
-                'espresso_registrations_new_registration',
1197
-                $EVT_ID
1198
-            )
1199
-        ) {
1200
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1201
-                'new_registration',
1202
-                'add-registrant',
1203
-                ['event_id' => $EVT_ID],
1204
-                'add-new-h2'
1205
-            );
1206
-        }
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     * This sets the _registration property for the registration details screen
1212
-     *
1213
-     * @return void
1214
-     * @throws EE_Error
1215
-     * @throws InvalidArgumentException
1216
-     * @throws InvalidDataTypeException
1217
-     * @throws InvalidInterfaceException
1218
-     */
1219
-    private function _set_registration_object()
1220
-    {
1221
-        // get out if we've already set the object
1222
-        if ($this->_registration instanceof EE_Registration) {
1223
-            return;
1224
-        }
1225
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1226
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1227
-            return;
1228
-        }
1229
-        $error_msg = sprintf(
1230
-            esc_html__(
1231
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1232
-                'event_espresso'
1233
-            ),
1234
-            $REG_ID
1235
-        );
1236
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1237
-        $this->_registration = null;
1238
-    }
1239
-
1240
-
1241
-    /**
1242
-     * Used to retrieve registrations for the list table.
1243
-     *
1244
-     * @param int  $per_page
1245
-     * @param bool $count
1246
-     * @param bool $this_month
1247
-     * @param bool $today
1248
-     * @return EE_Registration[]|int
1249
-     * @throws EE_Error
1250
-     * @throws InvalidArgumentException
1251
-     * @throws InvalidDataTypeException
1252
-     * @throws InvalidInterfaceException
1253
-     */
1254
-    public function get_registrations(
1255
-        $per_page = 10,
1256
-        $count = false,
1257
-        $this_month = false,
1258
-        $today = false
1259
-    ) {
1260
-        if ($this_month) {
1261
-            $this->request->setRequestParam('status', 'month');
1262
-        }
1263
-        if ($today) {
1264
-            $this->request->setRequestParam('status', 'today');
1265
-        }
1266
-        $query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1267
-        /**
1268
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1269
-         *
1270
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1271
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1272
-         *                      or if you have the development copy of EE you can view this at the path:
1273
-         *                      /docs/G--Model-System/model-query-params.md
1274
-         */
1275
-        $query_params['group_by'] = '';
1276
-
1277
-        return $count
1278
-            ? $this->getRegistrationModel()->count($query_params)
1279
-            /** @type EE_Registration[] */
1280
-            : $this->getRegistrationModel()->get_all($query_params);
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1286
-     * Note: this listens to values on the request for some of the query parameters.
1287
-     *
1288
-     * @param array $request
1289
-     * @param int   $per_page
1290
-     * @param bool  $count
1291
-     * @return array
1292
-     * @throws EE_Error
1293
-     * @throws InvalidArgumentException
1294
-     * @throws InvalidDataTypeException
1295
-     * @throws InvalidInterfaceException
1296
-     */
1297
-    protected function _get_registration_query_parameters(
1298
-        $request = [],
1299
-        $per_page = 10,
1300
-        $count = false
1301
-    ) {
1302
-        /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1303
-        $list_table_query_builder = $this->loader->getNew(
1304
-            'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1305
-            [null, null, $request]
1306
-        );
1307
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1308
-    }
1309
-
1310
-
1311
-    public function get_registration_status_array()
1312
-    {
1313
-        return self::$_reg_status;
1314
-    }
1315
-
1316
-
1317
-
1318
-
1319
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1320
-    /**
1321
-     * generates HTML for the View Registration Details Admin page
1322
-     *
1323
-     * @return void
1324
-     * @throws DomainException
1325
-     * @throws EE_Error
1326
-     * @throws InvalidArgumentException
1327
-     * @throws InvalidDataTypeException
1328
-     * @throws InvalidInterfaceException
1329
-     * @throws EntityNotFoundException
1330
-     * @throws ReflectionException
1331
-     */
1332
-    protected function _registration_details()
1333
-    {
1334
-        $this->_template_args = [];
1335
-        $this->_set_registration_object();
1336
-        if (is_object($this->_registration)) {
1337
-            $transaction                                   = $this->_registration->transaction()
1338
-                ? $this->_registration->transaction()
1339
-                : EE_Transaction::new_instance();
1340
-            $this->_session                                = $transaction->session_data();
1341
-            $event_id                                      = $this->_registration->event_ID();
1342
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1343
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1344
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1345
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1346
-            $this->_template_args['grand_total']           = $transaction->total();
1347
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1348
-            // link back to overview
1349
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1350
-            $this->_template_args['registration']                = $this->_registration;
1351
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
-                [
1353
-                    'action'   => 'default',
1354
-                    'event_id' => $event_id,
1355
-                ],
1356
-                REG_ADMIN_URL
1357
-            );
1358
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1359
-                [
1360
-                    'action' => 'default',
1361
-                    'EVT_ID' => $event_id,
1362
-                    'page'   => 'espresso_transactions',
1363
-                ],
1364
-                admin_url('admin.php')
1365
-            );
1366
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1367
-                [
1368
-                    'page'   => 'espresso_events',
1369
-                    'action' => 'edit',
1370
-                    'post'   => $event_id,
1371
-                ],
1372
-                admin_url('admin.php')
1373
-            );
1374
-            // next and previous links
1375
-            $next_reg                                      = $this->_registration->next(
1376
-                null,
1377
-                [],
1378
-                'REG_ID'
1379
-            );
1380
-            $this->_template_args['next_registration']     = $next_reg
1381
-                ? $this->_next_link(
1382
-                    EE_Admin_Page::add_query_args_and_nonce(
1383
-                        [
1384
-                            'action'  => 'view_registration',
1385
-                            '_REG_ID' => $next_reg['REG_ID'],
1386
-                        ],
1387
-                        REG_ADMIN_URL
1388
-                    ),
1389
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1390
-                )
1391
-                : '';
1392
-            $previous_reg                                  = $this->_registration->previous(
1393
-                null,
1394
-                [],
1395
-                'REG_ID'
1396
-            );
1397
-            $this->_template_args['previous_registration'] = $previous_reg
1398
-                ? $this->_previous_link(
1399
-                    EE_Admin_Page::add_query_args_and_nonce(
1400
-                        [
1401
-                            'action'  => 'view_registration',
1402
-                            '_REG_ID' => $previous_reg['REG_ID'],
1403
-                        ],
1404
-                        REG_ADMIN_URL
1405
-                    ),
1406
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1407
-                )
1408
-                : '';
1409
-            // grab header
1410
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1411
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1412
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1413
-                $template_path,
1414
-                $this->_template_args,
1415
-                true
1416
-            );
1417
-        } else {
1418
-            $this->_template_args['admin_page_header'] = '';
1419
-            $this->_display_espresso_notices();
1420
-        }
1421
-        // the details template wrapper
1422
-        $this->display_admin_page_with_sidebar();
1423
-    }
1424
-
1425
-
1426
-    /**
1427
-     * @throws EE_Error
1428
-     * @throws InvalidArgumentException
1429
-     * @throws InvalidDataTypeException
1430
-     * @throws InvalidInterfaceException
1431
-     * @throws ReflectionException
1432
-     * @since 4.10.2.p
1433
-     */
1434
-    protected function _registration_details_metaboxes()
1435
-    {
1436
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1437
-        $this->_set_registration_object();
1438
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1439
-        $this->addMetaBox(
1440
-            'edit-reg-status-mbox',
1441
-            esc_html__('Registration Status', 'event_espresso'),
1442
-            [$this, 'set_reg_status_buttons_metabox'],
1443
-            $this->_wp_page_slug
1444
-        );
1445
-        $this->addMetaBox(
1446
-            'edit-reg-details-mbox',
1447
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1448
-            . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1449
-            [$this, '_reg_details_meta_box'],
1450
-            $this->_wp_page_slug
1451
-        );
1452
-        if (
1453
-            $attendee instanceof EE_Attendee
1454
-            && EE_Registry::instance()->CAP->current_user_can(
1455
-                'ee_read_registration',
1456
-                'edit-reg-questions-mbox',
1457
-                $this->_registration->ID()
1458
-            )
1459
-        ) {
1460
-            $this->addMetaBox(
1461
-                'edit-reg-questions-mbox',
1462
-                esc_html__('Registration Form Answers', 'event_espresso'),
1463
-                [$this, '_reg_questions_meta_box'],
1464
-                $this->_wp_page_slug
1465
-            );
1466
-        }
1467
-        $this->addMetaBox(
1468
-            'edit-reg-registrant-mbox',
1469
-            esc_html__('Contact Details', 'event_espresso'),
1470
-            [$this, '_reg_registrant_side_meta_box'],
1471
-            $this->_wp_page_slug,
1472
-            'side'
1473
-        );
1474
-        if ($this->_registration->group_size() > 1) {
1475
-            $this->addMetaBox(
1476
-                'edit-reg-attendees-mbox',
1477
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1478
-                [$this, '_reg_attendees_meta_box'],
1479
-                $this->_wp_page_slug
1480
-            );
1481
-        }
1482
-    }
1483
-
1484
-
1485
-    /**
1486
-     * set_reg_status_buttons_metabox
1487
-     *
1488
-     * @return void
1489
-     * @throws EE_Error
1490
-     * @throws EntityNotFoundException
1491
-     * @throws InvalidArgumentException
1492
-     * @throws InvalidDataTypeException
1493
-     * @throws InvalidInterfaceException
1494
-     * @throws ReflectionException
1495
-     */
1496
-    public function set_reg_status_buttons_metabox()
1497
-    {
1498
-        $this->_set_registration_object();
1499
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1500
-        $output                 = $change_reg_status_form->form_open(
1501
-            self::add_query_args_and_nonce(
1502
-                [
1503
-                    'action' => 'change_reg_status',
1504
-                ],
1505
-                REG_ADMIN_URL
1506
-            )
1507
-        );
1508
-        $output                 .= $change_reg_status_form->get_html();
1509
-        $output                 .= $change_reg_status_form->form_close();
1510
-        echo wp_kses($output, AllowedTags::getWithFormTags());
1511
-    }
1512
-
1513
-
1514
-    /**
1515
-     * @return EE_Form_Section_Proper
1516
-     * @throws EE_Error
1517
-     * @throws InvalidArgumentException
1518
-     * @throws InvalidDataTypeException
1519
-     * @throws InvalidInterfaceException
1520
-     * @throws EntityNotFoundException
1521
-     * @throws ReflectionException
1522
-     */
1523
-    protected function _generate_reg_status_change_form()
1524
-    {
1525
-        $reg_status_change_form_array = [
1526
-            'name'            => 'reg_status_change_form',
1527
-            'html_id'         => 'reg-status-change-form',
1528
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1529
-            'subsections'     => [
1530
-                'return'         => new EE_Hidden_Input(
1531
-                    [
1532
-                        'name'    => 'return',
1533
-                        'default' => 'view_registration',
1534
-                    ]
1535
-                ),
1536
-                'REG_ID'         => new EE_Hidden_Input(
1537
-                    [
1538
-                        'name'    => 'REG_ID',
1539
-                        'default' => $this->_registration->ID(),
1540
-                    ]
1541
-                ),
1542
-            ],
1543
-        ];
1544
-        if (
1545
-            EE_Registry::instance()->CAP->current_user_can(
1546
-                'ee_edit_registration',
1547
-                'toggle_registration_status',
1548
-                $this->_registration->ID()
1549
-            )
1550
-        ) {
1551
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1552
-                $this->_get_reg_statuses(),
1553
-                [
1554
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1555
-                    'default'         => $this->_registration->status_ID(),
1556
-                ]
1557
-            );
1558
-            $reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1559
-                [
1560
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1561
-                    'default'         => false,
1562
-                    'html_help_text'  => esc_html__(
1563
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1564
-                        'event_espresso'
1565
-                    ),
1566
-                ]
1567
-            );
1568
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1569
-                [
1570
-                    'html_class'      => 'button--primary',
1571
-                    'html_label_text' => '&nbsp;',
1572
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1573
-                ]
1574
-            );
1575
-        }
1576
-        return new EE_Form_Section_Proper($reg_status_change_form_array);
1577
-    }
1578
-
1579
-
1580
-    /**
1581
-     * Returns an array of all the buttons for the various statuses and switch status actions
1582
-     *
1583
-     * @return array
1584
-     * @throws EE_Error
1585
-     * @throws InvalidArgumentException
1586
-     * @throws InvalidDataTypeException
1587
-     * @throws InvalidInterfaceException
1588
-     * @throws EntityNotFoundException
1589
-     */
1590
-    protected function _get_reg_statuses()
1591
-    {
1592
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1593
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1594
-        // get current reg status
1595
-        $current_status = $this->_registration->status_ID();
1596
-        // is registration for free event? This will determine whether to display the pending payment option
1597
-        if (
1598
-            $current_status !== EEM_Registration::status_id_pending_payment
1599
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1600
-        ) {
1601
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1602
-        }
1603
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1604
-    }
1605
-
1606
-
1607
-    /**
1608
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1609
-     *
1610
-     * @param bool $status REG status given for changing registrations to.
1611
-     * @param bool $notify Whether to send messages notifications or not.
1612
-     * @return array (array with reg_id(s) updated and whether update was successful.
1613
-     * @throws DomainException
1614
-     * @throws EE_Error
1615
-     * @throws EntityNotFoundException
1616
-     * @throws InvalidArgumentException
1617
-     * @throws InvalidDataTypeException
1618
-     * @throws InvalidInterfaceException
1619
-     * @throws ReflectionException
1620
-     * @throws RuntimeException
1621
-     */
1622
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1623
-    {
1624
-        $REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1625
-            ? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1626
-            : $this->request->getRequestParam('_REG_ID', [], 'int', true);
1627
-
1628
-        // sanitize $REG_IDs
1629
-        $REG_IDs = array_map('absint', $REG_IDs);
1630
-        // and remove empty entries
1631
-        $REG_IDs = array_filter($REG_IDs);
1632
-
1633
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1634
-
1635
-        /**
1636
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1637
-         * Currently this value is used downstream by the _process_resend_registration method.
1638
-         *
1639
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1640
-         * @param bool                     $status           The status registrations were changed to.
1641
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1642
-         * @param Registrations_Admin_Page $admin_page_object
1643
-         */
1644
-        $REG_ID = apply_filters(
1645
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1646
-            $result['REG_ID'],
1647
-            $status,
1648
-            $result['success'],
1649
-            $this
1650
-        );
1651
-        $this->request->setRequestParam('_REG_ID', $REG_ID);
1652
-
1653
-        // notify?
1654
-        if (
1655
-            $notify
1656
-            && $result['success']
1657
-            && ! empty($REG_ID)
1658
-            && EE_Registry::instance()->CAP->current_user_can(
1659
-                'ee_send_message',
1660
-                'espresso_registrations_resend_registration'
1661
-            )
1662
-        ) {
1663
-            $this->_process_resend_registration();
1664
-        }
1665
-        return $result;
1666
-    }
1667
-
1668
-
1669
-    /**
1670
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1671
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1672
-     *
1673
-     * @param array  $REG_IDs
1674
-     * @param string $status
1675
-     * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1676
-     *                       slug sent with setting the registration status.
1677
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1678
-     * @throws EE_Error
1679
-     * @throws InvalidArgumentException
1680
-     * @throws InvalidDataTypeException
1681
-     * @throws InvalidInterfaceException
1682
-     * @throws ReflectionException
1683
-     * @throws RuntimeException
1684
-     * @throws EntityNotFoundException
1685
-     * @throws DomainException
1686
-     */
1687
-    protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1688
-    {
1689
-        $success = false;
1690
-        // typecast $REG_IDs
1691
-        $REG_IDs = (array) $REG_IDs;
1692
-        if (! empty($REG_IDs)) {
1693
-            $success = true;
1694
-            // set default status if none is passed
1695
-            $status         = $status ?: EEM_Registration::status_id_pending_payment;
1696
-            $status_context = $notify
1697
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1698
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1699
-            // loop through REG_ID's and change status
1700
-            foreach ($REG_IDs as $REG_ID) {
1701
-                $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1702
-                if ($registration instanceof EE_Registration) {
1703
-                    $registration->set_status(
1704
-                        $status,
1705
-                        false,
1706
-                        new Context(
1707
-                            $status_context,
1708
-                            esc_html__(
1709
-                                'Manually triggered status change on a Registration Admin Page route.',
1710
-                                'event_espresso'
1711
-                            )
1712
-                        )
1713
-                    );
1714
-                    $result = $registration->save();
1715
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1716
-                    $success = $result !== false ? $success : false;
1717
-                }
1718
-            }
1719
-        }
1720
-
1721
-        // return $success and processed registrations
1722
-        return ['REG_ID' => $REG_IDs, 'success' => $success];
1723
-    }
1724
-
1725
-
1726
-    /**
1727
-     * Common logic for setting up success message and redirecting to appropriate route
1728
-     *
1729
-     * @param string $STS_ID status id for the registration changed to
1730
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1731
-     * @return void
1732
-     * @throws DomainException
1733
-     * @throws EE_Error
1734
-     * @throws EntityNotFoundException
1735
-     * @throws InvalidArgumentException
1736
-     * @throws InvalidDataTypeException
1737
-     * @throws InvalidInterfaceException
1738
-     * @throws ReflectionException
1739
-     * @throws RuntimeException
1740
-     */
1741
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1742
-    {
1743
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1744
-            : ['success' => false];
1745
-        $success = isset($result['success']) && $result['success'];
1746
-        // setup success message
1747
-        if ($success) {
1748
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1749
-                $msg = sprintf(
1750
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1751
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1752
-                );
1753
-            } else {
1754
-                $msg = sprintf(
1755
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1756
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1757
-                );
1758
-            }
1759
-            EE_Error::add_success($msg);
1760
-        } else {
1761
-            EE_Error::add_error(
1762
-                esc_html__(
1763
-                    'Something went wrong, and the status was not changed',
1764
-                    'event_espresso'
1765
-                ),
1766
-                __FILE__,
1767
-                __LINE__,
1768
-                __FUNCTION__
1769
-            );
1770
-        }
1771
-        $return = $this->request->getRequestParam('return');
1772
-        $route  = $return === 'view_registration'
1773
-            ? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1774
-            : ['action' => 'default'];
1775
-        $route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1776
-        $this->_redirect_after_action($success, '', '', $route, true);
1777
-    }
1778
-
1779
-
1780
-    /**
1781
-     * incoming reg status change from reg details page.
1782
-     *
1783
-     * @return void
1784
-     * @throws EE_Error
1785
-     * @throws EntityNotFoundException
1786
-     * @throws InvalidArgumentException
1787
-     * @throws InvalidDataTypeException
1788
-     * @throws InvalidInterfaceException
1789
-     * @throws ReflectionException
1790
-     * @throws RuntimeException
1791
-     * @throws DomainException
1792
-     */
1793
-    protected function _change_reg_status()
1794
-    {
1795
-        $this->request->setRequestParam('return', 'view_registration');
1796
-        // set notify based on whether the send notifications toggle is set or not
1797
-        $notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1798
-        $reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1799
-        $this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1800
-        switch ($reg_status) {
1801
-            case EEM_Registration::status_id_approved:
1802
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1803
-                $this->approve_registration($notify);
1804
-                break;
1805
-            case EEM_Registration::status_id_pending_payment:
1806
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1807
-                $this->pending_registration($notify);
1808
-                break;
1809
-            case EEM_Registration::status_id_not_approved:
1810
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1811
-                $this->not_approve_registration($notify);
1812
-                break;
1813
-            case EEM_Registration::status_id_declined:
1814
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1815
-                $this->decline_registration($notify);
1816
-                break;
1817
-            case EEM_Registration::status_id_cancelled:
1818
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1819
-                $this->cancel_registration($notify);
1820
-                break;
1821
-            case EEM_Registration::status_id_wait_list:
1822
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1823
-                $this->wait_list_registration($notify);
1824
-                break;
1825
-            case EEM_Registration::status_id_incomplete:
1826
-            default:
1827
-                $this->request->unSetRequestParam('return');
1828
-                $this->_reg_status_change_return('');
1829
-                break;
1830
-        }
1831
-    }
1832
-
1833
-
1834
-    /**
1835
-     * Callback for bulk action routes.
1836
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1837
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1838
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1839
-     * when an action is happening on just a single registration).
1840
-     *
1841
-     * @param      $action
1842
-     * @param bool $notify
1843
-     */
1844
-    protected function bulk_action_on_registrations($action, $notify = false)
1845
-    {
1846
-        do_action(
1847
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1848
-            $this,
1849
-            $action,
1850
-            $notify
1851
-        );
1852
-        $method = $action . '_registration';
1853
-        if (method_exists($this, $method)) {
1854
-            $this->$method($notify);
1855
-        }
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     * approve_registration
1861
-     *
1862
-     * @param bool $notify whether or not to notify the registrant about their approval.
1863
-     * @return void
1864
-     * @throws EE_Error
1865
-     * @throws EntityNotFoundException
1866
-     * @throws InvalidArgumentException
1867
-     * @throws InvalidDataTypeException
1868
-     * @throws InvalidInterfaceException
1869
-     * @throws ReflectionException
1870
-     * @throws RuntimeException
1871
-     * @throws DomainException
1872
-     */
1873
-    protected function approve_registration($notify = false)
1874
-    {
1875
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1876
-    }
1877
-
1878
-
1879
-    /**
1880
-     * decline_registration
1881
-     *
1882
-     * @param bool $notify whether or not to notify the registrant about their status change.
1883
-     * @return void
1884
-     * @throws EE_Error
1885
-     * @throws EntityNotFoundException
1886
-     * @throws InvalidArgumentException
1887
-     * @throws InvalidDataTypeException
1888
-     * @throws InvalidInterfaceException
1889
-     * @throws ReflectionException
1890
-     * @throws RuntimeException
1891
-     * @throws DomainException
1892
-     */
1893
-    protected function decline_registration($notify = false)
1894
-    {
1895
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1896
-    }
1897
-
1898
-
1899
-    /**
1900
-     * cancel_registration
1901
-     *
1902
-     * @param bool $notify whether or not to notify the registrant about their status change.
1903
-     * @return void
1904
-     * @throws EE_Error
1905
-     * @throws EntityNotFoundException
1906
-     * @throws InvalidArgumentException
1907
-     * @throws InvalidDataTypeException
1908
-     * @throws InvalidInterfaceException
1909
-     * @throws ReflectionException
1910
-     * @throws RuntimeException
1911
-     * @throws DomainException
1912
-     */
1913
-    protected function cancel_registration($notify = false)
1914
-    {
1915
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1916
-    }
1917
-
1918
-
1919
-    /**
1920
-     * not_approve_registration
1921
-     *
1922
-     * @param bool $notify whether or not to notify the registrant about their status change.
1923
-     * @return void
1924
-     * @throws EE_Error
1925
-     * @throws EntityNotFoundException
1926
-     * @throws InvalidArgumentException
1927
-     * @throws InvalidDataTypeException
1928
-     * @throws InvalidInterfaceException
1929
-     * @throws ReflectionException
1930
-     * @throws RuntimeException
1931
-     * @throws DomainException
1932
-     */
1933
-    protected function not_approve_registration($notify = false)
1934
-    {
1935
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1936
-    }
1937
-
1938
-
1939
-    /**
1940
-     * decline_registration
1941
-     *
1942
-     * @param bool $notify whether or not to notify the registrant about their status change.
1943
-     * @return void
1944
-     * @throws EE_Error
1945
-     * @throws EntityNotFoundException
1946
-     * @throws InvalidArgumentException
1947
-     * @throws InvalidDataTypeException
1948
-     * @throws InvalidInterfaceException
1949
-     * @throws ReflectionException
1950
-     * @throws RuntimeException
1951
-     * @throws DomainException
1952
-     */
1953
-    protected function pending_registration($notify = false)
1954
-    {
1955
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1956
-    }
1957
-
1958
-
1959
-    /**
1960
-     * waitlist_registration
1961
-     *
1962
-     * @param bool $notify whether or not to notify the registrant about their status change.
1963
-     * @return void
1964
-     * @throws EE_Error
1965
-     * @throws EntityNotFoundException
1966
-     * @throws InvalidArgumentException
1967
-     * @throws InvalidDataTypeException
1968
-     * @throws InvalidInterfaceException
1969
-     * @throws ReflectionException
1970
-     * @throws RuntimeException
1971
-     * @throws DomainException
1972
-     */
1973
-    protected function wait_list_registration($notify = false)
1974
-    {
1975
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1976
-    }
1977
-
1978
-
1979
-    /**
1980
-     * generates HTML for the Registration main meta box
1981
-     *
1982
-     * @return void
1983
-     * @throws DomainException
1984
-     * @throws EE_Error
1985
-     * @throws InvalidArgumentException
1986
-     * @throws InvalidDataTypeException
1987
-     * @throws InvalidInterfaceException
1988
-     * @throws ReflectionException
1989
-     * @throws EntityNotFoundException
1990
-     */
1991
-    public function _reg_details_meta_box()
1992
-    {
1993
-        EEH_Autoloader::register_line_item_display_autoloaders();
1994
-        EEH_Autoloader::register_line_item_filter_autoloaders();
1995
-        EE_Registry::instance()->load_helper('Line_Item');
1996
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
1997
-            : EE_Transaction::new_instance();
1998
-        $this->_session = $transaction->session_data();
1999
-        $filters        = new EE_Line_Item_Filter_Collection();
2000
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2003
-            $filters,
2004
-            $transaction->total_line_item()
2005
-        );
2006
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2007
-        $line_item_display                       = new EE_Line_Item_Display(
2008
-            'reg_admin_table',
2009
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2010
-        );
2011
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2012
-            $filtered_line_item_tree,
2013
-            ['EE_Registration' => $this->_registration]
2014
-        );
2015
-        $attendee                                = $this->_registration->attendee();
2016
-        if (
2017
-            EE_Registry::instance()->CAP->current_user_can(
2018
-                'ee_read_transaction',
2019
-                'espresso_transactions_view_transaction'
2020
-            )
2021
-        ) {
2022
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2023
-                EE_Admin_Page::add_query_args_and_nonce(
2024
-                    [
2025
-                        'action' => 'view_transaction',
2026
-                        'TXN_ID' => $transaction->ID(),
2027
-                    ],
2028
-                    TXN_ADMIN_URL
2029
-                ),
2030
-                esc_html__(' View Transaction', 'event_espresso'),
2031
-                'button button--secondary right',
2032
-                'dashicons dashicons-cart'
2033
-            );
2034
-        } else {
2035
-            $this->_template_args['view_transaction_button'] = '';
2036
-        }
2037
-        if (
2038
-            $attendee instanceof EE_Attendee
2039
-            && EE_Registry::instance()->CAP->current_user_can(
2040
-                'ee_send_message',
2041
-                'espresso_registrations_resend_registration'
2042
-            )
2043
-        ) {
2044
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2045
-                EE_Admin_Page::add_query_args_and_nonce(
2046
-                    [
2047
-                        'action'      => 'resend_registration',
2048
-                        '_REG_ID'     => $this->_registration->ID(),
2049
-                        'redirect_to' => 'view_registration',
2050
-                    ],
2051
-                    REG_ADMIN_URL
2052
-                ),
2053
-                esc_html__(' Resend Registration', 'event_espresso'),
2054
-                'button button--secondary right',
2055
-                'dashicons dashicons-email-alt'
2056
-            );
2057
-        } else {
2058
-            $this->_template_args['resend_registration_button'] = '';
2059
-        }
2060
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2061
-        $payment                               = $transaction->get_first_related('Payment');
2062
-        $payment                               = ! $payment instanceof EE_Payment
2063
-            ? EE_Payment::new_instance()
2064
-            : $payment;
2065
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2066
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2067
-            ? EE_Payment_Method::new_instance()
2068
-            : $payment_method;
2069
-        $reg_details                           = [
2070
-            'payment_method'       => $payment_method->name(),
2071
-            'response_msg'         => $payment->gateway_response(),
2072
-            'registration_id'      => $this->_registration->get('REG_code'),
2073
-            'registration_session' => $this->_registration->session_ID(),
2074
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2075
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2076
-        ];
2077
-        if (isset($reg_details['registration_id'])) {
2078
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2079
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2080
-                'Registration ID',
2081
-                'event_espresso'
2082
-            );
2083
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2084
-        }
2085
-        if (isset($reg_details['payment_method'])) {
2086
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2087
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2088
-                'Most Recent Payment Method',
2089
-                'event_espresso'
2090
-            );
2091
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2092
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2093
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2094
-                'Payment method response',
2095
-                'event_espresso'
2096
-            );
2097
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2098
-        }
2099
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2101
-            'Registration Session',
2102
-            'event_espresso'
2103
-        );
2104
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2105
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2106
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2107
-            'Registration placed from IP',
2108
-            'event_espresso'
2109
-        );
2110
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2111
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2112
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2113
-            'Registrant User Agent',
2114
-            'event_espresso'
2115
-        );
2116
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2117
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2118
-            [
2119
-                'action'   => 'default',
2120
-                'event_id' => $this->_registration->event_ID(),
2121
-            ],
2122
-            REG_ADMIN_URL
2123
-        );
2124
-
2125
-        $this->_template_args['REG_ID'] = $this->_registration->ID();
2126
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2127
-
2128
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2129
-        EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130
-    }
2131
-
2132
-
2133
-    /**
2134
-     * generates HTML for the Registration Questions meta box.
2135
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2136
-     * otherwise uses new forms system
2137
-     *
2138
-     * @return void
2139
-     * @throws DomainException
2140
-     * @throws EE_Error
2141
-     * @throws InvalidArgumentException
2142
-     * @throws InvalidDataTypeException
2143
-     * @throws InvalidInterfaceException
2144
-     * @throws ReflectionException
2145
-     */
2146
-    public function _reg_questions_meta_box()
2147
-    {
2148
-        // allow someone to override this method entirely
2149
-        if (
2150
-            apply_filters(
2151
-                'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2152
-                true,
2153
-                $this,
2154
-                $this->_registration
2155
-            )
2156
-        ) {
2157
-            $form = $this->_get_reg_custom_questions_form(
2158
-                $this->_registration->ID()
2159
-            );
2160
-
2161
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2162
-                ? $form->get_html_and_js()
2163
-                : '';
2164
-
2165
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166
-            $this->_template_args['REG_ID'] = $this->_registration->ID();
2167
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2168
-            EEH_Template::display_template($template_path, $this->_template_args);
2169
-        }
2170
-    }
2171
-
2172
-
2173
-    /**
2174
-     * form_before_question_group
2175
-     *
2176
-     * @param string $output
2177
-     * @return        string
2178
-     * @deprecated    as of 4.8.32.rc.000
2179
-     */
2180
-    public function form_before_question_group($output)
2181
-    {
2182
-        EE_Error::doing_it_wrong(
2183
-            __CLASS__ . '::' . __FUNCTION__,
2184
-            esc_html__(
2185
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2186
-                'event_espresso'
2187
-            ),
2188
-            '4.8.32.rc.000'
2189
-        );
2190
-        return '
24
+	/**
25
+	 * @var EE_Registration
26
+	 */
27
+	private $_registration;
28
+
29
+	/**
30
+	 * @var EE_Event
31
+	 */
32
+	private $_reg_event;
33
+
34
+	/**
35
+	 * @var EE_Session
36
+	 */
37
+	private $_session;
38
+
39
+	/**
40
+	 * @var array
41
+	 */
42
+	private static $_reg_status;
43
+
44
+	/**
45
+	 * Form for displaying the custom questions for this registration.
46
+	 * This gets used a few times throughout the request so its best to cache it
47
+	 *
48
+	 * @var EE_Registration_Custom_Questions_Form
49
+	 */
50
+	protected $_reg_custom_questions_form;
51
+
52
+	/**
53
+	 * @var EEM_Registration $registration_model
54
+	 */
55
+	private $registration_model;
56
+
57
+	/**
58
+	 * @var EEM_Attendee $attendee_model
59
+	 */
60
+	private $attendee_model;
61
+
62
+	/**
63
+	 * @var EEM_Event $event_model
64
+	 */
65
+	private $event_model;
66
+
67
+	/**
68
+	 * @var EEM_Status $status_model
69
+	 */
70
+	private $status_model;
71
+
72
+
73
+	/**
74
+	 * @param bool $routing
75
+	 * @throws EE_Error
76
+	 * @throws InvalidArgumentException
77
+	 * @throws InvalidDataTypeException
78
+	 * @throws InvalidInterfaceException
79
+	 * @throws ReflectionException
80
+	 */
81
+	public function __construct($routing = true)
82
+	{
83
+		parent::__construct($routing);
84
+		add_action('wp_loaded', [$this, 'wp_loaded']);
85
+	}
86
+
87
+
88
+	/**
89
+	 * @return EEM_Registration
90
+	 * @throws InvalidArgumentException
91
+	 * @throws InvalidDataTypeException
92
+	 * @throws InvalidInterfaceException
93
+	 * @since 4.10.2.p
94
+	 */
95
+	protected function getRegistrationModel()
96
+	{
97
+		if (! $this->registration_model instanceof EEM_Registration) {
98
+			$this->registration_model = $this->loader->getShared('EEM_Registration');
99
+		}
100
+		return $this->registration_model;
101
+	}
102
+
103
+
104
+	/**
105
+	 * @return EEM_Attendee
106
+	 * @throws InvalidArgumentException
107
+	 * @throws InvalidDataTypeException
108
+	 * @throws InvalidInterfaceException
109
+	 * @since 4.10.2.p
110
+	 */
111
+	protected function getAttendeeModel()
112
+	{
113
+		if (! $this->attendee_model instanceof EEM_Attendee) {
114
+			$this->attendee_model = $this->loader->getShared('EEM_Attendee');
115
+		}
116
+		return $this->attendee_model;
117
+	}
118
+
119
+
120
+	/**
121
+	 * @return EEM_Event
122
+	 * @throws InvalidArgumentException
123
+	 * @throws InvalidDataTypeException
124
+	 * @throws InvalidInterfaceException
125
+	 * @since 4.10.2.p
126
+	 */
127
+	protected function getEventModel()
128
+	{
129
+		if (! $this->event_model instanceof EEM_Event) {
130
+			$this->event_model = $this->loader->getShared('EEM_Event');
131
+		}
132
+		return $this->event_model;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EEM_Status
138
+	 * @throws InvalidArgumentException
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws InvalidInterfaceException
141
+	 * @since 4.10.2.p
142
+	 */
143
+	protected function getStatusModel()
144
+	{
145
+		if (! $this->status_model instanceof EEM_Status) {
146
+			$this->status_model = $this->loader->getShared('EEM_Status');
147
+		}
148
+		return $this->status_model;
149
+	}
150
+
151
+
152
+	public function wp_loaded()
153
+	{
154
+		// when adding a new registration...
155
+		$action = $this->request->getRequestParam('action');
156
+		if ($action === 'new_registration') {
157
+			EE_System::do_not_cache();
158
+			if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
159
+				// and it's NOT the attendee information reg step
160
+				// force cookie expiration by setting time to last week
161
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
162
+				// and update the global
163
+				$_COOKIE['ee_registration_added'] = 0;
164
+			}
165
+		}
166
+	}
167
+
168
+
169
+	protected function _init_page_props()
170
+	{
171
+		$this->page_slug        = REG_PG_SLUG;
172
+		$this->_admin_base_url  = REG_ADMIN_URL;
173
+		$this->_admin_base_path = REG_ADMIN;
174
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
175
+		$this->_cpt_routes      = [
176
+			'add_new_attendee' => 'espresso_attendees',
177
+			'edit_attendee'    => 'espresso_attendees',
178
+			'insert_attendee'  => 'espresso_attendees',
179
+			'update_attendee'  => 'espresso_attendees',
180
+		];
181
+		$this->_cpt_model_names = [
182
+			'add_new_attendee' => 'EEM_Attendee',
183
+			'edit_attendee'    => 'EEM_Attendee',
184
+		];
185
+		$this->_cpt_edit_routes = [
186
+			'espresso_attendees' => 'edit_attendee',
187
+		];
188
+		$this->_pagenow_map     = [
189
+			'add_new_attendee' => 'post-new.php',
190
+			'edit_attendee'    => 'post.php',
191
+			'trash'            => 'post.php',
192
+		];
193
+		add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
194
+		// add filters so that the comment urls don't take users to a confusing 404 page
195
+		add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
196
+	}
197
+
198
+
199
+	/**
200
+	 * @param string     $link    The comment permalink with '#comment-$id' appended.
201
+	 * @param WP_Comment $comment The current comment object.
202
+	 * @return string
203
+	 */
204
+	public function clear_comment_link($link, WP_Comment $comment)
205
+	{
206
+		// gotta make sure this only happens on this route
207
+		$post_type = get_post_type($comment->comment_post_ID);
208
+		if ($post_type === 'espresso_attendees') {
209
+			return '#commentsdiv';
210
+		}
211
+		return $link;
212
+	}
213
+
214
+
215
+	protected function _ajax_hooks()
216
+	{
217
+		// todo: all hooks for registrations ajax goes in here
218
+		add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
219
+	}
220
+
221
+
222
+	protected function _define_page_props()
223
+	{
224
+		$this->_admin_page_title = $this->page_label;
225
+		$this->_labels           = [
226
+			'buttons'                      => [
227
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
228
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
229
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
230
+				'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
231
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
+			],
234
+			'publishbox'                   => [
235
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
+			],
238
+			'hide_add_button_on_cpt_route' => [
239
+				'edit_attendee' => true,
240
+			],
241
+		];
242
+	}
243
+
244
+
245
+	/**
246
+	 * grab url requests and route them
247
+	 *
248
+	 * @return void
249
+	 * @throws EE_Error
250
+	 */
251
+	public function _set_page_routes()
252
+	{
253
+		$this->_get_registration_status_array();
254
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
+		$REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
+		$ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
+		$this->_page_routes = [
259
+			'default'                             => [
260
+				'func'       => [$this, '_registrations_overview_list_table'],
261
+				'capability' => 'ee_read_registrations',
262
+			],
263
+			'view_registration'                   => [
264
+				'func'       => '_registration_details',
265
+				'capability' => 'ee_read_registration',
266
+				'obj_id'     => $REG_ID,
267
+			],
268
+			'edit_registration'                   => [
269
+				'func'               => '_update_attendee_registration_form',
270
+				'noheader'           => true,
271
+				'headers_sent_route' => 'view_registration',
272
+				'capability'         => 'ee_edit_registration',
273
+				'obj_id'             => $REG_ID,
274
+				'_REG_ID'            => $REG_ID,
275
+			],
276
+			'trash_registrations'                 => [
277
+				'func'       => '_trash_or_restore_registrations',
278
+				'args'       => ['trash' => true],
279
+				'noheader'   => true,
280
+				'capability' => 'ee_delete_registrations',
281
+			],
282
+			'restore_registrations'               => [
283
+				'func'       => '_trash_or_restore_registrations',
284
+				'args'       => ['trash' => false],
285
+				'noheader'   => true,
286
+				'capability' => 'ee_delete_registrations',
287
+			],
288
+			'delete_registrations'                => [
289
+				'func'       => '_delete_registrations',
290
+				'noheader'   => true,
291
+				'capability' => 'ee_delete_registrations',
292
+			],
293
+			'new_registration'                    => [
294
+				'func'       => 'new_registration',
295
+				'capability' => 'ee_edit_registrations',
296
+			],
297
+			'process_reg_step'                    => [
298
+				'func'       => 'process_reg_step',
299
+				'noheader'   => true,
300
+				'capability' => 'ee_edit_registrations',
301
+			],
302
+			'redirect_to_txn'                     => [
303
+				'func'       => 'redirect_to_txn',
304
+				'noheader'   => true,
305
+				'capability' => 'ee_edit_registrations',
306
+			],
307
+			'change_reg_status'                   => [
308
+				'func'       => '_change_reg_status',
309
+				'noheader'   => true,
310
+				'capability' => 'ee_edit_registration',
311
+				'obj_id'     => $REG_ID,
312
+			],
313
+			'approve_registration'                => [
314
+				'func'       => 'approve_registration',
315
+				'noheader'   => true,
316
+				'capability' => 'ee_edit_registration',
317
+				'obj_id'     => $REG_ID,
318
+			],
319
+			'approve_and_notify_registration'     => [
320
+				'func'       => 'approve_registration',
321
+				'noheader'   => true,
322
+				'args'       => [true],
323
+				'capability' => 'ee_edit_registration',
324
+				'obj_id'     => $REG_ID,
325
+			],
326
+			'approve_registrations'               => [
327
+				'func'       => 'bulk_action_on_registrations',
328
+				'noheader'   => true,
329
+				'capability' => 'ee_edit_registrations',
330
+				'args'       => ['approve'],
331
+			],
332
+			'approve_and_notify_registrations'    => [
333
+				'func'       => 'bulk_action_on_registrations',
334
+				'noheader'   => true,
335
+				'capability' => 'ee_edit_registrations',
336
+				'args'       => ['approve', true],
337
+			],
338
+			'decline_registration'                => [
339
+				'func'       => 'decline_registration',
340
+				'noheader'   => true,
341
+				'capability' => 'ee_edit_registration',
342
+				'obj_id'     => $REG_ID,
343
+			],
344
+			'decline_and_notify_registration'     => [
345
+				'func'       => 'decline_registration',
346
+				'noheader'   => true,
347
+				'args'       => [true],
348
+				'capability' => 'ee_edit_registration',
349
+				'obj_id'     => $REG_ID,
350
+			],
351
+			'decline_registrations'               => [
352
+				'func'       => 'bulk_action_on_registrations',
353
+				'noheader'   => true,
354
+				'capability' => 'ee_edit_registrations',
355
+				'args'       => ['decline'],
356
+			],
357
+			'decline_and_notify_registrations'    => [
358
+				'func'       => 'bulk_action_on_registrations',
359
+				'noheader'   => true,
360
+				'capability' => 'ee_edit_registrations',
361
+				'args'       => ['decline', true],
362
+			],
363
+			'pending_registration'                => [
364
+				'func'       => 'pending_registration',
365
+				'noheader'   => true,
366
+				'capability' => 'ee_edit_registration',
367
+				'obj_id'     => $REG_ID,
368
+			],
369
+			'pending_and_notify_registration'     => [
370
+				'func'       => 'pending_registration',
371
+				'noheader'   => true,
372
+				'args'       => [true],
373
+				'capability' => 'ee_edit_registration',
374
+				'obj_id'     => $REG_ID,
375
+			],
376
+			'pending_registrations'               => [
377
+				'func'       => 'bulk_action_on_registrations',
378
+				'noheader'   => true,
379
+				'capability' => 'ee_edit_registrations',
380
+				'args'       => ['pending'],
381
+			],
382
+			'pending_and_notify_registrations'    => [
383
+				'func'       => 'bulk_action_on_registrations',
384
+				'noheader'   => true,
385
+				'capability' => 'ee_edit_registrations',
386
+				'args'       => ['pending', true],
387
+			],
388
+			'no_approve_registration'             => [
389
+				'func'       => 'not_approve_registration',
390
+				'noheader'   => true,
391
+				'capability' => 'ee_edit_registration',
392
+				'obj_id'     => $REG_ID,
393
+			],
394
+			'no_approve_and_notify_registration'  => [
395
+				'func'       => 'not_approve_registration',
396
+				'noheader'   => true,
397
+				'args'       => [true],
398
+				'capability' => 'ee_edit_registration',
399
+				'obj_id'     => $REG_ID,
400
+			],
401
+			'no_approve_registrations'            => [
402
+				'func'       => 'bulk_action_on_registrations',
403
+				'noheader'   => true,
404
+				'capability' => 'ee_edit_registrations',
405
+				'args'       => ['not_approve'],
406
+			],
407
+			'no_approve_and_notify_registrations' => [
408
+				'func'       => 'bulk_action_on_registrations',
409
+				'noheader'   => true,
410
+				'capability' => 'ee_edit_registrations',
411
+				'args'       => ['not_approve', true],
412
+			],
413
+			'cancel_registration'                 => [
414
+				'func'       => 'cancel_registration',
415
+				'noheader'   => true,
416
+				'capability' => 'ee_edit_registration',
417
+				'obj_id'     => $REG_ID,
418
+			],
419
+			'cancel_and_notify_registration'      => [
420
+				'func'       => 'cancel_registration',
421
+				'noheader'   => true,
422
+				'args'       => [true],
423
+				'capability' => 'ee_edit_registration',
424
+				'obj_id'     => $REG_ID,
425
+			],
426
+			'cancel_registrations'                => [
427
+				'func'       => 'bulk_action_on_registrations',
428
+				'noheader'   => true,
429
+				'capability' => 'ee_edit_registrations',
430
+				'args'       => ['cancel'],
431
+			],
432
+			'cancel_and_notify_registrations'     => [
433
+				'func'       => 'bulk_action_on_registrations',
434
+				'noheader'   => true,
435
+				'capability' => 'ee_edit_registrations',
436
+				'args'       => ['cancel', true],
437
+			],
438
+			'wait_list_registration'              => [
439
+				'func'       => 'wait_list_registration',
440
+				'noheader'   => true,
441
+				'capability' => 'ee_edit_registration',
442
+				'obj_id'     => $REG_ID,
443
+			],
444
+			'wait_list_and_notify_registration'   => [
445
+				'func'       => 'wait_list_registration',
446
+				'noheader'   => true,
447
+				'args'       => [true],
448
+				'capability' => 'ee_edit_registration',
449
+				'obj_id'     => $REG_ID,
450
+			],
451
+			'contact_list'                        => [
452
+				'func'       => '_attendee_contact_list_table',
453
+				'capability' => 'ee_read_contacts',
454
+			],
455
+			'add_new_attendee'                    => [
456
+				'func' => '_create_new_cpt_item',
457
+				'args' => [
458
+					'new_attendee' => true,
459
+					'capability'   => 'ee_edit_contacts',
460
+				],
461
+			],
462
+			'edit_attendee'                       => [
463
+				'func'       => '_edit_cpt_item',
464
+				'capability' => 'ee_edit_contacts',
465
+				'obj_id'     => $ATT_ID,
466
+			],
467
+			'duplicate_attendee'                  => [
468
+				'func'       => '_duplicate_attendee',
469
+				'noheader'   => true,
470
+				'capability' => 'ee_edit_contacts',
471
+				'obj_id'     => $ATT_ID,
472
+			],
473
+			'insert_attendee'                     => [
474
+				'func'       => '_insert_or_update_attendee',
475
+				'args'       => [
476
+					'new_attendee' => true,
477
+				],
478
+				'noheader'   => true,
479
+				'capability' => 'ee_edit_contacts',
480
+			],
481
+			'update_attendee'                     => [
482
+				'func'       => '_insert_or_update_attendee',
483
+				'args'       => [
484
+					'new_attendee' => false,
485
+				],
486
+				'noheader'   => true,
487
+				'capability' => 'ee_edit_contacts',
488
+				'obj_id'     => $ATT_ID,
489
+			],
490
+			'trash_attendees'                     => [
491
+				'func'       => '_trash_or_restore_attendees',
492
+				'args'       => [
493
+					'trash' => 'true',
494
+				],
495
+				'noheader'   => true,
496
+				'capability' => 'ee_delete_contacts',
497
+			],
498
+			'trash_attendee'                      => [
499
+				'func'       => '_trash_or_restore_attendees',
500
+				'args'       => [
501
+					'trash' => true,
502
+				],
503
+				'noheader'   => true,
504
+				'capability' => 'ee_delete_contacts',
505
+				'obj_id'     => $ATT_ID,
506
+			],
507
+			'restore_attendees'                   => [
508
+				'func'       => '_trash_or_restore_attendees',
509
+				'args'       => [
510
+					'trash' => false,
511
+				],
512
+				'noheader'   => true,
513
+				'capability' => 'ee_delete_contacts',
514
+				'obj_id'     => $ATT_ID,
515
+			],
516
+			'resend_registration'                 => [
517
+				'func'       => '_resend_registration',
518
+				'noheader'   => true,
519
+				'capability' => 'ee_send_message',
520
+			],
521
+			'registrations_report'                => [
522
+				'func'       => [$this, '_registrations_report'],
523
+				'noheader'   => true,
524
+				'capability' => 'ee_read_registrations',
525
+			],
526
+			'contact_list_export'                 => [
527
+				'func'       => '_contact_list_export',
528
+				'noheader'   => true,
529
+				'capability' => 'export',
530
+			],
531
+			'contact_list_report'                 => [
532
+				'func'       => '_contact_list_report',
533
+				'noheader'   => true,
534
+				'capability' => 'ee_read_contacts',
535
+			],
536
+		];
537
+	}
538
+
539
+
540
+	protected function _set_page_config()
541
+	{
542
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
+		$this->_page_config = [
545
+			'default'           => [
546
+				'nav'           => [
547
+					'label' => esc_html__('Overview', 'event_espresso'),
548
+					'icon' => 'dashicons-list-view',
549
+					'order' => 5,
550
+				],
551
+				'help_tabs'     => [
552
+					'registrations_overview_help_tab'                       => [
553
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
554
+						'filename' => 'registrations_overview',
555
+					],
556
+					'registrations_overview_table_column_headings_help_tab' => [
557
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
558
+						'filename' => 'registrations_overview_table_column_headings',
559
+					],
560
+					'registrations_overview_filters_help_tab'               => [
561
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
562
+						'filename' => 'registrations_overview_filters',
563
+					],
564
+					'registrations_overview_views_help_tab'                 => [
565
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
566
+						'filename' => 'registrations_overview_views',
567
+					],
568
+					'registrations_regoverview_other_help_tab'              => [
569
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
570
+						'filename' => 'registrations_overview_other',
571
+					],
572
+				],
573
+				'list_table'    => 'EE_Registrations_List_Table',
574
+				'require_nonce' => false,
575
+			],
576
+			'view_registration' => [
577
+				'nav'           => [
578
+					'label'      => esc_html__('REG Details', 'event_espresso'),
579
+					'icon' => 'dashicons-clipboard',
580
+					'order'      => 15,
581
+					'url'        => $REG_ID
582
+						? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
583
+						: $this->_admin_base_url,
584
+					'persistent' => false,
585
+				],
586
+				'help_tabs'     => [
587
+					'registrations_details_help_tab'                    => [
588
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
589
+						'filename' => 'registrations_details',
590
+					],
591
+					'registrations_details_table_help_tab'              => [
592
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
593
+						'filename' => 'registrations_details_table',
594
+					],
595
+					'registrations_details_form_answers_help_tab'       => [
596
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
597
+						'filename' => 'registrations_details_form_answers',
598
+					],
599
+					'registrations_details_registrant_details_help_tab' => [
600
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
601
+						'filename' => 'registrations_details_registrant_details',
602
+					],
603
+				],
604
+				'metaboxes'     => array_merge(
605
+					$this->_default_espresso_metaboxes,
606
+					['_registration_details_metaboxes']
607
+				),
608
+				'require_nonce' => false,
609
+			],
610
+			'new_registration'  => [
611
+				'nav'           => [
612
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
613
+					'icon' => 'dashicons-plus-alt',
614
+					'url'        => '#',
615
+					'order'      => 15,
616
+					'persistent' => false,
617
+				],
618
+				'metaboxes'     => $this->_default_espresso_metaboxes,
619
+				'labels'        => [
620
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
621
+				],
622
+				'require_nonce' => false,
623
+			],
624
+			'add_new_attendee'  => [
625
+				'nav'           => [
626
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
627
+					'icon' => 'dashicons-plus-alt',
628
+					'order'      => 15,
629
+					'persistent' => false,
630
+				],
631
+				'metaboxes'     => array_merge(
632
+					$this->_default_espresso_metaboxes,
633
+					['_publish_post_box', 'attendee_editor_metaboxes']
634
+				),
635
+				'require_nonce' => false,
636
+			],
637
+			'edit_attendee'     => [
638
+				'nav'           => [
639
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
640
+					'icon' => 'dashicons-edit-large',
641
+					'order'      => 15,
642
+					'persistent' => false,
643
+					'url'        => $ATT_ID
644
+						? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
+						: $this->_admin_base_url,
646
+				],
647
+				'metaboxes'     => array_merge(
648
+					$this->_default_espresso_metaboxes,
649
+					['attendee_editor_metaboxes']
650
+				),
651
+				'require_nonce' => false,
652
+			],
653
+			'contact_list'      => [
654
+				'nav'           => [
655
+					'label' => esc_html__('Contact List', 'event_espresso'),
656
+					'icon' => 'dashicons-id-alt',
657
+					'order' => 20,
658
+				],
659
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
660
+				'help_tabs'     => [
661
+					'registrations_contact_list_help_tab'                       => [
662
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
663
+						'filename' => 'registrations_contact_list',
664
+					],
665
+					'registrations_contact-list_table_column_headings_help_tab' => [
666
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
667
+						'filename' => 'registrations_contact_list_table_column_headings',
668
+					],
669
+					'registrations_contact_list_views_help_tab'                 => [
670
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
671
+						'filename' => 'registrations_contact_list_views',
672
+					],
673
+					'registrations_contact_list_other_help_tab'                 => [
674
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
675
+						'filename' => 'registrations_contact_list_other',
676
+					],
677
+				],
678
+				'metaboxes'     => [],
679
+				'require_nonce' => false,
680
+			],
681
+			// override default cpt routes
682
+			'create_new'        => '',
683
+			'edit'              => '',
684
+		];
685
+	}
686
+
687
+
688
+	/**
689
+	 * The below methods aren't used by this class currently
690
+	 */
691
+	protected function _add_screen_options()
692
+	{
693
+	}
694
+
695
+
696
+	protected function _add_feature_pointers()
697
+	{
698
+	}
699
+
700
+
701
+	public function admin_init()
702
+	{
703
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
704
+			'click "Update Registration Questions" to save your changes',
705
+			'event_espresso'
706
+		);
707
+	}
708
+
709
+
710
+	public function admin_notices()
711
+	{
712
+	}
713
+
714
+
715
+	public function admin_footer_scripts()
716
+	{
717
+	}
718
+
719
+
720
+	/**
721
+	 * get list of registration statuses
722
+	 *
723
+	 * @return void
724
+	 * @throws EE_Error
725
+	 */
726
+	private function _get_registration_status_array()
727
+	{
728
+		self::$_reg_status = EEM_Registration::reg_status_array([], true);
729
+	}
730
+
731
+
732
+	/**
733
+	 * @throws InvalidArgumentException
734
+	 * @throws InvalidDataTypeException
735
+	 * @throws InvalidInterfaceException
736
+	 * @since 4.10.2.p
737
+	 */
738
+	protected function _add_screen_options_default()
739
+	{
740
+		$this->_per_page_screen_option();
741
+	}
742
+
743
+
744
+	/**
745
+	 * @throws InvalidArgumentException
746
+	 * @throws InvalidDataTypeException
747
+	 * @throws InvalidInterfaceException
748
+	 * @since 4.10.2.p
749
+	 */
750
+	protected function _add_screen_options_contact_list()
751
+	{
752
+		$page_title              = $this->_admin_page_title;
753
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
754
+		$this->_per_page_screen_option();
755
+		$this->_admin_page_title = $page_title;
756
+	}
757
+
758
+
759
+	public function load_scripts_styles()
760
+	{
761
+		// style
762
+		wp_register_style(
763
+			'espresso_reg',
764
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
765
+			['ee-admin-css'],
766
+			EVENT_ESPRESSO_VERSION
767
+		);
768
+		wp_enqueue_style('espresso_reg');
769
+		// script
770
+		wp_register_script(
771
+			'espresso_reg',
772
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
773
+			['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774
+			EVENT_ESPRESSO_VERSION,
775
+			true
776
+		);
777
+		wp_enqueue_script('espresso_reg');
778
+	}
779
+
780
+
781
+	/**
782
+	 * @throws EE_Error
783
+	 * @throws InvalidArgumentException
784
+	 * @throws InvalidDataTypeException
785
+	 * @throws InvalidInterfaceException
786
+	 * @throws ReflectionException
787
+	 * @since 4.10.2.p
788
+	 */
789
+	public function load_scripts_styles_edit_attendee()
790
+	{
791
+		// stuff to only show up on our attendee edit details page.
792
+		$attendee_details_translations = [
793
+			'att_publish_text' => sprintf(
794
+			/* translators: The date and time */
795
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
797
+			),
798
+		];
799
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
800
+		wp_enqueue_script('jquery-validate');
801
+	}
802
+
803
+
804
+	/**
805
+	 * @throws EE_Error
806
+	 * @throws InvalidArgumentException
807
+	 * @throws InvalidDataTypeException
808
+	 * @throws InvalidInterfaceException
809
+	 * @throws ReflectionException
810
+	 * @since 4.10.2.p
811
+	 */
812
+	public function load_scripts_styles_view_registration()
813
+	{
814
+		// styles
815
+		wp_enqueue_style('espresso-ui-theme');
816
+		// scripts
817
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
818
+		$this->_reg_custom_questions_form->wp_enqueue_scripts();
819
+	}
820
+
821
+
822
+	public function load_scripts_styles_contact_list()
823
+	{
824
+		wp_dequeue_style('espresso_reg');
825
+		wp_register_style(
826
+			'espresso_att',
827
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
828
+			['ee-admin-css'],
829
+			EVENT_ESPRESSO_VERSION
830
+		);
831
+		wp_enqueue_style('espresso_att');
832
+	}
833
+
834
+
835
+	public function load_scripts_styles_new_registration()
836
+	{
837
+		wp_register_script(
838
+			'ee-spco-for-admin',
839
+			REG_ASSETS_URL . 'spco_for_admin.js',
840
+			['underscore', 'jquery'],
841
+			EVENT_ESPRESSO_VERSION,
842
+			true
843
+		);
844
+		wp_enqueue_script('ee-spco-for-admin');
845
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
846
+		EE_Form_Section_Proper::wp_enqueue_scripts();
847
+		EED_Ticket_Selector::load_tckt_slctr_assets();
848
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
849
+	}
850
+
851
+
852
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
853
+	{
854
+		add_filter('FHEE_load_EE_messages', '__return_true');
855
+	}
856
+
857
+
858
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
859
+	{
860
+		add_filter('FHEE_load_EE_messages', '__return_true');
861
+	}
862
+
863
+
864
+	/**
865
+	 * @throws EE_Error
866
+	 * @throws InvalidArgumentException
867
+	 * @throws InvalidDataTypeException
868
+	 * @throws InvalidInterfaceException
869
+	 * @throws ReflectionException
870
+	 * @since 4.10.2.p
871
+	 */
872
+	protected function _set_list_table_views_default()
873
+	{
874
+		// for notification related bulk actions we need to make sure only active messengers have an option.
875
+		EED_Messages::set_autoloaders();
876
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
877
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
878
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
879
+		// key= bulk_action_slug, value= message type.
880
+		$match_array = [
881
+			'approve_registrations'    => 'registration',
882
+			'decline_registrations'    => 'declined_registration',
883
+			'pending_registrations'    => 'pending_approval',
884
+			'no_approve_registrations' => 'not_approved_registration',
885
+			'cancel_registrations'     => 'cancelled_registration',
886
+		];
887
+		$can_send    = EE_Registry::instance()->CAP->current_user_can(
888
+			'ee_send_message',
889
+			'batch_send_messages'
890
+		);
891
+		/** setup reg status bulk actions **/
892
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
893
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
894
+			$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
895
+				'Approve and Notify Registrations',
896
+				'event_espresso'
897
+			);
898
+		}
899
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
900
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
901
+			$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
902
+				'Decline and Notify Registrations',
903
+				'event_espresso'
904
+			);
905
+		}
906
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
907
+			'Set Registrations to Pending Payment',
908
+			'event_espresso'
909
+		);
910
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
911
+			$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
912
+				'Set Registrations to Pending Payment and Notify',
913
+				'event_espresso'
914
+			);
915
+		}
916
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
917
+			'Set Registrations to Not Approved',
918
+			'event_espresso'
919
+		);
920
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
921
+			$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
922
+				'Set Registrations to Not Approved and Notify',
923
+				'event_espresso'
924
+			);
925
+		}
926
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
927
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
928
+			$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
929
+				'Cancel Registrations and Notify',
930
+				'event_espresso'
931
+			);
932
+		}
933
+		$def_reg_status_actions = apply_filters(
934
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
935
+			$def_reg_status_actions,
936
+			$active_mts,
937
+			$can_send
938
+		);
939
+
940
+		$this->_views = [
941
+			'all'   => [
942
+				'slug'        => 'all',
943
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
944
+				'count'       => 0,
945
+				'bulk_action' => array_merge(
946
+					$def_reg_status_actions,
947
+					[
948
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
949
+					]
950
+				),
951
+			],
952
+			'month' => [
953
+				'slug'        => 'month',
954
+				'label'       => esc_html__('This Month', 'event_espresso'),
955
+				'count'       => 0,
956
+				'bulk_action' => array_merge(
957
+					$def_reg_status_actions,
958
+					[
959
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
960
+					]
961
+				),
962
+			],
963
+			'today' => [
964
+				'slug'        => 'today',
965
+				'label'       => sprintf(
966
+					esc_html__('Today - %s', 'event_espresso'),
967
+					date('M d, Y', current_time('timestamp'))
968
+				),
969
+				'count'       => 0,
970
+				'bulk_action' => array_merge(
971
+					$def_reg_status_actions,
972
+					[
973
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
974
+					]
975
+				),
976
+			],
977
+		];
978
+		if (
979
+			EE_Registry::instance()->CAP->current_user_can(
980
+				'ee_delete_registrations',
981
+				'espresso_registrations_delete_registration'
982
+			)
983
+		) {
984
+			$this->_views['incomplete'] = [
985
+				'slug'        => 'incomplete',
986
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
987
+				'count'       => 0,
988
+				'bulk_action' => [
989
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
990
+				],
991
+			];
992
+			$this->_views['trash']      = [
993
+				'slug'        => 'trash',
994
+				'label'       => esc_html__('Trash', 'event_espresso'),
995
+				'count'       => 0,
996
+				'bulk_action' => [
997
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
998
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
999
+				],
1000
+			];
1001
+		}
1002
+	}
1003
+
1004
+
1005
+	protected function _set_list_table_views_contact_list()
1006
+	{
1007
+		$this->_views = [
1008
+			'in_use' => [
1009
+				'slug'        => 'in_use',
1010
+				'label'       => esc_html__('In Use', 'event_espresso'),
1011
+				'count'       => 0,
1012
+				'bulk_action' => [
1013
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1014
+				],
1015
+			],
1016
+		];
1017
+		if (
1018
+			EE_Registry::instance()->CAP->current_user_can(
1019
+				'ee_delete_contacts',
1020
+				'espresso_registrations_trash_attendees'
1021
+			)
1022
+		) {
1023
+			$this->_views['trash'] = [
1024
+				'slug'        => 'trash',
1025
+				'label'       => esc_html__('Trash', 'event_espresso'),
1026
+				'count'       => 0,
1027
+				'bulk_action' => [
1028
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1029
+				],
1030
+			];
1031
+		}
1032
+	}
1033
+
1034
+
1035
+	/**
1036
+	 * @return array
1037
+	 * @throws EE_Error
1038
+	 */
1039
+	protected function _registration_legend_items()
1040
+	{
1041
+		$fc_items = [
1042
+			'star-icon'        => [
1043
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1044
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1045
+			],
1046
+			'view_details'     => [
1047
+				'class' => 'dashicons dashicons-clipboard',
1048
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1049
+			],
1050
+			'edit_attendee'    => [
1051
+				'class' => 'dashicons dashicons-admin-users',
1052
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1053
+			],
1054
+			'view_transaction' => [
1055
+				'class' => 'dashicons dashicons-cart',
1056
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1057
+			],
1058
+			'view_invoice'     => [
1059
+				'class' => 'dashicons dashicons-media-spreadsheet',
1060
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1061
+			],
1062
+		];
1063
+		if (
1064
+			EE_Registry::instance()->CAP->current_user_can(
1065
+				'ee_send_message',
1066
+				'espresso_registrations_resend_registration'
1067
+			)
1068
+		) {
1069
+			$fc_items['resend_registration'] = [
1070
+				'class' => 'dashicons dashicons-email-alt',
1071
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1072
+			];
1073
+		} else {
1074
+			$fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1075
+		}
1076
+		if (
1077
+			EE_Registry::instance()->CAP->current_user_can(
1078
+				'ee_read_global_messages',
1079
+				'view_filtered_messages'
1080
+			)
1081
+		) {
1082
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1083
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1084
+				$fc_items['view_related_messages'] = [
1085
+					'class' => $related_for_icon['css_class'],
1086
+					'desc'  => $related_for_icon['label'],
1087
+				];
1088
+			}
1089
+		}
1090
+		$sc_items = [
1091
+			'approved_status'   => [
1092
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1093
+				'desc'  => EEH_Template::pretty_status(
1094
+					EEM_Registration::status_id_approved,
1095
+					false,
1096
+					'sentence'
1097
+				),
1098
+			],
1099
+			'pending_status'    => [
1100
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1101
+				'desc'  => EEH_Template::pretty_status(
1102
+					EEM_Registration::status_id_pending_payment,
1103
+					false,
1104
+					'sentence'
1105
+				),
1106
+			],
1107
+			'wait_list'         => [
1108
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1109
+				'desc'  => EEH_Template::pretty_status(
1110
+					EEM_Registration::status_id_wait_list,
1111
+					false,
1112
+					'sentence'
1113
+				),
1114
+			],
1115
+			'incomplete_status' => [
1116
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1117
+				'desc'  => EEH_Template::pretty_status(
1118
+					EEM_Registration::status_id_incomplete,
1119
+					false,
1120
+					'sentence'
1121
+				),
1122
+			],
1123
+			'not_approved'      => [
1124
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1125
+				'desc'  => EEH_Template::pretty_status(
1126
+					EEM_Registration::status_id_not_approved,
1127
+					false,
1128
+					'sentence'
1129
+				),
1130
+			],
1131
+			'declined_status'   => [
1132
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1133
+				'desc'  => EEH_Template::pretty_status(
1134
+					EEM_Registration::status_id_declined,
1135
+					false,
1136
+					'sentence'
1137
+				),
1138
+			],
1139
+			'cancelled_status'  => [
1140
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1141
+				'desc'  => EEH_Template::pretty_status(
1142
+					EEM_Registration::status_id_cancelled,
1143
+					false,
1144
+					'sentence'
1145
+				),
1146
+			],
1147
+		];
1148
+		return array_merge($fc_items, $sc_items);
1149
+	}
1150
+
1151
+
1152
+
1153
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1154
+
1155
+
1156
+	/**
1157
+	 * @throws DomainException
1158
+	 * @throws EE_Error
1159
+	 * @throws InvalidArgumentException
1160
+	 * @throws InvalidDataTypeException
1161
+	 * @throws InvalidInterfaceException
1162
+	 */
1163
+	protected function _registrations_overview_list_table()
1164
+	{
1165
+		$this->appendAddNewRegistrationButtonToPageTitle();
1166
+		$header_text                  = '';
1167
+		$admin_page_header_decorators = [
1168
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1169
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1170
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1171
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1172
+		];
1173
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1174
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1175
+			$header_text = $filter_header_decorator->getHeaderText($header_text);
1176
+		}
1177
+		$this->_template_args['before_list_table']  = $header_text;
1178
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1179
+		$this->display_admin_list_table_page_with_no_sidebar();
1180
+	}
1181
+
1182
+
1183
+	/**
1184
+	 * @throws EE_Error
1185
+	 * @throws InvalidArgumentException
1186
+	 * @throws InvalidDataTypeException
1187
+	 * @throws InvalidInterfaceException
1188
+	 */
1189
+	private function appendAddNewRegistrationButtonToPageTitle()
1190
+	{
1191
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1192
+		if (
1193
+			$EVT_ID
1194
+			&& EE_Registry::instance()->CAP->current_user_can(
1195
+				'ee_edit_registrations',
1196
+				'espresso_registrations_new_registration',
1197
+				$EVT_ID
1198
+			)
1199
+		) {
1200
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1201
+				'new_registration',
1202
+				'add-registrant',
1203
+				['event_id' => $EVT_ID],
1204
+				'add-new-h2'
1205
+			);
1206
+		}
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 * This sets the _registration property for the registration details screen
1212
+	 *
1213
+	 * @return void
1214
+	 * @throws EE_Error
1215
+	 * @throws InvalidArgumentException
1216
+	 * @throws InvalidDataTypeException
1217
+	 * @throws InvalidInterfaceException
1218
+	 */
1219
+	private function _set_registration_object()
1220
+	{
1221
+		// get out if we've already set the object
1222
+		if ($this->_registration instanceof EE_Registration) {
1223
+			return;
1224
+		}
1225
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1226
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1227
+			return;
1228
+		}
1229
+		$error_msg = sprintf(
1230
+			esc_html__(
1231
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1232
+				'event_espresso'
1233
+			),
1234
+			$REG_ID
1235
+		);
1236
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1237
+		$this->_registration = null;
1238
+	}
1239
+
1240
+
1241
+	/**
1242
+	 * Used to retrieve registrations for the list table.
1243
+	 *
1244
+	 * @param int  $per_page
1245
+	 * @param bool $count
1246
+	 * @param bool $this_month
1247
+	 * @param bool $today
1248
+	 * @return EE_Registration[]|int
1249
+	 * @throws EE_Error
1250
+	 * @throws InvalidArgumentException
1251
+	 * @throws InvalidDataTypeException
1252
+	 * @throws InvalidInterfaceException
1253
+	 */
1254
+	public function get_registrations(
1255
+		$per_page = 10,
1256
+		$count = false,
1257
+		$this_month = false,
1258
+		$today = false
1259
+	) {
1260
+		if ($this_month) {
1261
+			$this->request->setRequestParam('status', 'month');
1262
+		}
1263
+		if ($today) {
1264
+			$this->request->setRequestParam('status', 'today');
1265
+		}
1266
+		$query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1267
+		/**
1268
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1269
+		 *
1270
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1271
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1272
+		 *                      or if you have the development copy of EE you can view this at the path:
1273
+		 *                      /docs/G--Model-System/model-query-params.md
1274
+		 */
1275
+		$query_params['group_by'] = '';
1276
+
1277
+		return $count
1278
+			? $this->getRegistrationModel()->count($query_params)
1279
+			/** @type EE_Registration[] */
1280
+			: $this->getRegistrationModel()->get_all($query_params);
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1286
+	 * Note: this listens to values on the request for some of the query parameters.
1287
+	 *
1288
+	 * @param array $request
1289
+	 * @param int   $per_page
1290
+	 * @param bool  $count
1291
+	 * @return array
1292
+	 * @throws EE_Error
1293
+	 * @throws InvalidArgumentException
1294
+	 * @throws InvalidDataTypeException
1295
+	 * @throws InvalidInterfaceException
1296
+	 */
1297
+	protected function _get_registration_query_parameters(
1298
+		$request = [],
1299
+		$per_page = 10,
1300
+		$count = false
1301
+	) {
1302
+		/** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1303
+		$list_table_query_builder = $this->loader->getNew(
1304
+			'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1305
+			[null, null, $request]
1306
+		);
1307
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1308
+	}
1309
+
1310
+
1311
+	public function get_registration_status_array()
1312
+	{
1313
+		return self::$_reg_status;
1314
+	}
1315
+
1316
+
1317
+
1318
+
1319
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1320
+	/**
1321
+	 * generates HTML for the View Registration Details Admin page
1322
+	 *
1323
+	 * @return void
1324
+	 * @throws DomainException
1325
+	 * @throws EE_Error
1326
+	 * @throws InvalidArgumentException
1327
+	 * @throws InvalidDataTypeException
1328
+	 * @throws InvalidInterfaceException
1329
+	 * @throws EntityNotFoundException
1330
+	 * @throws ReflectionException
1331
+	 */
1332
+	protected function _registration_details()
1333
+	{
1334
+		$this->_template_args = [];
1335
+		$this->_set_registration_object();
1336
+		if (is_object($this->_registration)) {
1337
+			$transaction                                   = $this->_registration->transaction()
1338
+				? $this->_registration->transaction()
1339
+				: EE_Transaction::new_instance();
1340
+			$this->_session                                = $transaction->session_data();
1341
+			$event_id                                      = $this->_registration->event_ID();
1342
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1343
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1344
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1345
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1346
+			$this->_template_args['grand_total']           = $transaction->total();
1347
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1348
+			// link back to overview
1349
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1350
+			$this->_template_args['registration']                = $this->_registration;
1351
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1352
+				[
1353
+					'action'   => 'default',
1354
+					'event_id' => $event_id,
1355
+				],
1356
+				REG_ADMIN_URL
1357
+			);
1358
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1359
+				[
1360
+					'action' => 'default',
1361
+					'EVT_ID' => $event_id,
1362
+					'page'   => 'espresso_transactions',
1363
+				],
1364
+				admin_url('admin.php')
1365
+			);
1366
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1367
+				[
1368
+					'page'   => 'espresso_events',
1369
+					'action' => 'edit',
1370
+					'post'   => $event_id,
1371
+				],
1372
+				admin_url('admin.php')
1373
+			);
1374
+			// next and previous links
1375
+			$next_reg                                      = $this->_registration->next(
1376
+				null,
1377
+				[],
1378
+				'REG_ID'
1379
+			);
1380
+			$this->_template_args['next_registration']     = $next_reg
1381
+				? $this->_next_link(
1382
+					EE_Admin_Page::add_query_args_and_nonce(
1383
+						[
1384
+							'action'  => 'view_registration',
1385
+							'_REG_ID' => $next_reg['REG_ID'],
1386
+						],
1387
+						REG_ADMIN_URL
1388
+					),
1389
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1390
+				)
1391
+				: '';
1392
+			$previous_reg                                  = $this->_registration->previous(
1393
+				null,
1394
+				[],
1395
+				'REG_ID'
1396
+			);
1397
+			$this->_template_args['previous_registration'] = $previous_reg
1398
+				? $this->_previous_link(
1399
+					EE_Admin_Page::add_query_args_and_nonce(
1400
+						[
1401
+							'action'  => 'view_registration',
1402
+							'_REG_ID' => $previous_reg['REG_ID'],
1403
+						],
1404
+						REG_ADMIN_URL
1405
+					),
1406
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1407
+				)
1408
+				: '';
1409
+			// grab header
1410
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1411
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1412
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1413
+				$template_path,
1414
+				$this->_template_args,
1415
+				true
1416
+			);
1417
+		} else {
1418
+			$this->_template_args['admin_page_header'] = '';
1419
+			$this->_display_espresso_notices();
1420
+		}
1421
+		// the details template wrapper
1422
+		$this->display_admin_page_with_sidebar();
1423
+	}
1424
+
1425
+
1426
+	/**
1427
+	 * @throws EE_Error
1428
+	 * @throws InvalidArgumentException
1429
+	 * @throws InvalidDataTypeException
1430
+	 * @throws InvalidInterfaceException
1431
+	 * @throws ReflectionException
1432
+	 * @since 4.10.2.p
1433
+	 */
1434
+	protected function _registration_details_metaboxes()
1435
+	{
1436
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1437
+		$this->_set_registration_object();
1438
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1439
+		$this->addMetaBox(
1440
+			'edit-reg-status-mbox',
1441
+			esc_html__('Registration Status', 'event_espresso'),
1442
+			[$this, 'set_reg_status_buttons_metabox'],
1443
+			$this->_wp_page_slug
1444
+		);
1445
+		$this->addMetaBox(
1446
+			'edit-reg-details-mbox',
1447
+			'<span>' . esc_html__('Registration Details', 'event_espresso')
1448
+			. '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1449
+			[$this, '_reg_details_meta_box'],
1450
+			$this->_wp_page_slug
1451
+		);
1452
+		if (
1453
+			$attendee instanceof EE_Attendee
1454
+			&& EE_Registry::instance()->CAP->current_user_can(
1455
+				'ee_read_registration',
1456
+				'edit-reg-questions-mbox',
1457
+				$this->_registration->ID()
1458
+			)
1459
+		) {
1460
+			$this->addMetaBox(
1461
+				'edit-reg-questions-mbox',
1462
+				esc_html__('Registration Form Answers', 'event_espresso'),
1463
+				[$this, '_reg_questions_meta_box'],
1464
+				$this->_wp_page_slug
1465
+			);
1466
+		}
1467
+		$this->addMetaBox(
1468
+			'edit-reg-registrant-mbox',
1469
+			esc_html__('Contact Details', 'event_espresso'),
1470
+			[$this, '_reg_registrant_side_meta_box'],
1471
+			$this->_wp_page_slug,
1472
+			'side'
1473
+		);
1474
+		if ($this->_registration->group_size() > 1) {
1475
+			$this->addMetaBox(
1476
+				'edit-reg-attendees-mbox',
1477
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1478
+				[$this, '_reg_attendees_meta_box'],
1479
+				$this->_wp_page_slug
1480
+			);
1481
+		}
1482
+	}
1483
+
1484
+
1485
+	/**
1486
+	 * set_reg_status_buttons_metabox
1487
+	 *
1488
+	 * @return void
1489
+	 * @throws EE_Error
1490
+	 * @throws EntityNotFoundException
1491
+	 * @throws InvalidArgumentException
1492
+	 * @throws InvalidDataTypeException
1493
+	 * @throws InvalidInterfaceException
1494
+	 * @throws ReflectionException
1495
+	 */
1496
+	public function set_reg_status_buttons_metabox()
1497
+	{
1498
+		$this->_set_registration_object();
1499
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1500
+		$output                 = $change_reg_status_form->form_open(
1501
+			self::add_query_args_and_nonce(
1502
+				[
1503
+					'action' => 'change_reg_status',
1504
+				],
1505
+				REG_ADMIN_URL
1506
+			)
1507
+		);
1508
+		$output                 .= $change_reg_status_form->get_html();
1509
+		$output                 .= $change_reg_status_form->form_close();
1510
+		echo wp_kses($output, AllowedTags::getWithFormTags());
1511
+	}
1512
+
1513
+
1514
+	/**
1515
+	 * @return EE_Form_Section_Proper
1516
+	 * @throws EE_Error
1517
+	 * @throws InvalidArgumentException
1518
+	 * @throws InvalidDataTypeException
1519
+	 * @throws InvalidInterfaceException
1520
+	 * @throws EntityNotFoundException
1521
+	 * @throws ReflectionException
1522
+	 */
1523
+	protected function _generate_reg_status_change_form()
1524
+	{
1525
+		$reg_status_change_form_array = [
1526
+			'name'            => 'reg_status_change_form',
1527
+			'html_id'         => 'reg-status-change-form',
1528
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1529
+			'subsections'     => [
1530
+				'return'         => new EE_Hidden_Input(
1531
+					[
1532
+						'name'    => 'return',
1533
+						'default' => 'view_registration',
1534
+					]
1535
+				),
1536
+				'REG_ID'         => new EE_Hidden_Input(
1537
+					[
1538
+						'name'    => 'REG_ID',
1539
+						'default' => $this->_registration->ID(),
1540
+					]
1541
+				),
1542
+			],
1543
+		];
1544
+		if (
1545
+			EE_Registry::instance()->CAP->current_user_can(
1546
+				'ee_edit_registration',
1547
+				'toggle_registration_status',
1548
+				$this->_registration->ID()
1549
+			)
1550
+		) {
1551
+			$reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1552
+				$this->_get_reg_statuses(),
1553
+				[
1554
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1555
+					'default'         => $this->_registration->status_ID(),
1556
+				]
1557
+			);
1558
+			$reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1559
+				[
1560
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1561
+					'default'         => false,
1562
+					'html_help_text'  => esc_html__(
1563
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1564
+						'event_espresso'
1565
+					),
1566
+				]
1567
+			);
1568
+			$reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1569
+				[
1570
+					'html_class'      => 'button--primary',
1571
+					'html_label_text' => '&nbsp;',
1572
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1573
+				]
1574
+			);
1575
+		}
1576
+		return new EE_Form_Section_Proper($reg_status_change_form_array);
1577
+	}
1578
+
1579
+
1580
+	/**
1581
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1582
+	 *
1583
+	 * @return array
1584
+	 * @throws EE_Error
1585
+	 * @throws InvalidArgumentException
1586
+	 * @throws InvalidDataTypeException
1587
+	 * @throws InvalidInterfaceException
1588
+	 * @throws EntityNotFoundException
1589
+	 */
1590
+	protected function _get_reg_statuses()
1591
+	{
1592
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1593
+		unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1594
+		// get current reg status
1595
+		$current_status = $this->_registration->status_ID();
1596
+		// is registration for free event? This will determine whether to display the pending payment option
1597
+		if (
1598
+			$current_status !== EEM_Registration::status_id_pending_payment
1599
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1600
+		) {
1601
+			unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1602
+		}
1603
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1604
+	}
1605
+
1606
+
1607
+	/**
1608
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1609
+	 *
1610
+	 * @param bool $status REG status given for changing registrations to.
1611
+	 * @param bool $notify Whether to send messages notifications or not.
1612
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1613
+	 * @throws DomainException
1614
+	 * @throws EE_Error
1615
+	 * @throws EntityNotFoundException
1616
+	 * @throws InvalidArgumentException
1617
+	 * @throws InvalidDataTypeException
1618
+	 * @throws InvalidInterfaceException
1619
+	 * @throws ReflectionException
1620
+	 * @throws RuntimeException
1621
+	 */
1622
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1623
+	{
1624
+		$REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1625
+			? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1626
+			: $this->request->getRequestParam('_REG_ID', [], 'int', true);
1627
+
1628
+		// sanitize $REG_IDs
1629
+		$REG_IDs = array_map('absint', $REG_IDs);
1630
+		// and remove empty entries
1631
+		$REG_IDs = array_filter($REG_IDs);
1632
+
1633
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1634
+
1635
+		/**
1636
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1637
+		 * Currently this value is used downstream by the _process_resend_registration method.
1638
+		 *
1639
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1640
+		 * @param bool                     $status           The status registrations were changed to.
1641
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1642
+		 * @param Registrations_Admin_Page $admin_page_object
1643
+		 */
1644
+		$REG_ID = apply_filters(
1645
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1646
+			$result['REG_ID'],
1647
+			$status,
1648
+			$result['success'],
1649
+			$this
1650
+		);
1651
+		$this->request->setRequestParam('_REG_ID', $REG_ID);
1652
+
1653
+		// notify?
1654
+		if (
1655
+			$notify
1656
+			&& $result['success']
1657
+			&& ! empty($REG_ID)
1658
+			&& EE_Registry::instance()->CAP->current_user_can(
1659
+				'ee_send_message',
1660
+				'espresso_registrations_resend_registration'
1661
+			)
1662
+		) {
1663
+			$this->_process_resend_registration();
1664
+		}
1665
+		return $result;
1666
+	}
1667
+
1668
+
1669
+	/**
1670
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1671
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1672
+	 *
1673
+	 * @param array  $REG_IDs
1674
+	 * @param string $status
1675
+	 * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1676
+	 *                       slug sent with setting the registration status.
1677
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1678
+	 * @throws EE_Error
1679
+	 * @throws InvalidArgumentException
1680
+	 * @throws InvalidDataTypeException
1681
+	 * @throws InvalidInterfaceException
1682
+	 * @throws ReflectionException
1683
+	 * @throws RuntimeException
1684
+	 * @throws EntityNotFoundException
1685
+	 * @throws DomainException
1686
+	 */
1687
+	protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1688
+	{
1689
+		$success = false;
1690
+		// typecast $REG_IDs
1691
+		$REG_IDs = (array) $REG_IDs;
1692
+		if (! empty($REG_IDs)) {
1693
+			$success = true;
1694
+			// set default status if none is passed
1695
+			$status         = $status ?: EEM_Registration::status_id_pending_payment;
1696
+			$status_context = $notify
1697
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1698
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1699
+			// loop through REG_ID's and change status
1700
+			foreach ($REG_IDs as $REG_ID) {
1701
+				$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1702
+				if ($registration instanceof EE_Registration) {
1703
+					$registration->set_status(
1704
+						$status,
1705
+						false,
1706
+						new Context(
1707
+							$status_context,
1708
+							esc_html__(
1709
+								'Manually triggered status change on a Registration Admin Page route.',
1710
+								'event_espresso'
1711
+							)
1712
+						)
1713
+					);
1714
+					$result = $registration->save();
1715
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1716
+					$success = $result !== false ? $success : false;
1717
+				}
1718
+			}
1719
+		}
1720
+
1721
+		// return $success and processed registrations
1722
+		return ['REG_ID' => $REG_IDs, 'success' => $success];
1723
+	}
1724
+
1725
+
1726
+	/**
1727
+	 * Common logic for setting up success message and redirecting to appropriate route
1728
+	 *
1729
+	 * @param string $STS_ID status id for the registration changed to
1730
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1731
+	 * @return void
1732
+	 * @throws DomainException
1733
+	 * @throws EE_Error
1734
+	 * @throws EntityNotFoundException
1735
+	 * @throws InvalidArgumentException
1736
+	 * @throws InvalidDataTypeException
1737
+	 * @throws InvalidInterfaceException
1738
+	 * @throws ReflectionException
1739
+	 * @throws RuntimeException
1740
+	 */
1741
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1742
+	{
1743
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1744
+			: ['success' => false];
1745
+		$success = isset($result['success']) && $result['success'];
1746
+		// setup success message
1747
+		if ($success) {
1748
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1749
+				$msg = sprintf(
1750
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1751
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1752
+				);
1753
+			} else {
1754
+				$msg = sprintf(
1755
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1756
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1757
+				);
1758
+			}
1759
+			EE_Error::add_success($msg);
1760
+		} else {
1761
+			EE_Error::add_error(
1762
+				esc_html__(
1763
+					'Something went wrong, and the status was not changed',
1764
+					'event_espresso'
1765
+				),
1766
+				__FILE__,
1767
+				__LINE__,
1768
+				__FUNCTION__
1769
+			);
1770
+		}
1771
+		$return = $this->request->getRequestParam('return');
1772
+		$route  = $return === 'view_registration'
1773
+			? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1774
+			: ['action' => 'default'];
1775
+		$route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1776
+		$this->_redirect_after_action($success, '', '', $route, true);
1777
+	}
1778
+
1779
+
1780
+	/**
1781
+	 * incoming reg status change from reg details page.
1782
+	 *
1783
+	 * @return void
1784
+	 * @throws EE_Error
1785
+	 * @throws EntityNotFoundException
1786
+	 * @throws InvalidArgumentException
1787
+	 * @throws InvalidDataTypeException
1788
+	 * @throws InvalidInterfaceException
1789
+	 * @throws ReflectionException
1790
+	 * @throws RuntimeException
1791
+	 * @throws DomainException
1792
+	 */
1793
+	protected function _change_reg_status()
1794
+	{
1795
+		$this->request->setRequestParam('return', 'view_registration');
1796
+		// set notify based on whether the send notifications toggle is set or not
1797
+		$notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1798
+		$reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1799
+		$this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1800
+		switch ($reg_status) {
1801
+			case EEM_Registration::status_id_approved:
1802
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1803
+				$this->approve_registration($notify);
1804
+				break;
1805
+			case EEM_Registration::status_id_pending_payment:
1806
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1807
+				$this->pending_registration($notify);
1808
+				break;
1809
+			case EEM_Registration::status_id_not_approved:
1810
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1811
+				$this->not_approve_registration($notify);
1812
+				break;
1813
+			case EEM_Registration::status_id_declined:
1814
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1815
+				$this->decline_registration($notify);
1816
+				break;
1817
+			case EEM_Registration::status_id_cancelled:
1818
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1819
+				$this->cancel_registration($notify);
1820
+				break;
1821
+			case EEM_Registration::status_id_wait_list:
1822
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1823
+				$this->wait_list_registration($notify);
1824
+				break;
1825
+			case EEM_Registration::status_id_incomplete:
1826
+			default:
1827
+				$this->request->unSetRequestParam('return');
1828
+				$this->_reg_status_change_return('');
1829
+				break;
1830
+		}
1831
+	}
1832
+
1833
+
1834
+	/**
1835
+	 * Callback for bulk action routes.
1836
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1837
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1838
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1839
+	 * when an action is happening on just a single registration).
1840
+	 *
1841
+	 * @param      $action
1842
+	 * @param bool $notify
1843
+	 */
1844
+	protected function bulk_action_on_registrations($action, $notify = false)
1845
+	{
1846
+		do_action(
1847
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1848
+			$this,
1849
+			$action,
1850
+			$notify
1851
+		);
1852
+		$method = $action . '_registration';
1853
+		if (method_exists($this, $method)) {
1854
+			$this->$method($notify);
1855
+		}
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 * approve_registration
1861
+	 *
1862
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1863
+	 * @return void
1864
+	 * @throws EE_Error
1865
+	 * @throws EntityNotFoundException
1866
+	 * @throws InvalidArgumentException
1867
+	 * @throws InvalidDataTypeException
1868
+	 * @throws InvalidInterfaceException
1869
+	 * @throws ReflectionException
1870
+	 * @throws RuntimeException
1871
+	 * @throws DomainException
1872
+	 */
1873
+	protected function approve_registration($notify = false)
1874
+	{
1875
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1876
+	}
1877
+
1878
+
1879
+	/**
1880
+	 * decline_registration
1881
+	 *
1882
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1883
+	 * @return void
1884
+	 * @throws EE_Error
1885
+	 * @throws EntityNotFoundException
1886
+	 * @throws InvalidArgumentException
1887
+	 * @throws InvalidDataTypeException
1888
+	 * @throws InvalidInterfaceException
1889
+	 * @throws ReflectionException
1890
+	 * @throws RuntimeException
1891
+	 * @throws DomainException
1892
+	 */
1893
+	protected function decline_registration($notify = false)
1894
+	{
1895
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1896
+	}
1897
+
1898
+
1899
+	/**
1900
+	 * cancel_registration
1901
+	 *
1902
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1903
+	 * @return void
1904
+	 * @throws EE_Error
1905
+	 * @throws EntityNotFoundException
1906
+	 * @throws InvalidArgumentException
1907
+	 * @throws InvalidDataTypeException
1908
+	 * @throws InvalidInterfaceException
1909
+	 * @throws ReflectionException
1910
+	 * @throws RuntimeException
1911
+	 * @throws DomainException
1912
+	 */
1913
+	protected function cancel_registration($notify = false)
1914
+	{
1915
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1916
+	}
1917
+
1918
+
1919
+	/**
1920
+	 * not_approve_registration
1921
+	 *
1922
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1923
+	 * @return void
1924
+	 * @throws EE_Error
1925
+	 * @throws EntityNotFoundException
1926
+	 * @throws InvalidArgumentException
1927
+	 * @throws InvalidDataTypeException
1928
+	 * @throws InvalidInterfaceException
1929
+	 * @throws ReflectionException
1930
+	 * @throws RuntimeException
1931
+	 * @throws DomainException
1932
+	 */
1933
+	protected function not_approve_registration($notify = false)
1934
+	{
1935
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1936
+	}
1937
+
1938
+
1939
+	/**
1940
+	 * decline_registration
1941
+	 *
1942
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1943
+	 * @return void
1944
+	 * @throws EE_Error
1945
+	 * @throws EntityNotFoundException
1946
+	 * @throws InvalidArgumentException
1947
+	 * @throws InvalidDataTypeException
1948
+	 * @throws InvalidInterfaceException
1949
+	 * @throws ReflectionException
1950
+	 * @throws RuntimeException
1951
+	 * @throws DomainException
1952
+	 */
1953
+	protected function pending_registration($notify = false)
1954
+	{
1955
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1956
+	}
1957
+
1958
+
1959
+	/**
1960
+	 * waitlist_registration
1961
+	 *
1962
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1963
+	 * @return void
1964
+	 * @throws EE_Error
1965
+	 * @throws EntityNotFoundException
1966
+	 * @throws InvalidArgumentException
1967
+	 * @throws InvalidDataTypeException
1968
+	 * @throws InvalidInterfaceException
1969
+	 * @throws ReflectionException
1970
+	 * @throws RuntimeException
1971
+	 * @throws DomainException
1972
+	 */
1973
+	protected function wait_list_registration($notify = false)
1974
+	{
1975
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1976
+	}
1977
+
1978
+
1979
+	/**
1980
+	 * generates HTML for the Registration main meta box
1981
+	 *
1982
+	 * @return void
1983
+	 * @throws DomainException
1984
+	 * @throws EE_Error
1985
+	 * @throws InvalidArgumentException
1986
+	 * @throws InvalidDataTypeException
1987
+	 * @throws InvalidInterfaceException
1988
+	 * @throws ReflectionException
1989
+	 * @throws EntityNotFoundException
1990
+	 */
1991
+	public function _reg_details_meta_box()
1992
+	{
1993
+		EEH_Autoloader::register_line_item_display_autoloaders();
1994
+		EEH_Autoloader::register_line_item_filter_autoloaders();
1995
+		EE_Registry::instance()->load_helper('Line_Item');
1996
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
1997
+			: EE_Transaction::new_instance();
1998
+		$this->_session = $transaction->session_data();
1999
+		$filters        = new EE_Line_Item_Filter_Collection();
2000
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2003
+			$filters,
2004
+			$transaction->total_line_item()
2005
+		);
2006
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2007
+		$line_item_display                       = new EE_Line_Item_Display(
2008
+			'reg_admin_table',
2009
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2010
+		);
2011
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2012
+			$filtered_line_item_tree,
2013
+			['EE_Registration' => $this->_registration]
2014
+		);
2015
+		$attendee                                = $this->_registration->attendee();
2016
+		if (
2017
+			EE_Registry::instance()->CAP->current_user_can(
2018
+				'ee_read_transaction',
2019
+				'espresso_transactions_view_transaction'
2020
+			)
2021
+		) {
2022
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2023
+				EE_Admin_Page::add_query_args_and_nonce(
2024
+					[
2025
+						'action' => 'view_transaction',
2026
+						'TXN_ID' => $transaction->ID(),
2027
+					],
2028
+					TXN_ADMIN_URL
2029
+				),
2030
+				esc_html__(' View Transaction', 'event_espresso'),
2031
+				'button button--secondary right',
2032
+				'dashicons dashicons-cart'
2033
+			);
2034
+		} else {
2035
+			$this->_template_args['view_transaction_button'] = '';
2036
+		}
2037
+		if (
2038
+			$attendee instanceof EE_Attendee
2039
+			&& EE_Registry::instance()->CAP->current_user_can(
2040
+				'ee_send_message',
2041
+				'espresso_registrations_resend_registration'
2042
+			)
2043
+		) {
2044
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2045
+				EE_Admin_Page::add_query_args_and_nonce(
2046
+					[
2047
+						'action'      => 'resend_registration',
2048
+						'_REG_ID'     => $this->_registration->ID(),
2049
+						'redirect_to' => 'view_registration',
2050
+					],
2051
+					REG_ADMIN_URL
2052
+				),
2053
+				esc_html__(' Resend Registration', 'event_espresso'),
2054
+				'button button--secondary right',
2055
+				'dashicons dashicons-email-alt'
2056
+			);
2057
+		} else {
2058
+			$this->_template_args['resend_registration_button'] = '';
2059
+		}
2060
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2061
+		$payment                               = $transaction->get_first_related('Payment');
2062
+		$payment                               = ! $payment instanceof EE_Payment
2063
+			? EE_Payment::new_instance()
2064
+			: $payment;
2065
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2066
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2067
+			? EE_Payment_Method::new_instance()
2068
+			: $payment_method;
2069
+		$reg_details                           = [
2070
+			'payment_method'       => $payment_method->name(),
2071
+			'response_msg'         => $payment->gateway_response(),
2072
+			'registration_id'      => $this->_registration->get('REG_code'),
2073
+			'registration_session' => $this->_registration->session_ID(),
2074
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2075
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2076
+		];
2077
+		if (isset($reg_details['registration_id'])) {
2078
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2079
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2080
+				'Registration ID',
2081
+				'event_espresso'
2082
+			);
2083
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2084
+		}
2085
+		if (isset($reg_details['payment_method'])) {
2086
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2087
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2088
+				'Most Recent Payment Method',
2089
+				'event_espresso'
2090
+			);
2091
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2092
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2093
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2094
+				'Payment method response',
2095
+				'event_espresso'
2096
+			);
2097
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2098
+		}
2099
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2101
+			'Registration Session',
2102
+			'event_espresso'
2103
+		);
2104
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2105
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2106
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2107
+			'Registration placed from IP',
2108
+			'event_espresso'
2109
+		);
2110
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2111
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2112
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2113
+			'Registrant User Agent',
2114
+			'event_espresso'
2115
+		);
2116
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2117
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2118
+			[
2119
+				'action'   => 'default',
2120
+				'event_id' => $this->_registration->event_ID(),
2121
+			],
2122
+			REG_ADMIN_URL
2123
+		);
2124
+
2125
+		$this->_template_args['REG_ID'] = $this->_registration->ID();
2126
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2127
+
2128
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2129
+		EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130
+	}
2131
+
2132
+
2133
+	/**
2134
+	 * generates HTML for the Registration Questions meta box.
2135
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2136
+	 * otherwise uses new forms system
2137
+	 *
2138
+	 * @return void
2139
+	 * @throws DomainException
2140
+	 * @throws EE_Error
2141
+	 * @throws InvalidArgumentException
2142
+	 * @throws InvalidDataTypeException
2143
+	 * @throws InvalidInterfaceException
2144
+	 * @throws ReflectionException
2145
+	 */
2146
+	public function _reg_questions_meta_box()
2147
+	{
2148
+		// allow someone to override this method entirely
2149
+		if (
2150
+			apply_filters(
2151
+				'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2152
+				true,
2153
+				$this,
2154
+				$this->_registration
2155
+			)
2156
+		) {
2157
+			$form = $this->_get_reg_custom_questions_form(
2158
+				$this->_registration->ID()
2159
+			);
2160
+
2161
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2162
+				? $form->get_html_and_js()
2163
+				: '';
2164
+
2165
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166
+			$this->_template_args['REG_ID'] = $this->_registration->ID();
2167
+			$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2168
+			EEH_Template::display_template($template_path, $this->_template_args);
2169
+		}
2170
+	}
2171
+
2172
+
2173
+	/**
2174
+	 * form_before_question_group
2175
+	 *
2176
+	 * @param string $output
2177
+	 * @return        string
2178
+	 * @deprecated    as of 4.8.32.rc.000
2179
+	 */
2180
+	public function form_before_question_group($output)
2181
+	{
2182
+		EE_Error::doing_it_wrong(
2183
+			__CLASS__ . '::' . __FUNCTION__,
2184
+			esc_html__(
2185
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2186
+				'event_espresso'
2187
+			),
2188
+			'4.8.32.rc.000'
2189
+		);
2190
+		return '
2191 2191
 	<table class="form-table ee-width-100">
2192 2192
 		<tbody>
2193 2193
 			';
2194
-    }
2195
-
2196
-
2197
-    /**
2198
-     * form_after_question_group
2199
-     *
2200
-     * @param string $output
2201
-     * @return        string
2202
-     * @deprecated    as of 4.8.32.rc.000
2203
-     */
2204
-    public function form_after_question_group($output)
2205
-    {
2206
-        EE_Error::doing_it_wrong(
2207
-            __CLASS__ . '::' . __FUNCTION__,
2208
-            esc_html__(
2209
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2210
-                'event_espresso'
2211
-            ),
2212
-            '4.8.32.rc.000'
2213
-        );
2214
-        return '
2194
+	}
2195
+
2196
+
2197
+	/**
2198
+	 * form_after_question_group
2199
+	 *
2200
+	 * @param string $output
2201
+	 * @return        string
2202
+	 * @deprecated    as of 4.8.32.rc.000
2203
+	 */
2204
+	public function form_after_question_group($output)
2205
+	{
2206
+		EE_Error::doing_it_wrong(
2207
+			__CLASS__ . '::' . __FUNCTION__,
2208
+			esc_html__(
2209
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2210
+				'event_espresso'
2211
+			),
2212
+			'4.8.32.rc.000'
2213
+		);
2214
+		return '
2215 2215
 			<tr class="hide-if-no-js">
2216 2216
 				<th> </th>
2217 2217
 				<td class="reg-admin-edit-attendee-question-td">
2218 2218
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="'
2219
-               . esc_attr__('click to edit question', 'event_espresso')
2220
-               . '">
2219
+			   . esc_attr__('click to edit question', 'event_espresso')
2220
+			   . '">
2221 2221
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2222
-               . esc_html__('edit the above question group', 'event_espresso')
2223
-               . '</span>
2222
+			   . esc_html__('edit the above question group', 'event_espresso')
2223
+			   . '</span>
2224 2224
 						<div class="dashicons dashicons-edit"></div>
2225 2225
 					</a>
2226 2226
 				</td>
@@ -2228,640 +2228,640 @@  discard block
 block discarded – undo
2228 2228
 		</tbody>
2229 2229
 	</table>
2230 2230
 ';
2231
-    }
2232
-
2233
-
2234
-    /**
2235
-     * form_form_field_label_wrap
2236
-     *
2237
-     * @param string $label
2238
-     * @return        string
2239
-     * @deprecated    as of 4.8.32.rc.000
2240
-     */
2241
-    public function form_form_field_label_wrap($label)
2242
-    {
2243
-        EE_Error::doing_it_wrong(
2244
-            __CLASS__ . '::' . __FUNCTION__,
2245
-            esc_html__(
2246
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2247
-                'event_espresso'
2248
-            ),
2249
-            '4.8.32.rc.000'
2250
-        );
2251
-        return '
2231
+	}
2232
+
2233
+
2234
+	/**
2235
+	 * form_form_field_label_wrap
2236
+	 *
2237
+	 * @param string $label
2238
+	 * @return        string
2239
+	 * @deprecated    as of 4.8.32.rc.000
2240
+	 */
2241
+	public function form_form_field_label_wrap($label)
2242
+	{
2243
+		EE_Error::doing_it_wrong(
2244
+			__CLASS__ . '::' . __FUNCTION__,
2245
+			esc_html__(
2246
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2247
+				'event_espresso'
2248
+			),
2249
+			'4.8.32.rc.000'
2250
+		);
2251
+		return '
2252 2252
 			<tr>
2253 2253
 				<th>
2254 2254
 					' . $label . '
2255 2255
 				</th>';
2256
-    }
2257
-
2258
-
2259
-    /**
2260
-     * form_form_field_input__wrap
2261
-     *
2262
-     * @param string $input
2263
-     * @return        string
2264
-     * @deprecated    as of 4.8.32.rc.000
2265
-     */
2266
-    public function form_form_field_input__wrap($input)
2267
-    {
2268
-        EE_Error::doing_it_wrong(
2269
-            __CLASS__ . '::' . __FUNCTION__,
2270
-            esc_html__(
2271
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2272
-                'event_espresso'
2273
-            ),
2274
-            '4.8.32.rc.000'
2275
-        );
2276
-        return '
2256
+	}
2257
+
2258
+
2259
+	/**
2260
+	 * form_form_field_input__wrap
2261
+	 *
2262
+	 * @param string $input
2263
+	 * @return        string
2264
+	 * @deprecated    as of 4.8.32.rc.000
2265
+	 */
2266
+	public function form_form_field_input__wrap($input)
2267
+	{
2268
+		EE_Error::doing_it_wrong(
2269
+			__CLASS__ . '::' . __FUNCTION__,
2270
+			esc_html__(
2271
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2272
+				'event_espresso'
2273
+			),
2274
+			'4.8.32.rc.000'
2275
+		);
2276
+		return '
2277 2277
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2278 2278
 					' . $input . '
2279 2279
 				</td>
2280 2280
 			</tr>';
2281
-    }
2282
-
2283
-
2284
-    /**
2285
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2286
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2287
-     * to display the page
2288
-     *
2289
-     * @return void
2290
-     * @throws EE_Error
2291
-     * @throws InvalidArgumentException
2292
-     * @throws InvalidDataTypeException
2293
-     * @throws InvalidInterfaceException
2294
-     * @throws ReflectionException
2295
-     */
2296
-    protected function _update_attendee_registration_form()
2297
-    {
2298
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2299
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2300
-            $REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2301
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2302
-            if ($success) {
2303
-                $what  = esc_html__('Registration Form', 'event_espresso');
2304
-                $route = $REG_ID
2305
-                    ? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2306
-                    : ['action' => 'default'];
2307
-                $this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2308
-            }
2309
-        }
2310
-    }
2311
-
2312
-
2313
-    /**
2314
-     * Gets the form for saving registrations custom questions (if done
2315
-     * previously retrieves the cached form object, which may have validation errors in it)
2316
-     *
2317
-     * @param int $REG_ID
2318
-     * @return EE_Registration_Custom_Questions_Form
2319
-     * @throws EE_Error
2320
-     * @throws InvalidArgumentException
2321
-     * @throws InvalidDataTypeException
2322
-     * @throws InvalidInterfaceException
2323
-     * @throws ReflectionException
2324
-     */
2325
-    protected function _get_reg_custom_questions_form($REG_ID)
2326
-    {
2327
-        if (! $this->_reg_custom_questions_form) {
2328
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2329
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2330
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2331
-            );
2332
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2333
-        }
2334
-        return $this->_reg_custom_questions_form;
2335
-    }
2336
-
2337
-
2338
-    /**
2339
-     * Saves
2340
-     *
2341
-     * @param bool $REG_ID
2342
-     * @return bool
2343
-     * @throws EE_Error
2344
-     * @throws InvalidArgumentException
2345
-     * @throws InvalidDataTypeException
2346
-     * @throws InvalidInterfaceException
2347
-     * @throws ReflectionException
2348
-     */
2349
-    private function _save_reg_custom_questions_form($REG_ID = 0)
2350
-    {
2351
-        if (! $REG_ID) {
2352
-            EE_Error::add_error(
2353
-                esc_html__(
2354
-                    'An error occurred. No registration ID was received.',
2355
-                    'event_espresso'
2356
-                ),
2357
-                __FILE__,
2358
-                __FUNCTION__,
2359
-                __LINE__
2360
-            );
2361
-        }
2362
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2363
-        $form->receive_form_submission($this->request->requestParams());
2364
-        $success = false;
2365
-        if ($form->is_valid()) {
2366
-            foreach ($form->subforms() as $question_group_form) {
2367
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2368
-                    $where_conditions    = [
2369
-                        'QST_ID' => $question_id,
2370
-                        'REG_ID' => $REG_ID,
2371
-                    ];
2372
-                    $possibly_new_values = [
2373
-                        'ANS_value' => $input->normalized_value(),
2374
-                    ];
2375
-                    $answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2376
-                    if ($answer instanceof EE_Answer) {
2377
-                        $success = $answer->save($possibly_new_values);
2378
-                    } else {
2379
-                        // insert it then
2380
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2381
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2382
-                        $success     = $answer->save();
2383
-                    }
2384
-                }
2385
-            }
2386
-        } else {
2387
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2388
-        }
2389
-        return $success;
2390
-    }
2391
-
2392
-
2393
-    /**
2394
-     * generates HTML for the Registration main meta box
2395
-     *
2396
-     * @return void
2397
-     * @throws DomainException
2398
-     * @throws EE_Error
2399
-     * @throws InvalidArgumentException
2400
-     * @throws InvalidDataTypeException
2401
-     * @throws InvalidInterfaceException
2402
-     * @throws ReflectionException
2403
-     */
2404
-    public function _reg_attendees_meta_box()
2405
-    {
2406
-        $REG = $this->getRegistrationModel();
2407
-        // get all other registrations on this transaction, and cache
2408
-        // the attendees for them so we don't have to run another query using force_join
2409
-        $registrations                           = $REG->get_all(
2410
-            [
2411
-                [
2412
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2413
-                    'REG_ID' => ['!=', $this->_registration->ID()],
2414
-                ],
2415
-                'force_join'               => ['Attendee'],
2416
-                'default_where_conditions' => 'other_models_only',
2417
-            ]
2418
-        );
2419
-        $this->_template_args['attendees']       = [];
2420
-        $this->_template_args['attendee_notice'] = '';
2421
-        if (
2422
-            empty($registrations)
2423
-            || (is_array($registrations)
2424
-                && ! EEH_Array::get_one_item_from_array($registrations))
2425
-        ) {
2426
-            EE_Error::add_error(
2427
-                esc_html__(
2428
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2429
-                    'event_espresso'
2430
-                ),
2431
-                __FILE__,
2432
-                __FUNCTION__,
2433
-                __LINE__
2434
-            );
2435
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2436
-        } else {
2437
-            $att_nmbr = 1;
2438
-            foreach ($registrations as $registration) {
2439
-                /* @var $registration EE_Registration */
2440
-                $attendee                                                      = $registration->attendee()
2441
-                    ? $registration->attendee()
2442
-                    : $this->getAttendeeModel()->create_default_object();
2443
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2444
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2445
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2446
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2447
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2448
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2449
-                    ', ',
2450
-                    $attendee->full_address_as_array()
2451
-                );
2452
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2453
-                    [
2454
-                        'action' => 'edit_attendee',
2455
-                        'post'   => $attendee->ID(),
2456
-                    ],
2457
-                    REG_ADMIN_URL
2458
-                );
2459
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2460
-                    $registration->event_obj() instanceof EE_Event
2461
-                        ? $registration->event_obj()->name()
2462
-                        : '';
2463
-                $att_nmbr++;
2464
-            }
2465
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2466
-        }
2467
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2468
-        EEH_Template::display_template($template_path, $this->_template_args);
2469
-    }
2470
-
2471
-
2472
-    /**
2473
-     * generates HTML for the Edit Registration side meta box
2474
-     *
2475
-     * @return void
2476
-     * @throws DomainException
2477
-     * @throws EE_Error
2478
-     * @throws InvalidArgumentException
2479
-     * @throws InvalidDataTypeException
2480
-     * @throws InvalidInterfaceException
2481
-     * @throws ReflectionException
2482
-     */
2483
-    public function _reg_registrant_side_meta_box()
2484
-    {
2485
-        /*@var $attendee EE_Attendee */
2486
-        $att_check = $this->_registration->attendee();
2487
-        $attendee  = $att_check instanceof EE_Attendee
2488
-            ? $att_check
2489
-            : $this->getAttendeeModel()->create_default_object();
2490
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2491
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2492
-        // primary registration object (that way we know if we need to show create button or not)
2493
-        if (! $this->_registration->is_primary_registrant()) {
2494
-            $primary_registration = $this->_registration->get_primary_registration();
2495
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2496
-                : null;
2497
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2498
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2499
-                // custom attendee object so let's not worry about the primary reg.
2500
-                $primary_registration = null;
2501
-            }
2502
-        } else {
2503
-            $primary_registration = null;
2504
-        }
2505
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2506
-        $this->_template_args['fname']             = $attendee->fname();
2507
-        $this->_template_args['lname']             = $attendee->lname();
2508
-        $this->_template_args['email']             = $attendee->email();
2509
-        $this->_template_args['phone']             = $attendee->phone();
2510
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2511
-        // edit link
2512
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2513
-            [
2514
-                'action' => 'edit_attendee',
2515
-                'post'   => $attendee->ID(),
2516
-            ],
2517
-            REG_ADMIN_URL
2518
-        );
2519
-        $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2520
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2521
-        // create link
2522
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2523
-            ? EE_Admin_Page::add_query_args_and_nonce(
2524
-                [
2525
-                    'action'  => 'duplicate_attendee',
2526
-                    '_REG_ID' => $this->_registration->ID(),
2527
-                ],
2528
-                REG_ADMIN_URL
2529
-            ) : '';
2530
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2531
-        $this->_template_args['att_check'] = $att_check;
2532
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2533
-        EEH_Template::display_template($template_path, $this->_template_args);
2534
-    }
2535
-
2536
-
2537
-    /**
2538
-     * trash or restore registrations
2539
-     *
2540
-     * @param boolean $trash whether to archive or restore
2541
-     * @return void
2542
-     * @throws DomainException
2543
-     * @throws EE_Error
2544
-     * @throws EntityNotFoundException
2545
-     * @throws InvalidArgumentException
2546
-     * @throws InvalidDataTypeException
2547
-     * @throws InvalidInterfaceException
2548
-     * @throws ReflectionException
2549
-     * @throws RuntimeException
2550
-     * @throws UnexpectedEntityException
2551
-     */
2552
-    protected function _trash_or_restore_registrations($trash = true)
2553
-    {
2554
-        // if empty _REG_ID then get out because there's nothing to do
2555
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2556
-        if (empty($REG_IDs)) {
2557
-            EE_Error::add_error(
2558
-                sprintf(
2559
-                    esc_html__(
2560
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2561
-                        'event_espresso'
2562
-                    ),
2563
-                    $trash ? 'trash' : 'restore'
2564
-                ),
2565
-                __FILE__,
2566
-                __LINE__,
2567
-                __FUNCTION__
2568
-            );
2569
-            $this->_redirect_after_action(false, '', '', [], true);
2570
-        }
2571
-        $success        = 0;
2572
-        $overwrite_msgs = false;
2573
-        // Checkboxes
2574
-        $reg_count = count($REG_IDs);
2575
-        // cycle thru checkboxes
2576
-        foreach ($REG_IDs as $REG_ID) {
2577
-            /** @var EE_Registration $REG */
2578
-            $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2579
-            $payments = $REG->registration_payments();
2580
-            if (! empty($payments)) {
2581
-                $name           = $REG->attendee() instanceof EE_Attendee
2582
-                    ? $REG->attendee()->full_name()
2583
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2584
-                $overwrite_msgs = true;
2585
-                EE_Error::add_error(
2586
-                    sprintf(
2587
-                        esc_html__(
2588
-                            '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.',
2589
-                            'event_espresso'
2590
-                        ),
2591
-                        $name
2592
-                    ),
2593
-                    __FILE__,
2594
-                    __FUNCTION__,
2595
-                    __LINE__
2596
-                );
2597
-                // can't trash this registration because it has payments.
2598
-                continue;
2599
-            }
2600
-            $updated = $trash ? $REG->delete() : $REG->restore();
2601
-            if ($updated) {
2602
-                $success++;
2603
-            }
2604
-        }
2605
-        $this->_redirect_after_action(
2606
-            $success === $reg_count, // were ALL registrations affected?
2607
-            $success > 1
2608
-                ? esc_html__('Registrations', 'event_espresso')
2609
-                : esc_html__('Registration', 'event_espresso'),
2610
-            $trash
2611
-                ? esc_html__('moved to the trash', 'event_espresso')
2612
-                : esc_html__('restored', 'event_espresso'),
2613
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2614
-            $overwrite_msgs
2615
-        );
2616
-    }
2617
-
2618
-
2619
-    /**
2620
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2621
-     * registration but also.
2622
-     * 1. Removing relations to EE_Attendee
2623
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2624
-     * ALSO trashed.
2625
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2626
-     * 4. Removing relationships between all tickets and the related registrations
2627
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2628
-     * 6. Deleting permanently any related Checkins.
2629
-     *
2630
-     * @return void
2631
-     * @throws EE_Error
2632
-     * @throws InvalidArgumentException
2633
-     * @throws InvalidDataTypeException
2634
-     * @throws InvalidInterfaceException
2635
-     * @throws ReflectionException
2636
-     */
2637
-    protected function _delete_registrations()
2638
-    {
2639
-        $REG_MDL = $this->getRegistrationModel();
2640
-        $success = 0;
2641
-        // Checkboxes
2642
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2643
-
2644
-        if (! empty($REG_IDs)) {
2645
-            // if array has more than one element than success message should be plural
2646
-            $success = count($REG_IDs) > 1 ? 2 : 1;
2647
-            // cycle thru checkboxes
2648
-            foreach ($REG_IDs as $REG_ID) {
2649
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2650
-                if (! $REG instanceof EE_Registration) {
2651
-                    continue;
2652
-                }
2653
-                $deleted = $this->_delete_registration($REG);
2654
-                if (! $deleted) {
2655
-                    $success = 0;
2656
-                }
2657
-            }
2658
-        }
2659
-
2660
-        $what        = $success > 1
2661
-            ? esc_html__('Registrations', 'event_espresso')
2662
-            : esc_html__('Registration', 'event_espresso');
2663
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2664
-        $this->_redirect_after_action(
2665
-            $success,
2666
-            $what,
2667
-            $action_desc,
2668
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2669
-            true
2670
-        );
2671
-    }
2672
-
2673
-
2674
-    /**
2675
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2676
-     * models get affected.
2677
-     *
2678
-     * @param EE_Registration $REG registration to be deleted permanently
2679
-     * @return bool true = successful deletion, false = fail.
2680
-     * @throws EE_Error
2681
-     * @throws InvalidArgumentException
2682
-     * @throws InvalidDataTypeException
2683
-     * @throws InvalidInterfaceException
2684
-     * @throws ReflectionException
2685
-     */
2686
-    protected function _delete_registration(EE_Registration $REG)
2687
-    {
2688
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2689
-        // registrations on the transaction that are NOT trashed.
2690
-        $TXN = $REG->get_first_related('Transaction');
2691
-        if (! $TXN instanceof EE_Transaction) {
2692
-            EE_Error::add_error(
2693
-                sprintf(
2694
-                    esc_html__(
2695
-                        'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2696
-                        'event_espresso'
2697
-                    ),
2698
-                    $REG->id()
2699
-                ),
2700
-                __FILE__,
2701
-                __FUNCTION__,
2702
-                __LINE__
2703
-            );
2704
-            return false;
2705
-        }
2706
-        $REGS        = $TXN->get_many_related('Registration');
2707
-        $all_trashed = true;
2708
-        foreach ($REGS as $registration) {
2709
-            if (! $registration->get('REG_deleted')) {
2710
-                $all_trashed = false;
2711
-            }
2712
-        }
2713
-        if (! $all_trashed) {
2714
-            EE_Error::add_error(
2715
-                esc_html__(
2716
-                    '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.',
2717
-                    'event_espresso'
2718
-                ),
2719
-                __FILE__,
2720
-                __FUNCTION__,
2721
-                __LINE__
2722
-            );
2723
-            return false;
2724
-        }
2725
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2726
-        // separately from THIS one).
2727
-        foreach ($REGS as $registration) {
2728
-            // delete related answers
2729
-            $registration->delete_related_permanently('Answer');
2730
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2731
-            $attendee = $registration->get_first_related('Attendee');
2732
-            if ($attendee instanceof EE_Attendee) {
2733
-                $registration->_remove_relation_to($attendee, 'Attendee');
2734
-            }
2735
-            // now remove relationships to tickets on this registration.
2736
-            $registration->_remove_relations('Ticket');
2737
-            // now delete permanently the checkins related to this registration.
2738
-            $registration->delete_related_permanently('Checkin');
2739
-            if ($registration->ID() === $REG->ID()) {
2740
-                continue;
2741
-            } //we don't want to delete permanently the existing registration just yet.
2742
-            // remove relation to transaction for these registrations if NOT the existing registrations
2743
-            $registration->_remove_relations('Transaction');
2744
-            // delete permanently any related messages.
2745
-            $registration->delete_related_permanently('Message');
2746
-            // now delete this registration permanently
2747
-            $registration->delete_permanently();
2748
-        }
2749
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2750
-        // (the transaction and line items should be all that's left).
2751
-        // delete the line items related to the transaction for this registration.
2752
-        $TXN->delete_related_permanently('Line_Item');
2753
-        // we need to remove all the relationships on the transaction
2754
-        $TXN->delete_related_permanently('Payment');
2755
-        $TXN->delete_related_permanently('Extra_Meta');
2756
-        $TXN->delete_related_permanently('Message');
2757
-        // now we can delete this REG permanently (and the transaction of course)
2758
-        $REG->delete_related_permanently('Transaction');
2759
-        return $REG->delete_permanently();
2760
-    }
2761
-
2762
-
2763
-    /**
2764
-     *    generates HTML for the Register New Attendee Admin page
2765
-     *
2766
-     * @throws DomainException
2767
-     * @throws EE_Error
2768
-     * @throws InvalidArgumentException
2769
-     * @throws InvalidDataTypeException
2770
-     * @throws InvalidInterfaceException
2771
-     * @throws ReflectionException
2772
-     */
2773
-    public function new_registration()
2774
-    {
2775
-        if (! $this->_set_reg_event()) {
2776
-            throw new EE_Error(
2777
-                esc_html__(
2778
-                    'Unable to continue with registering because there is no Event ID in the request',
2779
-                    'event_espresso'
2780
-                )
2781
-            );
2782
-        }
2783
-        /** @var CurrentPage $current_page */
2784
-        $current_page = $this->loader->getShared(CurrentPage::class);
2785
-        $current_page->setEspressoPage(true);
2786
-        // gotta start with a clean slate if we're not coming here via ajax
2787
-        if (
2788
-            ! $this->request->isAjax()
2789
-            && (
2790
-                ! $this->request->requestParamIsSet('processing_registration')
2791
-                || $this->request->requestParamIsSet('step_error')
2792
-            )
2793
-        ) {
2794
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2795
-        }
2796
-        $this->_template_args['event_name'] = '';
2797
-        // event name
2798
-        if ($this->_reg_event) {
2799
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2800
-            $edit_event_url                     = self::add_query_args_and_nonce(
2801
-                [
2802
-                    'action' => 'edit',
2803
-                    'post'   => $this->_reg_event->ID(),
2804
-                ],
2805
-                EVENTS_ADMIN_URL
2806
-            );
2807
-            $edit_event_lnk                     = '<a href="'
2808
-                                                  . $edit_event_url
2809
-                                                  . '" aria-label="'
2810
-                                                  . esc_attr__('Edit ', 'event_espresso')
2811
-                                                  . $this->_reg_event->name()
2812
-                                                  . '">'
2813
-                                                  . esc_html__('Edit Event', 'event_espresso')
2814
-                                                  . '</a>';
2815
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2816
-                                                   . $edit_event_lnk
2817
-                                                   . '</span>';
2818
-        }
2819
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2820
-        if ($this->request->isAjax()) {
2821
-            $this->_return_json();
2822
-        }
2823
-        // grab header
2824
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2825
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2826
-            $template_path,
2827
-            $this->_template_args,
2828
-            true
2829
-        );
2830
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2831
-        // the details template wrapper
2832
-        $this->display_admin_page_with_sidebar();
2833
-    }
2834
-
2835
-
2836
-    /**
2837
-     * This returns the content for a registration step
2838
-     *
2839
-     * @return string html
2840
-     * @throws DomainException
2841
-     * @throws EE_Error
2842
-     * @throws InvalidArgumentException
2843
-     * @throws InvalidDataTypeException
2844
-     * @throws InvalidInterfaceException
2845
-     * @throws ReflectionException
2846
-     */
2847
-    protected function _get_registration_step_content()
2848
-    {
2849
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2850
-            $warning_msg = sprintf(
2851
-                esc_html__(
2852
-                    '%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',
2853
-                    'event_espresso'
2854
-                ),
2855
-                '<br />',
2856
-                '<h3 class="important-notice">',
2857
-                '</h3>',
2858
-                '<div class="float-right">',
2859
-                '<span id="redirect_timer" class="important-notice">30</span>',
2860
-                '</div>',
2861
-                '<b>',
2862
-                '</b>'
2863
-            );
2864
-            return '
2281
+	}
2282
+
2283
+
2284
+	/**
2285
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2286
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2287
+	 * to display the page
2288
+	 *
2289
+	 * @return void
2290
+	 * @throws EE_Error
2291
+	 * @throws InvalidArgumentException
2292
+	 * @throws InvalidDataTypeException
2293
+	 * @throws InvalidInterfaceException
2294
+	 * @throws ReflectionException
2295
+	 */
2296
+	protected function _update_attendee_registration_form()
2297
+	{
2298
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2299
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2300
+			$REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2301
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2302
+			if ($success) {
2303
+				$what  = esc_html__('Registration Form', 'event_espresso');
2304
+				$route = $REG_ID
2305
+					? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2306
+					: ['action' => 'default'];
2307
+				$this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2308
+			}
2309
+		}
2310
+	}
2311
+
2312
+
2313
+	/**
2314
+	 * Gets the form for saving registrations custom questions (if done
2315
+	 * previously retrieves the cached form object, which may have validation errors in it)
2316
+	 *
2317
+	 * @param int $REG_ID
2318
+	 * @return EE_Registration_Custom_Questions_Form
2319
+	 * @throws EE_Error
2320
+	 * @throws InvalidArgumentException
2321
+	 * @throws InvalidDataTypeException
2322
+	 * @throws InvalidInterfaceException
2323
+	 * @throws ReflectionException
2324
+	 */
2325
+	protected function _get_reg_custom_questions_form($REG_ID)
2326
+	{
2327
+		if (! $this->_reg_custom_questions_form) {
2328
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2329
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2330
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2331
+			);
2332
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2333
+		}
2334
+		return $this->_reg_custom_questions_form;
2335
+	}
2336
+
2337
+
2338
+	/**
2339
+	 * Saves
2340
+	 *
2341
+	 * @param bool $REG_ID
2342
+	 * @return bool
2343
+	 * @throws EE_Error
2344
+	 * @throws InvalidArgumentException
2345
+	 * @throws InvalidDataTypeException
2346
+	 * @throws InvalidInterfaceException
2347
+	 * @throws ReflectionException
2348
+	 */
2349
+	private function _save_reg_custom_questions_form($REG_ID = 0)
2350
+	{
2351
+		if (! $REG_ID) {
2352
+			EE_Error::add_error(
2353
+				esc_html__(
2354
+					'An error occurred. No registration ID was received.',
2355
+					'event_espresso'
2356
+				),
2357
+				__FILE__,
2358
+				__FUNCTION__,
2359
+				__LINE__
2360
+			);
2361
+		}
2362
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2363
+		$form->receive_form_submission($this->request->requestParams());
2364
+		$success = false;
2365
+		if ($form->is_valid()) {
2366
+			foreach ($form->subforms() as $question_group_form) {
2367
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2368
+					$where_conditions    = [
2369
+						'QST_ID' => $question_id,
2370
+						'REG_ID' => $REG_ID,
2371
+					];
2372
+					$possibly_new_values = [
2373
+						'ANS_value' => $input->normalized_value(),
2374
+					];
2375
+					$answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2376
+					if ($answer instanceof EE_Answer) {
2377
+						$success = $answer->save($possibly_new_values);
2378
+					} else {
2379
+						// insert it then
2380
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2381
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2382
+						$success     = $answer->save();
2383
+					}
2384
+				}
2385
+			}
2386
+		} else {
2387
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2388
+		}
2389
+		return $success;
2390
+	}
2391
+
2392
+
2393
+	/**
2394
+	 * generates HTML for the Registration main meta box
2395
+	 *
2396
+	 * @return void
2397
+	 * @throws DomainException
2398
+	 * @throws EE_Error
2399
+	 * @throws InvalidArgumentException
2400
+	 * @throws InvalidDataTypeException
2401
+	 * @throws InvalidInterfaceException
2402
+	 * @throws ReflectionException
2403
+	 */
2404
+	public function _reg_attendees_meta_box()
2405
+	{
2406
+		$REG = $this->getRegistrationModel();
2407
+		// get all other registrations on this transaction, and cache
2408
+		// the attendees for them so we don't have to run another query using force_join
2409
+		$registrations                           = $REG->get_all(
2410
+			[
2411
+				[
2412
+					'TXN_ID' => $this->_registration->transaction_ID(),
2413
+					'REG_ID' => ['!=', $this->_registration->ID()],
2414
+				],
2415
+				'force_join'               => ['Attendee'],
2416
+				'default_where_conditions' => 'other_models_only',
2417
+			]
2418
+		);
2419
+		$this->_template_args['attendees']       = [];
2420
+		$this->_template_args['attendee_notice'] = '';
2421
+		if (
2422
+			empty($registrations)
2423
+			|| (is_array($registrations)
2424
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2425
+		) {
2426
+			EE_Error::add_error(
2427
+				esc_html__(
2428
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2429
+					'event_espresso'
2430
+				),
2431
+				__FILE__,
2432
+				__FUNCTION__,
2433
+				__LINE__
2434
+			);
2435
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2436
+		} else {
2437
+			$att_nmbr = 1;
2438
+			foreach ($registrations as $registration) {
2439
+				/* @var $registration EE_Registration */
2440
+				$attendee                                                      = $registration->attendee()
2441
+					? $registration->attendee()
2442
+					: $this->getAttendeeModel()->create_default_object();
2443
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2444
+				$this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2445
+				$this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2446
+				$this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2447
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2448
+				$this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2449
+					', ',
2450
+					$attendee->full_address_as_array()
2451
+				);
2452
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2453
+					[
2454
+						'action' => 'edit_attendee',
2455
+						'post'   => $attendee->ID(),
2456
+					],
2457
+					REG_ADMIN_URL
2458
+				);
2459
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2460
+					$registration->event_obj() instanceof EE_Event
2461
+						? $registration->event_obj()->name()
2462
+						: '';
2463
+				$att_nmbr++;
2464
+			}
2465
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2466
+		}
2467
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2468
+		EEH_Template::display_template($template_path, $this->_template_args);
2469
+	}
2470
+
2471
+
2472
+	/**
2473
+	 * generates HTML for the Edit Registration side meta box
2474
+	 *
2475
+	 * @return void
2476
+	 * @throws DomainException
2477
+	 * @throws EE_Error
2478
+	 * @throws InvalidArgumentException
2479
+	 * @throws InvalidDataTypeException
2480
+	 * @throws InvalidInterfaceException
2481
+	 * @throws ReflectionException
2482
+	 */
2483
+	public function _reg_registrant_side_meta_box()
2484
+	{
2485
+		/*@var $attendee EE_Attendee */
2486
+		$att_check = $this->_registration->attendee();
2487
+		$attendee  = $att_check instanceof EE_Attendee
2488
+			? $att_check
2489
+			: $this->getAttendeeModel()->create_default_object();
2490
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2491
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2492
+		// primary registration object (that way we know if we need to show create button or not)
2493
+		if (! $this->_registration->is_primary_registrant()) {
2494
+			$primary_registration = $this->_registration->get_primary_registration();
2495
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2496
+				: null;
2497
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2498
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2499
+				// custom attendee object so let's not worry about the primary reg.
2500
+				$primary_registration = null;
2501
+			}
2502
+		} else {
2503
+			$primary_registration = null;
2504
+		}
2505
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2506
+		$this->_template_args['fname']             = $attendee->fname();
2507
+		$this->_template_args['lname']             = $attendee->lname();
2508
+		$this->_template_args['email']             = $attendee->email();
2509
+		$this->_template_args['phone']             = $attendee->phone();
2510
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2511
+		// edit link
2512
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2513
+			[
2514
+				'action' => 'edit_attendee',
2515
+				'post'   => $attendee->ID(),
2516
+			],
2517
+			REG_ADMIN_URL
2518
+		);
2519
+		$this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2520
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2521
+		// create link
2522
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2523
+			? EE_Admin_Page::add_query_args_and_nonce(
2524
+				[
2525
+					'action'  => 'duplicate_attendee',
2526
+					'_REG_ID' => $this->_registration->ID(),
2527
+				],
2528
+				REG_ADMIN_URL
2529
+			) : '';
2530
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2531
+		$this->_template_args['att_check'] = $att_check;
2532
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2533
+		EEH_Template::display_template($template_path, $this->_template_args);
2534
+	}
2535
+
2536
+
2537
+	/**
2538
+	 * trash or restore registrations
2539
+	 *
2540
+	 * @param boolean $trash whether to archive or restore
2541
+	 * @return void
2542
+	 * @throws DomainException
2543
+	 * @throws EE_Error
2544
+	 * @throws EntityNotFoundException
2545
+	 * @throws InvalidArgumentException
2546
+	 * @throws InvalidDataTypeException
2547
+	 * @throws InvalidInterfaceException
2548
+	 * @throws ReflectionException
2549
+	 * @throws RuntimeException
2550
+	 * @throws UnexpectedEntityException
2551
+	 */
2552
+	protected function _trash_or_restore_registrations($trash = true)
2553
+	{
2554
+		// if empty _REG_ID then get out because there's nothing to do
2555
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2556
+		if (empty($REG_IDs)) {
2557
+			EE_Error::add_error(
2558
+				sprintf(
2559
+					esc_html__(
2560
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2561
+						'event_espresso'
2562
+					),
2563
+					$trash ? 'trash' : 'restore'
2564
+				),
2565
+				__FILE__,
2566
+				__LINE__,
2567
+				__FUNCTION__
2568
+			);
2569
+			$this->_redirect_after_action(false, '', '', [], true);
2570
+		}
2571
+		$success        = 0;
2572
+		$overwrite_msgs = false;
2573
+		// Checkboxes
2574
+		$reg_count = count($REG_IDs);
2575
+		// cycle thru checkboxes
2576
+		foreach ($REG_IDs as $REG_ID) {
2577
+			/** @var EE_Registration $REG */
2578
+			$REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2579
+			$payments = $REG->registration_payments();
2580
+			if (! empty($payments)) {
2581
+				$name           = $REG->attendee() instanceof EE_Attendee
2582
+					? $REG->attendee()->full_name()
2583
+					: esc_html__('Unknown Attendee', 'event_espresso');
2584
+				$overwrite_msgs = true;
2585
+				EE_Error::add_error(
2586
+					sprintf(
2587
+						esc_html__(
2588
+							'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.',
2589
+							'event_espresso'
2590
+						),
2591
+						$name
2592
+					),
2593
+					__FILE__,
2594
+					__FUNCTION__,
2595
+					__LINE__
2596
+				);
2597
+				// can't trash this registration because it has payments.
2598
+				continue;
2599
+			}
2600
+			$updated = $trash ? $REG->delete() : $REG->restore();
2601
+			if ($updated) {
2602
+				$success++;
2603
+			}
2604
+		}
2605
+		$this->_redirect_after_action(
2606
+			$success === $reg_count, // were ALL registrations affected?
2607
+			$success > 1
2608
+				? esc_html__('Registrations', 'event_espresso')
2609
+				: esc_html__('Registration', 'event_espresso'),
2610
+			$trash
2611
+				? esc_html__('moved to the trash', 'event_espresso')
2612
+				: esc_html__('restored', 'event_espresso'),
2613
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2614
+			$overwrite_msgs
2615
+		);
2616
+	}
2617
+
2618
+
2619
+	/**
2620
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2621
+	 * registration but also.
2622
+	 * 1. Removing relations to EE_Attendee
2623
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2624
+	 * ALSO trashed.
2625
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2626
+	 * 4. Removing relationships between all tickets and the related registrations
2627
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2628
+	 * 6. Deleting permanently any related Checkins.
2629
+	 *
2630
+	 * @return void
2631
+	 * @throws EE_Error
2632
+	 * @throws InvalidArgumentException
2633
+	 * @throws InvalidDataTypeException
2634
+	 * @throws InvalidInterfaceException
2635
+	 * @throws ReflectionException
2636
+	 */
2637
+	protected function _delete_registrations()
2638
+	{
2639
+		$REG_MDL = $this->getRegistrationModel();
2640
+		$success = 0;
2641
+		// Checkboxes
2642
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2643
+
2644
+		if (! empty($REG_IDs)) {
2645
+			// if array has more than one element than success message should be plural
2646
+			$success = count($REG_IDs) > 1 ? 2 : 1;
2647
+			// cycle thru checkboxes
2648
+			foreach ($REG_IDs as $REG_ID) {
2649
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2650
+				if (! $REG instanceof EE_Registration) {
2651
+					continue;
2652
+				}
2653
+				$deleted = $this->_delete_registration($REG);
2654
+				if (! $deleted) {
2655
+					$success = 0;
2656
+				}
2657
+			}
2658
+		}
2659
+
2660
+		$what        = $success > 1
2661
+			? esc_html__('Registrations', 'event_espresso')
2662
+			: esc_html__('Registration', 'event_espresso');
2663
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2664
+		$this->_redirect_after_action(
2665
+			$success,
2666
+			$what,
2667
+			$action_desc,
2668
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2669
+			true
2670
+		);
2671
+	}
2672
+
2673
+
2674
+	/**
2675
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2676
+	 * models get affected.
2677
+	 *
2678
+	 * @param EE_Registration $REG registration to be deleted permanently
2679
+	 * @return bool true = successful deletion, false = fail.
2680
+	 * @throws EE_Error
2681
+	 * @throws InvalidArgumentException
2682
+	 * @throws InvalidDataTypeException
2683
+	 * @throws InvalidInterfaceException
2684
+	 * @throws ReflectionException
2685
+	 */
2686
+	protected function _delete_registration(EE_Registration $REG)
2687
+	{
2688
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2689
+		// registrations on the transaction that are NOT trashed.
2690
+		$TXN = $REG->get_first_related('Transaction');
2691
+		if (! $TXN instanceof EE_Transaction) {
2692
+			EE_Error::add_error(
2693
+				sprintf(
2694
+					esc_html__(
2695
+						'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2696
+						'event_espresso'
2697
+					),
2698
+					$REG->id()
2699
+				),
2700
+				__FILE__,
2701
+				__FUNCTION__,
2702
+				__LINE__
2703
+			);
2704
+			return false;
2705
+		}
2706
+		$REGS        = $TXN->get_many_related('Registration');
2707
+		$all_trashed = true;
2708
+		foreach ($REGS as $registration) {
2709
+			if (! $registration->get('REG_deleted')) {
2710
+				$all_trashed = false;
2711
+			}
2712
+		}
2713
+		if (! $all_trashed) {
2714
+			EE_Error::add_error(
2715
+				esc_html__(
2716
+					'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.',
2717
+					'event_espresso'
2718
+				),
2719
+				__FILE__,
2720
+				__FUNCTION__,
2721
+				__LINE__
2722
+			);
2723
+			return false;
2724
+		}
2725
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2726
+		// separately from THIS one).
2727
+		foreach ($REGS as $registration) {
2728
+			// delete related answers
2729
+			$registration->delete_related_permanently('Answer');
2730
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2731
+			$attendee = $registration->get_first_related('Attendee');
2732
+			if ($attendee instanceof EE_Attendee) {
2733
+				$registration->_remove_relation_to($attendee, 'Attendee');
2734
+			}
2735
+			// now remove relationships to tickets on this registration.
2736
+			$registration->_remove_relations('Ticket');
2737
+			// now delete permanently the checkins related to this registration.
2738
+			$registration->delete_related_permanently('Checkin');
2739
+			if ($registration->ID() === $REG->ID()) {
2740
+				continue;
2741
+			} //we don't want to delete permanently the existing registration just yet.
2742
+			// remove relation to transaction for these registrations if NOT the existing registrations
2743
+			$registration->_remove_relations('Transaction');
2744
+			// delete permanently any related messages.
2745
+			$registration->delete_related_permanently('Message');
2746
+			// now delete this registration permanently
2747
+			$registration->delete_permanently();
2748
+		}
2749
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2750
+		// (the transaction and line items should be all that's left).
2751
+		// delete the line items related to the transaction for this registration.
2752
+		$TXN->delete_related_permanently('Line_Item');
2753
+		// we need to remove all the relationships on the transaction
2754
+		$TXN->delete_related_permanently('Payment');
2755
+		$TXN->delete_related_permanently('Extra_Meta');
2756
+		$TXN->delete_related_permanently('Message');
2757
+		// now we can delete this REG permanently (and the transaction of course)
2758
+		$REG->delete_related_permanently('Transaction');
2759
+		return $REG->delete_permanently();
2760
+	}
2761
+
2762
+
2763
+	/**
2764
+	 *    generates HTML for the Register New Attendee Admin page
2765
+	 *
2766
+	 * @throws DomainException
2767
+	 * @throws EE_Error
2768
+	 * @throws InvalidArgumentException
2769
+	 * @throws InvalidDataTypeException
2770
+	 * @throws InvalidInterfaceException
2771
+	 * @throws ReflectionException
2772
+	 */
2773
+	public function new_registration()
2774
+	{
2775
+		if (! $this->_set_reg_event()) {
2776
+			throw new EE_Error(
2777
+				esc_html__(
2778
+					'Unable to continue with registering because there is no Event ID in the request',
2779
+					'event_espresso'
2780
+				)
2781
+			);
2782
+		}
2783
+		/** @var CurrentPage $current_page */
2784
+		$current_page = $this->loader->getShared(CurrentPage::class);
2785
+		$current_page->setEspressoPage(true);
2786
+		// gotta start with a clean slate if we're not coming here via ajax
2787
+		if (
2788
+			! $this->request->isAjax()
2789
+			&& (
2790
+				! $this->request->requestParamIsSet('processing_registration')
2791
+				|| $this->request->requestParamIsSet('step_error')
2792
+			)
2793
+		) {
2794
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2795
+		}
2796
+		$this->_template_args['event_name'] = '';
2797
+		// event name
2798
+		if ($this->_reg_event) {
2799
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2800
+			$edit_event_url                     = self::add_query_args_and_nonce(
2801
+				[
2802
+					'action' => 'edit',
2803
+					'post'   => $this->_reg_event->ID(),
2804
+				],
2805
+				EVENTS_ADMIN_URL
2806
+			);
2807
+			$edit_event_lnk                     = '<a href="'
2808
+												  . $edit_event_url
2809
+												  . '" aria-label="'
2810
+												  . esc_attr__('Edit ', 'event_espresso')
2811
+												  . $this->_reg_event->name()
2812
+												  . '">'
2813
+												  . esc_html__('Edit Event', 'event_espresso')
2814
+												  . '</a>';
2815
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2816
+												   . $edit_event_lnk
2817
+												   . '</span>';
2818
+		}
2819
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2820
+		if ($this->request->isAjax()) {
2821
+			$this->_return_json();
2822
+		}
2823
+		// grab header
2824
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2825
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2826
+			$template_path,
2827
+			$this->_template_args,
2828
+			true
2829
+		);
2830
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2831
+		// the details template wrapper
2832
+		$this->display_admin_page_with_sidebar();
2833
+	}
2834
+
2835
+
2836
+	/**
2837
+	 * This returns the content for a registration step
2838
+	 *
2839
+	 * @return string html
2840
+	 * @throws DomainException
2841
+	 * @throws EE_Error
2842
+	 * @throws InvalidArgumentException
2843
+	 * @throws InvalidDataTypeException
2844
+	 * @throws InvalidInterfaceException
2845
+	 * @throws ReflectionException
2846
+	 */
2847
+	protected function _get_registration_step_content()
2848
+	{
2849
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2850
+			$warning_msg = sprintf(
2851
+				esc_html__(
2852
+					'%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',
2853
+					'event_espresso'
2854
+				),
2855
+				'<br />',
2856
+				'<h3 class="important-notice">',
2857
+				'</h3>',
2858
+				'<div class="float-right">',
2859
+				'<span id="redirect_timer" class="important-notice">30</span>',
2860
+				'</div>',
2861
+				'<b>',
2862
+				'</b>'
2863
+			);
2864
+			return '
2865 2865
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2866 2866
 	<script >
2867 2867
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2874,841 +2874,841 @@  discard block
 block discarded – undo
2874 2874
 	        }
2875 2875
 	    }, 800 );
2876 2876
 	</script >';
2877
-        }
2878
-        $template_args = [
2879
-            'title'                    => '',
2880
-            'content'                  => '',
2881
-            'step_button_text'         => '',
2882
-            'show_notification_toggle' => false,
2883
-        ];
2884
-        // to indicate we're processing a new registration
2885
-        $hidden_fields = [
2886
-            'processing_registration' => [
2887
-                'type'  => 'hidden',
2888
-                'value' => 0,
2889
-            ],
2890
-            'event_id'                => [
2891
-                'type'  => 'hidden',
2892
-                'value' => $this->_reg_event->ID(),
2893
-            ],
2894
-        ];
2895
-        // if the cart is empty then we know we're at step one, so we'll display the ticket selector
2896
-        $cart = EE_Registry::instance()->SSN->cart();
2897
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2898
-        switch ($step) {
2899
-            case 'ticket':
2900
-                $hidden_fields['processing_registration']['value'] = 1;
2901
-                $template_args['title']                            = esc_html__(
2902
-                    'Step One: Select the Ticket for this registration',
2903
-                    'event_espresso'
2904
-                );
2905
-                $template_args['content'] = EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2906
-                $template_args['content'] .= '</div>';
2907
-                $template_args['step_button_text'] = esc_html__(
2908
-                    'Add Tickets and Continue to Registrant Details',
2909
-                    'event_espresso'
2910
-                );
2911
-                $template_args['show_notification_toggle']         = false;
2912
-                break;
2913
-            case 'questions':
2914
-                $hidden_fields['processing_registration']['value'] = 2;
2915
-                $template_args['title']                            = esc_html__(
2916
-                    'Step Two: Add Registrant Details for this Registration',
2917
-                    'event_espresso'
2918
-                );
2919
-                // in theory, we should be able to run EED_SPCO at this point
2920
-                // because the cart should have been set up properly by the first process_reg_step run.
2921
-                $template_args['content'] = EED_Single_Page_Checkout::registration_checkout_for_admin();
2922
-                $template_args['step_button_text'] = esc_html__(
2923
-                    'Save Registration and Continue to Details',
2924
-                    'event_espresso'
2925
-                );
2926
-                $template_args['show_notification_toggle'] = true;
2927
-                break;
2928
-        }
2929
-        // we come back to the process_registration_step route.
2930
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2931
-        return EEH_Template::display_template(
2932
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2933
-            $template_args,
2934
-            true
2935
-        );
2936
-    }
2937
-
2938
-
2939
-    /**
2940
-     * set_reg_event
2941
-     *
2942
-     * @return bool
2943
-     * @throws EE_Error
2944
-     * @throws InvalidArgumentException
2945
-     * @throws InvalidDataTypeException
2946
-     * @throws InvalidInterfaceException
2947
-     */
2948
-    private function _set_reg_event()
2949
-    {
2950
-        if (is_object($this->_reg_event)) {
2951
-            return true;
2952
-        }
2953
-
2954
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2955
-        if (! $EVT_ID) {
2956
-            return false;
2957
-        }
2958
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2959
-        return true;
2960
-    }
2961
-
2962
-
2963
-    /**
2964
-     * process_reg_step
2965
-     *
2966
-     * @return void
2967
-     * @throws DomainException
2968
-     * @throws EE_Error
2969
-     * @throws InvalidArgumentException
2970
-     * @throws InvalidDataTypeException
2971
-     * @throws InvalidInterfaceException
2972
-     * @throws ReflectionException
2973
-     * @throws RuntimeException
2974
-     */
2975
-    public function process_reg_step()
2976
-    {
2977
-        EE_System::do_not_cache();
2978
-        $this->_set_reg_event();
2979
-        /** @var CurrentPage $current_page */
2980
-        $current_page = $this->loader->getShared(CurrentPage::class);
2981
-        $current_page->setEspressoPage(true);
2982
-        $this->request->setRequestParam('uts', time());
2983
-        // what step are we on?
2984
-        $cart = EE_Registry::instance()->SSN->cart();
2985
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2986
-        // if doing ajax then we need to verify the nonce
2987
-        if ($this->request->isAjax()) {
2988
-            $nonce = $this->request->getRequestParam($this->_req_nonce, '');
2989
-            $this->_verify_nonce($nonce, $this->_req_nonce);
2990
-        }
2991
-        switch ($step) {
2992
-            case 'ticket':
2993
-                // process ticket selection
2994
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
2995
-                if ($success) {
2996
-                    EE_Error::add_success(
2997
-                        esc_html__(
2998
-                            'Tickets Selected. Now complete the registration.',
2999
-                            'event_espresso'
3000
-                        )
3001
-                    );
3002
-                } else {
3003
-                    $this->request->setRequestParam('step_error', true);
3004
-                    $query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3005
-                }
3006
-                if ($this->request->isAjax()) {
3007
-                    $this->new_registration(); // display next step
3008
-                } else {
3009
-                    $query_args = [
3010
-                        'action'                  => 'new_registration',
3011
-                        'processing_registration' => 1,
3012
-                        'event_id'                => $this->_reg_event->ID(),
3013
-                        'uts'                     => time(),
3014
-                    ];
3015
-                    $this->_redirect_after_action(
3016
-                        false,
3017
-                        '',
3018
-                        '',
3019
-                        $query_args,
3020
-                        true
3021
-                    );
3022
-                }
3023
-                break;
3024
-            case 'questions':
3025
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3026
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3027
-                }
3028
-                // process registration
3029
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3030
-                if ($cart instanceof EE_Cart) {
3031
-                    $grand_total = $cart->get_grand_total();
3032
-                    if ($grand_total instanceof EE_Line_Item) {
3033
-                        $grand_total->save_this_and_descendants_to_txn();
3034
-                    }
3035
-                }
3036
-                if (! $transaction instanceof EE_Transaction) {
3037
-                    $query_args = [
3038
-                        'action'                  => 'new_registration',
3039
-                        'processing_registration' => 2,
3040
-                        'event_id'                => $this->_reg_event->ID(),
3041
-                        'uts'                     => time(),
3042
-                    ];
3043
-                    if ($this->request->isAjax()) {
3044
-                        // display registration form again because there are errors (maybe validation?)
3045
-                        $this->new_registration();
3046
-                        return;
3047
-                    }
3048
-                    $this->_redirect_after_action(
3049
-                        false,
3050
-                        '',
3051
-                        '',
3052
-                        $query_args,
3053
-                        true
3054
-                    );
3055
-                    return;
3056
-                }
3057
-                // maybe update status, and make sure to save transaction if not done already
3058
-                if (! $transaction->update_status_based_on_total_paid()) {
3059
-                    $transaction->save();
3060
-                }
3061
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3062
-                $query_args = [
3063
-                    'action'        => 'redirect_to_txn',
3064
-                    'TXN_ID'        => $transaction->ID(),
3065
-                    'EVT_ID'        => $this->_reg_event->ID(),
3066
-                    'event_name'    => urlencode($this->_reg_event->name()),
3067
-                    'redirect_from' => 'new_registration',
3068
-                ];
3069
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3070
-                break;
3071
-        }
3072
-        // what are you looking here for?  Should be nothing to do at this point.
3073
-    }
3074
-
3075
-
3076
-    /**
3077
-     * redirect_to_txn
3078
-     *
3079
-     * @return void
3080
-     * @throws EE_Error
3081
-     * @throws InvalidArgumentException
3082
-     * @throws InvalidDataTypeException
3083
-     * @throws InvalidInterfaceException
3084
-     * @throws ReflectionException
3085
-     */
3086
-    public function redirect_to_txn()
3087
-    {
3088
-        EE_System::do_not_cache();
3089
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3090
-        $query_args = [
3091
-            'action' => 'view_transaction',
3092
-            'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3093
-            'page'   => 'espresso_transactions',
3094
-        ];
3095
-        if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3096
-            $query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3097
-            $query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3098
-            $query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3099
-        }
3100
-        EE_Error::add_success(
3101
-            esc_html__(
3102
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3103
-                'event_espresso'
3104
-            )
3105
-        );
3106
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3107
-    }
3108
-
3109
-
3110
-    /**
3111
-     * generates HTML for the Attendee Contact List
3112
-     *
3113
-     * @return void
3114
-     * @throws DomainException
3115
-     * @throws EE_Error
3116
-     */
3117
-    protected function _attendee_contact_list_table()
3118
-    {
3119
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3120
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3121
-        $this->display_admin_list_table_page_with_no_sidebar();
3122
-    }
3123
-
3124
-
3125
-    /**
3126
-     * get_attendees
3127
-     *
3128
-     * @param      $per_page
3129
-     * @param bool $count whether to return count or data.
3130
-     * @param bool $trash
3131
-     * @return array|int
3132
-     * @throws EE_Error
3133
-     * @throws InvalidArgumentException
3134
-     * @throws InvalidDataTypeException
3135
-     * @throws InvalidInterfaceException
3136
-     */
3137
-    public function get_attendees($per_page, $count = false, $trash = false)
3138
-    {
3139
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3140
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3141
-        $orderby = $this->request->getRequestParam('orderby');
3142
-        switch ($orderby) {
3143
-            case 'ATT_ID':
3144
-            case 'ATT_fname':
3145
-            case 'ATT_email':
3146
-            case 'ATT_city':
3147
-            case 'STA_ID':
3148
-            case 'CNT_ID':
3149
-                break;
3150
-            case 'Registration_Count':
3151
-                $orderby = 'Registration_Count';
3152
-                break;
3153
-            default:
3154
-                $orderby = 'ATT_lname';
3155
-        }
3156
-        $sort         = $this->request->getRequestParam('order', 'ASC');
3157
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
3158
-        $per_page     = absint($per_page) ? $per_page : 10;
3159
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3160
-        $_where       = [];
3161
-        $search_term  = $this->request->getRequestParam('s');
3162
-        if ($search_term) {
3163
-            $search_term  = '%' . $search_term . '%';
3164
-            $_where['OR'] = [
3165
-                'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3166
-                'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3167
-                'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3168
-                'ATT_fname'                         => ['LIKE', $search_term],
3169
-                'ATT_lname'                         => ['LIKE', $search_term],
3170
-                'ATT_short_bio'                     => ['LIKE', $search_term],
3171
-                'ATT_email'                         => ['LIKE', $search_term],
3172
-                'ATT_address'                       => ['LIKE', $search_term],
3173
-                'ATT_address2'                      => ['LIKE', $search_term],
3174
-                'ATT_city'                          => ['LIKE', $search_term],
3175
-                'Country.CNT_name'                  => ['LIKE', $search_term],
3176
-                'State.STA_name'                    => ['LIKE', $search_term],
3177
-                'ATT_phone'                         => ['LIKE', $search_term],
3178
-                'Registration.REG_final_price'      => ['LIKE', $search_term],
3179
-                'Registration.REG_code'             => ['LIKE', $search_term],
3180
-                'Registration.REG_group_size'       => ['LIKE', $search_term],
3181
-            ];
3182
-        }
3183
-        $offset     = ($current_page - 1) * $per_page;
3184
-        $limit      = $count ? null : [$offset, $per_page];
3185
-        $query_args = [
3186
-            $_where,
3187
-            'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3188
-            'limit'         => $limit,
3189
-        ];
3190
-        if (! $count) {
3191
-            $query_args['order_by'] = [$orderby => $sort];
3192
-        }
3193
-        $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3194
-        return $count
3195
-            ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3196
-            : $this->getAttendeeModel()->get_all($query_args);
3197
-    }
3198
-
3199
-
3200
-    /**
3201
-     * This is just taking care of resending the registration confirmation
3202
-     *
3203
-     * @return void
3204
-     * @throws EE_Error
3205
-     * @throws InvalidArgumentException
3206
-     * @throws InvalidDataTypeException
3207
-     * @throws InvalidInterfaceException
3208
-     * @throws ReflectionException
3209
-     */
3210
-    protected function _resend_registration()
3211
-    {
3212
-        $this->_process_resend_registration();
3213
-        $REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3214
-        $redirect_to = $this->request->getRequestParam('redirect_to');
3215
-        $query_args  = $redirect_to
3216
-            ? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3217
-            : ['action' => 'default'];
3218
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3219
-    }
3220
-
3221
-
3222
-    /**
3223
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3224
-     * to use when selecting registrations
3225
-     *
3226
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3227
-     *                                                     the query parameters from the request
3228
-     * @return void ends the request with a redirect or download
3229
-     */
3230
-    public function _registrations_report_base($method_name_for_getting_query_params)
3231
-    {
3232
-        $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3233
-            ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3234
-            : null;
3235
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3236
-            $return_url = $this->request->getRequestParam('return_url', '', DataType::URL);
3237
-            $filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3238
-            $report_params  = $this->$method_name_for_getting_query_params($filters);
3239
-            $use_filters = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3240
-            wp_redirect(
3241
-                EE_Admin_Page::add_query_args_and_nonce(
3242
-                    [
3243
-                        'page'        => EED_Batch::PAGE_SLUG,
3244
-                        'batch'       => EED_Batch::batch_file_job,
3245
-                        'EVT_ID'      => $EVT_ID,
3246
-                        'filters'     => urlencode(serialize($report_params)),
3247
-                        'use_filters' => urlencode($use_filters),
3248
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3249
-                        'return_url'  => urlencode($return_url),
3250
-                    ]
3251
-                )
3252
-            );
3253
-        } else {
3254
-            // Pull the current request params
3255
-            $request_args = $this->request->requestParams();
3256
-            // Set the required request_args to be passed to the export
3257
-            $required_request_args = [
3258
-                'export' => 'report',
3259
-                'action' => 'registrations_report_for_event',
3260
-                'EVT_ID' => $EVT_ID,
3261
-            ];
3262
-            // Merge required request args, overriding any currently set
3263
-            $request_args = array_merge($request_args, $required_request_args);
3264
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3265
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3266
-                $EE_Export = EE_Export::instance($request_args);
3267
-                $EE_Export->export();
3268
-            }
3269
-        }
3270
-    }
3271
-
3272
-
3273
-    /**
3274
-     * Creates a registration report using only query parameters in the request
3275
-     *
3276
-     * @return void
3277
-     */
3278
-    public function _registrations_report()
3279
-    {
3280
-        $this->_registrations_report_base('_get_registration_query_parameters');
3281
-    }
3282
-
3283
-
3284
-    public function _contact_list_export()
3285
-    {
3286
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3287
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3288
-            $EE_Export = EE_Export::instance($this->request->requestParams());
3289
-            $EE_Export->export_attendees();
3290
-        }
3291
-    }
3292
-
3293
-
3294
-    public function _contact_list_report()
3295
-    {
3296
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3297
-            wp_redirect(
3298
-                EE_Admin_Page::add_query_args_and_nonce(
3299
-                    [
3300
-                        'page'        => EED_Batch::PAGE_SLUG,
3301
-                        'batch'       => EED_Batch::batch_file_job,
3302
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3303
-                        'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3304
-                    ]
3305
-                )
3306
-            );
3307
-        } else {
3308
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3309
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3310
-                $EE_Export = EE_Export::instance($this->request->requestParams());
3311
-                $EE_Export->report_attendees();
3312
-            }
3313
-        }
3314
-    }
3315
-
3316
-
3317
-
3318
-
3319
-
3320
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3321
-    /**
3322
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3323
-     *
3324
-     * @return void
3325
-     * @throws EE_Error
3326
-     * @throws InvalidArgumentException
3327
-     * @throws InvalidDataTypeException
3328
-     * @throws InvalidInterfaceException
3329
-     * @throws ReflectionException
3330
-     */
3331
-    protected function _duplicate_attendee()
3332
-    {
3333
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3334
-        $action = $this->request->getRequestParam('return', 'default');
3335
-        // verify we have necessary info
3336
-        if (! $REG_ID) {
3337
-            EE_Error::add_error(
3338
-                esc_html__(
3339
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3340
-                    'event_espresso'
3341
-                ),
3342
-                __FILE__,
3343
-                __LINE__,
3344
-                __FUNCTION__
3345
-            );
3346
-            $query_args = ['action' => $action];
3347
-            $this->_redirect_after_action('', '', '', $query_args, true);
3348
-        }
3349
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3350
-        $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3351
-        if (! $registration instanceof EE_Registration) {
3352
-            throw new RuntimeException(
3353
-                sprintf(
3354
-                    esc_html__(
3355
-                        'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3356
-                        'event_espresso'
3357
-                    ),
3358
-                    $REG_ID
3359
-                )
3360
-            );
3361
-        }
3362
-        $attendee = $registration->attendee();
3363
-        // remove relation of existing attendee on registration
3364
-        $registration->_remove_relation_to($attendee, 'Attendee');
3365
-        // new attendee
3366
-        $new_attendee = clone $attendee;
3367
-        $new_attendee->set('ATT_ID', 0);
3368
-        $new_attendee->save();
3369
-        // add new attendee to reg
3370
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3371
-        EE_Error::add_success(
3372
-            esc_html__(
3373
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3374
-                'event_espresso'
3375
-            )
3376
-        );
3377
-        // redirect to edit page for attendee
3378
-        $query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3379
-        $this->_redirect_after_action('', '', '', $query_args, true);
3380
-    }
3381
-
3382
-
3383
-    /**
3384
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3385
-     *
3386
-     * @param int     $post_id
3387
-     * @param WP_Post $post
3388
-     * @throws DomainException
3389
-     * @throws EE_Error
3390
-     * @throws InvalidArgumentException
3391
-     * @throws InvalidDataTypeException
3392
-     * @throws InvalidInterfaceException
3393
-     * @throws LogicException
3394
-     * @throws InvalidFormSubmissionException
3395
-     * @throws ReflectionException
3396
-     */
3397
-    protected function _insert_update_cpt_item($post_id, $post)
3398
-    {
3399
-        $success  = true;
3400
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3401
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3402
-            : null;
3403
-        // for attendee updates
3404
-        if ($attendee instanceof EE_Attendee) {
3405
-            // note we should only be UPDATING attendees at this point.
3406
-            $fname          = $this->request->getRequestParam('ATT_fname', '');
3407
-            $lname          = $this->request->getRequestParam('ATT_lname', '');
3408
-            $updated_fields = [
3409
-                'ATT_fname'     => $fname,
3410
-                'ATT_lname'     => $lname,
3411
-                'ATT_full_name' => "{$fname} {$lname}",
3412
-                'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3413
-                'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3414
-                'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3415
-                'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3416
-                'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3417
-                'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3418
-            ];
3419
-            foreach ($updated_fields as $field => $value) {
3420
-                $attendee->set($field, $value);
3421
-            }
3422
-
3423
-            // process contact details metabox form handler (which will also save the attendee)
3424
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3425
-            $success              = $contact_details_form->process($this->request->requestParams());
3426
-
3427
-            $attendee_update_callbacks = apply_filters(
3428
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3429
-                []
3430
-            );
3431
-            foreach ($attendee_update_callbacks as $a_callback) {
3432
-                if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3433
-                    throw new EE_Error(
3434
-                        sprintf(
3435
-                            esc_html__(
3436
-                                '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.',
3437
-                                'event_espresso'
3438
-                            ),
3439
-                            $a_callback
3440
-                        )
3441
-                    );
3442
-                }
3443
-            }
3444
-        }
3445
-
3446
-        if ($success === false) {
3447
-            EE_Error::add_error(
3448
-                esc_html__(
3449
-                    'Something went wrong with updating the meta table data for the registration.',
3450
-                    'event_espresso'
3451
-                ),
3452
-                __FILE__,
3453
-                __FUNCTION__,
3454
-                __LINE__
3455
-            );
3456
-        }
3457
-    }
3458
-
3459
-
3460
-    public function trash_cpt_item($post_id)
3461
-    {
3462
-    }
3463
-
3464
-
3465
-    public function delete_cpt_item($post_id)
3466
-    {
3467
-    }
3468
-
3469
-
3470
-    public function restore_cpt_item($post_id)
3471
-    {
3472
-    }
3473
-
3474
-
3475
-    protected function _restore_cpt_item($post_id, $revision_id)
3476
-    {
3477
-    }
3478
-
3479
-
3480
-    /**
3481
-     * @throws EE_Error
3482
-     * @throws ReflectionException
3483
-     * @since 4.10.2.p
3484
-     */
3485
-    public function attendee_editor_metaboxes()
3486
-    {
3487
-        $this->verify_cpt_object();
3488
-        remove_meta_box(
3489
-            'postexcerpt',
3490
-            $this->_cpt_routes[ $this->_req_action ],
3491
-            'normal'
3492
-        );
3493
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3494
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3495
-            $this->addMetaBox(
3496
-                'postexcerpt',
3497
-                esc_html__('Short Biography', 'event_espresso'),
3498
-                'post_excerpt_meta_box',
3499
-                $this->_cpt_routes[ $this->_req_action ]
3500
-            );
3501
-        }
3502
-        if (post_type_supports('espresso_attendees', 'comments')) {
3503
-            $this->addMetaBox(
3504
-                'commentsdiv',
3505
-                esc_html__('Notes on the Contact', 'event_espresso'),
3506
-                'post_comment_meta_box',
3507
-                $this->_cpt_routes[ $this->_req_action ],
3508
-                'normal',
3509
-                'core'
3510
-            );
3511
-        }
3512
-        $this->addMetaBox(
3513
-            'attendee_contact_info',
3514
-            esc_html__('Contact Info', 'event_espresso'),
3515
-            [$this, 'attendee_contact_info'],
3516
-            $this->_cpt_routes[ $this->_req_action ],
3517
-            'side',
3518
-            'core'
3519
-        );
3520
-        $this->addMetaBox(
3521
-            'attendee_details_address',
3522
-            esc_html__('Address Details', 'event_espresso'),
3523
-            [$this, 'attendee_address_details'],
3524
-            $this->_cpt_routes[ $this->_req_action ],
3525
-            'normal',
3526
-            'core'
3527
-        );
3528
-        $this->addMetaBox(
3529
-            'attendee_registrations',
3530
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3531
-            [$this, 'attendee_registrations_meta_box'],
3532
-            $this->_cpt_routes[ $this->_req_action ]
3533
-        );
3534
-    }
3535
-
3536
-
3537
-    /**
3538
-     * Metabox for attendee contact info
3539
-     *
3540
-     * @param WP_Post $post wp post object
3541
-     * @return void attendee contact info ( and form )
3542
-     * @throws EE_Error
3543
-     * @throws InvalidArgumentException
3544
-     * @throws InvalidDataTypeException
3545
-     * @throws InvalidInterfaceException
3546
-     * @throws LogicException
3547
-     * @throws DomainException
3548
-     */
3549
-    public function attendee_contact_info($post)
3550
-    {
3551
-        // get attendee object ( should already have it )
3552
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3553
-        $form->enqueueStylesAndScripts();
3554
-        echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3555
-    }
3556
-
3557
-
3558
-    /**
3559
-     * Return form handler for the contact details metabox
3560
-     *
3561
-     * @param EE_Attendee $attendee
3562
-     * @return AttendeeContactDetailsMetaboxFormHandler
3563
-     * @throws DomainException
3564
-     * @throws InvalidArgumentException
3565
-     * @throws InvalidDataTypeException
3566
-     * @throws InvalidInterfaceException
3567
-     */
3568
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3569
-    {
3570
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3571
-    }
3572
-
3573
-
3574
-    /**
3575
-     * Metabox for attendee details
3576
-     *
3577
-     * @param WP_Post $post wp post object
3578
-     * @throws EE_Error
3579
-     * @throws ReflectionException
3580
-     */
3581
-    public function attendee_address_details($post)
3582
-    {
3583
-        // get attendee object (should already have it)
3584
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3585
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3586
-            new EE_Question_Form_Input(
3587
-                EE_Question::new_instance(
3588
-                    [
3589
-                        'QST_ID'           => 0,
3590
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3591
-                        'QST_system'       => 'admin-state',
3592
-                    ]
3593
-                ),
3594
-                EE_Answer::new_instance(
3595
-                    [
3596
-                        'ANS_ID'    => 0,
3597
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3598
-                    ]
3599
-                ),
3600
-                [
3601
-                    'input_id'       => 'STA_ID',
3602
-                    'input_name'     => 'STA_ID',
3603
-                    'input_prefix'   => '',
3604
-                    'append_qstn_id' => false,
3605
-                ]
3606
-            )
3607
-        );
3608
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3609
-            new EE_Question_Form_Input(
3610
-                EE_Question::new_instance(
3611
-                    [
3612
-                        'QST_ID'           => 0,
3613
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3614
-                        'QST_system'       => 'admin-country',
3615
-                    ]
3616
-                ),
3617
-                EE_Answer::new_instance(
3618
-                    [
3619
-                        'ANS_ID'    => 0,
3620
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3621
-                    ]
3622
-                ),
3623
-                [
3624
-                    'input_id'       => 'CNT_ISO',
3625
-                    'input_name'     => 'CNT_ISO',
3626
-                    'input_prefix'   => '',
3627
-                    'append_qstn_id' => false,
3628
-                ]
3629
-            )
3630
-        );
3631
-        $template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3632
-        EEH_Template::display_template($template, $this->_template_args);
3633
-    }
3634
-
3635
-
3636
-    /**
3637
-     * _attendee_details
3638
-     *
3639
-     * @param $post
3640
-     * @return void
3641
-     * @throws DomainException
3642
-     * @throws EE_Error
3643
-     * @throws InvalidArgumentException
3644
-     * @throws InvalidDataTypeException
3645
-     * @throws InvalidInterfaceException
3646
-     * @throws ReflectionException
3647
-     */
3648
-    public function attendee_registrations_meta_box($post)
3649
-    {
3650
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3651
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3652
-        $template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3653
-        EEH_Template::display_template($template, $this->_template_args);
3654
-    }
3655
-
3656
-
3657
-    /**
3658
-     * add in the form fields for the attendee edit
3659
-     *
3660
-     * @param WP_Post $post wp post object
3661
-     * @return void echos html for new form.
3662
-     * @throws DomainException
3663
-     */
3664
-    public function after_title_form_fields($post)
3665
-    {
3666
-        if ($post->post_type === 'espresso_attendees') {
3667
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3668
-            $template_args['attendee'] = $this->_cpt_model_obj;
3669
-            EEH_Template::display_template($template, $template_args);
3670
-        }
3671
-    }
3672
-
3673
-
3674
-    /**
3675
-     * _trash_or_restore_attendee
3676
-     *
3677
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3678
-     * @return void
3679
-     * @throws EE_Error
3680
-     * @throws InvalidArgumentException
3681
-     * @throws InvalidDataTypeException
3682
-     * @throws InvalidInterfaceException
3683
-     */
3684
-    protected function _trash_or_restore_attendees($trash = true)
3685
-    {
3686
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3687
-        $status = $trash ? 'trash' : 'publish';
3688
-        // Checkboxes
3689
-        if ($this->request->requestParamIsSet('checkbox')) {
3690
-            $ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3691
-            // if array has more than one element than success message should be plural
3692
-            $success = count($ATT_IDs) > 1 ? 2 : 1;
3693
-            // cycle thru checkboxes
3694
-            foreach ($ATT_IDs as $ATT_ID) {
3695
-                $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3696
-                if (! $updated) {
3697
-                    $success = 0;
3698
-                }
3699
-            }
3700
-        } else {
3701
-            // grab single id and delete
3702
-            $ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3703
-            // update attendee
3704
-            $success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3705
-        }
3706
-        $what        = $success > 1
3707
-            ? esc_html__('Contacts', 'event_espresso')
3708
-            : esc_html__('Contact', 'event_espresso');
3709
-        $action_desc = $trash
3710
-            ? esc_html__('moved to the trash', 'event_espresso')
3711
-            : esc_html__('restored', 'event_espresso');
3712
-        $this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3713
-    }
2877
+		}
2878
+		$template_args = [
2879
+			'title'                    => '',
2880
+			'content'                  => '',
2881
+			'step_button_text'         => '',
2882
+			'show_notification_toggle' => false,
2883
+		];
2884
+		// to indicate we're processing a new registration
2885
+		$hidden_fields = [
2886
+			'processing_registration' => [
2887
+				'type'  => 'hidden',
2888
+				'value' => 0,
2889
+			],
2890
+			'event_id'                => [
2891
+				'type'  => 'hidden',
2892
+				'value' => $this->_reg_event->ID(),
2893
+			],
2894
+		];
2895
+		// if the cart is empty then we know we're at step one, so we'll display the ticket selector
2896
+		$cart = EE_Registry::instance()->SSN->cart();
2897
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2898
+		switch ($step) {
2899
+			case 'ticket':
2900
+				$hidden_fields['processing_registration']['value'] = 1;
2901
+				$template_args['title']                            = esc_html__(
2902
+					'Step One: Select the Ticket for this registration',
2903
+					'event_espresso'
2904
+				);
2905
+				$template_args['content'] = EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2906
+				$template_args['content'] .= '</div>';
2907
+				$template_args['step_button_text'] = esc_html__(
2908
+					'Add Tickets and Continue to Registrant Details',
2909
+					'event_espresso'
2910
+				);
2911
+				$template_args['show_notification_toggle']         = false;
2912
+				break;
2913
+			case 'questions':
2914
+				$hidden_fields['processing_registration']['value'] = 2;
2915
+				$template_args['title']                            = esc_html__(
2916
+					'Step Two: Add Registrant Details for this Registration',
2917
+					'event_espresso'
2918
+				);
2919
+				// in theory, we should be able to run EED_SPCO at this point
2920
+				// because the cart should have been set up properly by the first process_reg_step run.
2921
+				$template_args['content'] = EED_Single_Page_Checkout::registration_checkout_for_admin();
2922
+				$template_args['step_button_text'] = esc_html__(
2923
+					'Save Registration and Continue to Details',
2924
+					'event_espresso'
2925
+				);
2926
+				$template_args['show_notification_toggle'] = true;
2927
+				break;
2928
+		}
2929
+		// we come back to the process_registration_step route.
2930
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2931
+		return EEH_Template::display_template(
2932
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2933
+			$template_args,
2934
+			true
2935
+		);
2936
+	}
2937
+
2938
+
2939
+	/**
2940
+	 * set_reg_event
2941
+	 *
2942
+	 * @return bool
2943
+	 * @throws EE_Error
2944
+	 * @throws InvalidArgumentException
2945
+	 * @throws InvalidDataTypeException
2946
+	 * @throws InvalidInterfaceException
2947
+	 */
2948
+	private function _set_reg_event()
2949
+	{
2950
+		if (is_object($this->_reg_event)) {
2951
+			return true;
2952
+		}
2953
+
2954
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2955
+		if (! $EVT_ID) {
2956
+			return false;
2957
+		}
2958
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2959
+		return true;
2960
+	}
2961
+
2962
+
2963
+	/**
2964
+	 * process_reg_step
2965
+	 *
2966
+	 * @return void
2967
+	 * @throws DomainException
2968
+	 * @throws EE_Error
2969
+	 * @throws InvalidArgumentException
2970
+	 * @throws InvalidDataTypeException
2971
+	 * @throws InvalidInterfaceException
2972
+	 * @throws ReflectionException
2973
+	 * @throws RuntimeException
2974
+	 */
2975
+	public function process_reg_step()
2976
+	{
2977
+		EE_System::do_not_cache();
2978
+		$this->_set_reg_event();
2979
+		/** @var CurrentPage $current_page */
2980
+		$current_page = $this->loader->getShared(CurrentPage::class);
2981
+		$current_page->setEspressoPage(true);
2982
+		$this->request->setRequestParam('uts', time());
2983
+		// what step are we on?
2984
+		$cart = EE_Registry::instance()->SSN->cart();
2985
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2986
+		// if doing ajax then we need to verify the nonce
2987
+		if ($this->request->isAjax()) {
2988
+			$nonce = $this->request->getRequestParam($this->_req_nonce, '');
2989
+			$this->_verify_nonce($nonce, $this->_req_nonce);
2990
+		}
2991
+		switch ($step) {
2992
+			case 'ticket':
2993
+				// process ticket selection
2994
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
2995
+				if ($success) {
2996
+					EE_Error::add_success(
2997
+						esc_html__(
2998
+							'Tickets Selected. Now complete the registration.',
2999
+							'event_espresso'
3000
+						)
3001
+					);
3002
+				} else {
3003
+					$this->request->setRequestParam('step_error', true);
3004
+					$query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3005
+				}
3006
+				if ($this->request->isAjax()) {
3007
+					$this->new_registration(); // display next step
3008
+				} else {
3009
+					$query_args = [
3010
+						'action'                  => 'new_registration',
3011
+						'processing_registration' => 1,
3012
+						'event_id'                => $this->_reg_event->ID(),
3013
+						'uts'                     => time(),
3014
+					];
3015
+					$this->_redirect_after_action(
3016
+						false,
3017
+						'',
3018
+						'',
3019
+						$query_args,
3020
+						true
3021
+					);
3022
+				}
3023
+				break;
3024
+			case 'questions':
3025
+				if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3026
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3027
+				}
3028
+				// process registration
3029
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3030
+				if ($cart instanceof EE_Cart) {
3031
+					$grand_total = $cart->get_grand_total();
3032
+					if ($grand_total instanceof EE_Line_Item) {
3033
+						$grand_total->save_this_and_descendants_to_txn();
3034
+					}
3035
+				}
3036
+				if (! $transaction instanceof EE_Transaction) {
3037
+					$query_args = [
3038
+						'action'                  => 'new_registration',
3039
+						'processing_registration' => 2,
3040
+						'event_id'                => $this->_reg_event->ID(),
3041
+						'uts'                     => time(),
3042
+					];
3043
+					if ($this->request->isAjax()) {
3044
+						// display registration form again because there are errors (maybe validation?)
3045
+						$this->new_registration();
3046
+						return;
3047
+					}
3048
+					$this->_redirect_after_action(
3049
+						false,
3050
+						'',
3051
+						'',
3052
+						$query_args,
3053
+						true
3054
+					);
3055
+					return;
3056
+				}
3057
+				// maybe update status, and make sure to save transaction if not done already
3058
+				if (! $transaction->update_status_based_on_total_paid()) {
3059
+					$transaction->save();
3060
+				}
3061
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3062
+				$query_args = [
3063
+					'action'        => 'redirect_to_txn',
3064
+					'TXN_ID'        => $transaction->ID(),
3065
+					'EVT_ID'        => $this->_reg_event->ID(),
3066
+					'event_name'    => urlencode($this->_reg_event->name()),
3067
+					'redirect_from' => 'new_registration',
3068
+				];
3069
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3070
+				break;
3071
+		}
3072
+		// what are you looking here for?  Should be nothing to do at this point.
3073
+	}
3074
+
3075
+
3076
+	/**
3077
+	 * redirect_to_txn
3078
+	 *
3079
+	 * @return void
3080
+	 * @throws EE_Error
3081
+	 * @throws InvalidArgumentException
3082
+	 * @throws InvalidDataTypeException
3083
+	 * @throws InvalidInterfaceException
3084
+	 * @throws ReflectionException
3085
+	 */
3086
+	public function redirect_to_txn()
3087
+	{
3088
+		EE_System::do_not_cache();
3089
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3090
+		$query_args = [
3091
+			'action' => 'view_transaction',
3092
+			'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3093
+			'page'   => 'espresso_transactions',
3094
+		];
3095
+		if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3096
+			$query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3097
+			$query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3098
+			$query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3099
+		}
3100
+		EE_Error::add_success(
3101
+			esc_html__(
3102
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3103
+				'event_espresso'
3104
+			)
3105
+		);
3106
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3107
+	}
3108
+
3109
+
3110
+	/**
3111
+	 * generates HTML for the Attendee Contact List
3112
+	 *
3113
+	 * @return void
3114
+	 * @throws DomainException
3115
+	 * @throws EE_Error
3116
+	 */
3117
+	protected function _attendee_contact_list_table()
3118
+	{
3119
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3120
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3121
+		$this->display_admin_list_table_page_with_no_sidebar();
3122
+	}
3123
+
3124
+
3125
+	/**
3126
+	 * get_attendees
3127
+	 *
3128
+	 * @param      $per_page
3129
+	 * @param bool $count whether to return count or data.
3130
+	 * @param bool $trash
3131
+	 * @return array|int
3132
+	 * @throws EE_Error
3133
+	 * @throws InvalidArgumentException
3134
+	 * @throws InvalidDataTypeException
3135
+	 * @throws InvalidInterfaceException
3136
+	 */
3137
+	public function get_attendees($per_page, $count = false, $trash = false)
3138
+	{
3139
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3140
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3141
+		$orderby = $this->request->getRequestParam('orderby');
3142
+		switch ($orderby) {
3143
+			case 'ATT_ID':
3144
+			case 'ATT_fname':
3145
+			case 'ATT_email':
3146
+			case 'ATT_city':
3147
+			case 'STA_ID':
3148
+			case 'CNT_ID':
3149
+				break;
3150
+			case 'Registration_Count':
3151
+				$orderby = 'Registration_Count';
3152
+				break;
3153
+			default:
3154
+				$orderby = 'ATT_lname';
3155
+		}
3156
+		$sort         = $this->request->getRequestParam('order', 'ASC');
3157
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
3158
+		$per_page     = absint($per_page) ? $per_page : 10;
3159
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3160
+		$_where       = [];
3161
+		$search_term  = $this->request->getRequestParam('s');
3162
+		if ($search_term) {
3163
+			$search_term  = '%' . $search_term . '%';
3164
+			$_where['OR'] = [
3165
+				'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3166
+				'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3167
+				'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3168
+				'ATT_fname'                         => ['LIKE', $search_term],
3169
+				'ATT_lname'                         => ['LIKE', $search_term],
3170
+				'ATT_short_bio'                     => ['LIKE', $search_term],
3171
+				'ATT_email'                         => ['LIKE', $search_term],
3172
+				'ATT_address'                       => ['LIKE', $search_term],
3173
+				'ATT_address2'                      => ['LIKE', $search_term],
3174
+				'ATT_city'                          => ['LIKE', $search_term],
3175
+				'Country.CNT_name'                  => ['LIKE', $search_term],
3176
+				'State.STA_name'                    => ['LIKE', $search_term],
3177
+				'ATT_phone'                         => ['LIKE', $search_term],
3178
+				'Registration.REG_final_price'      => ['LIKE', $search_term],
3179
+				'Registration.REG_code'             => ['LIKE', $search_term],
3180
+				'Registration.REG_group_size'       => ['LIKE', $search_term],
3181
+			];
3182
+		}
3183
+		$offset     = ($current_page - 1) * $per_page;
3184
+		$limit      = $count ? null : [$offset, $per_page];
3185
+		$query_args = [
3186
+			$_where,
3187
+			'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3188
+			'limit'         => $limit,
3189
+		];
3190
+		if (! $count) {
3191
+			$query_args['order_by'] = [$orderby => $sort];
3192
+		}
3193
+		$query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3194
+		return $count
3195
+			? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3196
+			: $this->getAttendeeModel()->get_all($query_args);
3197
+	}
3198
+
3199
+
3200
+	/**
3201
+	 * This is just taking care of resending the registration confirmation
3202
+	 *
3203
+	 * @return void
3204
+	 * @throws EE_Error
3205
+	 * @throws InvalidArgumentException
3206
+	 * @throws InvalidDataTypeException
3207
+	 * @throws InvalidInterfaceException
3208
+	 * @throws ReflectionException
3209
+	 */
3210
+	protected function _resend_registration()
3211
+	{
3212
+		$this->_process_resend_registration();
3213
+		$REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3214
+		$redirect_to = $this->request->getRequestParam('redirect_to');
3215
+		$query_args  = $redirect_to
3216
+			? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3217
+			: ['action' => 'default'];
3218
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3219
+	}
3220
+
3221
+
3222
+	/**
3223
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3224
+	 * to use when selecting registrations
3225
+	 *
3226
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3227
+	 *                                                     the query parameters from the request
3228
+	 * @return void ends the request with a redirect or download
3229
+	 */
3230
+	public function _registrations_report_base($method_name_for_getting_query_params)
3231
+	{
3232
+		$EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3233
+			? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3234
+			: null;
3235
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3236
+			$return_url = $this->request->getRequestParam('return_url', '', DataType::URL);
3237
+			$filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3238
+			$report_params  = $this->$method_name_for_getting_query_params($filters);
3239
+			$use_filters = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3240
+			wp_redirect(
3241
+				EE_Admin_Page::add_query_args_and_nonce(
3242
+					[
3243
+						'page'        => EED_Batch::PAGE_SLUG,
3244
+						'batch'       => EED_Batch::batch_file_job,
3245
+						'EVT_ID'      => $EVT_ID,
3246
+						'filters'     => urlencode(serialize($report_params)),
3247
+						'use_filters' => urlencode($use_filters),
3248
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3249
+						'return_url'  => urlencode($return_url),
3250
+					]
3251
+				)
3252
+			);
3253
+		} else {
3254
+			// Pull the current request params
3255
+			$request_args = $this->request->requestParams();
3256
+			// Set the required request_args to be passed to the export
3257
+			$required_request_args = [
3258
+				'export' => 'report',
3259
+				'action' => 'registrations_report_for_event',
3260
+				'EVT_ID' => $EVT_ID,
3261
+			];
3262
+			// Merge required request args, overriding any currently set
3263
+			$request_args = array_merge($request_args, $required_request_args);
3264
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3265
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3266
+				$EE_Export = EE_Export::instance($request_args);
3267
+				$EE_Export->export();
3268
+			}
3269
+		}
3270
+	}
3271
+
3272
+
3273
+	/**
3274
+	 * Creates a registration report using only query parameters in the request
3275
+	 *
3276
+	 * @return void
3277
+	 */
3278
+	public function _registrations_report()
3279
+	{
3280
+		$this->_registrations_report_base('_get_registration_query_parameters');
3281
+	}
3282
+
3283
+
3284
+	public function _contact_list_export()
3285
+	{
3286
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3287
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3288
+			$EE_Export = EE_Export::instance($this->request->requestParams());
3289
+			$EE_Export->export_attendees();
3290
+		}
3291
+	}
3292
+
3293
+
3294
+	public function _contact_list_report()
3295
+	{
3296
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3297
+			wp_redirect(
3298
+				EE_Admin_Page::add_query_args_and_nonce(
3299
+					[
3300
+						'page'        => EED_Batch::PAGE_SLUG,
3301
+						'batch'       => EED_Batch::batch_file_job,
3302
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3303
+						'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3304
+					]
3305
+				)
3306
+			);
3307
+		} else {
3308
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3309
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3310
+				$EE_Export = EE_Export::instance($this->request->requestParams());
3311
+				$EE_Export->report_attendees();
3312
+			}
3313
+		}
3314
+	}
3315
+
3316
+
3317
+
3318
+
3319
+
3320
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3321
+	/**
3322
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3323
+	 *
3324
+	 * @return void
3325
+	 * @throws EE_Error
3326
+	 * @throws InvalidArgumentException
3327
+	 * @throws InvalidDataTypeException
3328
+	 * @throws InvalidInterfaceException
3329
+	 * @throws ReflectionException
3330
+	 */
3331
+	protected function _duplicate_attendee()
3332
+	{
3333
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3334
+		$action = $this->request->getRequestParam('return', 'default');
3335
+		// verify we have necessary info
3336
+		if (! $REG_ID) {
3337
+			EE_Error::add_error(
3338
+				esc_html__(
3339
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3340
+					'event_espresso'
3341
+				),
3342
+				__FILE__,
3343
+				__LINE__,
3344
+				__FUNCTION__
3345
+			);
3346
+			$query_args = ['action' => $action];
3347
+			$this->_redirect_after_action('', '', '', $query_args, true);
3348
+		}
3349
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3350
+		$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3351
+		if (! $registration instanceof EE_Registration) {
3352
+			throw new RuntimeException(
3353
+				sprintf(
3354
+					esc_html__(
3355
+						'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3356
+						'event_espresso'
3357
+					),
3358
+					$REG_ID
3359
+				)
3360
+			);
3361
+		}
3362
+		$attendee = $registration->attendee();
3363
+		// remove relation of existing attendee on registration
3364
+		$registration->_remove_relation_to($attendee, 'Attendee');
3365
+		// new attendee
3366
+		$new_attendee = clone $attendee;
3367
+		$new_attendee->set('ATT_ID', 0);
3368
+		$new_attendee->save();
3369
+		// add new attendee to reg
3370
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3371
+		EE_Error::add_success(
3372
+			esc_html__(
3373
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3374
+				'event_espresso'
3375
+			)
3376
+		);
3377
+		// redirect to edit page for attendee
3378
+		$query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3379
+		$this->_redirect_after_action('', '', '', $query_args, true);
3380
+	}
3381
+
3382
+
3383
+	/**
3384
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3385
+	 *
3386
+	 * @param int     $post_id
3387
+	 * @param WP_Post $post
3388
+	 * @throws DomainException
3389
+	 * @throws EE_Error
3390
+	 * @throws InvalidArgumentException
3391
+	 * @throws InvalidDataTypeException
3392
+	 * @throws InvalidInterfaceException
3393
+	 * @throws LogicException
3394
+	 * @throws InvalidFormSubmissionException
3395
+	 * @throws ReflectionException
3396
+	 */
3397
+	protected function _insert_update_cpt_item($post_id, $post)
3398
+	{
3399
+		$success  = true;
3400
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3401
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3402
+			: null;
3403
+		// for attendee updates
3404
+		if ($attendee instanceof EE_Attendee) {
3405
+			// note we should only be UPDATING attendees at this point.
3406
+			$fname          = $this->request->getRequestParam('ATT_fname', '');
3407
+			$lname          = $this->request->getRequestParam('ATT_lname', '');
3408
+			$updated_fields = [
3409
+				'ATT_fname'     => $fname,
3410
+				'ATT_lname'     => $lname,
3411
+				'ATT_full_name' => "{$fname} {$lname}",
3412
+				'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3413
+				'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3414
+				'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3415
+				'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3416
+				'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3417
+				'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3418
+			];
3419
+			foreach ($updated_fields as $field => $value) {
3420
+				$attendee->set($field, $value);
3421
+			}
3422
+
3423
+			// process contact details metabox form handler (which will also save the attendee)
3424
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3425
+			$success              = $contact_details_form->process($this->request->requestParams());
3426
+
3427
+			$attendee_update_callbacks = apply_filters(
3428
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3429
+				[]
3430
+			);
3431
+			foreach ($attendee_update_callbacks as $a_callback) {
3432
+				if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3433
+					throw new EE_Error(
3434
+						sprintf(
3435
+							esc_html__(
3436
+								'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.',
3437
+								'event_espresso'
3438
+							),
3439
+							$a_callback
3440
+						)
3441
+					);
3442
+				}
3443
+			}
3444
+		}
3445
+
3446
+		if ($success === false) {
3447
+			EE_Error::add_error(
3448
+				esc_html__(
3449
+					'Something went wrong with updating the meta table data for the registration.',
3450
+					'event_espresso'
3451
+				),
3452
+				__FILE__,
3453
+				__FUNCTION__,
3454
+				__LINE__
3455
+			);
3456
+		}
3457
+	}
3458
+
3459
+
3460
+	public function trash_cpt_item($post_id)
3461
+	{
3462
+	}
3463
+
3464
+
3465
+	public function delete_cpt_item($post_id)
3466
+	{
3467
+	}
3468
+
3469
+
3470
+	public function restore_cpt_item($post_id)
3471
+	{
3472
+	}
3473
+
3474
+
3475
+	protected function _restore_cpt_item($post_id, $revision_id)
3476
+	{
3477
+	}
3478
+
3479
+
3480
+	/**
3481
+	 * @throws EE_Error
3482
+	 * @throws ReflectionException
3483
+	 * @since 4.10.2.p
3484
+	 */
3485
+	public function attendee_editor_metaboxes()
3486
+	{
3487
+		$this->verify_cpt_object();
3488
+		remove_meta_box(
3489
+			'postexcerpt',
3490
+			$this->_cpt_routes[ $this->_req_action ],
3491
+			'normal'
3492
+		);
3493
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3494
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3495
+			$this->addMetaBox(
3496
+				'postexcerpt',
3497
+				esc_html__('Short Biography', 'event_espresso'),
3498
+				'post_excerpt_meta_box',
3499
+				$this->_cpt_routes[ $this->_req_action ]
3500
+			);
3501
+		}
3502
+		if (post_type_supports('espresso_attendees', 'comments')) {
3503
+			$this->addMetaBox(
3504
+				'commentsdiv',
3505
+				esc_html__('Notes on the Contact', 'event_espresso'),
3506
+				'post_comment_meta_box',
3507
+				$this->_cpt_routes[ $this->_req_action ],
3508
+				'normal',
3509
+				'core'
3510
+			);
3511
+		}
3512
+		$this->addMetaBox(
3513
+			'attendee_contact_info',
3514
+			esc_html__('Contact Info', 'event_espresso'),
3515
+			[$this, 'attendee_contact_info'],
3516
+			$this->_cpt_routes[ $this->_req_action ],
3517
+			'side',
3518
+			'core'
3519
+		);
3520
+		$this->addMetaBox(
3521
+			'attendee_details_address',
3522
+			esc_html__('Address Details', 'event_espresso'),
3523
+			[$this, 'attendee_address_details'],
3524
+			$this->_cpt_routes[ $this->_req_action ],
3525
+			'normal',
3526
+			'core'
3527
+		);
3528
+		$this->addMetaBox(
3529
+			'attendee_registrations',
3530
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3531
+			[$this, 'attendee_registrations_meta_box'],
3532
+			$this->_cpt_routes[ $this->_req_action ]
3533
+		);
3534
+	}
3535
+
3536
+
3537
+	/**
3538
+	 * Metabox for attendee contact info
3539
+	 *
3540
+	 * @param WP_Post $post wp post object
3541
+	 * @return void attendee contact info ( and form )
3542
+	 * @throws EE_Error
3543
+	 * @throws InvalidArgumentException
3544
+	 * @throws InvalidDataTypeException
3545
+	 * @throws InvalidInterfaceException
3546
+	 * @throws LogicException
3547
+	 * @throws DomainException
3548
+	 */
3549
+	public function attendee_contact_info($post)
3550
+	{
3551
+		// get attendee object ( should already have it )
3552
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3553
+		$form->enqueueStylesAndScripts();
3554
+		echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3555
+	}
3556
+
3557
+
3558
+	/**
3559
+	 * Return form handler for the contact details metabox
3560
+	 *
3561
+	 * @param EE_Attendee $attendee
3562
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3563
+	 * @throws DomainException
3564
+	 * @throws InvalidArgumentException
3565
+	 * @throws InvalidDataTypeException
3566
+	 * @throws InvalidInterfaceException
3567
+	 */
3568
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3569
+	{
3570
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3571
+	}
3572
+
3573
+
3574
+	/**
3575
+	 * Metabox for attendee details
3576
+	 *
3577
+	 * @param WP_Post $post wp post object
3578
+	 * @throws EE_Error
3579
+	 * @throws ReflectionException
3580
+	 */
3581
+	public function attendee_address_details($post)
3582
+	{
3583
+		// get attendee object (should already have it)
3584
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3585
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3586
+			new EE_Question_Form_Input(
3587
+				EE_Question::new_instance(
3588
+					[
3589
+						'QST_ID'           => 0,
3590
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3591
+						'QST_system'       => 'admin-state',
3592
+					]
3593
+				),
3594
+				EE_Answer::new_instance(
3595
+					[
3596
+						'ANS_ID'    => 0,
3597
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3598
+					]
3599
+				),
3600
+				[
3601
+					'input_id'       => 'STA_ID',
3602
+					'input_name'     => 'STA_ID',
3603
+					'input_prefix'   => '',
3604
+					'append_qstn_id' => false,
3605
+				]
3606
+			)
3607
+		);
3608
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3609
+			new EE_Question_Form_Input(
3610
+				EE_Question::new_instance(
3611
+					[
3612
+						'QST_ID'           => 0,
3613
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3614
+						'QST_system'       => 'admin-country',
3615
+					]
3616
+				),
3617
+				EE_Answer::new_instance(
3618
+					[
3619
+						'ANS_ID'    => 0,
3620
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3621
+					]
3622
+				),
3623
+				[
3624
+					'input_id'       => 'CNT_ISO',
3625
+					'input_name'     => 'CNT_ISO',
3626
+					'input_prefix'   => '',
3627
+					'append_qstn_id' => false,
3628
+				]
3629
+			)
3630
+		);
3631
+		$template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3632
+		EEH_Template::display_template($template, $this->_template_args);
3633
+	}
3634
+
3635
+
3636
+	/**
3637
+	 * _attendee_details
3638
+	 *
3639
+	 * @param $post
3640
+	 * @return void
3641
+	 * @throws DomainException
3642
+	 * @throws EE_Error
3643
+	 * @throws InvalidArgumentException
3644
+	 * @throws InvalidDataTypeException
3645
+	 * @throws InvalidInterfaceException
3646
+	 * @throws ReflectionException
3647
+	 */
3648
+	public function attendee_registrations_meta_box($post)
3649
+	{
3650
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3651
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3652
+		$template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3653
+		EEH_Template::display_template($template, $this->_template_args);
3654
+	}
3655
+
3656
+
3657
+	/**
3658
+	 * add in the form fields for the attendee edit
3659
+	 *
3660
+	 * @param WP_Post $post wp post object
3661
+	 * @return void echos html for new form.
3662
+	 * @throws DomainException
3663
+	 */
3664
+	public function after_title_form_fields($post)
3665
+	{
3666
+		if ($post->post_type === 'espresso_attendees') {
3667
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3668
+			$template_args['attendee'] = $this->_cpt_model_obj;
3669
+			EEH_Template::display_template($template, $template_args);
3670
+		}
3671
+	}
3672
+
3673
+
3674
+	/**
3675
+	 * _trash_or_restore_attendee
3676
+	 *
3677
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3678
+	 * @return void
3679
+	 * @throws EE_Error
3680
+	 * @throws InvalidArgumentException
3681
+	 * @throws InvalidDataTypeException
3682
+	 * @throws InvalidInterfaceException
3683
+	 */
3684
+	protected function _trash_or_restore_attendees($trash = true)
3685
+	{
3686
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3687
+		$status = $trash ? 'trash' : 'publish';
3688
+		// Checkboxes
3689
+		if ($this->request->requestParamIsSet('checkbox')) {
3690
+			$ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3691
+			// if array has more than one element than success message should be plural
3692
+			$success = count($ATT_IDs) > 1 ? 2 : 1;
3693
+			// cycle thru checkboxes
3694
+			foreach ($ATT_IDs as $ATT_ID) {
3695
+				$updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3696
+				if (! $updated) {
3697
+					$success = 0;
3698
+				}
3699
+			}
3700
+		} else {
3701
+			// grab single id and delete
3702
+			$ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3703
+			// update attendee
3704
+			$success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3705
+		}
3706
+		$what        = $success > 1
3707
+			? esc_html__('Contacts', 'event_espresso')
3708
+			: esc_html__('Contact', 'event_espresso');
3709
+		$action_desc = $trash
3710
+			? esc_html__('moved to the trash', 'event_espresso')
3711
+			: esc_html__('restored', 'event_espresso');
3712
+		$this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3713
+	}
3714 3714
 }
Please login to merge, or discard this patch.
Spacing   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
      */
95 95
     protected function getRegistrationModel()
96 96
     {
97
-        if (! $this->registration_model instanceof EEM_Registration) {
97
+        if ( ! $this->registration_model instanceof EEM_Registration) {
98 98
             $this->registration_model = $this->loader->getShared('EEM_Registration');
99 99
         }
100 100
         return $this->registration_model;
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
      */
111 111
     protected function getAttendeeModel()
112 112
     {
113
-        if (! $this->attendee_model instanceof EEM_Attendee) {
113
+        if ( ! $this->attendee_model instanceof EEM_Attendee) {
114 114
             $this->attendee_model = $this->loader->getShared('EEM_Attendee');
115 115
         }
116 116
         return $this->attendee_model;
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
      */
127 127
     protected function getEventModel()
128 128
     {
129
-        if (! $this->event_model instanceof EEM_Event) {
129
+        if ( ! $this->event_model instanceof EEM_Event) {
130 130
             $this->event_model = $this->loader->getShared('EEM_Event');
131 131
         }
132 132
         return $this->event_model;
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
      */
143 143
     protected function getStatusModel()
144 144
     {
145
-        if (! $this->status_model instanceof EEM_Status) {
145
+        if ( ! $this->status_model instanceof EEM_Status) {
146 146
             $this->status_model = $this->loader->getShared('EEM_Status');
147 147
         }
148 148
         return $this->status_model;
@@ -761,7 +761,7 @@  discard block
 block discarded – undo
761 761
         // style
762 762
         wp_register_style(
763 763
             'espresso_reg',
764
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
764
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
765 765
             ['ee-admin-css'],
766 766
             EVENT_ESPRESSO_VERSION
767 767
         );
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
         // script
770 770
         wp_register_script(
771 771
             'espresso_reg',
772
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
772
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
773 773
             ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774 774
             EVENT_ESPRESSO_VERSION,
775 775
             true
@@ -793,7 +793,7 @@  discard block
 block discarded – undo
793 793
             'att_publish_text' => sprintf(
794 794
             /* translators: The date and time */
795 795
                 wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
796
+                '<b>'.$this->_cpt_model_obj->get_datetime('ATT_created').'</b>'
797 797
             ),
798 798
         ];
799 799
         wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
@@ -824,7 +824,7 @@  discard block
 block discarded – undo
824 824
         wp_dequeue_style('espresso_reg');
825 825
         wp_register_style(
826 826
             'espresso_att',
827
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
827
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
828 828
             ['ee-admin-css'],
829 829
             EVENT_ESPRESSO_VERSION
830 830
         );
@@ -836,7 +836,7 @@  discard block
 block discarded – undo
836 836
     {
837 837
         wp_register_script(
838 838
             'ee-spco-for-admin',
839
-            REG_ASSETS_URL . 'spco_for_admin.js',
839
+            REG_ASSETS_URL.'spco_for_admin.js',
840 840
             ['underscore', 'jquery'],
841 841
             EVENT_ESPRESSO_VERSION,
842 842
             true
@@ -884,7 +884,7 @@  discard block
 block discarded – undo
884 884
             'no_approve_registrations' => 'not_approved_registration',
885 885
             'cancel_registrations'     => 'cancelled_registration',
886 886
         ];
887
-        $can_send    = EE_Registry::instance()->CAP->current_user_can(
887
+        $can_send = EE_Registry::instance()->CAP->current_user_can(
888 888
             'ee_send_message',
889 889
             'batch_send_messages'
890 890
         );
@@ -989,7 +989,7 @@  discard block
 block discarded – undo
989 989
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
990 990
                 ],
991 991
             ];
992
-            $this->_views['trash']      = [
992
+            $this->_views['trash'] = [
993 993
                 'slug'        => 'trash',
994 994
                 'label'       => esc_html__('Trash', 'event_espresso'),
995 995
                 'count'       => 0,
@@ -1089,7 +1089,7 @@  discard block
 block discarded – undo
1089 1089
         }
1090 1090
         $sc_items = [
1091 1091
             'approved_status'   => [
1092
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1092
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_approved,
1093 1093
                 'desc'  => EEH_Template::pretty_status(
1094 1094
                     EEM_Registration::status_id_approved,
1095 1095
                     false,
@@ -1097,7 +1097,7 @@  discard block
 block discarded – undo
1097 1097
                 ),
1098 1098
             ],
1099 1099
             'pending_status'    => [
1100
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1100
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_pending_payment,
1101 1101
                 'desc'  => EEH_Template::pretty_status(
1102 1102
                     EEM_Registration::status_id_pending_payment,
1103 1103
                     false,
@@ -1105,7 +1105,7 @@  discard block
 block discarded – undo
1105 1105
                 ),
1106 1106
             ],
1107 1107
             'wait_list'         => [
1108
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1108
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_wait_list,
1109 1109
                 'desc'  => EEH_Template::pretty_status(
1110 1110
                     EEM_Registration::status_id_wait_list,
1111 1111
                     false,
@@ -1113,7 +1113,7 @@  discard block
 block discarded – undo
1113 1113
                 ),
1114 1114
             ],
1115 1115
             'incomplete_status' => [
1116
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1116
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_incomplete,
1117 1117
                 'desc'  => EEH_Template::pretty_status(
1118 1118
                     EEM_Registration::status_id_incomplete,
1119 1119
                     false,
@@ -1121,7 +1121,7 @@  discard block
 block discarded – undo
1121 1121
                 ),
1122 1122
             ],
1123 1123
             'not_approved'      => [
1124
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1124
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_not_approved,
1125 1125
                 'desc'  => EEH_Template::pretty_status(
1126 1126
                     EEM_Registration::status_id_not_approved,
1127 1127
                     false,
@@ -1129,7 +1129,7 @@  discard block
 block discarded – undo
1129 1129
                 ),
1130 1130
             ],
1131 1131
             'declined_status'   => [
1132
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1132
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_declined,
1133 1133
                 'desc'  => EEH_Template::pretty_status(
1134 1134
                     EEM_Registration::status_id_declined,
1135 1135
                     false,
@@ -1137,7 +1137,7 @@  discard block
 block discarded – undo
1137 1137
                 ),
1138 1138
             ],
1139 1139
             'cancelled_status'  => [
1140
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1140
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_cancelled,
1141 1141
                 'desc'  => EEH_Template::pretty_status(
1142 1142
                     EEM_Registration::status_id_cancelled,
1143 1143
                     false,
@@ -1174,8 +1174,8 @@  discard block
 block discarded – undo
1174 1174
             $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1175 1175
             $header_text = $filter_header_decorator->getHeaderText($header_text);
1176 1176
         }
1177
-        $this->_template_args['before_list_table']  = $header_text;
1178
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1177
+        $this->_template_args['before_list_table'] = $header_text;
1178
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_registration_legend_items());
1179 1179
         $this->display_admin_list_table_page_with_no_sidebar();
1180 1180
     }
1181 1181
 
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
                 $EVT_ID
1198 1198
             )
1199 1199
         ) {
1200
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1200
+            $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1201 1201
                 'new_registration',
1202 1202
                 'add-registrant',
1203 1203
                 ['event_id' => $EVT_ID],
@@ -1355,7 +1355,7 @@  discard block
 block discarded – undo
1355 1355
                 ],
1356 1356
                 REG_ADMIN_URL
1357 1357
             );
1358
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1358
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1359 1359
                 [
1360 1360
                     'action' => 'default',
1361 1361
                     'EVT_ID' => $event_id,
@@ -1363,7 +1363,7 @@  discard block
 block discarded – undo
1363 1363
                 ],
1364 1364
                 admin_url('admin.php')
1365 1365
             );
1366
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1366
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1367 1367
                 [
1368 1368
                     'page'   => 'espresso_events',
1369 1369
                     'action' => 'edit',
@@ -1372,12 +1372,12 @@  discard block
 block discarded – undo
1372 1372
                 admin_url('admin.php')
1373 1373
             );
1374 1374
             // next and previous links
1375
-            $next_reg                                      = $this->_registration->next(
1375
+            $next_reg = $this->_registration->next(
1376 1376
                 null,
1377 1377
                 [],
1378 1378
                 'REG_ID'
1379 1379
             );
1380
-            $this->_template_args['next_registration']     = $next_reg
1380
+            $this->_template_args['next_registration'] = $next_reg
1381 1381
                 ? $this->_next_link(
1382 1382
                     EE_Admin_Page::add_query_args_and_nonce(
1383 1383
                         [
@@ -1389,7 +1389,7 @@  discard block
 block discarded – undo
1389 1389
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1390 1390
                 )
1391 1391
                 : '';
1392
-            $previous_reg                                  = $this->_registration->previous(
1392
+            $previous_reg = $this->_registration->previous(
1393 1393
                 null,
1394 1394
                 [],
1395 1395
                 'REG_ID'
@@ -1407,7 +1407,7 @@  discard block
 block discarded – undo
1407 1407
                 )
1408 1408
                 : '';
1409 1409
             // grab header
1410
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1410
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1411 1411
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1412 1412
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1413 1413
                 $template_path,
@@ -1444,7 +1444,7 @@  discard block
 block discarded – undo
1444 1444
         );
1445 1445
         $this->addMetaBox(
1446 1446
             'edit-reg-details-mbox',
1447
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1447
+            '<span>'.esc_html__('Registration Details', 'event_espresso')
1448 1448
             . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1449 1449
             [$this, '_reg_details_meta_box'],
1450 1450
             $this->_wp_page_slug
@@ -1548,7 +1548,7 @@  discard block
 block discarded – undo
1548 1548
                 $this->_registration->ID()
1549 1549
             )
1550 1550
         ) {
1551
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1551
+            $reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1552 1552
                 $this->_get_reg_statuses(),
1553 1553
                 [
1554 1554
                     'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
@@ -1565,7 +1565,7 @@  discard block
 block discarded – undo
1565 1565
                     ),
1566 1566
                 ]
1567 1567
             );
1568
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1568
+            $reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1569 1569
                 [
1570 1570
                     'html_class'      => 'button--primary',
1571 1571
                     'html_label_text' => '&nbsp;',
@@ -1590,7 +1590,7 @@  discard block
 block discarded – undo
1590 1590
     protected function _get_reg_statuses()
1591 1591
     {
1592 1592
         $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1593
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1593
+        unset($reg_status_array[EEM_Registration::status_id_incomplete]);
1594 1594
         // get current reg status
1595 1595
         $current_status = $this->_registration->status_ID();
1596 1596
         // is registration for free event? This will determine whether to display the pending payment option
@@ -1598,7 +1598,7 @@  discard block
 block discarded – undo
1598 1598
             $current_status !== EEM_Registration::status_id_pending_payment
1599 1599
             && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1600 1600
         ) {
1601
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1601
+            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1602 1602
         }
1603 1603
         return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1604 1604
     }
@@ -1689,7 +1689,7 @@  discard block
 block discarded – undo
1689 1689
         $success = false;
1690 1690
         // typecast $REG_IDs
1691 1691
         $REG_IDs = (array) $REG_IDs;
1692
-        if (! empty($REG_IDs)) {
1692
+        if ( ! empty($REG_IDs)) {
1693 1693
             $success = true;
1694 1694
             // set default status if none is passed
1695 1695
             $status         = $status ?: EEM_Registration::status_id_pending_payment;
@@ -1849,7 +1849,7 @@  discard block
 block discarded – undo
1849 1849
             $action,
1850 1850
             $notify
1851 1851
         );
1852
-        $method = $action . '_registration';
1852
+        $method = $action.'_registration';
1853 1853
         if (method_exists($this, $method)) {
1854 1854
             $this->$method($notify);
1855 1855
         }
@@ -1999,7 +1999,7 @@  discard block
 block discarded – undo
1999 1999
         $filters        = new EE_Line_Item_Filter_Collection();
2000 2000
         $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001 2001
         $filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2002
+        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2003 2003
             $filters,
2004 2004
             $transaction->total_line_item()
2005 2005
         );
@@ -2012,7 +2012,7 @@  discard block
 block discarded – undo
2012 2012
             $filtered_line_item_tree,
2013 2013
             ['EE_Registration' => $this->_registration]
2014 2014
         );
2015
-        $attendee                                = $this->_registration->attendee();
2015
+        $attendee = $this->_registration->attendee();
2016 2016
         if (
2017 2017
             EE_Registry::instance()->CAP->current_user_can(
2018 2018
                 'ee_read_transaction',
@@ -2094,7 +2094,7 @@  discard block
 block discarded – undo
2094 2094
                 'Payment method response',
2095 2095
                 'event_espresso'
2096 2096
             );
2097
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2097
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2098 2098
         }
2099 2099
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100 2100
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2125,7 +2125,7 @@  discard block
 block discarded – undo
2125 2125
         $this->_template_args['REG_ID'] = $this->_registration->ID();
2126 2126
         $this->_template_args['event_id'] = $this->_registration->event_ID();
2127 2127
 
2128
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2128
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2129 2129
         EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130 2130
     }
2131 2131
 
@@ -2164,7 +2164,7 @@  discard block
 block discarded – undo
2164 2164
 
2165 2165
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166 2166
             $this->_template_args['REG_ID'] = $this->_registration->ID();
2167
-            $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2167
+            $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2168 2168
             EEH_Template::display_template($template_path, $this->_template_args);
2169 2169
         }
2170 2170
     }
@@ -2180,7 +2180,7 @@  discard block
 block discarded – undo
2180 2180
     public function form_before_question_group($output)
2181 2181
     {
2182 2182
         EE_Error::doing_it_wrong(
2183
-            __CLASS__ . '::' . __FUNCTION__,
2183
+            __CLASS__.'::'.__FUNCTION__,
2184 2184
             esc_html__(
2185 2185
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2186 2186
                 'event_espresso'
@@ -2204,7 +2204,7 @@  discard block
 block discarded – undo
2204 2204
     public function form_after_question_group($output)
2205 2205
     {
2206 2206
         EE_Error::doing_it_wrong(
2207
-            __CLASS__ . '::' . __FUNCTION__,
2207
+            __CLASS__.'::'.__FUNCTION__,
2208 2208
             esc_html__(
2209 2209
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2210 2210
                 'event_espresso'
@@ -2241,7 +2241,7 @@  discard block
 block discarded – undo
2241 2241
     public function form_form_field_label_wrap($label)
2242 2242
     {
2243 2243
         EE_Error::doing_it_wrong(
2244
-            __CLASS__ . '::' . __FUNCTION__,
2244
+            __CLASS__.'::'.__FUNCTION__,
2245 2245
             esc_html__(
2246 2246
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2247 2247
                 'event_espresso'
@@ -2251,7 +2251,7 @@  discard block
 block discarded – undo
2251 2251
         return '
2252 2252
 			<tr>
2253 2253
 				<th>
2254
-					' . $label . '
2254
+					' . $label.'
2255 2255
 				</th>';
2256 2256
     }
2257 2257
 
@@ -2266,7 +2266,7 @@  discard block
 block discarded – undo
2266 2266
     public function form_form_field_input__wrap($input)
2267 2267
     {
2268 2268
         EE_Error::doing_it_wrong(
2269
-            __CLASS__ . '::' . __FUNCTION__,
2269
+            __CLASS__.'::'.__FUNCTION__,
2270 2270
             esc_html__(
2271 2271
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2272 2272
                 'event_espresso'
@@ -2275,7 +2275,7 @@  discard block
 block discarded – undo
2275 2275
         );
2276 2276
         return '
2277 2277
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2278
-					' . $input . '
2278
+					' . $input.'
2279 2279
 				</td>
2280 2280
 			</tr>';
2281 2281
     }
@@ -2324,8 +2324,8 @@  discard block
 block discarded – undo
2324 2324
      */
2325 2325
     protected function _get_reg_custom_questions_form($REG_ID)
2326 2326
     {
2327
-        if (! $this->_reg_custom_questions_form) {
2328
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2327
+        if ( ! $this->_reg_custom_questions_form) {
2328
+            require_once(REG_ADMIN.'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2329 2329
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2330 2330
                 $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2331 2331
             );
@@ -2348,7 +2348,7 @@  discard block
 block discarded – undo
2348 2348
      */
2349 2349
     private function _save_reg_custom_questions_form($REG_ID = 0)
2350 2350
     {
2351
-        if (! $REG_ID) {
2351
+        if ( ! $REG_ID) {
2352 2352
             EE_Error::add_error(
2353 2353
                 esc_html__(
2354 2354
                     'An error occurred. No registration ID was received.',
@@ -2365,7 +2365,7 @@  discard block
 block discarded – undo
2365 2365
         if ($form->is_valid()) {
2366 2366
             foreach ($form->subforms() as $question_group_form) {
2367 2367
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2368
-                    $where_conditions    = [
2368
+                    $where_conditions = [
2369 2369
                         'QST_ID' => $question_id,
2370 2370
                         'REG_ID' => $REG_ID,
2371 2371
                     ];
@@ -2406,7 +2406,7 @@  discard block
 block discarded – undo
2406 2406
         $REG = $this->getRegistrationModel();
2407 2407
         // get all other registrations on this transaction, and cache
2408 2408
         // the attendees for them so we don't have to run another query using force_join
2409
-        $registrations                           = $REG->get_all(
2409
+        $registrations = $REG->get_all(
2410 2410
             [
2411 2411
                 [
2412 2412
                     'TXN_ID' => $this->_registration->transaction_ID(),
@@ -2440,23 +2440,23 @@  discard block
 block discarded – undo
2440 2440
                 $attendee                                                      = $registration->attendee()
2441 2441
                     ? $registration->attendee()
2442 2442
                     : $this->getAttendeeModel()->create_default_object();
2443
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2444
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2445
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2446
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2447
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2448
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2443
+                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2444
+                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2445
+                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2446
+                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2447
+                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2448
+                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2449 2449
                     ', ',
2450 2450
                     $attendee->full_address_as_array()
2451 2451
                 );
2452
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2452
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2453 2453
                     [
2454 2454
                         'action' => 'edit_attendee',
2455 2455
                         'post'   => $attendee->ID(),
2456 2456
                     ],
2457 2457
                     REG_ADMIN_URL
2458 2458
                 );
2459
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2459
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] =
2460 2460
                     $registration->event_obj() instanceof EE_Event
2461 2461
                         ? $registration->event_obj()->name()
2462 2462
                         : '';
@@ -2464,7 +2464,7 @@  discard block
 block discarded – undo
2464 2464
             }
2465 2465
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2466 2466
         }
2467
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2467
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2468 2468
         EEH_Template::display_template($template_path, $this->_template_args);
2469 2469
     }
2470 2470
 
@@ -2490,11 +2490,11 @@  discard block
 block discarded – undo
2490 2490
         // now let's determine if this is not the primary registration.  If it isn't then we set the
2491 2491
         // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2492 2492
         // primary registration object (that way we know if we need to show create button or not)
2493
-        if (! $this->_registration->is_primary_registrant()) {
2493
+        if ( ! $this->_registration->is_primary_registrant()) {
2494 2494
             $primary_registration = $this->_registration->get_primary_registration();
2495 2495
             $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2496 2496
                 : null;
2497
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2497
+            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2498 2498
                 // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2499 2499
                 // custom attendee object so let's not worry about the primary reg.
2500 2500
                 $primary_registration = null;
@@ -2509,7 +2509,7 @@  discard block
 block discarded – undo
2509 2509
         $this->_template_args['phone']             = $attendee->phone();
2510 2510
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2511 2511
         // edit link
2512
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2512
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2513 2513
             [
2514 2514
                 'action' => 'edit_attendee',
2515 2515
                 'post'   => $attendee->ID(),
@@ -2519,7 +2519,7 @@  discard block
 block discarded – undo
2519 2519
         $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2520 2520
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2521 2521
         // create link
2522
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2522
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2523 2523
             ? EE_Admin_Page::add_query_args_and_nonce(
2524 2524
                 [
2525 2525
                     'action'  => 'duplicate_attendee',
@@ -2529,7 +2529,7 @@  discard block
 block discarded – undo
2529 2529
             ) : '';
2530 2530
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2531 2531
         $this->_template_args['att_check'] = $att_check;
2532
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2532
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2533 2533
         EEH_Template::display_template($template_path, $this->_template_args);
2534 2534
     }
2535 2535
 
@@ -2577,7 +2577,7 @@  discard block
 block discarded – undo
2577 2577
             /** @var EE_Registration $REG */
2578 2578
             $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2579 2579
             $payments = $REG->registration_payments();
2580
-            if (! empty($payments)) {
2580
+            if ( ! empty($payments)) {
2581 2581
                 $name           = $REG->attendee() instanceof EE_Attendee
2582 2582
                     ? $REG->attendee()->full_name()
2583 2583
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2641,17 +2641,17 @@  discard block
 block discarded – undo
2641 2641
         // Checkboxes
2642 2642
         $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2643 2643
 
2644
-        if (! empty($REG_IDs)) {
2644
+        if ( ! empty($REG_IDs)) {
2645 2645
             // if array has more than one element than success message should be plural
2646 2646
             $success = count($REG_IDs) > 1 ? 2 : 1;
2647 2647
             // cycle thru checkboxes
2648 2648
             foreach ($REG_IDs as $REG_ID) {
2649 2649
                 $REG = $REG_MDL->get_one_by_ID($REG_ID);
2650
-                if (! $REG instanceof EE_Registration) {
2650
+                if ( ! $REG instanceof EE_Registration) {
2651 2651
                     continue;
2652 2652
                 }
2653 2653
                 $deleted = $this->_delete_registration($REG);
2654
-                if (! $deleted) {
2654
+                if ( ! $deleted) {
2655 2655
                     $success = 0;
2656 2656
                 }
2657 2657
             }
@@ -2688,7 +2688,7 @@  discard block
 block discarded – undo
2688 2688
         // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2689 2689
         // registrations on the transaction that are NOT trashed.
2690 2690
         $TXN = $REG->get_first_related('Transaction');
2691
-        if (! $TXN instanceof EE_Transaction) {
2691
+        if ( ! $TXN instanceof EE_Transaction) {
2692 2692
             EE_Error::add_error(
2693 2693
                 sprintf(
2694 2694
                     esc_html__(
@@ -2706,11 +2706,11 @@  discard block
 block discarded – undo
2706 2706
         $REGS        = $TXN->get_many_related('Registration');
2707 2707
         $all_trashed = true;
2708 2708
         foreach ($REGS as $registration) {
2709
-            if (! $registration->get('REG_deleted')) {
2709
+            if ( ! $registration->get('REG_deleted')) {
2710 2710
                 $all_trashed = false;
2711 2711
             }
2712 2712
         }
2713
-        if (! $all_trashed) {
2713
+        if ( ! $all_trashed) {
2714 2714
             EE_Error::add_error(
2715 2715
                 esc_html__(
2716 2716
                     '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.',
@@ -2772,7 +2772,7 @@  discard block
 block discarded – undo
2772 2772
      */
2773 2773
     public function new_registration()
2774 2774
     {
2775
-        if (! $this->_set_reg_event()) {
2775
+        if ( ! $this->_set_reg_event()) {
2776 2776
             throw new EE_Error(
2777 2777
                 esc_html__(
2778 2778
                     'Unable to continue with registering because there is no Event ID in the request',
@@ -2804,7 +2804,7 @@  discard block
 block discarded – undo
2804 2804
                 ],
2805 2805
                 EVENTS_ADMIN_URL
2806 2806
             );
2807
-            $edit_event_lnk                     = '<a href="'
2807
+            $edit_event_lnk = '<a href="'
2808 2808
                                                   . $edit_event_url
2809 2809
                                                   . '" aria-label="'
2810 2810
                                                   . esc_attr__('Edit ', 'event_espresso')
@@ -2821,7 +2821,7 @@  discard block
 block discarded – undo
2821 2821
             $this->_return_json();
2822 2822
         }
2823 2823
         // grab header
2824
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2824
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2825 2825
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2826 2826
             $template_path,
2827 2827
             $this->_template_args,
@@ -2862,7 +2862,7 @@  discard block
 block discarded – undo
2862 2862
                 '</b>'
2863 2863
             );
2864 2864
             return '
2865
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2865
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2866 2866
 	<script >
2867 2867
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2868 2868
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2929,7 +2929,7 @@  discard block
 block discarded – undo
2929 2929
         // we come back to the process_registration_step route.
2930 2930
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2931 2931
         return EEH_Template::display_template(
2932
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2932
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
2933 2933
             $template_args,
2934 2934
             true
2935 2935
         );
@@ -2952,7 +2952,7 @@  discard block
 block discarded – undo
2952 2952
         }
2953 2953
 
2954 2954
         $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2955
-        if (! $EVT_ID) {
2955
+        if ( ! $EVT_ID) {
2956 2956
             return false;
2957 2957
         }
2958 2958
         $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
@@ -3022,7 +3022,7 @@  discard block
 block discarded – undo
3022 3022
                 }
3023 3023
                 break;
3024 3024
             case 'questions':
3025
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3025
+                if ( ! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3026 3026
                     add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3027 3027
                 }
3028 3028
                 // process registration
@@ -3033,7 +3033,7 @@  discard block
 block discarded – undo
3033 3033
                         $grand_total->save_this_and_descendants_to_txn();
3034 3034
                     }
3035 3035
                 }
3036
-                if (! $transaction instanceof EE_Transaction) {
3036
+                if ( ! $transaction instanceof EE_Transaction) {
3037 3037
                     $query_args = [
3038 3038
                         'action'                  => 'new_registration',
3039 3039
                         'processing_registration' => 2,
@@ -3055,7 +3055,7 @@  discard block
 block discarded – undo
3055 3055
                     return;
3056 3056
                 }
3057 3057
                 // maybe update status, and make sure to save transaction if not done already
3058
-                if (! $transaction->update_status_based_on_total_paid()) {
3058
+                if ( ! $transaction->update_status_based_on_total_paid()) {
3059 3059
                     $transaction->save();
3060 3060
                 }
3061 3061
                 EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
@@ -3137,7 +3137,7 @@  discard block
 block discarded – undo
3137 3137
     public function get_attendees($per_page, $count = false, $trash = false)
3138 3138
     {
3139 3139
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3140
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3140
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3141 3141
         $orderby = $this->request->getRequestParam('orderby');
3142 3142
         switch ($orderby) {
3143 3143
             case 'ATT_ID':
@@ -3160,7 +3160,7 @@  discard block
 block discarded – undo
3160 3160
         $_where       = [];
3161 3161
         $search_term  = $this->request->getRequestParam('s');
3162 3162
         if ($search_term) {
3163
-            $search_term  = '%' . $search_term . '%';
3163
+            $search_term  = '%'.$search_term.'%';
3164 3164
             $_where['OR'] = [
3165 3165
                 'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3166 3166
                 'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
@@ -3187,7 +3187,7 @@  discard block
 block discarded – undo
3187 3187
             'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3188 3188
             'limit'         => $limit,
3189 3189
         ];
3190
-        if (! $count) {
3190
+        if ( ! $count) {
3191 3191
             $query_args['order_by'] = [$orderby => $sort];
3192 3192
         }
3193 3193
         $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
@@ -3232,10 +3232,10 @@  discard block
 block discarded – undo
3232 3232
         $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3233 3233
             ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3234 3234
             : null;
3235
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3235
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3236 3236
             $return_url = $this->request->getRequestParam('return_url', '', DataType::URL);
3237 3237
             $filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3238
-            $report_params  = $this->$method_name_for_getting_query_params($filters);
3238
+            $report_params = $this->$method_name_for_getting_query_params($filters);
3239 3239
             $use_filters = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3240 3240
             wp_redirect(
3241 3241
                 EE_Admin_Page::add_query_args_and_nonce(
@@ -3261,8 +3261,8 @@  discard block
 block discarded – undo
3261 3261
             ];
3262 3262
             // Merge required request args, overriding any currently set
3263 3263
             $request_args = array_merge($request_args, $required_request_args);
3264
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3265
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3264
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3265
+                require_once(EE_CLASSES.'EE_Export.class.php');
3266 3266
                 $EE_Export = EE_Export::instance($request_args);
3267 3267
                 $EE_Export->export();
3268 3268
             }
@@ -3283,8 +3283,8 @@  discard block
 block discarded – undo
3283 3283
 
3284 3284
     public function _contact_list_export()
3285 3285
     {
3286
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3287
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3286
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3287
+            require_once(EE_CLASSES.'EE_Export.class.php');
3288 3288
             $EE_Export = EE_Export::instance($this->request->requestParams());
3289 3289
             $EE_Export->export_attendees();
3290 3290
         }
@@ -3293,7 +3293,7 @@  discard block
 block discarded – undo
3293 3293
 
3294 3294
     public function _contact_list_report()
3295 3295
     {
3296
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3296
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3297 3297
             wp_redirect(
3298 3298
                 EE_Admin_Page::add_query_args_and_nonce(
3299 3299
                     [
@@ -3305,8 +3305,8 @@  discard block
 block discarded – undo
3305 3305
                 )
3306 3306
             );
3307 3307
         } else {
3308
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3309
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3308
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3309
+                require_once(EE_CLASSES.'EE_Export.class.php');
3310 3310
                 $EE_Export = EE_Export::instance($this->request->requestParams());
3311 3311
                 $EE_Export->report_attendees();
3312 3312
             }
@@ -3333,7 +3333,7 @@  discard block
 block discarded – undo
3333 3333
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3334 3334
         $action = $this->request->getRequestParam('return', 'default');
3335 3335
         // verify we have necessary info
3336
-        if (! $REG_ID) {
3336
+        if ( ! $REG_ID) {
3337 3337
             EE_Error::add_error(
3338 3338
                 esc_html__(
3339 3339
                     'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
@@ -3348,7 +3348,7 @@  discard block
 block discarded – undo
3348 3348
         }
3349 3349
         // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3350 3350
         $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3351
-        if (! $registration instanceof EE_Registration) {
3351
+        if ( ! $registration instanceof EE_Registration) {
3352 3352
             throw new RuntimeException(
3353 3353
                 sprintf(
3354 3354
                     esc_html__(
@@ -3487,16 +3487,16 @@  discard block
 block discarded – undo
3487 3487
         $this->verify_cpt_object();
3488 3488
         remove_meta_box(
3489 3489
             'postexcerpt',
3490
-            $this->_cpt_routes[ $this->_req_action ],
3490
+            $this->_cpt_routes[$this->_req_action],
3491 3491
             'normal'
3492 3492
         );
3493
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3493
+        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal');
3494 3494
         if (post_type_supports('espresso_attendees', 'excerpt')) {
3495 3495
             $this->addMetaBox(
3496 3496
                 'postexcerpt',
3497 3497
                 esc_html__('Short Biography', 'event_espresso'),
3498 3498
                 'post_excerpt_meta_box',
3499
-                $this->_cpt_routes[ $this->_req_action ]
3499
+                $this->_cpt_routes[$this->_req_action]
3500 3500
             );
3501 3501
         }
3502 3502
         if (post_type_supports('espresso_attendees', 'comments')) {
@@ -3504,7 +3504,7 @@  discard block
 block discarded – undo
3504 3504
                 'commentsdiv',
3505 3505
                 esc_html__('Notes on the Contact', 'event_espresso'),
3506 3506
                 'post_comment_meta_box',
3507
-                $this->_cpt_routes[ $this->_req_action ],
3507
+                $this->_cpt_routes[$this->_req_action],
3508 3508
                 'normal',
3509 3509
                 'core'
3510 3510
             );
@@ -3513,7 +3513,7 @@  discard block
 block discarded – undo
3513 3513
             'attendee_contact_info',
3514 3514
             esc_html__('Contact Info', 'event_espresso'),
3515 3515
             [$this, 'attendee_contact_info'],
3516
-            $this->_cpt_routes[ $this->_req_action ],
3516
+            $this->_cpt_routes[$this->_req_action],
3517 3517
             'side',
3518 3518
             'core'
3519 3519
         );
@@ -3521,7 +3521,7 @@  discard block
 block discarded – undo
3521 3521
             'attendee_details_address',
3522 3522
             esc_html__('Address Details', 'event_espresso'),
3523 3523
             [$this, 'attendee_address_details'],
3524
-            $this->_cpt_routes[ $this->_req_action ],
3524
+            $this->_cpt_routes[$this->_req_action],
3525 3525
             'normal',
3526 3526
             'core'
3527 3527
         );
@@ -3529,7 +3529,7 @@  discard block
 block discarded – undo
3529 3529
             'attendee_registrations',
3530 3530
             esc_html__('Registrations for this Contact', 'event_espresso'),
3531 3531
             [$this, 'attendee_registrations_meta_box'],
3532
-            $this->_cpt_routes[ $this->_req_action ]
3532
+            $this->_cpt_routes[$this->_req_action]
3533 3533
         );
3534 3534
     }
3535 3535
 
@@ -3628,7 +3628,7 @@  discard block
 block discarded – undo
3628 3628
                 ]
3629 3629
             )
3630 3630
         );
3631
-        $template = REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3631
+        $template = REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3632 3632
         EEH_Template::display_template($template, $this->_template_args);
3633 3633
     }
3634 3634
 
@@ -3649,7 +3649,7 @@  discard block
 block discarded – undo
3649 3649
     {
3650 3650
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3651 3651
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3652
-        $template = REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3652
+        $template = REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3653 3653
         EEH_Template::display_template($template, $this->_template_args);
3654 3654
     }
3655 3655
 
@@ -3664,7 +3664,7 @@  discard block
 block discarded – undo
3664 3664
     public function after_title_form_fields($post)
3665 3665
     {
3666 3666
         if ($post->post_type === 'espresso_attendees') {
3667
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3667
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3668 3668
             $template_args['attendee'] = $this->_cpt_model_obj;
3669 3669
             EEH_Template::display_template($template, $template_args);
3670 3670
         }
@@ -3693,7 +3693,7 @@  discard block
 block discarded – undo
3693 3693
             // cycle thru checkboxes
3694 3694
             foreach ($ATT_IDs as $ATT_ID) {
3695 3695
                 $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3696
-                if (! $updated) {
3696
+                if ( ! $updated) {
3697 3697
                     $success = 0;
3698 3698
                 }
3699 3699
             }
Please login to merge, or discard this patch.
admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php 2 patches
Indentation   +386 added lines, -386 removed lines patch added patch discarded remove patch
@@ -12,412 +12,412 @@
 block discarded – undo
12 12
  */
13 13
 class EE_Attendee_Contact_List_Table extends EE_Admin_List_Table
14 14
 {
15
-    /**
16
-     * @var Registrations_Admin_Page
17
-     */
18
-    protected $_admin_page;
19
-
20
-
21
-    /**
22
-     * Initial setup of data (called by parent).
23
-     *
24
-     * @throws EE_Error
25
-     */
26
-    protected function _setup_data()
27
-    {
28
-        $this->_data = $this->_view !== 'trash'
29
-            ? $this->_admin_page->get_attendees($this->_per_page)
30
-            : $this->_admin_page->get_attendees($this->_per_page, false, true);
31
-
32
-        $this->_all_data_count = $this->_view !== 'trash'
33
-            ? $this->_admin_page->get_attendees($this->_per_page, true)
34
-            : $this->_admin_page->get_attendees($this->_per_page, true, true);
35
-    }
36
-
37
-
38
-    /**
39
-     * Initial setup of properties.
40
-     */
41
-    protected function _set_properties()
42
-    {
43
-        $this->_wp_list_args = [
44
-            'singular' => esc_html__('attendee', 'event_espresso'),
45
-            'plural'   => esc_html__('attendees', 'event_espresso'),
46
-            'ajax'     => true,
47
-            'screen'   => $this->_admin_page->get_current_screen()->id,
48
-        ];
49
-
50
-        $this->_columns = [
51
-            'cb'                 => '<input type="checkbox" />', // Render a checkbox instead of text
52
-            'id'                 => esc_html__('ID', 'event_espresso'),
53
-            'ATT_fname'          => esc_html__('First Name', 'event_espresso'),
54
-            'ATT_lname'          => esc_html__('Last Name', 'event_espresso'),
55
-            'ATT_email'          => esc_html__('Email Address', 'event_espresso'),
56
-            'Registration_Count' => esc_html__('# Reg', 'event_espresso'),
57
-            'ATT_phone'          => esc_html__('Phone', 'event_espresso'),
58
-            'ATT_address'        => esc_html__('Address', 'event_espresso'),
59
-            'ATT_city'           => esc_html__('City', 'event_espresso'),
60
-            'STA_ID'             => esc_html__('State/Province', 'event_espresso'),
61
-            'CNT_ISO'            => esc_html__('Country', 'event_espresso'),
62
-        ];
63
-
64
-        $this->_sortable_columns = [
65
-            'id'                 => ['id' => false],
66
-            'ATT_lname'          => ['ATT_lname' => true], // true means its already sorted
67
-            'ATT_fname'          => ['ATT_fname' => false],
68
-            'ATT_email'          => ['ATT_email' => false],
69
-            'Registration_Count' => ['Registration_Count' => false],
70
-            'ATT_city'           => ['ATT_city' => false],
71
-            'STA_ID'             => ['STA_ID' => false],
72
-            'CNT_ISO'            => ['CNT_ISO' => false],
73
-        ];
74
-
75
-        $this->_hidden_columns = [
76
-            'ATT_phone',
77
-            'ATT_address',
78
-            'ATT_city',
79
-            'STA_ID',
80
-            'CNT_ISO',
81
-        ];
82
-    }
83
-
84
-
85
-    /**
86
-     * Initial setup of filters
87
-     *
88
-     * @return array
89
-     */
90
-    protected function _get_table_filters(): array
91
-    {
92
-        return [];
93
-    }
94
-
95
-
96
-    /**
97
-     * Initial setup of counts for views
98
-     *
99
-     * @throws InvalidArgumentException
100
-     * @throws InvalidDataTypeException
101
-     * @throws InvalidInterfaceException
102
-     * @throws EE_Error
103
-     * @throws EE_Error
104
-     */
105
-    protected function _add_view_counts()
106
-    {
107
-        $this->_views['in_use']['count'] = $this->_admin_page->get_attendees($this->_per_page, true);
108
-        if (
109
-            EE_Registry::instance()->CAP->current_user_can(
110
-                'ee_delete_contacts',
111
-                'espresso_registrations_delete_registration'
112
-            )
113
-        ) {
114
-            $this->_views['trash']['count'] = $this->_admin_page->get_attendees($this->_per_page, true, true);
115
-        }
116
-    }
117
-
118
-
119
-    /**
120
-     * Get count of attendees.
121
-     *
122
-     * @return int
123
-     * @throws EE_Error
124
-     * @throws InvalidArgumentException
125
-     * @throws InvalidDataTypeException
126
-     * @throws InvalidInterfaceException
127
-     * @throws ReflectionException
128
-     */
129
-    protected function _get_attendees_count(): int
130
-    {
131
-        return EEM_Attendee::instance()->count();
132
-    }
133
-
134
-
135
-    /**
136
-     * Checkbox column
137
-     *
138
-     * @param EE_Attendee $item Unable to typehint this method because overrides parent.
139
-     * @return string
140
-     * @throws EE_Error
141
-     * @throws ReflectionException
142
-     */
143
-    public function column_cb($item): string
144
-    {
145
-        if (! $item instanceof EE_Attendee) {
146
-            return '';
147
-        }
148
-        return sprintf(
149
-            '<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />',
150
-            $item->ID()
151
-        );
152
-    }
153
-
154
-
155
-    /**
156
-     * @param EE_Attendee|null $attendee
157
-     * @return string
158
-     * @throws EE_Error
159
-     * @throws ReflectionException
160
-     */
161
-    public function column_id(?EE_Attendee $attendee): string
162
-    {
163
-        $content = '
15
+	/**
16
+	 * @var Registrations_Admin_Page
17
+	 */
18
+	protected $_admin_page;
19
+
20
+
21
+	/**
22
+	 * Initial setup of data (called by parent).
23
+	 *
24
+	 * @throws EE_Error
25
+	 */
26
+	protected function _setup_data()
27
+	{
28
+		$this->_data = $this->_view !== 'trash'
29
+			? $this->_admin_page->get_attendees($this->_per_page)
30
+			: $this->_admin_page->get_attendees($this->_per_page, false, true);
31
+
32
+		$this->_all_data_count = $this->_view !== 'trash'
33
+			? $this->_admin_page->get_attendees($this->_per_page, true)
34
+			: $this->_admin_page->get_attendees($this->_per_page, true, true);
35
+	}
36
+
37
+
38
+	/**
39
+	 * Initial setup of properties.
40
+	 */
41
+	protected function _set_properties()
42
+	{
43
+		$this->_wp_list_args = [
44
+			'singular' => esc_html__('attendee', 'event_espresso'),
45
+			'plural'   => esc_html__('attendees', 'event_espresso'),
46
+			'ajax'     => true,
47
+			'screen'   => $this->_admin_page->get_current_screen()->id,
48
+		];
49
+
50
+		$this->_columns = [
51
+			'cb'                 => '<input type="checkbox" />', // Render a checkbox instead of text
52
+			'id'                 => esc_html__('ID', 'event_espresso'),
53
+			'ATT_fname'          => esc_html__('First Name', 'event_espresso'),
54
+			'ATT_lname'          => esc_html__('Last Name', 'event_espresso'),
55
+			'ATT_email'          => esc_html__('Email Address', 'event_espresso'),
56
+			'Registration_Count' => esc_html__('# Reg', 'event_espresso'),
57
+			'ATT_phone'          => esc_html__('Phone', 'event_espresso'),
58
+			'ATT_address'        => esc_html__('Address', 'event_espresso'),
59
+			'ATT_city'           => esc_html__('City', 'event_espresso'),
60
+			'STA_ID'             => esc_html__('State/Province', 'event_espresso'),
61
+			'CNT_ISO'            => esc_html__('Country', 'event_espresso'),
62
+		];
63
+
64
+		$this->_sortable_columns = [
65
+			'id'                 => ['id' => false],
66
+			'ATT_lname'          => ['ATT_lname' => true], // true means its already sorted
67
+			'ATT_fname'          => ['ATT_fname' => false],
68
+			'ATT_email'          => ['ATT_email' => false],
69
+			'Registration_Count' => ['Registration_Count' => false],
70
+			'ATT_city'           => ['ATT_city' => false],
71
+			'STA_ID'             => ['STA_ID' => false],
72
+			'CNT_ISO'            => ['CNT_ISO' => false],
73
+		];
74
+
75
+		$this->_hidden_columns = [
76
+			'ATT_phone',
77
+			'ATT_address',
78
+			'ATT_city',
79
+			'STA_ID',
80
+			'CNT_ISO',
81
+		];
82
+	}
83
+
84
+
85
+	/**
86
+	 * Initial setup of filters
87
+	 *
88
+	 * @return array
89
+	 */
90
+	protected function _get_table_filters(): array
91
+	{
92
+		return [];
93
+	}
94
+
95
+
96
+	/**
97
+	 * Initial setup of counts for views
98
+	 *
99
+	 * @throws InvalidArgumentException
100
+	 * @throws InvalidDataTypeException
101
+	 * @throws InvalidInterfaceException
102
+	 * @throws EE_Error
103
+	 * @throws EE_Error
104
+	 */
105
+	protected function _add_view_counts()
106
+	{
107
+		$this->_views['in_use']['count'] = $this->_admin_page->get_attendees($this->_per_page, true);
108
+		if (
109
+			EE_Registry::instance()->CAP->current_user_can(
110
+				'ee_delete_contacts',
111
+				'espresso_registrations_delete_registration'
112
+			)
113
+		) {
114
+			$this->_views['trash']['count'] = $this->_admin_page->get_attendees($this->_per_page, true, true);
115
+		}
116
+	}
117
+
118
+
119
+	/**
120
+	 * Get count of attendees.
121
+	 *
122
+	 * @return int
123
+	 * @throws EE_Error
124
+	 * @throws InvalidArgumentException
125
+	 * @throws InvalidDataTypeException
126
+	 * @throws InvalidInterfaceException
127
+	 * @throws ReflectionException
128
+	 */
129
+	protected function _get_attendees_count(): int
130
+	{
131
+		return EEM_Attendee::instance()->count();
132
+	}
133
+
134
+
135
+	/**
136
+	 * Checkbox column
137
+	 *
138
+	 * @param EE_Attendee $item Unable to typehint this method because overrides parent.
139
+	 * @return string
140
+	 * @throws EE_Error
141
+	 * @throws ReflectionException
142
+	 */
143
+	public function column_cb($item): string
144
+	{
145
+		if (! $item instanceof EE_Attendee) {
146
+			return '';
147
+		}
148
+		return sprintf(
149
+			'<input type="checkbox" name="checkbox[%1$s]" value="%1$s" />',
150
+			$item->ID()
151
+		);
152
+	}
153
+
154
+
155
+	/**
156
+	 * @param EE_Attendee|null $attendee
157
+	 * @return string
158
+	 * @throws EE_Error
159
+	 * @throws ReflectionException
160
+	 */
161
+	public function column_id(?EE_Attendee $attendee): string
162
+	{
163
+		$content = '
164 164
             <span class="ee-entity-id">' . $attendee->ID() . '</span>
165 165
             <span class="show-on-mobile-view-only">
166 166
                 ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()) . '
167 167
             </span>';
168
-        return $this->columnContent('id', $content, 'end');
169
-    }
170
-
171
-
172
-    /**
173
-     * ATT_lname column
174
-     *
175
-     * @param EE_Attendee $attendee
176
-     * @return string
177
-     * @throws EE_Error
178
-     * @throws ReflectionException
179
-     */
180
-    public function column_ATT_lname(EE_Attendee $attendee): string
181
-    {
182
-        // edit attendee link
183
-        $content = $this->editAttendeeLink($attendee->ID(), $attendee->lname());
184
-        return $this->columnContent('ATT_lname', $content);
185
-    }
186
-
187
-
188
-    /**
189
-     * @param int    $ID
190
-     * @param string $attendee_name
191
-     * @return string
192
-     * @since   $VID:$
193
-     */
194
-    private function editAttendeeLink(int $ID, string $attendee_name): string
195
-    {
196
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
197
-            [
198
-                'action' => 'edit_attendee',
199
-                'post'   => $ID,
200
-            ],
201
-            REG_ADMIN_URL
202
-        );
203
-        return EE_Registry::instance()->CAP->current_user_can(
204
-            'ee_edit_contacts',
205
-            'espresso_registrations_edit_attendee'
206
-        )
207
-            ? '
168
+		return $this->columnContent('id', $content, 'end');
169
+	}
170
+
171
+
172
+	/**
173
+	 * ATT_lname column
174
+	 *
175
+	 * @param EE_Attendee $attendee
176
+	 * @return string
177
+	 * @throws EE_Error
178
+	 * @throws ReflectionException
179
+	 */
180
+	public function column_ATT_lname(EE_Attendee $attendee): string
181
+	{
182
+		// edit attendee link
183
+		$content = $this->editAttendeeLink($attendee->ID(), $attendee->lname());
184
+		return $this->columnContent('ATT_lname', $content);
185
+	}
186
+
187
+
188
+	/**
189
+	 * @param int    $ID
190
+	 * @param string $attendee_name
191
+	 * @return string
192
+	 * @since   $VID:$
193
+	 */
194
+	private function editAttendeeLink(int $ID, string $attendee_name): string
195
+	{
196
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
197
+			[
198
+				'action' => 'edit_attendee',
199
+				'post'   => $ID,
200
+			],
201
+			REG_ADMIN_URL
202
+		);
203
+		return EE_Registry::instance()->CAP->current_user_can(
204
+			'ee_edit_contacts',
205
+			'espresso_registrations_edit_attendee'
206
+		)
207
+			? '
208 208
             <a  href="' . $edit_lnk_url . '"
209 209
                 class="ee-aria-tooltip"
210 210
                 aria-label="' . esc_attr__('Edit Contact', 'event_espresso') . '"
211 211
             >
212 212
                 ' . $attendee_name . '
213 213
             </a>'
214
-            : $attendee_name;
215
-    }
216
-
217
-
218
-    /**
219
-     * ATT_fname column
220
-     *
221
-     * @param EE_Attendee $attendee
222
-     * @return string
223
-     * @throws InvalidArgumentException
224
-     * @throws InvalidDataTypeException
225
-     * @throws InvalidInterfaceException
226
-     * @throws EE_Error
227
-     * @throws ReflectionException
228
-     * @throws ReflectionException
229
-     * @throws ReflectionException
230
-     * @throws ReflectionException
231
-     */
232
-    public function column_ATT_fname(EE_Attendee $attendee): string
233
-    {
234
-        // Build row actions
235
-        $actions = [];
236
-        // edit attendee link
237
-        if (
238
-            EE_Registry::instance()->CAP->current_user_can(
239
-                'ee_edit_contacts',
240
-                'espresso_registrations_edit_attendee'
241
-            )
242
-        ) {
243
-            $actions['edit'] = $this->editAttendeeLink(
244
-                $attendee->ID(),
245
-                esc_html__('Edit Contact', 'event_espresso')
246
-            );
247
-        }
248
-
249
-        if ($this->_view === 'in_use') {
250
-            // trash attendee link
251
-            if (
252
-                EE_Registry::instance()->CAP->current_user_can(
253
-                    'ee_delete_contacts',
254
-                    'espresso_registrations_trash_attendees'
255
-                )
256
-            ) {
257
-                $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
258
-                    [
259
-                        'action' => 'trash_attendee',
260
-                        'ATT_ID' => $attendee->ID(),
261
-                    ],
262
-                    REG_ADMIN_URL
263
-                );
264
-                $actions['trash'] = '
214
+			: $attendee_name;
215
+	}
216
+
217
+
218
+	/**
219
+	 * ATT_fname column
220
+	 *
221
+	 * @param EE_Attendee $attendee
222
+	 * @return string
223
+	 * @throws InvalidArgumentException
224
+	 * @throws InvalidDataTypeException
225
+	 * @throws InvalidInterfaceException
226
+	 * @throws EE_Error
227
+	 * @throws ReflectionException
228
+	 * @throws ReflectionException
229
+	 * @throws ReflectionException
230
+	 * @throws ReflectionException
231
+	 */
232
+	public function column_ATT_fname(EE_Attendee $attendee): string
233
+	{
234
+		// Build row actions
235
+		$actions = [];
236
+		// edit attendee link
237
+		if (
238
+			EE_Registry::instance()->CAP->current_user_can(
239
+				'ee_edit_contacts',
240
+				'espresso_registrations_edit_attendee'
241
+			)
242
+		) {
243
+			$actions['edit'] = $this->editAttendeeLink(
244
+				$attendee->ID(),
245
+				esc_html__('Edit Contact', 'event_espresso')
246
+			);
247
+		}
248
+
249
+		if ($this->_view === 'in_use') {
250
+			// trash attendee link
251
+			if (
252
+				EE_Registry::instance()->CAP->current_user_can(
253
+					'ee_delete_contacts',
254
+					'espresso_registrations_trash_attendees'
255
+				)
256
+			) {
257
+				$trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
258
+					[
259
+						'action' => 'trash_attendee',
260
+						'ATT_ID' => $attendee->ID(),
261
+					],
262
+					REG_ADMIN_URL
263
+				);
264
+				$actions['trash'] = '
265 265
                     <a  href="' . $trash_lnk_url . '"
266 266
                         class="ee-aria-tooltip"
267 267
                         aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso') . '"
268 268
                     >
269 269
                         ' . esc_html__('Trash', 'event_espresso') . '
270 270
                     </a>';
271
-            }
272
-        } else {
273
-            if (
274
-                EE_Registry::instance()->CAP->current_user_can(
275
-                    'ee_delete_contacts',
276
-                    'espresso_registrations_restore_attendees'
277
-                )
278
-            ) {
279
-                // restore attendee link
280
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
281
-                    [
282
-                        'action' => 'restore_attendees',
283
-                        'ATT_ID' => $attendee->ID(),
284
-                    ],
285
-                    REG_ADMIN_URL
286
-                );
287
-                $actions['restore'] = '
271
+			}
272
+		} else {
273
+			if (
274
+				EE_Registry::instance()->CAP->current_user_can(
275
+					'ee_delete_contacts',
276
+					'espresso_registrations_restore_attendees'
277
+				)
278
+			) {
279
+				// restore attendee link
280
+				$restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
281
+					[
282
+						'action' => 'restore_attendees',
283
+						'ATT_ID' => $attendee->ID(),
284
+					],
285
+					REG_ADMIN_URL
286
+				);
287
+				$actions['restore'] = '
288 288
                     <a  href="' . $restore_lnk_url . '"
289 289
                         class="ee-aria-tooltip"
290 290
                         aria-label="' . esc_attr__('Restore Contact', 'event_espresso') . '"
291 291
                     >
292 292
                         ' . esc_html__('Restore', 'event_espresso') . '
293 293
                     </a>';
294
-            }
295
-        }
296
-
297
-        $name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
298
-
299
-        // Return the name contents
300
-        $content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
301
-        return $this->columnContent('ATT_fname', $content);
302
-    }
303
-
304
-
305
-    /**
306
-     * Email Column
307
-     *
308
-     * @param EE_Attendee $attendee
309
-     * @return string
310
-     * @throws EE_Error
311
-     */
312
-    public function column_ATT_email(EE_Attendee $attendee): string
313
-    {
314
-        $content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
315
-        return $this->columnContent('ATT_email', $content);
316
-    }
317
-
318
-
319
-    /**
320
-     * Column displaying count of registrations attached to Attendee.
321
-     *
322
-     * @param EE_Attendee $attendee
323
-     * @return string
324
-     * @throws EE_Error
325
-     * @throws ReflectionException
326
-     */
327
-    public function column_Registration_Count(EE_Attendee $attendee): string
328
-    {
329
-        $link = EEH_URL::add_query_args_and_nonce(
330
-            [
331
-                'action' => 'default',
332
-                'ATT_ID' => $attendee->ID(),
333
-            ],
334
-            REG_ADMIN_URL
335
-        );
336
-        $content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
337
-        return $this->columnContent('Registration_Count', $content, 'end');
338
-    }
339
-
340
-
341
-    /**
342
-     * ATT_address column
343
-     *
344
-     * @param EE_Attendee $attendee
345
-     * @return string
346
-     * @throws EE_Error
347
-     */
348
-    public function column_ATT_address(EE_Attendee $attendee): string
349
-    {
350
-        return $this->columnContent('ATT_address', $attendee->address());
351
-    }
352
-
353
-
354
-    /**
355
-     * ATT_city column
356
-     *
357
-     * @param EE_Attendee $attendee
358
-     * @return string
359
-     * @throws EE_Error
360
-     */
361
-    public function column_ATT_city(EE_Attendee $attendee): string
362
-    {
363
-        return $this->columnContent('ATT_city', $attendee->city());
364
-    }
365
-
366
-
367
-    /**
368
-     * State Column
369
-     *
370
-     * @param EE_Attendee $attendee
371
-     * @return string
372
-     * @throws EE_Error
373
-     * @throws InvalidArgumentException
374
-     * @throws InvalidDataTypeException
375
-     * @throws InvalidInterfaceException
376
-     * @throws ReflectionException
377
-     */
378
-    public function column_STA_ID(EE_Attendee $attendee): string
379
-    {
380
-        $states = EEM_State::instance()->get_all_states();
381
-        $state  = isset($states[ $attendee->state_ID() ])
382
-            ? $states[ $attendee->state_ID() ]->get('STA_name')
383
-            : $attendee->state_ID();
384
-        $content = ! is_numeric($state) ? $state : '';
385
-        return $this->columnContent('STA_ID', $content);
386
-    }
387
-
388
-
389
-    /**
390
-     * Country Column
391
-     *
392
-     * @param EE_Attendee $attendee
393
-     * @return string
394
-     * @throws EE_Error
395
-     * @throws InvalidArgumentException
396
-     * @throws InvalidDataTypeException
397
-     * @throws InvalidInterfaceException
398
-     * @throws ReflectionException
399
-     * @throws ReflectionException
400
-     */
401
-    public function column_CNT_ISO(EE_Attendee $attendee): string
402
-    {
403
-        $countries = EEM_Country::instance()->get_all_countries();
404
-        $country   = isset($countries[ $attendee->country_ID() ])
405
-            ? $countries[ $attendee->country_ID() ]->get('CNT_name')
406
-            : $attendee->country_ID();
407
-        $content = ! is_numeric($country) ? $country : '';
408
-        return $this->columnContent('CNT_ISO', $content);
409
-    }
410
-
411
-
412
-    /**
413
-     * Phone Number column
414
-     *
415
-     * @param EE_Attendee $attendee
416
-     * @return string
417
-     * @throws EE_Error
418
-     */
419
-    public function column_ATT_phone(EE_Attendee $attendee): string
420
-    {
421
-        return $this->columnContent('ATT_phone', $attendee->phone());
422
-    }
294
+			}
295
+		}
296
+
297
+		$name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
298
+
299
+		// Return the name contents
300
+		$content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
301
+		return $this->columnContent('ATT_fname', $content);
302
+	}
303
+
304
+
305
+	/**
306
+	 * Email Column
307
+	 *
308
+	 * @param EE_Attendee $attendee
309
+	 * @return string
310
+	 * @throws EE_Error
311
+	 */
312
+	public function column_ATT_email(EE_Attendee $attendee): string
313
+	{
314
+		$content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
315
+		return $this->columnContent('ATT_email', $content);
316
+	}
317
+
318
+
319
+	/**
320
+	 * Column displaying count of registrations attached to Attendee.
321
+	 *
322
+	 * @param EE_Attendee $attendee
323
+	 * @return string
324
+	 * @throws EE_Error
325
+	 * @throws ReflectionException
326
+	 */
327
+	public function column_Registration_Count(EE_Attendee $attendee): string
328
+	{
329
+		$link = EEH_URL::add_query_args_and_nonce(
330
+			[
331
+				'action' => 'default',
332
+				'ATT_ID' => $attendee->ID(),
333
+			],
334
+			REG_ADMIN_URL
335
+		);
336
+		$content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
337
+		return $this->columnContent('Registration_Count', $content, 'end');
338
+	}
339
+
340
+
341
+	/**
342
+	 * ATT_address column
343
+	 *
344
+	 * @param EE_Attendee $attendee
345
+	 * @return string
346
+	 * @throws EE_Error
347
+	 */
348
+	public function column_ATT_address(EE_Attendee $attendee): string
349
+	{
350
+		return $this->columnContent('ATT_address', $attendee->address());
351
+	}
352
+
353
+
354
+	/**
355
+	 * ATT_city column
356
+	 *
357
+	 * @param EE_Attendee $attendee
358
+	 * @return string
359
+	 * @throws EE_Error
360
+	 */
361
+	public function column_ATT_city(EE_Attendee $attendee): string
362
+	{
363
+		return $this->columnContent('ATT_city', $attendee->city());
364
+	}
365
+
366
+
367
+	/**
368
+	 * State Column
369
+	 *
370
+	 * @param EE_Attendee $attendee
371
+	 * @return string
372
+	 * @throws EE_Error
373
+	 * @throws InvalidArgumentException
374
+	 * @throws InvalidDataTypeException
375
+	 * @throws InvalidInterfaceException
376
+	 * @throws ReflectionException
377
+	 */
378
+	public function column_STA_ID(EE_Attendee $attendee): string
379
+	{
380
+		$states = EEM_State::instance()->get_all_states();
381
+		$state  = isset($states[ $attendee->state_ID() ])
382
+			? $states[ $attendee->state_ID() ]->get('STA_name')
383
+			: $attendee->state_ID();
384
+		$content = ! is_numeric($state) ? $state : '';
385
+		return $this->columnContent('STA_ID', $content);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Country Column
391
+	 *
392
+	 * @param EE_Attendee $attendee
393
+	 * @return string
394
+	 * @throws EE_Error
395
+	 * @throws InvalidArgumentException
396
+	 * @throws InvalidDataTypeException
397
+	 * @throws InvalidInterfaceException
398
+	 * @throws ReflectionException
399
+	 * @throws ReflectionException
400
+	 */
401
+	public function column_CNT_ISO(EE_Attendee $attendee): string
402
+	{
403
+		$countries = EEM_Country::instance()->get_all_countries();
404
+		$country   = isset($countries[ $attendee->country_ID() ])
405
+			? $countries[ $attendee->country_ID() ]->get('CNT_name')
406
+			: $attendee->country_ID();
407
+		$content = ! is_numeric($country) ? $country : '';
408
+		return $this->columnContent('CNT_ISO', $content);
409
+	}
410
+
411
+
412
+	/**
413
+	 * Phone Number column
414
+	 *
415
+	 * @param EE_Attendee $attendee
416
+	 * @return string
417
+	 * @throws EE_Error
418
+	 */
419
+	public function column_ATT_phone(EE_Attendee $attendee): string
420
+	{
421
+		return $this->columnContent('ATT_phone', $attendee->phone());
422
+	}
423 423
 }
Please login to merge, or discard this patch.
Spacing   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
      */
143 143
     public function column_cb($item): string
144 144
     {
145
-        if (! $item instanceof EE_Attendee) {
145
+        if ( ! $item instanceof EE_Attendee) {
146 146
             return '';
147 147
         }
148 148
         return sprintf(
@@ -161,9 +161,9 @@  discard block
 block discarded – undo
161 161
     public function column_id(?EE_Attendee $attendee): string
162 162
     {
163 163
         $content = '
164
-            <span class="ee-entity-id">' . $attendee->ID() . '</span>
164
+            <span class="ee-entity-id">' . $attendee->ID().'</span>
165 165
             <span class="show-on-mobile-view-only">
166
-                ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()) . '
166
+                ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()).'
167 167
             </span>';
168 168
         return $this->columnContent('id', $content, 'end');
169 169
     }
@@ -205,11 +205,11 @@  discard block
 block discarded – undo
205 205
             'espresso_registrations_edit_attendee'
206 206
         )
207 207
             ? '
208
-            <a  href="' . $edit_lnk_url . '"
208
+            <a  href="' . $edit_lnk_url.'"
209 209
                 class="ee-aria-tooltip"
210
-                aria-label="' . esc_attr__('Edit Contact', 'event_espresso') . '"
210
+                aria-label="' . esc_attr__('Edit Contact', 'event_espresso').'"
211 211
             >
212
-                ' . $attendee_name . '
212
+                ' . $attendee_name.'
213 213
             </a>'
214 214
             : $attendee_name;
215 215
     }
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
                     'espresso_registrations_trash_attendees'
255 255
                 )
256 256
             ) {
257
-                $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
257
+                $trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
258 258
                     [
259 259
                         'action' => 'trash_attendee',
260 260
                         'ATT_ID' => $attendee->ID(),
@@ -262,11 +262,11 @@  discard block
 block discarded – undo
262 262
                     REG_ADMIN_URL
263 263
                 );
264 264
                 $actions['trash'] = '
265
-                    <a  href="' . $trash_lnk_url . '"
265
+                    <a  href="' . $trash_lnk_url.'"
266 266
                         class="ee-aria-tooltip"
267
-                        aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso') . '"
267
+                        aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso').'"
268 268
                     >
269
-                        ' . esc_html__('Trash', 'event_espresso') . '
269
+                        ' . esc_html__('Trash', 'event_espresso').'
270 270
                     </a>';
271 271
             }
272 272
         } else {
@@ -277,7 +277,7 @@  discard block
 block discarded – undo
277 277
                 )
278 278
             ) {
279 279
                 // restore attendee link
280
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
280
+                $restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
281 281
                     [
282 282
                         'action' => 'restore_attendees',
283 283
                         'ATT_ID' => $attendee->ID(),
@@ -285,16 +285,16 @@  discard block
 block discarded – undo
285 285
                     REG_ADMIN_URL
286 286
                 );
287 287
                 $actions['restore'] = '
288
-                    <a  href="' . $restore_lnk_url . '"
288
+                    <a  href="' . $restore_lnk_url.'"
289 289
                         class="ee-aria-tooltip"
290
-                        aria-label="' . esc_attr__('Restore Contact', 'event_espresso') . '"
290
+                        aria-label="' . esc_attr__('Restore Contact', 'event_espresso').'"
291 291
                     >
292
-                        ' . esc_html__('Restore', 'event_espresso') . '
292
+                        ' . esc_html__('Restore', 'event_espresso').'
293 293
                     </a>';
294 294
             }
295 295
         }
296 296
 
297
-        $name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
297
+        $name_link = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
298 298
 
299 299
         // Return the name contents
300 300
         $content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
      */
312 312
     public function column_ATT_email(EE_Attendee $attendee): string
313 313
     {
314
-        $content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
314
+        $content = '<a href="mailto:'.$attendee->email().'">'.$attendee->email().'</a>';
315 315
         return $this->columnContent('ATT_email', $content);
316 316
     }
317 317
 
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
             ],
334 334
             REG_ADMIN_URL
335 335
         );
336
-        $content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
336
+        $content = '<a href="'.$link.'">'.$attendee->getCustomSelect('Registration_Count').'</a>';
337 337
         return $this->columnContent('Registration_Count', $content, 'end');
338 338
     }
339 339
 
@@ -378,8 +378,8 @@  discard block
 block discarded – undo
378 378
     public function column_STA_ID(EE_Attendee $attendee): string
379 379
     {
380 380
         $states = EEM_State::instance()->get_all_states();
381
-        $state  = isset($states[ $attendee->state_ID() ])
382
-            ? $states[ $attendee->state_ID() ]->get('STA_name')
381
+        $state  = isset($states[$attendee->state_ID()])
382
+            ? $states[$attendee->state_ID()]->get('STA_name')
383 383
             : $attendee->state_ID();
384 384
         $content = ! is_numeric($state) ? $state : '';
385 385
         return $this->columnContent('STA_ID', $content);
@@ -401,8 +401,8 @@  discard block
 block discarded – undo
401 401
     public function column_CNT_ISO(EE_Attendee $attendee): string
402 402
     {
403 403
         $countries = EEM_Country::instance()->get_all_countries();
404
-        $country   = isset($countries[ $attendee->country_ID() ])
405
-            ? $countries[ $attendee->country_ID() ]->get('CNT_name')
404
+        $country   = isset($countries[$attendee->country_ID()])
405
+            ? $countries[$attendee->country_ID()]->get('CNT_name')
406 406
             : $attendee->country_ID();
407 407
         $content = ! is_numeric($country) ? $country : '';
408 408
         return $this->columnContent('CNT_ISO', $content);
Please login to merge, or discard this patch.