Completed
Branch master (7421d0)
by
unknown
11:25 queued 06:55
created
admin_pages/transactions/Transactions_Admin_Page.core.php 2 patches
Indentation   +2548 added lines, -2548 removed lines patch added patch discarded remove patch
@@ -14,2552 +14,2552 @@
 block discarded – undo
14 14
  */
15 15
 class Transactions_Admin_Page extends EE_Admin_Page
16 16
 {
17
-    /**
18
-     * @var EE_Transaction
19
-     */
20
-    private $_transaction;
21
-
22
-    /**
23
-     * @var EE_Session
24
-     */
25
-    private $_session;
26
-
27
-    /**
28
-     * @var array $_txn_status
29
-     */
30
-    private static $_txn_status;
31
-
32
-    /**
33
-     * @var array $_pay_status
34
-     */
35
-    private static $_pay_status;
36
-
37
-    /**
38
-     * @var array $_existing_reg_payment_REG_IDs
39
-     */
40
-    protected $_existing_reg_payment_REG_IDs;
41
-
42
-
43
-    /**
44
-     *    _init_page_props
45
-     *
46
-     * @return void
47
-     */
48
-    protected function _init_page_props()
49
-    {
50
-        $this->page_slug        = TXN_PG_SLUG;
51
-        $this->page_label       = esc_html__('Transactions', 'event_espresso');
52
-        $this->_admin_base_url  = TXN_ADMIN_URL;
53
-        $this->_admin_base_path = TXN_ADMIN;
54
-    }
55
-
56
-
57
-    /**
58
-     *    _ajax_hooks
59
-     *
60
-     * @return void
61
-     */
62
-    protected function _ajax_hooks()
63
-    {
64
-        // add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
65
-        // add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
66
-        // add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
67
-    }
68
-
69
-
70
-    /**
71
-     *    _define_page_props
72
-     *
73
-     * @return void
74
-     */
75
-    protected function _define_page_props()
76
-    {
77
-        $this->_admin_page_title = $this->page_label;
78
-        $this->_labels           = [
79
-            'buttons' => [
80
-                'add'    => esc_html__('Add New Transaction', 'event_espresso'),
81
-                'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
82
-                'delete' => esc_html__('Delete Transaction', 'event_espresso'),
83
-            ],
84
-        ];
85
-    }
86
-
87
-
88
-    /**
89
-     *        grab url requests and route them
90
-     *
91
-     * @access private
92
-     * @return void
93
-     * @throws EE_Error
94
-     * @throws InvalidArgumentException
95
-     * @throws InvalidDataTypeException
96
-     * @throws InvalidInterfaceException
97
-     * @throws ReflectionException
98
-     */
99
-    public function _set_page_routes()
100
-    {
101
-        $this->_set_transaction_status_array();
102
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
103
-
104
-        $this->_page_routes = [
105
-
106
-            'default' => [
107
-                'func'       => '_transactions_overview_list_table',
108
-                'capability' => 'ee_read_transactions',
109
-            ],
110
-
111
-            'view_transaction' => [
112
-                'func'       => '_transaction_details',
113
-                'capability' => 'ee_read_transaction',
114
-                'obj_id'     => $TXN_ID,
115
-            ],
116
-
117
-            'send_payment_reminder' => [
118
-                'func'       => '_send_payment_reminder',
119
-                'noheader'   => true,
120
-                'capability' => 'ee_send_message',
121
-            ],
122
-
123
-            'espresso_apply_payment' => [
124
-                'func'       => [$this, 'apply_payments_or_refunds'],
125
-                'noheader'   => true,
126
-                'capability' => 'ee_edit_payments',
127
-            ],
128
-
129
-            'espresso_apply_refund' => [
130
-                'func'       => [$this, 'apply_payments_or_refunds'],
131
-                'noheader'   => true,
132
-                'capability' => 'ee_edit_payments',
133
-            ],
134
-
135
-            'espresso_delete_payment' => [
136
-                'func'       => [$this, 'delete_payment'],
137
-                'noheader'   => true,
138
-                'capability' => 'ee_delete_payments',
139
-            ],
140
-
141
-            'espresso_recalculate_line_items' => [
142
-                'func'       => 'recalculateLineItems',
143
-                'noheader'   => true,
144
-                'capability' => 'ee_edit_payments',
145
-            ],
146
-
147
-        ];
148
-    }
149
-
150
-
151
-    protected function _set_page_config()
152
-    {
153
-        $TXN_ID             = $this->request->getRequestParam('TXN_ID', 0, 'int');
154
-        $this->_page_config = [
155
-            'default'          => [
156
-                'nav'           => [
157
-                    'label' => esc_html__('Overview', 'event_espresso'),
158
-                    'icon'  => 'dashicons-list-view',
159
-                    'order' => 10,
160
-                ],
161
-                'list_table'    => 'EE_Admin_Transactions_List_Table',
162
-                'help_tabs'     => [
163
-                    'transactions_overview_help_tab'                       => [
164
-                        'title'    => esc_html__('Transactions Overview', 'event_espresso'),
165
-                        'filename' => 'transactions_overview',
166
-                    ],
167
-                    'transactions_overview_table_column_headings_help_tab' => [
168
-                        'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
169
-                        'filename' => 'transactions_overview_table_column_headings',
170
-                    ],
171
-                    'transactions_overview_views_filters_help_tab'         => [
172
-                        'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
173
-                        'filename' => 'transactions_overview_views_filters_search',
174
-                    ],
175
-                ],
176
-                'require_nonce' => false,
177
-            ],
178
-            'view_transaction' => [
179
-                'nav'       => [
180
-                    'label'      => esc_html__('View Transaction', 'event_espresso'),
181
-                    'icon'       => 'dashicons-cart',
182
-                    'order'      => 5,
183
-                    'url'        => $TXN_ID
184
-                        ? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
185
-                        : $this->_admin_base_url,
186
-                    'persistent' => false,
187
-                ],
188
-                'help_tabs' => [
189
-                    'transactions_view_transaction_help_tab'                                              => [
190
-                        'title'    => esc_html__('View Transaction', 'event_espresso'),
191
-                        'filename' => 'transactions_view_transaction',
192
-                    ],
193
-                    'transactions_view_transaction_transaction_details_table_help_tab'                    => [
194
-                        'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
195
-                        'filename' => 'transactions_view_transaction_transaction_details_table',
196
-                    ],
197
-                    'transactions_view_transaction_attendees_registered_help_tab'                         => [
198
-                        'title'    => esc_html__('Attendees Registered', 'event_espresso'),
199
-                        'filename' => 'transactions_view_transaction_attendees_registered',
200
-                    ],
201
-                    'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
202
-                        'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
203
-                        'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
204
-                    ],
205
-                ],
206
-                'qtips'     => ['Transaction_Details_Tips'],
207
-                'metaboxes' => ['_transaction_details_metaboxes'],
208
-
209
-                'require_nonce' => false,
210
-            ],
211
-        ];
212
-    }
213
-
214
-
215
-    /**
216
-     * The below methods aren't used by this class currently
217
-     */
218
-    protected function _add_screen_options()
219
-    {
220
-        // noop
221
-    }
222
-
223
-
224
-    protected function _add_feature_pointers()
225
-    {
226
-        // noop
227
-    }
228
-
229
-
230
-    public function admin_init()
231
-    {
232
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
233
-        $event_name    = $this->request->getRequestParam('event_name');
234
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
235
-        // IF a registration was JUST added via the admin...
236
-        if ($EVT_ID && $event_name && $redirect_from) {
237
-            // then set a cookie so that we can block any attempts to use
238
-            // the back button as a way to enter another registration.
239
-            setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
240
-            // and update the global
241
-            $_COOKIE['ee_registration_added'] = $EVT_ID;
242
-        }
243
-        EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
244
-            '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.',
245
-            'event_espresso'
246
-        );
247
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
248
-            'An error occurred! Please refresh the page and try again.',
249
-            'event_espresso'
250
-        );
251
-        EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
252
-        EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
253
-        EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
254
-        EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
255
-            'This transaction has been overpaid ! Payments Total',
256
-            'event_espresso'
257
-        );
258
-    }
259
-
260
-
261
-    public function admin_notices()
262
-    {
263
-        // noop
264
-    }
265
-
266
-
267
-    public function admin_footer_scripts()
268
-    {
269
-        // noop
270
-    }
271
-
272
-
273
-    /**
274
-     * _set_transaction_status_array
275
-     * sets list of transaction statuses
276
-     *
277
-     * @access private
278
-     * @return void
279
-     * @throws EE_Error
280
-     * @throws InvalidArgumentException
281
-     * @throws InvalidDataTypeException
282
-     * @throws InvalidInterfaceException
283
-     * @throws ReflectionException
284
-     */
285
-    private function _set_transaction_status_array()
286
-    {
287
-        self::$_txn_status = EEM_Transaction::instance()->status_array(true);
288
-    }
289
-
290
-
291
-    /**
292
-     * get_transaction_status_array
293
-     * return the transaction status array for wp_list_table
294
-     *
295
-     * @access public
296
-     * @return array
297
-     */
298
-    public function get_transaction_status_array()
299
-    {
300
-        return self::$_txn_status;
301
-    }
302
-
303
-
304
-    /**
305
-     *    get list of payment statuses
306
-     *
307
-     * @access private
308
-     * @return void
309
-     * @throws EE_Error
310
-     * @throws InvalidArgumentException
311
-     * @throws InvalidDataTypeException
312
-     * @throws InvalidInterfaceException
313
-     * @throws ReflectionException
314
-     */
315
-    private function _get_payment_status_array()
316
-    {
317
-        self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
318
-        $this->_template_args['payment_status'] = self::$_pay_status;
319
-    }
320
-
321
-
322
-    /**
323
-     *    _add_screen_options_default
324
-     *
325
-     * @access protected
326
-     * @return void
327
-     * @throws InvalidArgumentException
328
-     * @throws InvalidDataTypeException
329
-     * @throws InvalidInterfaceException
330
-     */
331
-    protected function _add_screen_options_default()
332
-    {
333
-        $this->_per_page_screen_option();
334
-    }
335
-
336
-
337
-    /**
338
-     * load_scripts_styles
339
-     *
340
-     * @access public
341
-     * @return void
342
-     */
343
-    public function load_scripts_styles()
344
-    {
345
-        // enqueue style
346
-        wp_register_style(
347
-            'espresso_txn',
348
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
349
-            [],
350
-            EVENT_ESPRESSO_VERSION
351
-        );
352
-        wp_enqueue_style('espresso_txn');
353
-        // scripts
354
-        wp_register_script(
355
-            'espresso_txn',
356
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
357
-            [
358
-                'ee_admin_js',
359
-                'ee-datepicker',
360
-                'jquery-ui-datepicker',
361
-                'jquery-ui-draggable',
362
-                'ee-dialog',
363
-                'ee-accounting',
364
-                'ee-serialize-full-array',
365
-            ],
366
-            EVENT_ESPRESSO_VERSION,
367
-            true
368
-        );
369
-        wp_enqueue_script('espresso_txn');
370
-    }
371
-
372
-
373
-    /**
374
-     *    load_scripts_styles_view_transaction
375
-     *
376
-     * @access public
377
-     * @return void
378
-     */
379
-    public function load_scripts_styles_view_transaction()
380
-    {
381
-        // styles
382
-        wp_enqueue_style('espresso-ui-theme');
383
-    }
384
-
385
-
386
-    /**
387
-     *    load_scripts_styles_default
388
-     *
389
-     * @access public
390
-     * @return void
391
-     */
392
-    public function load_scripts_styles_default()
393
-    {
394
-        // styles
395
-        wp_enqueue_style('espresso-ui-theme');
396
-    }
397
-
398
-
399
-    /**
400
-     *    _set_list_table_views_default
401
-     *
402
-     * @access protected
403
-     * @return void
404
-     */
405
-    protected function _set_list_table_views_default()
406
-    {
407
-        $this->_views = [
408
-            'all'        => [
409
-                'slug'  => 'all',
410
-                'label' => esc_html__('View All Transactions', 'event_espresso'),
411
-                'count' => 0,
412
-            ],
413
-            'abandoned'  => [
414
-                'slug'  => 'abandoned',
415
-                'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
416
-                'count' => 0,
417
-            ],
418
-            'incomplete' => [
419
-                'slug'  => 'incomplete',
420
-                'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
421
-                'count' => 0,
422
-            ],
423
-        ];
424
-        if (
425
-            /**
426
-             * Filters whether a link to the "Failed Transactions" list table
427
-             * appears on the Transactions Admin Page list table.
428
-             * List display can be turned back on via the following:
429
-             * add_filter(
430
-             *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
431
-             *     '__return_true'
432
-             * );
433
-             *
434
-             * @param boolean                 $display_failed_txns_list
435
-             * @param Transactions_Admin_Page $this
436
-             * @since 4.9.70.p
437
-             */
438
-        apply_filters(
439
-            'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
440
-            false,
441
-            $this
442
-        )
443
-        ) {
444
-            $this->_views['failed'] = [
445
-                'slug'  => 'failed',
446
-                'label' => esc_html__('Failed Transactions', 'event_espresso'),
447
-                'count' => 0,
448
-            ];
449
-        }
450
-    }
451
-
452
-
453
-    /**
454
-     * _set_transaction_object
455
-     * This sets the _transaction property for the transaction details screen
456
-     *
457
-     * @access private
458
-     * @return void
459
-     * @throws EE_Error
460
-     * @throws InvalidArgumentException
461
-     * @throws RuntimeException
462
-     * @throws InvalidDataTypeException
463
-     * @throws InvalidInterfaceException
464
-     * @throws ReflectionException
465
-     */
466
-    private function _set_transaction_object()
467
-    {
468
-        if ($this->_transaction instanceof EE_Transaction) {
469
-            return;
470
-        } //get out we've already set the object
471
-
472
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
473
-
474
-        // get transaction object
475
-        $this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
476
-        $this->_session     = $this->_transaction instanceof EE_Transaction
477
-            ? $this->_transaction->session_data()
478
-            : null;
479
-        if ($this->_transaction instanceof EE_Transaction) {
480
-            $this->_transaction->verify_abandoned_transaction_status();
481
-        }
482
-
483
-        if (! $this->_transaction instanceof EE_Transaction) {
484
-            $error_msg = sprintf(
485
-                esc_html__(
486
-                    'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
487
-                    'event_espresso'
488
-                ),
489
-                $TXN_ID
490
-            );
491
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
492
-        }
493
-    }
494
-
495
-
496
-    /**
497
-     *    _transaction_legend_items
498
-     *
499
-     * @access protected
500
-     * @return array
501
-     * @throws EE_Error
502
-     * @throws InvalidArgumentException
503
-     * @throws ReflectionException
504
-     * @throws InvalidDataTypeException
505
-     * @throws InvalidInterfaceException
506
-     */
507
-    protected function _transaction_legend_items()
508
-    {
509
-        EE_Registry::instance()->load_helper('MSG_Template');
510
-        $items = [];
511
-
512
-        if (
513
-            $this->capabilities->current_user_can(
514
-                'ee_read_global_messages',
515
-                'view_filtered_messages'
516
-            )
517
-        ) {
518
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
519
-            if (
520
-                is_array($related_for_icon)
521
-                && isset($related_for_icon['css_class'], $related_for_icon['label'])
522
-            ) {
523
-                $items['view_related_messages'] = [
524
-                    'class' => $related_for_icon['css_class'],
525
-                    'desc'  => $related_for_icon['label'],
526
-                ];
527
-            }
528
-        }
529
-
530
-        $items = apply_filters(
531
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
532
-            array_merge(
533
-                $items,
534
-                [
535
-                    'view_details'          => [
536
-                        'class' => 'dashicons dashicons-cart',
537
-                        'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
538
-                    ],
539
-                    'view_invoice'          => [
540
-                        'class' => 'dashicons dashicons-media-spreadsheet',
541
-                        'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
542
-                    ],
543
-                    'view_receipt'          => [
544
-                        'class' => 'dashicons dashicons-text-page',
545
-                        'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
546
-                    ],
547
-                    'view_registration'     => [
548
-                        'class' => 'dashicons dashicons-clipboard',
549
-                        'desc'  => esc_html__('View Registration Details', 'event_espresso'),
550
-                    ],
551
-                    'payment_overview_link' => [
552
-                        'class' => 'dashicons dashicons-money',
553
-                        'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
554
-                    ],
555
-                ]
556
-            )
557
-        );
558
-
559
-        if (
560
-            EEH_MSG_Template::is_mt_active('payment_reminder')
561
-            && $this->capabilities->current_user_can(
562
-                'ee_send_message',
563
-                'espresso_transactions_send_payment_reminder'
564
-            )
565
-        ) {
566
-            $items['send_payment_reminder'] = [
567
-                'class' => 'dashicons dashicons-email-alt',
568
-                'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
569
-            ];
570
-        } else {
571
-            $items['blank*'] = [
572
-                'class' => '',
573
-                'desc'  => '',
574
-            ];
575
-        }
576
-        $more_items = apply_filters(
577
-            'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
578
-            [
579
-                'overpaid'   => [
580
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
581
-                    'desc'  => EEH_Template::pretty_status(
582
-                        EEM_Transaction::overpaid_status_code,
583
-                        false,
584
-                        'sentence'
585
-                    ),
586
-                ],
587
-                'complete'   => [
588
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
589
-                    'desc'  => EEH_Template::pretty_status(
590
-                        EEM_Transaction::complete_status_code,
591
-                        false,
592
-                        'sentence'
593
-                    ),
594
-                ],
595
-                'incomplete' => [
596
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
597
-                    'desc'  => EEH_Template::pretty_status(
598
-                        EEM_Transaction::incomplete_status_code,
599
-                        false,
600
-                        'sentence'
601
-                    ),
602
-                ],
603
-                'abandoned'  => [
604
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
605
-                    'desc'  => EEH_Template::pretty_status(
606
-                        EEM_Transaction::abandoned_status_code,
607
-                        false,
608
-                        'sentence'
609
-                    ),
610
-                ],
611
-                'failed'     => [
612
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
613
-                    'desc'  => EEH_Template::pretty_status(
614
-                        EEM_Transaction::failed_status_code,
615
-                        false,
616
-                        'sentence'
617
-                    ),
618
-                ],
619
-            ]
620
-        );
621
-
622
-        return array_merge($items, $more_items);
623
-    }
624
-
625
-
626
-    /**
627
-     *    _transactions_overview_list_table
628
-     *
629
-     * @access protected
630
-     * @return void
631
-     * @throws DomainException
632
-     * @throws EE_Error
633
-     * @throws InvalidArgumentException
634
-     * @throws InvalidDataTypeException
635
-     * @throws InvalidInterfaceException
636
-     * @throws ReflectionException
637
-     */
638
-    protected function _transactions_overview_list_table()
639
-    {
640
-        $this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
641
-
642
-        $EVT_ID                                    = $this->request->getRequestParam('EVT_ID', 0, 'int');
643
-        $event                                     = EEM_Event::instance()->get_one_by_ID($EVT_ID);
644
-        $this->_template_args['admin_page_header'] = $event instanceof EE_Event
645
-            ? sprintf(
646
-                esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
647
-                '<h3>',
648
-                '<a href="'
649
-                . EE_Admin_Page::add_query_args_and_nonce(
650
-                    ['action' => 'edit', 'post' => $event->ID()],
651
-                    EVENTS_ADMIN_URL
652
-                )
653
-                . '" aria-label="'
654
-                . esc_attr__('Click to Edit event', 'event_espresso')
655
-                . '">' . $event->name() . '</a>',
656
-                '</h3>'
657
-            )
658
-            : '';
659
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
660
-        $this->display_admin_list_table_page_with_no_sidebar();
661
-    }
662
-
663
-
664
-    /**
665
-     *    _transaction_details
666
-     * generates HTML for the View Transaction Details Admin page
667
-     *
668
-     * @access protected
669
-     * @return void
670
-     * @throws DomainException
671
-     * @throws EE_Error
672
-     * @throws InvalidArgumentException
673
-     * @throws InvalidDataTypeException
674
-     * @throws InvalidInterfaceException
675
-     * @throws RuntimeException
676
-     * @throws ReflectionException
677
-     */
678
-    protected function _transaction_details()
679
-    {
680
-        do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
681
-
682
-        $this->_set_transaction_status_array();
683
-
684
-        $this->_template_args                      = [];
685
-        $this->_template_args['transactions_page'] = $this->_wp_page_slug;
686
-
687
-        $this->_set_transaction_object();
688
-
689
-        if (! $this->_transaction instanceof EE_Transaction) {
690
-            return;
691
-        }
692
-
693
-        $this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
694
-        $this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
695
-
696
-        $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
697
-        $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
698
-
699
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
700
-        $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
701
-        $this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
702
-
703
-        $txn_total  = $this->_transaction->total();
704
-        $total_paid = $this->_transaction->paid();
705
-        $amount_due = $txn_total - $total_paid;
706
-
707
-        $this->_template_args['grand_total'] = $txn_total;
708
-        $this->_template_args['total_paid']  = $total_paid;
709
-
710
-        $this->_template_args['amount_due']     = EEH_Template::format_currency($amount_due, false, false);
711
-        $this->_template_args['amount_due_raw'] = $amount_due;
712
-
713
-        $this->_template_args['amount_due_class'] = '';
714
-
715
-        if ($txn_total === (float) 0) {
716
-            // free event
717
-            $this->_template_args['amount_due'] = false;
718
-        } elseif ($amount_due < (float) 0) {
719
-            // overpaid
720
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
721
-        } elseif ($amount_due > (float) 0) {
722
-            // monies owing
723
-            $this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
724
-        } elseif ($total_paid === (float) 0) {
725
-            // no payments made yet
726
-            $this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
727
-        }
728
-
729
-        $payment_method = $this->_transaction->payment_method();
730
-
731
-        $this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
732
-            ? $payment_method->admin_name()
733
-            : esc_html__('Unknown', 'event_espresso');
734
-
735
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
736
-        // link back to overview
737
-        $this->_template_args['txn_overview_url'] = $this->request->getServerParam(
738
-            'HTTP_REFERER',
739
-            TXN_ADMIN_URL
740
-        );
741
-
742
-
743
-        // next link
744
-        $next_txn                                 = $this->_transaction->next(
745
-            null,
746
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
747
-            'TXN_ID'
748
-        );
749
-        $this->_template_args['next_transaction'] = $next_txn
750
-            ? $this->_next_link(
751
-                EE_Admin_Page::add_query_args_and_nonce(
752
-                    ['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
753
-                    TXN_ADMIN_URL
754
-                ),
755
-                'dashicons dashicons-arrow-right ee-icon-size-22'
756
-            )
757
-            : '';
758
-        // previous link
759
-        $previous_txn                                 = $this->_transaction->previous(
760
-            null,
761
-            [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
762
-            'TXN_ID'
763
-        );
764
-        $this->_template_args['previous_transaction'] = $previous_txn
765
-            ? $this->_previous_link(
766
-                EE_Admin_Page::add_query_args_and_nonce(
767
-                    ['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
768
-                    TXN_ADMIN_URL
769
-                ),
770
-                'dashicons dashicons-arrow-left ee-icon-size-22'
771
-            )
772
-            : '';
773
-
774
-        $EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
775
-        $event_name    = $this->request->getRequestParam('event_name');
776
-        $redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
777
-
778
-        // were we just redirected here after adding a new registration ???
779
-        if ($EVT_ID && $event_name && $redirect_from) {
780
-            if (
781
-                $this->capabilities->current_user_can(
782
-                    'ee_edit_registrations',
783
-                    'espresso_registrations_new_registration',
784
-                    $EVT_ID
785
-                )
786
-            ) {
787
-                $this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
788
-                $this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
789
-                    [
790
-                        'page'     => 'espresso_registrations',
791
-                        'action'   => 'new_registration',
792
-                        'return'   => 'default',
793
-                        'TXN_ID'   => $this->_transaction->ID(),
794
-                        'event_id' => $EVT_ID,
795
-                    ],
796
-                    REG_ADMIN_URL
797
-                );
798
-                $this->_admin_page_title .= '">';
799
-
800
-                $this->_admin_page_title .= sprintf(
801
-                    esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
802
-                    htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
803
-                );
804
-                $this->_admin_page_title .= '</a>';
805
-            }
806
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
807
-        }
808
-        // grab messages at the last second
809
-        $this->_template_args['notices'] = EE_Error::get_notices();
810
-        // path to template
811
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
812
-        $this->_template_args['admin_page_header'] = EEH_Template::display_template(
813
-            $template_path,
814
-            $this->_template_args,
815
-            true
816
-        );
817
-
818
-        // the details template wrapper
819
-        $this->display_admin_page_with_sidebar();
820
-    }
821
-
822
-
823
-    /**
824
-     *        _transaction_details_metaboxes
825
-     *
826
-     * @access protected
827
-     * @return void
828
-     * @throws EE_Error
829
-     * @throws InvalidArgumentException
830
-     * @throws InvalidDataTypeException
831
-     * @throws InvalidInterfaceException
832
-     * @throws RuntimeException
833
-     * @throws ReflectionException
834
-     */
835
-    protected function _transaction_details_metaboxes()
836
-    {
837
-        $this->_set_transaction_object();
838
-
839
-        if (! $this->_transaction instanceof EE_Transaction) {
840
-            return;
841
-        }
842
-        $this->addMetaBox(
843
-            'edit-txn-details-mbox',
844
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
845
-            . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
846
-            [$this, 'txn_details_meta_box'],
847
-            $this->_wp_page_slug
848
-        );
849
-        $this->addMetaBox(
850
-            'edit-txn-attendees-mbox',
851
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
852
-            . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
853
-            [$this, 'txn_attendees_meta_box'],
854
-            $this->_wp_page_slug,
855
-            'normal',
856
-            'high',
857
-            ['TXN_ID' => $this->_transaction->ID()]
858
-        );
859
-        $this->addMetaBox(
860
-            'edit-txn-registrant-mbox',
861
-            esc_html__('Primary Contact', 'event_espresso'),
862
-            [$this, 'txn_registrant_side_meta_box'],
863
-            $this->_wp_page_slug,
864
-            'side'
865
-        );
866
-        $this->addMetaBox(
867
-            'edit-txn-billing-info-mbox',
868
-            esc_html__('Billing Information', 'event_espresso'),
869
-            [$this, 'txn_billing_info_side_meta_box'],
870
-            $this->_wp_page_slug,
871
-            'side'
872
-        );
873
-    }
874
-
875
-
876
-    /**
877
-     * Callback for transaction actions metabox.
878
-     *
879
-     * @param EE_Transaction|null $transaction
880
-     * @return string
881
-     * @throws DomainException
882
-     * @throws EE_Error
883
-     * @throws InvalidArgumentException
884
-     * @throws InvalidDataTypeException
885
-     * @throws InvalidInterfaceException
886
-     * @throws ReflectionException
887
-     * @throws RuntimeException
888
-     */
889
-    public function getActionButtons(EE_Transaction $transaction = null)
890
-    {
891
-        $content = '';
892
-        $actions = [];
893
-        if (! $transaction instanceof EE_Transaction) {
894
-            return $content;
895
-        }
896
-        /** @var EE_Registration $primary_registration */
897
-        $primary_registration = $transaction->primary_registration();
898
-        $attendee             = $primary_registration instanceof EE_Registration
899
-            ? $primary_registration->attendee()
900
-            : null;
901
-
902
-        if (
903
-            $attendee instanceof EE_Attendee
904
-            && $this->capabilities->current_user_can(
905
-                'ee_send_message',
906
-                'espresso_transactions_send_payment_reminder'
907
-            )
908
-        ) {
909
-            $actions['payment_reminder'] =
910
-                EEH_MSG_Template::is_mt_active('payment_reminder')
911
-                && $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
912
-                && $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
913
-                    ? EEH_Template::get_button_or_link(
914
-                    EE_Admin_Page::add_query_args_and_nonce(
915
-                        [
916
-                            'action'      => 'send_payment_reminder',
917
-                            'TXN_ID'      => $this->_transaction->ID(),
918
-                            'redirect_to' => 'view_transaction',
919
-                        ],
920
-                        TXN_ADMIN_URL
921
-                    ),
922
-                    esc_html__(' Send Payment Reminder', 'event_espresso'),
923
-                    'button button--secondary',
924
-                    'dashicons dashicons-email-alt'
925
-                )
926
-                    : '';
927
-        }
928
-
929
-        if (
930
-            $this->capabilities->current_user_can(
931
-                'ee_edit_payments',
932
-                'espresso_transactions_recalculate_line_items'
933
-            )
934
-        ) {
935
-            $actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
936
-                EE_Admin_Page::add_query_args_and_nonce(
937
-                    [
938
-                        'action'      => 'espresso_recalculate_line_items',
939
-                        'TXN_ID'      => $this->_transaction->ID(),
940
-                        'redirect_to' => 'view_transaction',
941
-                    ],
942
-                    TXN_ADMIN_URL
943
-                ),
944
-                esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
945
-                'button button--secondary',
946
-                'dashicons dashicons-update'
947
-            );
948
-        }
949
-
950
-        if (
951
-            $primary_registration instanceof EE_Registration
952
-            && EEH_MSG_Template::is_mt_active('receipt')
953
-        ) {
954
-            $actions['receipt'] = EEH_Template::get_button_or_link(
955
-                $primary_registration->receipt_url(),
956
-                esc_html__('View Receipt', 'event_espresso'),
957
-                'button button--secondary',
958
-                'dashicons dashicons-text-page'
959
-            );
960
-        }
961
-
962
-        if (
963
-            $primary_registration instanceof EE_Registration
964
-            && EEH_MSG_Template::is_mt_active('invoice')
965
-        ) {
966
-            $actions['invoice'] = EEH_Template::get_button_or_link(
967
-                $primary_registration->invoice_url(),
968
-                esc_html__('View Invoice', 'event_espresso'),
969
-                'button button--secondary',
970
-                'dashicons dashicons-media-spreadsheet'
971
-            );
972
-        }
973
-        $actions = array_filter(
974
-            apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
975
-        );
976
-        if ($actions) {
977
-            $content .= implode('', $actions);
978
-        }
979
-        return $content;
980
-    }
981
-
982
-
983
-    /**
984
-     * txn_details_meta_box
985
-     * generates HTML for the Transaction main meta box
986
-     *
987
-     * @return void
988
-     * @throws DomainException
989
-     * @throws EE_Error
990
-     * @throws InvalidArgumentException
991
-     * @throws InvalidDataTypeException
992
-     * @throws InvalidInterfaceException
993
-     * @throws RuntimeException
994
-     * @throws ReflectionException
995
-     */
996
-    public function txn_details_meta_box()
997
-    {
998
-        $this->_set_transaction_object();
999
-        $this->_template_args['TXN_ID']              = $this->_transaction->ID();
1000
-        $this->_template_args['attendee']            =
1001
-            $this->_transaction->primary_registration() instanceof EE_Registration
1002
-                ? $this->_transaction->primary_registration()->attendee()
1003
-                : null;
1004
-        $this->_template_args['can_edit_payments']   = $this->capabilities->current_user_can(
1005
-            'ee_edit_payments',
1006
-            'apply_payment_or_refund_from_registration_details'
1007
-        );
1008
-        $this->_template_args['can_delete_payments'] = $this->capabilities->current_user_can(
1009
-            'ee_delete_payments',
1010
-            'delete_payment_from_registration_details'
1011
-        );
1012
-
1013
-        // get line table
1014
-        EEH_Autoloader::register_line_item_display_autoloaders();
1015
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1016
-            'admin_table',
1017
-            'EE_Admin_Table_Line_Item_Display_Strategy'
1018
-        );
1019
-        $this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1020
-            $this->_transaction->total_line_item()
1021
-        );
1022
-        $this->_template_args['REG_code']        =
1023
-            $this->_transaction->primary_registration() instanceof EE_Registration
1024
-                ? $this->_transaction->primary_registration()->reg_code()
1025
-                : null;
1026
-        // process taxes
1027
-        $taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1028
-        $this->_template_args['taxes'] = ! empty($taxes)
1029
-            ? $taxes
1030
-            : false;
1031
-
1032
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1033
-            $this->_transaction->total(),
1034
-            false,
1035
-            false
1036
-        );
1037
-        $this->_template_args['grand_raw_total'] = $this->_transaction->total();
1038
-        $this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1039
-
1040
-        // process payment details
1041
-        $payments = $this->_transaction->payments();
1042
-        if (! empty($payments)) {
1043
-            $this->_template_args['payments']              = $payments;
1044
-            $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1045
-        } else {
1046
-            $this->_template_args['payments']              = false;
1047
-            $this->_template_args['existing_reg_payments'] = [];
1048
-        }
1049
-
1050
-        $this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1051
-        $this->_template_args['delete_payment_url'] = add_query_arg(
1052
-            ['action' => 'espresso_delete_payment'],
1053
-            TXN_ADMIN_URL
1054
-        );
1055
-
1056
-        if (isset($txn_details['invoice_number'])) {
1057
-            $this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1058
-            $this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1059
-                'Invoice Number',
1060
-                'event_espresso'
1061
-            );
1062
-        }
1063
-
1064
-        $this->_template_args['txn_details']['registration_session']['value'] =
1065
-            $this->_transaction->primary_registration() instanceof EE_Registration
1066
-                ? $this->_transaction->primary_registration()->session_ID()
1067
-                : null;
1068
-        $this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1069
-            'Registration Session',
1070
-            'event_espresso'
1071
-        );
1072
-
1073
-        $this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1074
-        $this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1075
-            'Transaction placed from IP',
1076
-            'event_espresso'
1077
-        );
1078
-
1079
-        $this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1080
-        $this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1081
-            'Registrant User Agent',
1082
-            'event_espresso'
1083
-        );
1084
-
1085
-        $reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1086
-        foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1087
-            if ($reg_step_status === true) {
1088
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1089
-                              . sprintf(
1090
-                                  esc_html__('%1$s : Completed', 'event_espresso'),
1091
-                                  ucwords(str_replace('_', ' ', $reg_step))
1092
-                              )
1093
-                              . '</div>';
1094
-            } elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1095
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1096
-                              . sprintf(
1097
-                                  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1098
-                                  ucwords(str_replace('_', ' ', $reg_step)),
1099
-                                  date(
1100
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1101
-                                      $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1102
-                                  )
1103
-                              )
1104
-                              . '</div>';
1105
-            } else {
1106
-                $reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1107
-                              . sprintf(
1108
-                                  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1109
-                                  ucwords(str_replace('_', ' ', $reg_step))
1110
-                              )
1111
-                              . '</div>';
1112
-            }
1113
-        }
1114
-        $reg_steps                                                 .= '</ul>';
1115
-        $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1116
-        $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1117
-            'Registration Step Progress',
1118
-            'event_espresso'
1119
-        );
1120
-
1121
-
1122
-        $this->_get_registrations_to_apply_payment_to();
1123
-        $this->_get_payment_methods($payments);
1124
-        $this->_get_payment_status_array();
1125
-        $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1126
-
1127
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1128
-            [
1129
-                'action'  => 'edit_transaction',
1130
-                'process' => 'transaction',
1131
-            ],
1132
-            TXN_ADMIN_URL
1133
-        );
1134
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1135
-            [
1136
-                'page'   => 'espresso_transactions',
1137
-                'action' => 'espresso_apply_payment',
1138
-            ],
1139
-            TXN_ADMIN_URL
1140
-        );
1141
-        $this->_template_args['delete_payment_form_url'] = add_query_arg(
1142
-            [
1143
-                'page'   => 'espresso_transactions',
1144
-                'action' => 'espresso_delete_payment',
1145
-            ],
1146
-            TXN_ADMIN_URL
1147
-        );
1148
-
1149
-        $this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1150
-
1151
-        // 'espresso_delete_payment_nonce'
1152
-
1153
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1154
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1155
-    }
1156
-
1157
-
1158
-    /**
1159
-     * _get_registration_payment_IDs
1160
-     *    generates an array of Payment IDs and their corresponding Registration IDs
1161
-     *
1162
-     * @access protected
1163
-     * @param EE_Payment[] $payments
1164
-     * @return array
1165
-     * @throws EE_Error
1166
-     * @throws InvalidArgumentException
1167
-     * @throws InvalidDataTypeException
1168
-     * @throws InvalidInterfaceException
1169
-     * @throws ReflectionException
1170
-     */
1171
-    protected function _get_registration_payment_IDs($payments = [])
1172
-    {
1173
-        $existing_reg_payments = [];
1174
-        // get all reg payments for these payments
1175
-        $reg_payments = EEM_Registration_Payment::instance()->get_all(
1176
-            [
1177
-                [
1178
-                    'PAY_ID' => [
1179
-                        'IN',
1180
-                        array_keys($payments),
1181
-                    ],
1182
-                ],
1183
-            ]
1184
-        );
1185
-        if (! empty($reg_payments)) {
1186
-            foreach ($payments as $payment) {
1187
-                if (! $payment instanceof EE_Payment) {
1188
-                    continue;
1189
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1190
-                    $existing_reg_payments[ $payment->ID() ] = [];
1191
-                }
1192
-                foreach ($reg_payments as $reg_payment) {
1193
-                    if (
1194
-                        $reg_payment instanceof EE_Registration_Payment
1195
-                        && $reg_payment->payment_ID() === $payment->ID()
1196
-                    ) {
1197
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1198
-                    }
1199
-                }
1200
-            }
1201
-        }
1202
-
1203
-        return $existing_reg_payments;
1204
-    }
1205
-
1206
-
1207
-    /**
1208
-     * _get_registrations_to_apply_payment_to
1209
-     *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1210
-     * which allows the admin to only apply the payment to the specific registrations
1211
-     *
1212
-     * @access protected
1213
-     * @return void
1214
-     * @throws EE_Error
1215
-     * @throws InvalidArgumentException
1216
-     * @throws InvalidDataTypeException
1217
-     * @throws InvalidInterfaceException
1218
-     * @throws ReflectionException
1219
-     */
1220
-    protected function _get_registrations_to_apply_payment_to()
1221
-    {
1222
-        // we want any registration with an active status (ie: not deleted or cancelled)
1223
-        $query_params                      = [
1224
-            [
1225
-                'STS_ID' => [
1226
-                    'IN',
1227
-                    [
1228
-                        RegStatus::APPROVED,
1229
-                        RegStatus::PENDING_PAYMENT,
1230
-                        RegStatus::AWAITING_REVIEW,
1231
-                    ],
1232
-                ],
1233
-            ],
1234
-        ];
1235
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1236
-                '',
1237
-                'txn-admin-apply-payment-to-registrations-dv',
1238
-                '',
1239
-                'clear: both; margin: 1.5em 0 0; display: none;'
1240
-            );
1241
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1242
-        $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1243
-        $registrations_to_apply_payment_to .= EEH_HTML::thead(
1244
-            EEH_HTML::tr(
1245
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1246
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1247
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1248
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1249
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1250
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1251
-                EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1252
-            )
1253
-        );
1254
-        $registrations_to_apply_payment_to .= EEH_HTML::tbody();
1255
-        // get registrations for TXN
1256
-        $registrations         = $this->_transaction->registrations($query_params);
1257
-        $existing_reg_payments = $this->_template_args['existing_reg_payments'];
1258
-        foreach ($registrations as $registration) {
1259
-            if ($registration instanceof EE_Registration) {
1260
-                $attendee_name                     = $registration->attendee() instanceof EE_Attendee
1261
-                    ? $registration->attendee()->full_name()
1262
-                    : esc_html__('Unknown Attendee', 'event_espresso');
1263
-                $owing                             = $registration->final_price() - $registration->paid();
1264
-                $taxable                           = $registration->ticket()->taxable()
1265
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1266
-                    : '';
1267
-                $checked                           = empty($existing_reg_payments)
1268
-                                                     || in_array($registration->ID(), $existing_reg_payments, true)
1269
-                    ? ' checked'
1270
-                    : '';
1271
-                $disabled                          = $registration->final_price() > 0
1272
-                    ? ''
1273
-                    : ' disabled';
1274
-                $registrations_to_apply_payment_to .= EEH_HTML::tr(
1275
-                    EEH_HTML::td($registration->ID()) .
1276
-                    EEH_HTML::td($attendee_name) .
1277
-                    EEH_HTML::td(
1278
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1279
-                    ) .
1280
-                    EEH_HTML::td($registration->event_name()) .
1281
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1282
-                    EEH_HTML::td(
1283
-                        EEH_Template::format_currency($owing),
1284
-                        '',
1285
-                        'txn-admin-payment-owing-td jst-cntr'
1286
-                    ) .
1287
-                    EEH_HTML::td(
1288
-                        '<input type="checkbox" value="' . $registration->ID()
1289
-                        . '" name="txn_admin_payment[registrations]"'
1290
-                        . $checked . $disabled . '>',
1291
-                        '',
1292
-                        'jst-cntr'
1293
-                    ),
1294
-                    'apply-payment-registration-row-' . $registration->ID()
1295
-                );
1296
-            }
1297
-        }
1298
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1299
-        $registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1300
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1301
-        $registrations_to_apply_payment_to                         .= EEH_HTML::p(
1302
-            esc_html__(
1303
-                '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.',
1304
-                'event_espresso'
1305
-            ),
1306
-            '',
1307
-            'clear description'
1308
-        );
1309
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1310
-        $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1311
-    }
1312
-
1313
-
1314
-    /**
1315
-     * _get_reg_status_selection
1316
-     *
1317
-     * @return void
1318
-     * @throws EE_Error
1319
-     * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1320
-     *         instead of events.
1321
-     * @access protected
1322
-     */
1323
-    protected function _get_reg_status_selection()
1324
-    {
1325
-        // first get all possible statuses
1326
-        $statuses = EEM_Registration::reg_status_array([], true);
1327
-        // let's add a "don't change" option.
1328
-        $status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1329
-        $status_array                                        = array_merge($status_array, $statuses);
1330
-        $this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1331
-            'txn_reg_status_change[reg_status]',
1332
-            $status_array,
1333
-            'NAN',
1334
-            'id="txn-admin-payment-reg-status-inp"',
1335
-            'txn-reg-status-change-reg-status'
1336
-        );
1337
-        $this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1338
-            'delete_txn_reg_status_change[reg_status]',
1339
-            $status_array,
1340
-            'NAN',
1341
-            'delete-txn-admin-payment-reg-status-inp',
1342
-            'delete-txn-reg-status-change-reg-status'
1343
-        );
1344
-    }
1345
-
1346
-
1347
-    /**
1348
-     *    _get_payment_methods
1349
-     * Gets all the payment methods available generally, or the ones that are already
1350
-     * selected on these payments (in case their payment methods are no longer active).
1351
-     * Has the side-effect of updating the template args' payment_methods item
1352
-     *
1353
-     * @access private
1354
-     * @param EE_Payment[] to show on this page
1355
-     * @return void
1356
-     * @throws EE_Error
1357
-     * @throws InvalidArgumentException
1358
-     * @throws InvalidDataTypeException
1359
-     * @throws InvalidInterfaceException
1360
-     * @throws ReflectionException
1361
-     */
1362
-    private function _get_payment_methods($payments = [])
1363
-    {
1364
-        $payment_methods_of_payments = [];
1365
-        foreach ($payments as $payment) {
1366
-            if ($payment instanceof EE_Payment) {
1367
-                $payment_methods_of_payments[] = $payment->ID();
1368
-            }
1369
-        }
1370
-        if ($payment_methods_of_payments) {
1371
-            $query_args = [
1372
-                [
1373
-                    'OR*payment_method_for_payment' => [
1374
-                        'PMD_ID'    => ['IN', $payment_methods_of_payments],
1375
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1376
-                    ],
1377
-                ],
1378
-            ];
1379
-        } else {
1380
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1381
-        }
1382
-        $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1383
-    }
1384
-
1385
-
1386
-    /**
1387
-     * txn_attendees_meta_box
1388
-     *    generates HTML for the Attendees Transaction main meta box
1389
-     *
1390
-     * @access public
1391
-     * @param WP_Post $post
1392
-     * @param array   $metabox
1393
-     * @return void
1394
-     * @throws DomainException
1395
-     * @throws EE_Error
1396
-     * @throws InvalidArgumentException
1397
-     * @throws InvalidDataTypeException
1398
-     * @throws InvalidInterfaceException
1399
-     * @throws ReflectionException
1400
-     */
1401
-    public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1402
-    {
1403
-        /** @noinspection NonSecureExtractUsageInspection */
1404
-        extract($metabox['args']);
1405
-        $this->_template_args['post']            = $post;
1406
-        $this->_template_args['event_attendees'] = [];
1407
-        // process items in cart
1408
-        $line_items = $this->_transaction->get_many_related(
1409
-            'Line_Item',
1410
-            [['LIN_type' => 'line-item']]
1411
-        );
1412
-        if (! empty($line_items)) {
1413
-            foreach ($line_items as $item) {
1414
-                if ($item instanceof EE_Line_Item) {
1415
-                    switch ($item->OBJ_type()) {
1416
-                        case 'Event':
1417
-                            break;
1418
-                        case 'Ticket':
1419
-                            $ticket = $item->ticket();
1420
-                            // right now we're only handling tickets here.
1421
-                            // Cause its expected that only tickets will have attendees right?
1422
-                            if (! $ticket instanceof EE_Ticket) {
1423
-                                break;
1424
-                            }
1425
-                            try {
1426
-                                $event_name = $ticket->get_event_name();
1427
-                            } catch (Exception $e) {
1428
-                                EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1429
-                                $event_name = esc_html__('Unknown Event', 'event_espresso');
1430
-                            }
1431
-                            $event_name   .= ' - ' . $item->name();
1432
-                            $ticket_price = EEH_Template::format_currency($item->unit_price());
1433
-                            // now get all of the registrations for this transaction that use this ticket
1434
-                            $registrations = $ticket->registrations(
1435
-                                [['TXN_ID' => $this->_transaction->ID()]]
1436
-                            );
1437
-                            foreach ($registrations as $registration) {
1438
-                                if (! $registration instanceof EE_Registration) {
1439
-                                    break;
1440
-                                }
1441
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1442
-                                    = $registration->status_ID();
1443
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1444
-                                    = $registration->count();
1445
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1446
-                                    = $event_name;
1447
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1448
-                                    = $ticket_price;
1449
-                                // attendee info
1450
-                                $attendee = $registration->get_first_related('Attendee');
1451
-                                if ($attendee instanceof EE_Attendee) {
1452
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1453
-                                        = $attendee->ID();
1454
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1455
-                                        = $attendee->full_name();
1456
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1457
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1458
-                                          . esc_html__(
1459
-                                              ' Event',
1460
-                                              'event_espresso'
1461
-                                          )
1462
-                                          . '">' . $attendee->email() . '</a>';
1463
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1464
-                                        = EEH_Address::format($attendee, 'inline', false, false);
1465
-                                } else {
1466
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1467
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1468
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1469
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1470
-                                }
1471
-                            }
1472
-                            break;
1473
-                    }
1474
-                }
1475
-            }
1476
-
1477
-            $this->_template_args['transaction_form_url'] = add_query_arg(
1478
-                [
1479
-                    'action'  => 'edit_transaction',
1480
-                    'process' => 'attendees',
1481
-                ],
1482
-                TXN_ADMIN_URL
1483
-            );
1484
-            echo EEH_Template::display_template(
1485
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1486
-                $this->_template_args,
1487
-                true
1488
-            );
1489
-        } else {
1490
-            printf(
1491
-                esc_html__(
1492
-                    '%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1493
-                    'event_espresso'
1494
-                ),
1495
-                '<p class="important-notice">',
1496
-                '</p>'
1497
-            );
1498
-        }
1499
-    }
1500
-
1501
-
1502
-    /**
1503
-     * txn_registrant_side_meta_box
1504
-     * generates HTML for the Edit Transaction side meta box
1505
-     *
1506
-     * @access public
1507
-     * @return void
1508
-     * @throws DomainException
1509
-     * @throws EE_Error
1510
-     * @throws InvalidArgumentException
1511
-     * @throws InvalidDataTypeException
1512
-     * @throws InvalidInterfaceException
1513
-     * @throws ReflectionException
1514
-     */
1515
-    public function txn_registrant_side_meta_box()
1516
-    {
1517
-        $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1518
-            ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1519
-            : null;
1520
-        if (! $primary_att instanceof EE_Attendee) {
1521
-            $this->_template_args['no_attendee_message'] = esc_html__(
1522
-                'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1523
-                'event_espresso'
1524
-            );
1525
-            $primary_att                                 = EEM_Attendee::instance()->create_default_object();
1526
-        }
1527
-        $this->_template_args['ATT_ID']            = $primary_att->ID();
1528
-        $this->_template_args['prime_reg_fname']   = $primary_att->fname();
1529
-        $this->_template_args['prime_reg_lname']   = $primary_att->lname();
1530
-        $this->_template_args['prime_reg_email']   = $primary_att->email();
1531
-        $this->_template_args['prime_reg_phone']   = $primary_att->phone();
1532
-        $this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1533
-            [
1534
-                'action' => 'edit_attendee',
1535
-                'post'   => $primary_att->ID(),
1536
-            ],
1537
-            REG_ADMIN_URL
1538
-        );
1539
-        // get formatted address for registrant
1540
-        $formatted_address                         = EEH_Address::format($primary_att);
1541
-        $formatted_address                         =
1542
-            $formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1543
-                ? $formatted_address
1544
-                : '';
1545
-        $this->_template_args['formatted_address'] = $formatted_address;
1546
-        echo EEH_Template::display_template(
1547
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1548
-            $this->_template_args,
1549
-            true
1550
-        );
1551
-    }
1552
-
1553
-
1554
-    /**
1555
-     * txn_billing_info_side_meta_box
1556
-     *    generates HTML for the Edit Transaction side meta box
1557
-     *
1558
-     * @access public
1559
-     * @return void
1560
-     * @throws DomainException
1561
-     * @throws EE_Error
1562
-     * @throws ReflectionException
1563
-     */
1564
-    public function txn_billing_info_side_meta_box()
1565
-    {
1566
-        $this->_template_args['billing_form']     = $this->_transaction->billing_info();
1567
-        $this->_template_args['billing_form_url'] = add_query_arg(
1568
-            ['action' => 'edit_transaction', 'process' => 'billing'],
1569
-            TXN_ADMIN_URL
1570
-        );
1571
-
1572
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1573
-        echo EEH_Template::display_template($template_path, $this->_template_args, true);
1574
-    }
1575
-
1576
-
1577
-    /**
1578
-     * apply_payments_or_refunds
1579
-     *    registers a payment or refund made towards a transaction
1580
-     *
1581
-     * @access public
1582
-     * @return void
1583
-     * @throws EE_Error
1584
-     * @throws InvalidArgumentException
1585
-     * @throws ReflectionException
1586
-     * @throws RuntimeException
1587
-     * @throws InvalidDataTypeException
1588
-     * @throws InvalidInterfaceException
1589
-     */
1590
-    public function apply_payments_or_refunds()
1591
-    {
1592
-        $valid_data = $this->_validate_payment_request_data();
1593
-        $has_access = $this->capabilities->current_user_can(
1594
-            'ee_edit_payments',
1595
-            'apply_payment_or_refund_from_registration_details'
1596
-        );
1597
-        $TXD_ID     = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1598
-        $amount     = 0;
1599
-        if (! empty($valid_data) && $has_access) {
1600
-            $PAY_ID = $valid_data['PAY_ID'];
1601
-            // save  the new payment
1602
-            $payment = $this->_create_payment_from_request_data($valid_data);
1603
-            $amount  = $payment->amount();
1604
-            // get the TXN for this payment
1605
-            $transaction = $payment->transaction();
1606
-            // verify transaction
1607
-            if ($transaction instanceof EE_Transaction) {
1608
-                // calculate_total_payments_and_update_status
1609
-                $this->_process_transaction_payments($transaction);
1610
-                $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1611
-                $this->_remove_existing_registration_payments($payment, $PAY_ID);
1612
-                // apply payment to registrations (if applicable)
1613
-                if (! empty($REG_IDs)) {
1614
-                    $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1615
-                    $this->_maybe_send_notifications();
1616
-                    // now process status changes for the same registrations
1617
-                    $this->_process_registration_status_change($transaction, $REG_IDs);
1618
-                }
1619
-                $this->_maybe_send_notifications($payment);
1620
-                // prepare to render page
1621
-                do_action(
1622
-                    'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1623
-                    $transaction,
1624
-                    $payment
1625
-                );
1626
-            } else {
1627
-                EE_Error::add_error(
1628
-                    esc_html__(
1629
-                        'A valid Transaction for this payment could not be retrieved.',
1630
-                        'event_espresso'
1631
-                    ),
1632
-                    __FILE__,
1633
-                    __FUNCTION__,
1634
-                    __LINE__
1635
-                );
1636
-            }
1637
-        } elseif ($has_access) {
1638
-            EE_Error::add_error(
1639
-                esc_html__(
1640
-                    'The payment form data could not be processed. Please try again.',
1641
-                    'event_espresso'
1642
-                ),
1643
-                __FILE__,
1644
-                __FUNCTION__,
1645
-                __LINE__
1646
-            );
1647
-        } else {
1648
-            EE_Error::add_error(
1649
-                esc_html__(
1650
-                    'You do not have access to apply payments or refunds to a registration.',
1651
-                    'event_espresso'
1652
-                ),
1653
-                __FILE__,
1654
-                __FUNCTION__,
1655
-                __LINE__
1656
-            );
1657
-        }
1658
-        $query_args = [
1659
-            'page'   => 'espresso_transactions',
1660
-            'action' => 'view_transaction',
1661
-            'TXN_ID' => $TXD_ID,
1662
-        ];
1663
-
1664
-        $this->_redirect_after_action(
1665
-            ! EE_Error::has_error(),
1666
-            $amount > 0
1667
-                ? esc_html__('payment', 'event_espresso')
1668
-                : esc_html__('refund', 'event_espresso'),
1669
-            esc_html__('processed', 'event_espresso'),
1670
-            $query_args
1671
-        );
1672
-    }
1673
-
1674
-
1675
-    /**
1676
-     * _validate_payment_request_data
1677
-     *
1678
-     * @return array
1679
-     * @throws EE_Error
1680
-     * @throws InvalidArgumentException
1681
-     * @throws InvalidDataTypeException
1682
-     * @throws InvalidInterfaceException
1683
-     */
1684
-    protected function _validate_payment_request_data()
1685
-    {
1686
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1687
-            return [];
1688
-        }
1689
-        $payment_form = $this->_generate_payment_form_section();
1690
-        try {
1691
-            if ($payment_form->was_submitted()) {
1692
-                $payment_form->receive_form_submission();
1693
-                if (! $payment_form->is_valid()) {
1694
-                    $submission_error_messages = [];
1695
-                    foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1696
-                        if ($validation_error instanceof EE_Validation_Error) {
1697
-                            $form_input                  = $validation_error->get_form_section();
1698
-                            $submission_error_messages[] = sprintf(
1699
-                                _x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1700
-                                $form_input instanceof EE_Form_Input_Base
1701
-                                    ? $form_input->html_label_text()
1702
-                                    : '',
1703
-                                $validation_error->getMessage()
1704
-                            );
1705
-                        }
1706
-                    }
1707
-                    EE_Error::add_error(
1708
-                        implode('<br />', $submission_error_messages),
1709
-                        __FILE__,
1710
-                        __FUNCTION__,
1711
-                        __LINE__
1712
-                    );
1713
-                    return [];
1714
-                }
1715
-            }
1716
-        } catch (EE_Error $e) {
1717
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1718
-            return [];
1719
-        }
1720
-
1721
-        return $payment_form->valid_data();
1722
-    }
1723
-
1724
-
1725
-    /**
1726
-     * _generate_payment_form_section
1727
-     *
1728
-     * @return EE_Form_Section_Proper
1729
-     * @throws EE_Error
1730
-     */
1731
-    protected function _generate_payment_form_section()
1732
-    {
1733
-        return new EE_Form_Section_Proper(
1734
-            [
1735
-                'name'        => 'txn_admin_payment',
1736
-                'subsections' => [
1737
-                    'PAY_ID'          => new EE_Text_Input(
1738
-                        [
1739
-                            'default'               => 0,
1740
-                            'required'              => false,
1741
-                            'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1742
-                            'validation_strategies' => [new EE_Int_Normalization()],
1743
-                        ]
1744
-                    ),
1745
-                    'TXN_ID'          => new EE_Text_Input(
1746
-                        [
1747
-                            'default'               => 0,
1748
-                            'required'              => true,
1749
-                            'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1750
-                            'validation_strategies' => [new EE_Int_Normalization()],
1751
-                        ]
1752
-                    ),
1753
-                    'type'            => new EE_Text_Input(
1754
-                        [
1755
-                            'default'               => 1,
1756
-                            'required'              => true,
1757
-                            'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1758
-                            'validation_strategies' => [new EE_Int_Normalization()],
1759
-                        ]
1760
-                    ),
1761
-                    'amount'          => new EE_Text_Input(
1762
-                        [
1763
-                            'default'               => 0,
1764
-                            'required'              => true,
1765
-                            'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1766
-                            'validation_strategies' => [new EE_Float_Normalization()],
1767
-                        ]
1768
-                    ),
1769
-                    'status'          => new EE_Text_Input(
1770
-                        [
1771
-                            'default'         => EEM_Payment::status_id_approved,
1772
-                            'required'        => true,
1773
-                            'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1774
-                        ]
1775
-                    ),
1776
-                    'PMD_ID'          => new EE_Text_Input(
1777
-                        [
1778
-                            'default'               => 2,
1779
-                            'required'              => true,
1780
-                            'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1781
-                            'validation_strategies' => [new EE_Int_Normalization()],
1782
-                        ]
1783
-                    ),
1784
-                    'date'            => new EE_Text_Input(
1785
-                        [
1786
-                            'default'         => time(),
1787
-                            'required'        => true,
1788
-                            'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1789
-                        ]
1790
-                    ),
1791
-                    'txn_id_chq_nmbr' => new EE_Text_Input(
1792
-                        [
1793
-                            'default'               => '',
1794
-                            'required'              => false,
1795
-                            'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1796
-                            'validation_strategies' => [
1797
-                                new EE_Max_Length_Validation_Strategy(
1798
-                                    esc_html__('Input too long', 'event_espresso'),
1799
-                                    100
1800
-                                ),
1801
-                            ],
1802
-                        ]
1803
-                    ),
1804
-                    'po_number'       => new EE_Text_Input(
1805
-                        [
1806
-                            'default'               => '',
1807
-                            'required'              => false,
1808
-                            'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1809
-                            'validation_strategies' => [
1810
-                                new EE_Max_Length_Validation_Strategy(
1811
-                                    esc_html__('Input too long', 'event_espresso'),
1812
-                                    100
1813
-                                ),
1814
-                            ],
1815
-                        ]
1816
-                    ),
1817
-                    'accounting'      => new EE_Text_Input(
1818
-                        [
1819
-                            'default'               => '',
1820
-                            'required'              => false,
1821
-                            'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1822
-                            'validation_strategies' => [
1823
-                                new EE_Max_Length_Validation_Strategy(
1824
-                                    esc_html__('Input too long', 'event_espresso'),
1825
-                                    100
1826
-                                ),
1827
-                            ],
1828
-                        ]
1829
-                    ),
1830
-                ],
1831
-            ]
1832
-        );
1833
-    }
1834
-
1835
-
1836
-    /**
1837
-     * _create_payment_from_request_data
1838
-     *
1839
-     * @param array $valid_data
1840
-     * @return EE_Payment
1841
-     * @throws EE_Error
1842
-     * @throws InvalidArgumentException
1843
-     * @throws InvalidDataTypeException
1844
-     * @throws InvalidInterfaceException
1845
-     * @throws ReflectionException
1846
-     */
1847
-    protected function _create_payment_from_request_data($valid_data)
1848
-    {
1849
-        $PAY_ID = $valid_data['PAY_ID'];
1850
-        // get payment amount
1851
-        $amount = $valid_data['amount']
1852
-            ? EEH_Money::strip_localized_money_formatting($valid_data['amount'])
1853
-            : 0;
1854
-        // payments have a type value of 1 and refunds have a type value of -1
1855
-        // so multiplying amount by type will give a positive value for payments, and negative values for refunds
1856
-        $amount = $valid_data['type'] < 0
1857
-            ? $amount * -1
1858
-            : $amount;
1859
-        // for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1860
-        $date    = $valid_data['date']
1861
-            ? preg_replace('/\s+/', ' ', $valid_data['date'])
1862
-            : date('Y-m-d g:i a', current_time('timestamp'));
1863
-        $payment = EE_Payment::new_instance(
1864
-            [
1865
-                'TXN_ID'              => $valid_data['TXN_ID'],
1866
-                'STS_ID'              => $valid_data['status'],
1867
-                'PAY_timestamp'       => $date,
1868
-                'PAY_source'          => EEM_Payment_Method::scope_admin,
1869
-                'PMD_ID'              => $valid_data['PMD_ID'],
1870
-                'PAY_amount'          => $amount,
1871
-                'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1872
-                'PAY_po_number'       => $valid_data['po_number'],
1873
-                'PAY_extra_accntng'   => $valid_data['accounting'],
1874
-                'PAY_details'         => $valid_data,
1875
-                'PAY_ID'              => $PAY_ID,
1876
-            ],
1877
-            '',
1878
-            ['Y-m-d', 'g:i a']
1879
-        );
1880
-
1881
-        if (! $payment->save()) {
1882
-            EE_Error::add_error(
1883
-                sprintf(
1884
-                    esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1885
-                    $payment->ID()
1886
-                ),
1887
-                __FILE__,
1888
-                __FUNCTION__,
1889
-                __LINE__
1890
-            );
1891
-        }
1892
-
1893
-        return $payment;
1894
-    }
1895
-
1896
-
1897
-    /**
1898
-     * _process_transaction_payments
1899
-     *
1900
-     * @param EE_Transaction $transaction
1901
-     * @return void
1902
-     * @throws EE_Error
1903
-     * @throws InvalidArgumentException
1904
-     * @throws ReflectionException
1905
-     * @throws InvalidDataTypeException
1906
-     * @throws InvalidInterfaceException
1907
-     */
1908
-    protected function _process_transaction_payments(EE_Transaction $transaction)
1909
-    {
1910
-        /** @type EE_Transaction_Payments $transaction_payments */
1911
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1912
-        // update the transaction with this payment
1913
-        if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1914
-            EE_Error::add_success(
1915
-                esc_html__(
1916
-                    'The payment has been processed successfully.',
1917
-                    'event_espresso'
1918
-                ),
1919
-                __FILE__,
1920
-                __FUNCTION__,
1921
-                __LINE__
1922
-            );
1923
-        } else {
1924
-            EE_Error::add_error(
1925
-                esc_html__(
1926
-                    'The payment was processed successfully but the amount paid for the transaction was not updated.',
1927
-                    'event_espresso'
1928
-                ),
1929
-                __FILE__,
1930
-                __FUNCTION__,
1931
-                __LINE__
1932
-            );
1933
-        }
1934
-    }
1935
-
1936
-
1937
-    /**
1938
-     * _get_REG_IDs_to_apply_payment_to
1939
-     * returns a list of registration IDs that the payment will apply to
1940
-     *
1941
-     * @param EE_Payment $payment
1942
-     * @return array
1943
-     * @throws EE_Error
1944
-     * @throws InvalidArgumentException
1945
-     * @throws InvalidDataTypeException
1946
-     * @throws InvalidInterfaceException
1947
-     * @throws ReflectionException
1948
-     */
1949
-    protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1950
-    {
1951
-        // grab array of IDs for specific registrations to apply changes to
1952
-        $apply_to_all = $this->request->getRequestParam(
1953
-            'txn_admin_payment[apply_to_all_registrations]',
1954
-            false,
1955
-            DataType::BOOL
1956
-        );
1957
-        $REG_IDs      = ! $apply_to_all
1958
-            ? $this->request->getRequestParam(
1959
-                'txn_admin_payment[registrations]',
1960
-                [],
1961
-                DataType::INT,
1962
-                true
1963
-            )
1964
-            : [];
1965
-        // nothing specified ? then get all reg IDs
1966
-        if ($apply_to_all || empty($REG_IDs)) {
1967
-            $registrations = $payment->transaction()->registrations(
1968
-                [
1969
-                    [
1970
-                        'STS_ID' => [
1971
-                            'NOT_IN', [ RegStatus::CANCELLED ]
1972
-                        ]
1973
-                    ]
1974
-                ]
1975
-            );
1976
-            $REG_IDs       = ! empty($registrations)
1977
-                ? array_keys($registrations)
1978
-                : $this->_get_existing_reg_payment_REG_IDs($payment);
1979
-        }
1980
-        // ensure that REG_IDs are integers and NOT strings
1981
-        return array_map('absint', $REG_IDs);
1982
-    }
1983
-
1984
-
1985
-    /**
1986
-     * @return array
1987
-     */
1988
-    public function existing_reg_payment_REG_IDs()
1989
-    {
1990
-        return $this->_existing_reg_payment_REG_IDs;
1991
-    }
1992
-
1993
-
1994
-    /**
1995
-     * @param array $existing_reg_payment_REG_IDs
1996
-     */
1997
-    public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1998
-    {
1999
-        $this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
2000
-    }
2001
-
2002
-
2003
-    /**
2004
-     * _get_existing_reg_payment_REG_IDs
2005
-     * returns a list of registration IDs that the payment is currently related to
2006
-     * as recorded in the database
2007
-     *
2008
-     * @param EE_Payment $payment
2009
-     * @return array
2010
-     * @throws EE_Error
2011
-     * @throws InvalidArgumentException
2012
-     * @throws InvalidDataTypeException
2013
-     * @throws InvalidInterfaceException
2014
-     * @throws ReflectionException
2015
-     */
2016
-    protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2017
-    {
2018
-        if ($this->existing_reg_payment_REG_IDs() === null) {
2019
-            // let's get any existing reg payment records for this payment
2020
-            $existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2021
-            // but we only want the REG IDs, so grab the array keys
2022
-            $existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2023
-                ? array_keys($existing_reg_payment_REG_IDs)
2024
-                : [];
2025
-            $this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2026
-        }
2027
-
2028
-        return $this->existing_reg_payment_REG_IDs();
2029
-    }
2030
-
2031
-
2032
-    /**
2033
-     * _remove_existing_registration_payments
2034
-     * this calculates the difference between existing relations
2035
-     * to the supplied payment and the new list registration IDs,
2036
-     * removes any related registrations that no longer apply,
2037
-     * and then updates the registration paid fields
2038
-     *
2039
-     * @param EE_Payment $payment
2040
-     * @param int        $PAY_ID
2041
-     * @return bool;
2042
-     * @throws EE_Error
2043
-     * @throws InvalidArgumentException
2044
-     * @throws ReflectionException
2045
-     * @throws InvalidDataTypeException
2046
-     * @throws InvalidInterfaceException
2047
-     */
2048
-    protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2049
-    {
2050
-        // newly created payments will have nothing recorded for $PAY_ID
2051
-        if (absint($PAY_ID) === 0) {
2052
-            return false;
2053
-        }
2054
-        $existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2055
-        if (empty($existing_reg_payment_REG_IDs)) {
2056
-            return false;
2057
-        }
2058
-        /** @type EE_Transaction_Payments $transaction_payments */
2059
-        $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2060
-
2061
-        return $transaction_payments->delete_registration_payments_and_update_registrations(
2062
-            $payment,
2063
-            [
2064
-                [
2065
-                    'PAY_ID' => $payment->ID(),
2066
-                    'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2067
-                ],
2068
-            ]
2069
-        );
2070
-    }
2071
-
2072
-
2073
-    /**
2074
-     * _update_registration_payments
2075
-     * this applies the payments to the selected registrations
2076
-     * but only if they have not already been paid for
2077
-     *
2078
-     * @param EE_Transaction $transaction
2079
-     * @param EE_Payment     $payment
2080
-     * @param array          $REG_IDs
2081
-     * @return void
2082
-     * @throws EE_Error
2083
-     * @throws InvalidArgumentException
2084
-     * @throws ReflectionException
2085
-     * @throws RuntimeException
2086
-     * @throws InvalidDataTypeException
2087
-     * @throws InvalidInterfaceException
2088
-     */
2089
-    protected function _update_registration_payments(
2090
-        EE_Transaction $transaction,
2091
-        EE_Payment $payment,
2092
-        $REG_IDs = []
2093
-    ) {
2094
-        // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2095
-        // so let's do that using our set of REG_IDs from the form
2096
-        $registration_query_where_params = [
2097
-            'REG_ID' => ['IN', $REG_IDs],
2098
-        ];
2099
-        // but add in some conditions regarding payment,
2100
-        // so that we don't apply payments to registrations that are free or have already been paid for
2101
-        // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2102
-        if (! $payment->is_a_refund()) {
2103
-            $registration_query_where_params['REG_final_price']  = ['!=', 0];
2104
-            $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2105
-        }
2106
-        $registrations = $transaction->registrations([$registration_query_where_params]);
2107
-        if (! empty($registrations)) {
2108
-            /** @type EE_Payment_Processor $payment_processor */
2109
-            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2110
-            $payment_processor->process_registration_payments($transaction, $payment, $registrations);
2111
-        }
2112
-    }
2113
-
2114
-
2115
-    /**
2116
-     * _process_registration_status_change
2117
-     * This processes requested registration status changes for all the registrations
2118
-     * on a given transaction and (optionally) sends out notifications for the changes.
2119
-     *
2120
-     * @param EE_Transaction $transaction
2121
-     * @param array          $REG_IDs
2122
-     * @return bool
2123
-     * @throws EE_Error
2124
-     * @throws InvalidArgumentException
2125
-     * @throws ReflectionException
2126
-     * @throws InvalidDataTypeException
2127
-     * @throws InvalidInterfaceException
2128
-     */
2129
-    protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2130
-    {
2131
-        // first if there is no change in status then we get out.
2132
-        $reg_status = $reg_status
2133
-            ?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2134
-        if ($reg_status === 'NAN') {
2135
-            // no error message, no change requested, just nothing to do man.
2136
-            return false;
2137
-        }
2138
-        /** @type EE_Transaction_Processor $transaction_processor */
2139
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2140
-
2141
-        // made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2142
-        return $transaction_processor->manually_update_registration_statuses(
2143
-            $transaction,
2144
-            $reg_status,
2145
-            [['REG_ID' => ['IN', $REG_IDs]]]
2146
-        );
2147
-    }
2148
-
2149
-
2150
-    /**
2151
-     * _build_payment_json_response
2152
-     *
2153
-     * @access public
2154
-     * @param EE_Payment  $payment
2155
-     * @param array       $REG_IDs
2156
-     * @param bool | null $delete_txn_reg_status_change
2157
-     * @return array
2158
-     * @throws EE_Error
2159
-     * @throws InvalidArgumentException
2160
-     * @throws InvalidDataTypeException
2161
-     * @throws InvalidInterfaceException
2162
-     * @throws ReflectionException
2163
-     */
2164
-    protected function _build_payment_json_response(
2165
-        EE_Payment $payment,
2166
-        $REG_IDs = [],
2167
-        $delete_txn_reg_status_change = null
2168
-    ) {
2169
-        // was the payment deleted ?
2170
-        if (is_bool($delete_txn_reg_status_change)) {
2171
-            return [
2172
-                'PAY_ID'                       => $payment->ID(),
2173
-                'amount'                       => $payment->amount(),
2174
-                'total_paid'                   => $payment->transaction()->paid(),
2175
-                'txn_status'                   => $payment->transaction()->status_ID(),
2176
-                'pay_status'                   => $payment->STS_ID(),
2177
-                'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2178
-                'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2179
-            ];
2180
-        }
2181
-
2182
-        $this->_get_payment_status_array();
2183
-        $payment_method = $payment->payment_method();
2184
-        return [
2185
-            'amount'           => $payment->amount(),
2186
-            'total_paid'       => $payment->transaction()->paid(),
2187
-            'txn_status'       => $payment->transaction()->status_ID(),
2188
-            'pay_status'       => $payment->STS_ID(),
2189
-            'PAY_ID'           => $payment->ID(),
2190
-            'STS_ID'           => $payment->STS_ID(),
2191
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2192
-            'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2193
-            'method'           => strtoupper($payment->source()),
2194
-            'PM_ID'            => $payment_method instanceof EE_Payment_Method
2195
-                ? $payment_method->ID()
2196
-                : 1,
2197
-            'gateway'          => $payment_method instanceof EE_Payment_Method
2198
-                ? $payment_method->admin_name()
2199
-                : esc_html__('Unknown', 'event_espresso'),
2200
-            'gateway_response' => $payment->gateway_response(),
2201
-            'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2202
-            'po_number'        => $payment->po_number(),
2203
-            'extra_accntng'    => $payment->extra_accntng(),
2204
-            'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2205
-        ];
2206
-    }
2207
-
2208
-
2209
-    /**
2210
-     * delete_payment
2211
-     *    delete a payment or refund made towards a transaction
2212
-     *
2213
-     * @access public
2214
-     * @return void
2215
-     * @throws EE_Error
2216
-     * @throws InvalidArgumentException
2217
-     * @throws ReflectionException
2218
-     * @throws InvalidDataTypeException
2219
-     * @throws InvalidInterfaceException
2220
-     */
2221
-    public function delete_payment()
2222
-    {
2223
-        $TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2224
-        // $json_response_data = ['return_data' => false];
2225
-        $PAY_ID     = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2226
-        $amount     = 0;
2227
-        $can_delete = $this->capabilities->current_user_can(
2228
-            'ee_delete_payments',
2229
-            'delete_payment_from_registration_details'
2230
-        );
2231
-        if ($PAY_ID && $can_delete) {
2232
-            $delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2233
-            $payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2234
-            if ($payment instanceof EE_Payment) {
2235
-                $amount  = $payment->amount();
2236
-                $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2237
-                /** @type EE_Transaction_Payments $transaction_payments */
2238
-                $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2239
-                if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2240
-                    if ($delete_txn_reg_status_change) {
2241
-                        $this->_maybe_send_notifications();
2242
-                        $this->_process_registration_status_change(
2243
-                            $payment->transaction(),
2244
-                            $REG_IDs,
2245
-                            $delete_txn_reg_status_change
2246
-                        );
2247
-                    }
2248
-                }
2249
-            } else {
2250
-                EE_Error::add_error(
2251
-                    esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2252
-                    __FILE__,
2253
-                    __FUNCTION__,
2254
-                    __LINE__
2255
-                );
2256
-            }
2257
-        } elseif ($can_delete) {
2258
-            EE_Error::add_error(
2259
-                esc_html__(
2260
-                    'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2261
-                    'event_espresso'
2262
-                ),
2263
-                __FILE__,
2264
-                __FUNCTION__,
2265
-                __LINE__
2266
-            );
2267
-        } else {
2268
-            EE_Error::add_error(
2269
-                esc_html__(
2270
-                    'You do not have access to delete a payment.',
2271
-                    'event_espresso'
2272
-                ),
2273
-                __FILE__,
2274
-                __FUNCTION__,
2275
-                __LINE__
2276
-            );
2277
-        }
2278
-        $query_args = [
2279
-            'page'   => 'espresso_transactions',
2280
-            'action' => 'view_transaction',
2281
-            'TXN_ID' => $TXD_ID,
2282
-        ];
2283
-        $this->_redirect_after_action(
2284
-            ! EE_Error::has_error(),
2285
-            $amount > 0
2286
-                ? esc_html__('payment', 'event_espresso')
2287
-                : esc_html__('refund', 'event_espresso'),
2288
-            esc_html__('deleted', 'event_espresso'),
2289
-            $query_args
2290
-        );
2291
-    }
2292
-
2293
-
2294
-    /**
2295
-     * _registration_payment_data_array
2296
-     * adds info for 'owing' and 'paid' for each registration to the json response
2297
-     *
2298
-     * @access protected
2299
-     * @param array $REG_IDs
2300
-     * @return array
2301
-     * @throws EE_Error
2302
-     * @throws InvalidArgumentException
2303
-     * @throws InvalidDataTypeException
2304
-     * @throws InvalidInterfaceException
2305
-     * @throws ReflectionException
2306
-     */
2307
-    protected function _registration_payment_data_array($REG_IDs)
2308
-    {
2309
-        $registration_payment_data = [];
2310
-        // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2311
-        if (! empty($REG_IDs)) {
2312
-            $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2313
-            foreach ($registrations as $registration) {
2314
-                if ($registration instanceof EE_Registration) {
2315
-                    $registration_payment_data[ $registration->ID() ] = [
2316
-                        'paid'  => $registration->pretty_paid(),
2317
-                        'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2318
-                    ];
2319
-                }
2320
-            }
2321
-        }
2322
-
2323
-        return $registration_payment_data;
2324
-    }
2325
-
2326
-
2327
-    /**
2328
-     * _maybe_send_notifications
2329
-     * determines whether or not the admin has indicated that notifications should be sent.
2330
-     * If so, will toggle a filter switch for delivering registration notices.
2331
-     * If passed an EE_Payment object, then it will trigger payment notifications instead.
2332
-     *
2333
-     * @access protected
2334
-     * @param EE_Payment | null $payment
2335
-     */
2336
-    protected function _maybe_send_notifications($payment = null)
2337
-    {
2338
-        switch ($payment instanceof EE_Payment) {
2339
-            // payment notifications
2340
-            case true:
2341
-                if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2342
-                    $this->_process_payment_notification($payment);
2343
-                }
2344
-                break;
2345
-            // registration notifications
2346
-            case false:
2347
-                if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2348
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2349
-                }
2350
-                break;
2351
-        }
2352
-    }
2353
-
2354
-
2355
-    /**
2356
-     * _send_payment_reminder
2357
-     *    generates HTML for the View Transaction Details Admin page
2358
-     *
2359
-     * @access protected
2360
-     * @return void
2361
-     * @throws EE_Error
2362
-     * @throws InvalidArgumentException
2363
-     * @throws InvalidDataTypeException
2364
-     * @throws InvalidInterfaceException
2365
-     */
2366
-    protected function _send_payment_reminder()
2367
-    {
2368
-        $TXN_ID      = $this->request->getRequestParam('TXN_ID', 0, 'int');
2369
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2370
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2371
-        $query_args  = $redirect_to
2372
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2373
-            : [];
2374
-        do_action(
2375
-            'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2376
-            $transaction
2377
-        );
2378
-        $this->_redirect_after_action(
2379
-            false,
2380
-            esc_html__('payment reminder', 'event_espresso'),
2381
-            esc_html__('sent', 'event_espresso'),
2382
-            $query_args,
2383
-            true
2384
-        );
2385
-    }
2386
-
2387
-
2388
-    /**
2389
-     *  get_transactions
2390
-     *    get transactions for given parameters (used by list table)
2391
-     *
2392
-     * @param int     $per_page how many transactions displayed per page
2393
-     * @param boolean $count    return the count or objects
2394
-     * @param string  $view
2395
-     * @return EE_Transaction[]|int int = count || array of transaction objects
2396
-     * @throws EE_Error
2397
-     * @throws InvalidArgumentException
2398
-     * @throws InvalidDataTypeException
2399
-     * @throws InvalidInterfaceException
2400
-     * @throws ReflectionException
2401
-     */
2402
-    public function get_transactions($per_page, $count = false, $view = '')
2403
-    {
2404
-        $start_date = wp_strip_all_tags(
2405
-            $this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2406
-        );
2407
-        $end_date   = wp_strip_all_tags(
2408
-            $this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2409
-        );
2410
-
2411
-        // make sure our timestamps start and end right at the boundaries for each day
2412
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2413
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2414
-
2415
-
2416
-        // convert to timestamps
2417
-        $start_date = strtotime($start_date);
2418
-        $end_date   = strtotime($end_date);
2419
-
2420
-        // makes sure start date is the lowest value and vice versa
2421
-        $start_date = min($start_date, $end_date);
2422
-        $end_date   = max($start_date, $end_date);
2423
-
2424
-        // convert to correct format for query
2425
-        $start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2426
-            'TXN_timestamp',
2427
-            date('Y-m-d H:i:s', $start_date),
2428
-            'Y-m-d H:i:s'
2429
-        );
2430
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2431
-            'TXN_timestamp',
2432
-            date('Y-m-d H:i:s', $end_date),
2433
-            'Y-m-d H:i:s'
2434
-        );
2435
-
2436
-
2437
-        // set orderby
2438
-        $orderby = $this->request->getRequestParam('orderby');
2439
-
2440
-        switch ($orderby) {
2441
-            case 'TXN_ID':
2442
-                break;
2443
-            case 'ATT_fname':
2444
-                $orderby = 'Registration.Attendee.ATT_fname';
2445
-                break;
2446
-            case 'event_name':
2447
-                $orderby = 'Registration.Event.EVT_name';
2448
-                break;
2449
-            default: // 'TXN_timestamp'
2450
-                $orderby = 'TXN_timestamp';
2451
-        }
2452
-
2453
-        $sort         = $this->request->getRequestParam('order', 'DESC');
2454
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
2455
-
2456
-        $per_page = absint($per_page)
2457
-            ? $per_page
2458
-            : 10;
2459
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2460
-
2461
-        $offset = ($current_page - 1) * $per_page;
2462
-        $limit  = [$offset, $per_page];
2463
-
2464
-        $_where = [
2465
-            'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2466
-            'Registration.REG_count' => 1,
2467
-        ];
2468
-
2469
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2470
-        if ($EVT_ID) {
2471
-            $_where['Registration.EVT_ID'] = $EVT_ID;
2472
-        }
2473
-
2474
-        $search_term = $this->request->getRequestParam('s');
2475
-        if ($search_term) {
2476
-            $search_term  = '%' . $search_term . '%';
2477
-            $_where['OR'] = [
2478
-                'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2479
-                'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2480
-                'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2481
-                'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2482
-                'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2483
-                'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2484
-                'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2485
-                'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2486
-                'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2487
-                'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2488
-                'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2489
-                'Registration.REG_final_price'        => ['LIKE', $search_term],
2490
-                'Registration.REG_code'               => ['LIKE', $search_term],
2491
-                'Registration.REG_count'              => ['LIKE', $search_term],
2492
-                'Registration.REG_group_size'         => ['LIKE', $search_term],
2493
-                'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2494
-                'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2495
-                'Payment.PAY_source'                  => ['LIKE', $search_term],
2496
-                'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2497
-                'TXN_session_data'                    => ['LIKE', $search_term],
2498
-                'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2499
-            ];
2500
-        }
2501
-
2502
-        $status = $this->request->getRequestParam('status');
2503
-        // failed transactions
2504
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2505
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2506
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2507
-
2508
-        if ($failed) {
2509
-            $_where['STS_ID'] = EEM_Transaction::failed_status_code;
2510
-        } elseif ($abandoned) {
2511
-            $_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2512
-        } elseif ($incomplete) {
2513
-            $_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2514
-        } else {
2515
-            $_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2516
-            $_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2517
-        }
2518
-
2519
-        $query_params = apply_filters(
2520
-            'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2521
-            [
2522
-                $_where,
2523
-                'order_by'                 => [$orderby => $sort],
2524
-                'limit'                    => $limit,
2525
-                'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2526
-            ],
2527
-            $this->request->requestParams(),
2528
-            $view,
2529
-            $count
2530
-        );
2531
-
2532
-        return $count
2533
-            ? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2534
-            : EEM_Transaction::instance()->get_all($query_params);
2535
-    }
2536
-
2537
-
2538
-    /**
2539
-     * @throws EE_Error
2540
-     * @throws InvalidArgumentException
2541
-     * @throws InvalidDataTypeException
2542
-     * @throws InvalidInterfaceException
2543
-     * @throws ReflectionException
2544
-     * @throws RuntimeException
2545
-     * @since 4.9.79.p
2546
-     */
2547
-    public function recalculateLineItems()
2548
-    {
2549
-        $TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2550
-        /** @var EE_Transaction $transaction */
2551
-        $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2552
-        $success     = $transaction->recalculateLineItems();
2553
-        $redirect_to = $this->request->getRequestParam('redirect_to');
2554
-        $query_args  = $redirect_to
2555
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2556
-            : [];
2557
-        $this->_redirect_after_action(
2558
-            $success,
2559
-            esc_html__('Transaction taxes and totals', 'event_espresso'),
2560
-            esc_html__('recalculated', 'event_espresso'),
2561
-            $query_args,
2562
-            true
2563
-        );
2564
-    }
17
+	/**
18
+	 * @var EE_Transaction
19
+	 */
20
+	private $_transaction;
21
+
22
+	/**
23
+	 * @var EE_Session
24
+	 */
25
+	private $_session;
26
+
27
+	/**
28
+	 * @var array $_txn_status
29
+	 */
30
+	private static $_txn_status;
31
+
32
+	/**
33
+	 * @var array $_pay_status
34
+	 */
35
+	private static $_pay_status;
36
+
37
+	/**
38
+	 * @var array $_existing_reg_payment_REG_IDs
39
+	 */
40
+	protected $_existing_reg_payment_REG_IDs;
41
+
42
+
43
+	/**
44
+	 *    _init_page_props
45
+	 *
46
+	 * @return void
47
+	 */
48
+	protected function _init_page_props()
49
+	{
50
+		$this->page_slug        = TXN_PG_SLUG;
51
+		$this->page_label       = esc_html__('Transactions', 'event_espresso');
52
+		$this->_admin_base_url  = TXN_ADMIN_URL;
53
+		$this->_admin_base_path = TXN_ADMIN;
54
+	}
55
+
56
+
57
+	/**
58
+	 *    _ajax_hooks
59
+	 *
60
+	 * @return void
61
+	 */
62
+	protected function _ajax_hooks()
63
+	{
64
+		// add_action('wp_ajax_espresso_apply_payment', [$this, 'apply_payments_or_refunds']);
65
+		// add_action('wp_ajax_espresso_apply_refund', [$this, 'apply_payments_or_refunds']);
66
+		// add_action('wp_ajax_espresso_delete_payment', [$this, 'delete_payment']);
67
+	}
68
+
69
+
70
+	/**
71
+	 *    _define_page_props
72
+	 *
73
+	 * @return void
74
+	 */
75
+	protected function _define_page_props()
76
+	{
77
+		$this->_admin_page_title = $this->page_label;
78
+		$this->_labels           = [
79
+			'buttons' => [
80
+				'add'    => esc_html__('Add New Transaction', 'event_espresso'),
81
+				'edit'   => esc_html__('Edit Transaction', 'event_espresso'),
82
+				'delete' => esc_html__('Delete Transaction', 'event_espresso'),
83
+			],
84
+		];
85
+	}
86
+
87
+
88
+	/**
89
+	 *        grab url requests and route them
90
+	 *
91
+	 * @access private
92
+	 * @return void
93
+	 * @throws EE_Error
94
+	 * @throws InvalidArgumentException
95
+	 * @throws InvalidDataTypeException
96
+	 * @throws InvalidInterfaceException
97
+	 * @throws ReflectionException
98
+	 */
99
+	public function _set_page_routes()
100
+	{
101
+		$this->_set_transaction_status_array();
102
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
103
+
104
+		$this->_page_routes = [
105
+
106
+			'default' => [
107
+				'func'       => '_transactions_overview_list_table',
108
+				'capability' => 'ee_read_transactions',
109
+			],
110
+
111
+			'view_transaction' => [
112
+				'func'       => '_transaction_details',
113
+				'capability' => 'ee_read_transaction',
114
+				'obj_id'     => $TXN_ID,
115
+			],
116
+
117
+			'send_payment_reminder' => [
118
+				'func'       => '_send_payment_reminder',
119
+				'noheader'   => true,
120
+				'capability' => 'ee_send_message',
121
+			],
122
+
123
+			'espresso_apply_payment' => [
124
+				'func'       => [$this, 'apply_payments_or_refunds'],
125
+				'noheader'   => true,
126
+				'capability' => 'ee_edit_payments',
127
+			],
128
+
129
+			'espresso_apply_refund' => [
130
+				'func'       => [$this, 'apply_payments_or_refunds'],
131
+				'noheader'   => true,
132
+				'capability' => 'ee_edit_payments',
133
+			],
134
+
135
+			'espresso_delete_payment' => [
136
+				'func'       => [$this, 'delete_payment'],
137
+				'noheader'   => true,
138
+				'capability' => 'ee_delete_payments',
139
+			],
140
+
141
+			'espresso_recalculate_line_items' => [
142
+				'func'       => 'recalculateLineItems',
143
+				'noheader'   => true,
144
+				'capability' => 'ee_edit_payments',
145
+			],
146
+
147
+		];
148
+	}
149
+
150
+
151
+	protected function _set_page_config()
152
+	{
153
+		$TXN_ID             = $this->request->getRequestParam('TXN_ID', 0, 'int');
154
+		$this->_page_config = [
155
+			'default'          => [
156
+				'nav'           => [
157
+					'label' => esc_html__('Overview', 'event_espresso'),
158
+					'icon'  => 'dashicons-list-view',
159
+					'order' => 10,
160
+				],
161
+				'list_table'    => 'EE_Admin_Transactions_List_Table',
162
+				'help_tabs'     => [
163
+					'transactions_overview_help_tab'                       => [
164
+						'title'    => esc_html__('Transactions Overview', 'event_espresso'),
165
+						'filename' => 'transactions_overview',
166
+					],
167
+					'transactions_overview_table_column_headings_help_tab' => [
168
+						'title'    => esc_html__('Transactions Table Column Headings', 'event_espresso'),
169
+						'filename' => 'transactions_overview_table_column_headings',
170
+					],
171
+					'transactions_overview_views_filters_help_tab'         => [
172
+						'title'    => esc_html__('Transaction Views & Filters & Search', 'event_espresso'),
173
+						'filename' => 'transactions_overview_views_filters_search',
174
+					],
175
+				],
176
+				'require_nonce' => false,
177
+			],
178
+			'view_transaction' => [
179
+				'nav'       => [
180
+					'label'      => esc_html__('View Transaction', 'event_espresso'),
181
+					'icon'       => 'dashicons-cart',
182
+					'order'      => 5,
183
+					'url'        => $TXN_ID
184
+						? add_query_arg(['TXN_ID' => $TXN_ID], $this->_current_page_view_url)
185
+						: $this->_admin_base_url,
186
+					'persistent' => false,
187
+				],
188
+				'help_tabs' => [
189
+					'transactions_view_transaction_help_tab'                                              => [
190
+						'title'    => esc_html__('View Transaction', 'event_espresso'),
191
+						'filename' => 'transactions_view_transaction',
192
+					],
193
+					'transactions_view_transaction_transaction_details_table_help_tab'                    => [
194
+						'title'    => esc_html__('Transaction Details Table', 'event_espresso'),
195
+						'filename' => 'transactions_view_transaction_transaction_details_table',
196
+					],
197
+					'transactions_view_transaction_attendees_registered_help_tab'                         => [
198
+						'title'    => esc_html__('Attendees Registered', 'event_espresso'),
199
+						'filename' => 'transactions_view_transaction_attendees_registered',
200
+					],
201
+					'transactions_view_transaction_views_primary_registrant_billing_information_help_tab' => [
202
+						'title'    => esc_html__('Primary Registrant & Billing Information', 'event_espresso'),
203
+						'filename' => 'transactions_view_transaction_primary_registrant_billing_information',
204
+					],
205
+				],
206
+				'qtips'     => ['Transaction_Details_Tips'],
207
+				'metaboxes' => ['_transaction_details_metaboxes'],
208
+
209
+				'require_nonce' => false,
210
+			],
211
+		];
212
+	}
213
+
214
+
215
+	/**
216
+	 * The below methods aren't used by this class currently
217
+	 */
218
+	protected function _add_screen_options()
219
+	{
220
+		// noop
221
+	}
222
+
223
+
224
+	protected function _add_feature_pointers()
225
+	{
226
+		// noop
227
+	}
228
+
229
+
230
+	public function admin_init()
231
+	{
232
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
233
+		$event_name    = $this->request->getRequestParam('event_name');
234
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
235
+		// IF a registration was JUST added via the admin...
236
+		if ($EVT_ID && $event_name && $redirect_from) {
237
+			// then set a cookie so that we can block any attempts to use
238
+			// the back button as a way to enter another registration.
239
+			setcookie('ee_registration_added', $EVT_ID, time() + WEEK_IN_SECONDS, '/');
240
+			// and update the global
241
+			$_COOKIE['ee_registration_added'] = $EVT_ID;
242
+		}
243
+		EE_Registry::$i18n_js_strings['invalid_server_response'] = esc_html__(
244
+			'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.',
245
+			'event_espresso'
246
+		);
247
+		EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
248
+			'An error occurred! Please refresh the page and try again.',
249
+			'event_espresso'
250
+		);
251
+		EE_Registry::$i18n_js_strings['txn_status_array']        = self::$_txn_status;
252
+		EE_Registry::$i18n_js_strings['pay_status_array']        = self::$_pay_status;
253
+		EE_Registry::$i18n_js_strings['payments_total']          = esc_html__('Payments Total', 'event_espresso');
254
+		EE_Registry::$i18n_js_strings['transaction_overpaid']    = esc_html__(
255
+			'This transaction has been overpaid ! Payments Total',
256
+			'event_espresso'
257
+		);
258
+	}
259
+
260
+
261
+	public function admin_notices()
262
+	{
263
+		// noop
264
+	}
265
+
266
+
267
+	public function admin_footer_scripts()
268
+	{
269
+		// noop
270
+	}
271
+
272
+
273
+	/**
274
+	 * _set_transaction_status_array
275
+	 * sets list of transaction statuses
276
+	 *
277
+	 * @access private
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 * @throws InvalidArgumentException
281
+	 * @throws InvalidDataTypeException
282
+	 * @throws InvalidInterfaceException
283
+	 * @throws ReflectionException
284
+	 */
285
+	private function _set_transaction_status_array()
286
+	{
287
+		self::$_txn_status = EEM_Transaction::instance()->status_array(true);
288
+	}
289
+
290
+
291
+	/**
292
+	 * get_transaction_status_array
293
+	 * return the transaction status array for wp_list_table
294
+	 *
295
+	 * @access public
296
+	 * @return array
297
+	 */
298
+	public function get_transaction_status_array()
299
+	{
300
+		return self::$_txn_status;
301
+	}
302
+
303
+
304
+	/**
305
+	 *    get list of payment statuses
306
+	 *
307
+	 * @access private
308
+	 * @return void
309
+	 * @throws EE_Error
310
+	 * @throws InvalidArgumentException
311
+	 * @throws InvalidDataTypeException
312
+	 * @throws InvalidInterfaceException
313
+	 * @throws ReflectionException
314
+	 */
315
+	private function _get_payment_status_array()
316
+	{
317
+		self::$_pay_status                      = EEM_Payment::instance()->status_array(true);
318
+		$this->_template_args['payment_status'] = self::$_pay_status;
319
+	}
320
+
321
+
322
+	/**
323
+	 *    _add_screen_options_default
324
+	 *
325
+	 * @access protected
326
+	 * @return void
327
+	 * @throws InvalidArgumentException
328
+	 * @throws InvalidDataTypeException
329
+	 * @throws InvalidInterfaceException
330
+	 */
331
+	protected function _add_screen_options_default()
332
+	{
333
+		$this->_per_page_screen_option();
334
+	}
335
+
336
+
337
+	/**
338
+	 * load_scripts_styles
339
+	 *
340
+	 * @access public
341
+	 * @return void
342
+	 */
343
+	public function load_scripts_styles()
344
+	{
345
+		// enqueue style
346
+		wp_register_style(
347
+			'espresso_txn',
348
+			TXN_ASSETS_URL . 'espresso_transactions_admin.css',
349
+			[],
350
+			EVENT_ESPRESSO_VERSION
351
+		);
352
+		wp_enqueue_style('espresso_txn');
353
+		// scripts
354
+		wp_register_script(
355
+			'espresso_txn',
356
+			TXN_ASSETS_URL . 'espresso_transactions_admin.js',
357
+			[
358
+				'ee_admin_js',
359
+				'ee-datepicker',
360
+				'jquery-ui-datepicker',
361
+				'jquery-ui-draggable',
362
+				'ee-dialog',
363
+				'ee-accounting',
364
+				'ee-serialize-full-array',
365
+			],
366
+			EVENT_ESPRESSO_VERSION,
367
+			true
368
+		);
369
+		wp_enqueue_script('espresso_txn');
370
+	}
371
+
372
+
373
+	/**
374
+	 *    load_scripts_styles_view_transaction
375
+	 *
376
+	 * @access public
377
+	 * @return void
378
+	 */
379
+	public function load_scripts_styles_view_transaction()
380
+	{
381
+		// styles
382
+		wp_enqueue_style('espresso-ui-theme');
383
+	}
384
+
385
+
386
+	/**
387
+	 *    load_scripts_styles_default
388
+	 *
389
+	 * @access public
390
+	 * @return void
391
+	 */
392
+	public function load_scripts_styles_default()
393
+	{
394
+		// styles
395
+		wp_enqueue_style('espresso-ui-theme');
396
+	}
397
+
398
+
399
+	/**
400
+	 *    _set_list_table_views_default
401
+	 *
402
+	 * @access protected
403
+	 * @return void
404
+	 */
405
+	protected function _set_list_table_views_default()
406
+	{
407
+		$this->_views = [
408
+			'all'        => [
409
+				'slug'  => 'all',
410
+				'label' => esc_html__('View All Transactions', 'event_espresso'),
411
+				'count' => 0,
412
+			],
413
+			'abandoned'  => [
414
+				'slug'  => 'abandoned',
415
+				'label' => esc_html__('Abandoned Transactions', 'event_espresso'),
416
+				'count' => 0,
417
+			],
418
+			'incomplete' => [
419
+				'slug'  => 'incomplete',
420
+				'label' => esc_html__('Incomplete Transactions', 'event_espresso'),
421
+				'count' => 0,
422
+			],
423
+		];
424
+		if (
425
+			/**
426
+			 * Filters whether a link to the "Failed Transactions" list table
427
+			 * appears on the Transactions Admin Page list table.
428
+			 * List display can be turned back on via the following:
429
+			 * add_filter(
430
+			 *     'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
431
+			 *     '__return_true'
432
+			 * );
433
+			 *
434
+			 * @param boolean                 $display_failed_txns_list
435
+			 * @param Transactions_Admin_Page $this
436
+			 * @since 4.9.70.p
437
+			 */
438
+		apply_filters(
439
+			'FHEE__Transactions_Admin_Page___set_list_table_views_default__display_failed_txns_list',
440
+			false,
441
+			$this
442
+		)
443
+		) {
444
+			$this->_views['failed'] = [
445
+				'slug'  => 'failed',
446
+				'label' => esc_html__('Failed Transactions', 'event_espresso'),
447
+				'count' => 0,
448
+			];
449
+		}
450
+	}
451
+
452
+
453
+	/**
454
+	 * _set_transaction_object
455
+	 * This sets the _transaction property for the transaction details screen
456
+	 *
457
+	 * @access private
458
+	 * @return void
459
+	 * @throws EE_Error
460
+	 * @throws InvalidArgumentException
461
+	 * @throws RuntimeException
462
+	 * @throws InvalidDataTypeException
463
+	 * @throws InvalidInterfaceException
464
+	 * @throws ReflectionException
465
+	 */
466
+	private function _set_transaction_object()
467
+	{
468
+		if ($this->_transaction instanceof EE_Transaction) {
469
+			return;
470
+		} //get out we've already set the object
471
+
472
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
473
+
474
+		// get transaction object
475
+		$this->_transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
476
+		$this->_session     = $this->_transaction instanceof EE_Transaction
477
+			? $this->_transaction->session_data()
478
+			: null;
479
+		if ($this->_transaction instanceof EE_Transaction) {
480
+			$this->_transaction->verify_abandoned_transaction_status();
481
+		}
482
+
483
+		if (! $this->_transaction instanceof EE_Transaction) {
484
+			$error_msg = sprintf(
485
+				esc_html__(
486
+					'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
487
+					'event_espresso'
488
+				),
489
+				$TXN_ID
490
+			);
491
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
492
+		}
493
+	}
494
+
495
+
496
+	/**
497
+	 *    _transaction_legend_items
498
+	 *
499
+	 * @access protected
500
+	 * @return array
501
+	 * @throws EE_Error
502
+	 * @throws InvalidArgumentException
503
+	 * @throws ReflectionException
504
+	 * @throws InvalidDataTypeException
505
+	 * @throws InvalidInterfaceException
506
+	 */
507
+	protected function _transaction_legend_items()
508
+	{
509
+		EE_Registry::instance()->load_helper('MSG_Template');
510
+		$items = [];
511
+
512
+		if (
513
+			$this->capabilities->current_user_can(
514
+				'ee_read_global_messages',
515
+				'view_filtered_messages'
516
+			)
517
+		) {
518
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
519
+			if (
520
+				is_array($related_for_icon)
521
+				&& isset($related_for_icon['css_class'], $related_for_icon['label'])
522
+			) {
523
+				$items['view_related_messages'] = [
524
+					'class' => $related_for_icon['css_class'],
525
+					'desc'  => $related_for_icon['label'],
526
+				];
527
+			}
528
+		}
529
+
530
+		$items = apply_filters(
531
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__items',
532
+			array_merge(
533
+				$items,
534
+				[
535
+					'view_details'          => [
536
+						'class' => 'dashicons dashicons-cart',
537
+						'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
538
+					],
539
+					'view_invoice'          => [
540
+						'class' => 'dashicons dashicons-media-spreadsheet',
541
+						'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
542
+					],
543
+					'view_receipt'          => [
544
+						'class' => 'dashicons dashicons-text-page',
545
+						'desc'  => esc_html__('View Transaction Receipt', 'event_espresso'),
546
+					],
547
+					'view_registration'     => [
548
+						'class' => 'dashicons dashicons-clipboard',
549
+						'desc'  => esc_html__('View Registration Details', 'event_espresso'),
550
+					],
551
+					'payment_overview_link' => [
552
+						'class' => 'dashicons dashicons-money',
553
+						'desc'  => esc_html__('Make Payment on Frontend', 'event_espresso'),
554
+					],
555
+				]
556
+			)
557
+		);
558
+
559
+		if (
560
+			EEH_MSG_Template::is_mt_active('payment_reminder')
561
+			&& $this->capabilities->current_user_can(
562
+				'ee_send_message',
563
+				'espresso_transactions_send_payment_reminder'
564
+			)
565
+		) {
566
+			$items['send_payment_reminder'] = [
567
+				'class' => 'dashicons dashicons-email-alt',
568
+				'desc'  => esc_html__('Send Payment Reminder', 'event_espresso'),
569
+			];
570
+		} else {
571
+			$items['blank*'] = [
572
+				'class' => '',
573
+				'desc'  => '',
574
+			];
575
+		}
576
+		$more_items = apply_filters(
577
+			'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
578
+			[
579
+				'overpaid'   => [
580
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
581
+					'desc'  => EEH_Template::pretty_status(
582
+						EEM_Transaction::overpaid_status_code,
583
+						false,
584
+						'sentence'
585
+					),
586
+				],
587
+				'complete'   => [
588
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
589
+					'desc'  => EEH_Template::pretty_status(
590
+						EEM_Transaction::complete_status_code,
591
+						false,
592
+						'sentence'
593
+					),
594
+				],
595
+				'incomplete' => [
596
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
597
+					'desc'  => EEH_Template::pretty_status(
598
+						EEM_Transaction::incomplete_status_code,
599
+						false,
600
+						'sentence'
601
+					),
602
+				],
603
+				'abandoned'  => [
604
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
605
+					'desc'  => EEH_Template::pretty_status(
606
+						EEM_Transaction::abandoned_status_code,
607
+						false,
608
+						'sentence'
609
+					),
610
+				],
611
+				'failed'     => [
612
+					'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
613
+					'desc'  => EEH_Template::pretty_status(
614
+						EEM_Transaction::failed_status_code,
615
+						false,
616
+						'sentence'
617
+					),
618
+				],
619
+			]
620
+		);
621
+
622
+		return array_merge($items, $more_items);
623
+	}
624
+
625
+
626
+	/**
627
+	 *    _transactions_overview_list_table
628
+	 *
629
+	 * @access protected
630
+	 * @return void
631
+	 * @throws DomainException
632
+	 * @throws EE_Error
633
+	 * @throws InvalidArgumentException
634
+	 * @throws InvalidDataTypeException
635
+	 * @throws InvalidInterfaceException
636
+	 * @throws ReflectionException
637
+	 */
638
+	protected function _transactions_overview_list_table()
639
+	{
640
+		$this->_admin_page_title = esc_html__('Transactions', 'event_espresso');
641
+
642
+		$EVT_ID                                    = $this->request->getRequestParam('EVT_ID', 0, 'int');
643
+		$event                                     = EEM_Event::instance()->get_one_by_ID($EVT_ID);
644
+		$this->_template_args['admin_page_header'] = $event instanceof EE_Event
645
+			? sprintf(
646
+				esc_html__('%sViewing Transactions for the Event: %s%s', 'event_espresso'),
647
+				'<h3>',
648
+				'<a href="'
649
+				. EE_Admin_Page::add_query_args_and_nonce(
650
+					['action' => 'edit', 'post' => $event->ID()],
651
+					EVENTS_ADMIN_URL
652
+				)
653
+				. '" aria-label="'
654
+				. esc_attr__('Click to Edit event', 'event_espresso')
655
+				. '">' . $event->name() . '</a>',
656
+				'</h3>'
657
+			)
658
+			: '';
659
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
660
+		$this->display_admin_list_table_page_with_no_sidebar();
661
+	}
662
+
663
+
664
+	/**
665
+	 *    _transaction_details
666
+	 * generates HTML for the View Transaction Details Admin page
667
+	 *
668
+	 * @access protected
669
+	 * @return void
670
+	 * @throws DomainException
671
+	 * @throws EE_Error
672
+	 * @throws InvalidArgumentException
673
+	 * @throws InvalidDataTypeException
674
+	 * @throws InvalidInterfaceException
675
+	 * @throws RuntimeException
676
+	 * @throws ReflectionException
677
+	 */
678
+	protected function _transaction_details()
679
+	{
680
+		do_action('AHEE__Transactions_Admin_Page__transaction_details__start', $this->_transaction);
681
+
682
+		$this->_set_transaction_status_array();
683
+
684
+		$this->_template_args                      = [];
685
+		$this->_template_args['transactions_page'] = $this->_wp_page_slug;
686
+
687
+		$this->_set_transaction_object();
688
+
689
+		if (! $this->_transaction instanceof EE_Transaction) {
690
+			return;
691
+		}
692
+
693
+		$this->_template_args['txn_nmbr']['value'] = $this->_transaction->ID();
694
+		$this->_template_args['txn_nmbr']['label'] = esc_html__('Transaction Number', 'event_espresso');
695
+
696
+		$this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
697
+		$this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
698
+
699
+		$this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
700
+		$this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
701
+		$this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
702
+
703
+		$txn_total  = $this->_transaction->total();
704
+		$total_paid = $this->_transaction->paid();
705
+		$amount_due = $txn_total - $total_paid;
706
+
707
+		$this->_template_args['grand_total'] = $txn_total;
708
+		$this->_template_args['total_paid']  = $total_paid;
709
+
710
+		$this->_template_args['amount_due']     = EEH_Template::format_currency($amount_due, false, false);
711
+		$this->_template_args['amount_due_raw'] = $amount_due;
712
+
713
+		$this->_template_args['amount_due_class'] = '';
714
+
715
+		if ($txn_total === (float) 0) {
716
+			// free event
717
+			$this->_template_args['amount_due'] = false;
718
+		} elseif ($amount_due < (float) 0) {
719
+			// overpaid
720
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
721
+		} elseif ($amount_due > (float) 0) {
722
+			// monies owing
723
+			$this->_template_args['amount_due_class'] = 'txn-overview-part-payment-spn ee-txn-amount-owing';
724
+		} elseif ($total_paid === (float) 0) {
725
+			// no payments made yet
726
+			$this->_template_args['amount_due_class'] = 'txn-overview-no-payment-spn';
727
+		}
728
+
729
+		$payment_method = $this->_transaction->payment_method();
730
+
731
+		$this->_template_args['method_of_payment_name'] = $payment_method instanceof EE_Payment_Method
732
+			? $payment_method->admin_name()
733
+			: esc_html__('Unknown', 'event_espresso');
734
+
735
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
736
+		// link back to overview
737
+		$this->_template_args['txn_overview_url'] = $this->request->getServerParam(
738
+			'HTTP_REFERER',
739
+			TXN_ADMIN_URL
740
+		);
741
+
742
+
743
+		// next link
744
+		$next_txn                                 = $this->_transaction->next(
745
+			null,
746
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
747
+			'TXN_ID'
748
+		);
749
+		$this->_template_args['next_transaction'] = $next_txn
750
+			? $this->_next_link(
751
+				EE_Admin_Page::add_query_args_and_nonce(
752
+					['action' => 'view_transaction', 'TXN_ID' => $next_txn['TXN_ID']],
753
+					TXN_ADMIN_URL
754
+				),
755
+				'dashicons dashicons-arrow-right ee-icon-size-22'
756
+			)
757
+			: '';
758
+		// previous link
759
+		$previous_txn                                 = $this->_transaction->previous(
760
+			null,
761
+			[['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
762
+			'TXN_ID'
763
+		);
764
+		$this->_template_args['previous_transaction'] = $previous_txn
765
+			? $this->_previous_link(
766
+				EE_Admin_Page::add_query_args_and_nonce(
767
+					['action' => 'view_transaction', 'TXN_ID' => $previous_txn['TXN_ID']],
768
+					TXN_ADMIN_URL
769
+				),
770
+				'dashicons dashicons-arrow-left ee-icon-size-22'
771
+			)
772
+			: '';
773
+
774
+		$EVT_ID        = $this->request->getRequestParam('EVT_ID', 0, 'int');
775
+		$event_name    = $this->request->getRequestParam('event_name');
776
+		$redirect_from = $this->request->getRequestParam('redirect_from', '', 'url');
777
+
778
+		// were we just redirected here after adding a new registration ???
779
+		if ($EVT_ID && $event_name && $redirect_from) {
780
+			if (
781
+				$this->capabilities->current_user_can(
782
+					'ee_edit_registrations',
783
+					'espresso_registrations_new_registration',
784
+					$EVT_ID
785
+				)
786
+			) {
787
+				$this->_admin_page_title .= '<a id="add-new-registration" class="add-new-h2 button--primary" href="';
788
+				$this->_admin_page_title .= EE_Admin_Page::add_query_args_and_nonce(
789
+					[
790
+						'page'     => 'espresso_registrations',
791
+						'action'   => 'new_registration',
792
+						'return'   => 'default',
793
+						'TXN_ID'   => $this->_transaction->ID(),
794
+						'event_id' => $EVT_ID,
795
+					],
796
+					REG_ADMIN_URL
797
+				);
798
+				$this->_admin_page_title .= '">';
799
+
800
+				$this->_admin_page_title .= sprintf(
801
+					esc_html__('Add Another New Registration to Event: "%1$s" ?', 'event_espresso'),
802
+					htmlentities(urldecode($event_name), ENT_QUOTES, 'UTF-8')
803
+				);
804
+				$this->_admin_page_title .= '</a>';
805
+			}
806
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
807
+		}
808
+		// grab messages at the last second
809
+		$this->_template_args['notices'] = EE_Error::get_notices();
810
+		// path to template
811
+		$template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
812
+		$this->_template_args['admin_page_header'] = EEH_Template::display_template(
813
+			$template_path,
814
+			$this->_template_args,
815
+			true
816
+		);
817
+
818
+		// the details template wrapper
819
+		$this->display_admin_page_with_sidebar();
820
+	}
821
+
822
+
823
+	/**
824
+	 *        _transaction_details_metaboxes
825
+	 *
826
+	 * @access protected
827
+	 * @return void
828
+	 * @throws EE_Error
829
+	 * @throws InvalidArgumentException
830
+	 * @throws InvalidDataTypeException
831
+	 * @throws InvalidInterfaceException
832
+	 * @throws RuntimeException
833
+	 * @throws ReflectionException
834
+	 */
835
+	protected function _transaction_details_metaboxes()
836
+	{
837
+		$this->_set_transaction_object();
838
+
839
+		if (! $this->_transaction instanceof EE_Transaction) {
840
+			return;
841
+		}
842
+		$this->addMetaBox(
843
+			'edit-txn-details-mbox',
844
+			'<span>' . esc_html__('Transaction Details', 'event_espresso')
845
+			. '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
846
+			[$this, 'txn_details_meta_box'],
847
+			$this->_wp_page_slug
848
+		);
849
+		$this->addMetaBox(
850
+			'edit-txn-attendees-mbox',
851
+			'<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
852
+			. '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
853
+			[$this, 'txn_attendees_meta_box'],
854
+			$this->_wp_page_slug,
855
+			'normal',
856
+			'high',
857
+			['TXN_ID' => $this->_transaction->ID()]
858
+		);
859
+		$this->addMetaBox(
860
+			'edit-txn-registrant-mbox',
861
+			esc_html__('Primary Contact', 'event_espresso'),
862
+			[$this, 'txn_registrant_side_meta_box'],
863
+			$this->_wp_page_slug,
864
+			'side'
865
+		);
866
+		$this->addMetaBox(
867
+			'edit-txn-billing-info-mbox',
868
+			esc_html__('Billing Information', 'event_espresso'),
869
+			[$this, 'txn_billing_info_side_meta_box'],
870
+			$this->_wp_page_slug,
871
+			'side'
872
+		);
873
+	}
874
+
875
+
876
+	/**
877
+	 * Callback for transaction actions metabox.
878
+	 *
879
+	 * @param EE_Transaction|null $transaction
880
+	 * @return string
881
+	 * @throws DomainException
882
+	 * @throws EE_Error
883
+	 * @throws InvalidArgumentException
884
+	 * @throws InvalidDataTypeException
885
+	 * @throws InvalidInterfaceException
886
+	 * @throws ReflectionException
887
+	 * @throws RuntimeException
888
+	 */
889
+	public function getActionButtons(EE_Transaction $transaction = null)
890
+	{
891
+		$content = '';
892
+		$actions = [];
893
+		if (! $transaction instanceof EE_Transaction) {
894
+			return $content;
895
+		}
896
+		/** @var EE_Registration $primary_registration */
897
+		$primary_registration = $transaction->primary_registration();
898
+		$attendee             = $primary_registration instanceof EE_Registration
899
+			? $primary_registration->attendee()
900
+			: null;
901
+
902
+		if (
903
+			$attendee instanceof EE_Attendee
904
+			&& $this->capabilities->current_user_can(
905
+				'ee_send_message',
906
+				'espresso_transactions_send_payment_reminder'
907
+			)
908
+		) {
909
+			$actions['payment_reminder'] =
910
+				EEH_MSG_Template::is_mt_active('payment_reminder')
911
+				&& $this->_transaction->status_ID() !== EEM_Transaction::complete_status_code
912
+				&& $this->_transaction->status_ID() !== EEM_Transaction::overpaid_status_code
913
+					? EEH_Template::get_button_or_link(
914
+					EE_Admin_Page::add_query_args_and_nonce(
915
+						[
916
+							'action'      => 'send_payment_reminder',
917
+							'TXN_ID'      => $this->_transaction->ID(),
918
+							'redirect_to' => 'view_transaction',
919
+						],
920
+						TXN_ADMIN_URL
921
+					),
922
+					esc_html__(' Send Payment Reminder', 'event_espresso'),
923
+					'button button--secondary',
924
+					'dashicons dashicons-email-alt'
925
+				)
926
+					: '';
927
+		}
928
+
929
+		if (
930
+			$this->capabilities->current_user_can(
931
+				'ee_edit_payments',
932
+				'espresso_transactions_recalculate_line_items'
933
+			)
934
+		) {
935
+			$actions['recalculate_line_items'] = EEH_Template::get_button_or_link(
936
+				EE_Admin_Page::add_query_args_and_nonce(
937
+					[
938
+						'action'      => 'espresso_recalculate_line_items',
939
+						'TXN_ID'      => $this->_transaction->ID(),
940
+						'redirect_to' => 'view_transaction',
941
+					],
942
+					TXN_ADMIN_URL
943
+				),
944
+				esc_html__(' Recalculate Taxes and Total', 'event_espresso'),
945
+				'button button--secondary',
946
+				'dashicons dashicons-update'
947
+			);
948
+		}
949
+
950
+		if (
951
+			$primary_registration instanceof EE_Registration
952
+			&& EEH_MSG_Template::is_mt_active('receipt')
953
+		) {
954
+			$actions['receipt'] = EEH_Template::get_button_or_link(
955
+				$primary_registration->receipt_url(),
956
+				esc_html__('View Receipt', 'event_espresso'),
957
+				'button button--secondary',
958
+				'dashicons dashicons-text-page'
959
+			);
960
+		}
961
+
962
+		if (
963
+			$primary_registration instanceof EE_Registration
964
+			&& EEH_MSG_Template::is_mt_active('invoice')
965
+		) {
966
+			$actions['invoice'] = EEH_Template::get_button_or_link(
967
+				$primary_registration->invoice_url(),
968
+				esc_html__('View Invoice', 'event_espresso'),
969
+				'button button--secondary',
970
+				'dashicons dashicons-media-spreadsheet'
971
+			);
972
+		}
973
+		$actions = array_filter(
974
+			apply_filters('FHEE__Transactions_Admin_Page__getActionButtons__actions', $actions, $transaction)
975
+		);
976
+		if ($actions) {
977
+			$content .= implode('', $actions);
978
+		}
979
+		return $content;
980
+	}
981
+
982
+
983
+	/**
984
+	 * txn_details_meta_box
985
+	 * generates HTML for the Transaction main meta box
986
+	 *
987
+	 * @return void
988
+	 * @throws DomainException
989
+	 * @throws EE_Error
990
+	 * @throws InvalidArgumentException
991
+	 * @throws InvalidDataTypeException
992
+	 * @throws InvalidInterfaceException
993
+	 * @throws RuntimeException
994
+	 * @throws ReflectionException
995
+	 */
996
+	public function txn_details_meta_box()
997
+	{
998
+		$this->_set_transaction_object();
999
+		$this->_template_args['TXN_ID']              = $this->_transaction->ID();
1000
+		$this->_template_args['attendee']            =
1001
+			$this->_transaction->primary_registration() instanceof EE_Registration
1002
+				? $this->_transaction->primary_registration()->attendee()
1003
+				: null;
1004
+		$this->_template_args['can_edit_payments']   = $this->capabilities->current_user_can(
1005
+			'ee_edit_payments',
1006
+			'apply_payment_or_refund_from_registration_details'
1007
+		);
1008
+		$this->_template_args['can_delete_payments'] = $this->capabilities->current_user_can(
1009
+			'ee_delete_payments',
1010
+			'delete_payment_from_registration_details'
1011
+		);
1012
+
1013
+		// get line table
1014
+		EEH_Autoloader::register_line_item_display_autoloaders();
1015
+		$Line_Item_Display                       = new EE_Line_Item_Display(
1016
+			'admin_table',
1017
+			'EE_Admin_Table_Line_Item_Display_Strategy'
1018
+		);
1019
+		$this->_template_args['line_item_table'] = $Line_Item_Display->display_line_item(
1020
+			$this->_transaction->total_line_item()
1021
+		);
1022
+		$this->_template_args['REG_code']        =
1023
+			$this->_transaction->primary_registration() instanceof EE_Registration
1024
+				? $this->_transaction->primary_registration()->reg_code()
1025
+				: null;
1026
+		// process taxes
1027
+		$taxes                         = $this->_transaction->line_items([['LIN_type' => EEM_Line_Item::type_tax]]);
1028
+		$this->_template_args['taxes'] = ! empty($taxes)
1029
+			? $taxes
1030
+			: false;
1031
+
1032
+		$this->_template_args['grand_total']     = EEH_Template::format_currency(
1033
+			$this->_transaction->total(),
1034
+			false,
1035
+			false
1036
+		);
1037
+		$this->_template_args['grand_raw_total'] = $this->_transaction->total();
1038
+		$this->_template_args['TXN_status']      = $this->_transaction->status_ID();
1039
+
1040
+		// process payment details
1041
+		$payments = $this->_transaction->payments();
1042
+		if (! empty($payments)) {
1043
+			$this->_template_args['payments']              = $payments;
1044
+			$this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1045
+		} else {
1046
+			$this->_template_args['payments']              = false;
1047
+			$this->_template_args['existing_reg_payments'] = [];
1048
+		}
1049
+
1050
+		$this->_template_args['edit_payment_url']   = add_query_arg(['action' => 'edit_payment'], TXN_ADMIN_URL);
1051
+		$this->_template_args['delete_payment_url'] = add_query_arg(
1052
+			['action' => 'espresso_delete_payment'],
1053
+			TXN_ADMIN_URL
1054
+		);
1055
+
1056
+		if (isset($txn_details['invoice_number'])) {
1057
+			$this->_template_args['txn_details']['invoice_number']['value'] = $this->_template_args['REG_code'];
1058
+			$this->_template_args['txn_details']['invoice_number']['label'] = esc_html__(
1059
+				'Invoice Number',
1060
+				'event_espresso'
1061
+			);
1062
+		}
1063
+
1064
+		$this->_template_args['txn_details']['registration_session']['value'] =
1065
+			$this->_transaction->primary_registration() instanceof EE_Registration
1066
+				? $this->_transaction->primary_registration()->session_ID()
1067
+				: null;
1068
+		$this->_template_args['txn_details']['registration_session']['label'] = esc_html__(
1069
+			'Registration Session',
1070
+			'event_espresso'
1071
+		);
1072
+
1073
+		$this->_template_args['txn_details']['ip_address']['value'] = $this->_session['ip_address'] ?? '';
1074
+		$this->_template_args['txn_details']['ip_address']['label'] = esc_html__(
1075
+			'Transaction placed from IP',
1076
+			'event_espresso'
1077
+		);
1078
+
1079
+		$this->_template_args['txn_details']['user_agent']['value'] = $this->_session['user_agent'] ?? '';
1080
+		$this->_template_args['txn_details']['user_agent']['label'] = esc_html__(
1081
+			'Registrant User Agent',
1082
+			'event_espresso'
1083
+		);
1084
+
1085
+		$reg_steps = '<div class="ee-txn-reg-step-status-steps ee-layout-row">';
1086
+		foreach ($this->_transaction->reg_steps() as $reg_step => $reg_step_status) {
1087
+			if ($reg_step_status === true) {
1088
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--success">'
1089
+							  . sprintf(
1090
+								  esc_html__('%1$s : Completed', 'event_espresso'),
1091
+								  ucwords(str_replace('_', ' ', $reg_step))
1092
+							  )
1093
+							  . '</div>';
1094
+			} elseif ($reg_step_status !== false && is_numeric($reg_step_status)) {
1095
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--attention">'
1096
+							  . sprintf(
1097
+								  esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1098
+								  ucwords(str_replace('_', ' ', $reg_step)),
1099
+								  date(
1100
+									  get_option('date_format') . ' ' . get_option('time_format'),
1101
+									  $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1102
+								  )
1103
+							  )
1104
+							  . '</div>';
1105
+			} else {
1106
+				$reg_steps .= '<div class="ee-status-pill ee-status-bg--error">'
1107
+							  . sprintf(
1108
+								  esc_html__('%1$s : Never Initiated', 'event_espresso'),
1109
+								  ucwords(str_replace('_', ' ', $reg_step))
1110
+							  )
1111
+							  . '</div>';
1112
+			}
1113
+		}
1114
+		$reg_steps                                                 .= '</ul>';
1115
+		$this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1116
+		$this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1117
+			'Registration Step Progress',
1118
+			'event_espresso'
1119
+		);
1120
+
1121
+
1122
+		$this->_get_registrations_to_apply_payment_to();
1123
+		$this->_get_payment_methods($payments);
1124
+		$this->_get_payment_status_array();
1125
+		$this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1126
+
1127
+		$this->_template_args['transaction_form_url']    = add_query_arg(
1128
+			[
1129
+				'action'  => 'edit_transaction',
1130
+				'process' => 'transaction',
1131
+			],
1132
+			TXN_ADMIN_URL
1133
+		);
1134
+		$this->_template_args['apply_payment_form_url']  = add_query_arg(
1135
+			[
1136
+				'page'   => 'espresso_transactions',
1137
+				'action' => 'espresso_apply_payment',
1138
+			],
1139
+			TXN_ADMIN_URL
1140
+		);
1141
+		$this->_template_args['delete_payment_form_url'] = add_query_arg(
1142
+			[
1143
+				'page'   => 'espresso_transactions',
1144
+				'action' => 'espresso_delete_payment',
1145
+			],
1146
+			TXN_ADMIN_URL
1147
+		);
1148
+
1149
+		$this->_template_args['action_buttons'] = $this->getActionButtons($this->_transaction);
1150
+
1151
+		// 'espresso_delete_payment_nonce'
1152
+
1153
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1154
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1155
+	}
1156
+
1157
+
1158
+	/**
1159
+	 * _get_registration_payment_IDs
1160
+	 *    generates an array of Payment IDs and their corresponding Registration IDs
1161
+	 *
1162
+	 * @access protected
1163
+	 * @param EE_Payment[] $payments
1164
+	 * @return array
1165
+	 * @throws EE_Error
1166
+	 * @throws InvalidArgumentException
1167
+	 * @throws InvalidDataTypeException
1168
+	 * @throws InvalidInterfaceException
1169
+	 * @throws ReflectionException
1170
+	 */
1171
+	protected function _get_registration_payment_IDs($payments = [])
1172
+	{
1173
+		$existing_reg_payments = [];
1174
+		// get all reg payments for these payments
1175
+		$reg_payments = EEM_Registration_Payment::instance()->get_all(
1176
+			[
1177
+				[
1178
+					'PAY_ID' => [
1179
+						'IN',
1180
+						array_keys($payments),
1181
+					],
1182
+				],
1183
+			]
1184
+		);
1185
+		if (! empty($reg_payments)) {
1186
+			foreach ($payments as $payment) {
1187
+				if (! $payment instanceof EE_Payment) {
1188
+					continue;
1189
+				} elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1190
+					$existing_reg_payments[ $payment->ID() ] = [];
1191
+				}
1192
+				foreach ($reg_payments as $reg_payment) {
1193
+					if (
1194
+						$reg_payment instanceof EE_Registration_Payment
1195
+						&& $reg_payment->payment_ID() === $payment->ID()
1196
+					) {
1197
+						$existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1198
+					}
1199
+				}
1200
+			}
1201
+		}
1202
+
1203
+		return $existing_reg_payments;
1204
+	}
1205
+
1206
+
1207
+	/**
1208
+	 * _get_registrations_to_apply_payment_to
1209
+	 *    generates HTML for displaying a series of checkboxes in the admin payment modal window
1210
+	 * which allows the admin to only apply the payment to the specific registrations
1211
+	 *
1212
+	 * @access protected
1213
+	 * @return void
1214
+	 * @throws EE_Error
1215
+	 * @throws InvalidArgumentException
1216
+	 * @throws InvalidDataTypeException
1217
+	 * @throws InvalidInterfaceException
1218
+	 * @throws ReflectionException
1219
+	 */
1220
+	protected function _get_registrations_to_apply_payment_to()
1221
+	{
1222
+		// we want any registration with an active status (ie: not deleted or cancelled)
1223
+		$query_params                      = [
1224
+			[
1225
+				'STS_ID' => [
1226
+					'IN',
1227
+					[
1228
+						RegStatus::APPROVED,
1229
+						RegStatus::PENDING_PAYMENT,
1230
+						RegStatus::AWAITING_REVIEW,
1231
+					],
1232
+				],
1233
+			],
1234
+		];
1235
+		$registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1236
+				'',
1237
+				'txn-admin-apply-payment-to-registrations-dv',
1238
+				'',
1239
+				'clear: both; margin: 1.5em 0 0; display: none;'
1240
+			);
1241
+		$registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1242
+		$registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1243
+		$registrations_to_apply_payment_to .= EEH_HTML::thead(
1244
+			EEH_HTML::tr(
1245
+				EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1246
+				EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1247
+				EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1248
+				EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1249
+				EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1250
+				EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1251
+				EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1252
+			)
1253
+		);
1254
+		$registrations_to_apply_payment_to .= EEH_HTML::tbody();
1255
+		// get registrations for TXN
1256
+		$registrations         = $this->_transaction->registrations($query_params);
1257
+		$existing_reg_payments = $this->_template_args['existing_reg_payments'];
1258
+		foreach ($registrations as $registration) {
1259
+			if ($registration instanceof EE_Registration) {
1260
+				$attendee_name                     = $registration->attendee() instanceof EE_Attendee
1261
+					? $registration->attendee()->full_name()
1262
+					: esc_html__('Unknown Attendee', 'event_espresso');
1263
+				$owing                             = $registration->final_price() - $registration->paid();
1264
+				$taxable                           = $registration->ticket()->taxable()
1265
+					? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1266
+					: '';
1267
+				$checked                           = empty($existing_reg_payments)
1268
+													 || in_array($registration->ID(), $existing_reg_payments, true)
1269
+					? ' checked'
1270
+					: '';
1271
+				$disabled                          = $registration->final_price() > 0
1272
+					? ''
1273
+					: ' disabled';
1274
+				$registrations_to_apply_payment_to .= EEH_HTML::tr(
1275
+					EEH_HTML::td($registration->ID()) .
1276
+					EEH_HTML::td($attendee_name) .
1277
+					EEH_HTML::td(
1278
+						$registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1279
+					) .
1280
+					EEH_HTML::td($registration->event_name()) .
1281
+					EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1282
+					EEH_HTML::td(
1283
+						EEH_Template::format_currency($owing),
1284
+						'',
1285
+						'txn-admin-payment-owing-td jst-cntr'
1286
+					) .
1287
+					EEH_HTML::td(
1288
+						'<input type="checkbox" value="' . $registration->ID()
1289
+						. '" name="txn_admin_payment[registrations]"'
1290
+						. $checked . $disabled . '>',
1291
+						'',
1292
+						'jst-cntr'
1293
+					),
1294
+					'apply-payment-registration-row-' . $registration->ID()
1295
+				);
1296
+			}
1297
+		}
1298
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tbodyx();
1299
+		$registrations_to_apply_payment_to                         .= EEH_HTML::tablex();
1300
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1301
+		$registrations_to_apply_payment_to                         .= EEH_HTML::p(
1302
+			esc_html__(
1303
+				'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.',
1304
+				'event_espresso'
1305
+			),
1306
+			'',
1307
+			'clear description'
1308
+		);
1309
+		$registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1310
+		$this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1311
+	}
1312
+
1313
+
1314
+	/**
1315
+	 * _get_reg_status_selection
1316
+	 *
1317
+	 * @return void
1318
+	 * @throws EE_Error
1319
+	 * @todo   this will need to be adjusted either once MER comes along OR we move default reg status to tickets
1320
+	 *         instead of events.
1321
+	 * @access protected
1322
+	 */
1323
+	protected function _get_reg_status_selection()
1324
+	{
1325
+		// first get all possible statuses
1326
+		$statuses = EEM_Registration::reg_status_array([], true);
1327
+		// let's add a "don't change" option.
1328
+		$status_array['NAN']                                 = esc_html__('Leave the Same', 'event_espresso');
1329
+		$status_array                                        = array_merge($status_array, $statuses);
1330
+		$this->_template_args['status_change_select']        = EEH_Form_Fields::select_input(
1331
+			'txn_reg_status_change[reg_status]',
1332
+			$status_array,
1333
+			'NAN',
1334
+			'id="txn-admin-payment-reg-status-inp"',
1335
+			'txn-reg-status-change-reg-status'
1336
+		);
1337
+		$this->_template_args['delete_status_change_select'] = EEH_Form_Fields::select_input(
1338
+			'delete_txn_reg_status_change[reg_status]',
1339
+			$status_array,
1340
+			'NAN',
1341
+			'delete-txn-admin-payment-reg-status-inp',
1342
+			'delete-txn-reg-status-change-reg-status'
1343
+		);
1344
+	}
1345
+
1346
+
1347
+	/**
1348
+	 *    _get_payment_methods
1349
+	 * Gets all the payment methods available generally, or the ones that are already
1350
+	 * selected on these payments (in case their payment methods are no longer active).
1351
+	 * Has the side-effect of updating the template args' payment_methods item
1352
+	 *
1353
+	 * @access private
1354
+	 * @param EE_Payment[] to show on this page
1355
+	 * @return void
1356
+	 * @throws EE_Error
1357
+	 * @throws InvalidArgumentException
1358
+	 * @throws InvalidDataTypeException
1359
+	 * @throws InvalidInterfaceException
1360
+	 * @throws ReflectionException
1361
+	 */
1362
+	private function _get_payment_methods($payments = [])
1363
+	{
1364
+		$payment_methods_of_payments = [];
1365
+		foreach ($payments as $payment) {
1366
+			if ($payment instanceof EE_Payment) {
1367
+				$payment_methods_of_payments[] = $payment->ID();
1368
+			}
1369
+		}
1370
+		if ($payment_methods_of_payments) {
1371
+			$query_args = [
1372
+				[
1373
+					'OR*payment_method_for_payment' => [
1374
+						'PMD_ID'    => ['IN', $payment_methods_of_payments],
1375
+						'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1376
+					],
1377
+				],
1378
+			];
1379
+		} else {
1380
+			$query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1381
+		}
1382
+		$this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1383
+	}
1384
+
1385
+
1386
+	/**
1387
+	 * txn_attendees_meta_box
1388
+	 *    generates HTML for the Attendees Transaction main meta box
1389
+	 *
1390
+	 * @access public
1391
+	 * @param WP_Post $post
1392
+	 * @param array   $metabox
1393
+	 * @return void
1394
+	 * @throws DomainException
1395
+	 * @throws EE_Error
1396
+	 * @throws InvalidArgumentException
1397
+	 * @throws InvalidDataTypeException
1398
+	 * @throws InvalidInterfaceException
1399
+	 * @throws ReflectionException
1400
+	 */
1401
+	public function txn_attendees_meta_box($post, $metabox = ['args' => []])
1402
+	{
1403
+		/** @noinspection NonSecureExtractUsageInspection */
1404
+		extract($metabox['args']);
1405
+		$this->_template_args['post']            = $post;
1406
+		$this->_template_args['event_attendees'] = [];
1407
+		// process items in cart
1408
+		$line_items = $this->_transaction->get_many_related(
1409
+			'Line_Item',
1410
+			[['LIN_type' => 'line-item']]
1411
+		);
1412
+		if (! empty($line_items)) {
1413
+			foreach ($line_items as $item) {
1414
+				if ($item instanceof EE_Line_Item) {
1415
+					switch ($item->OBJ_type()) {
1416
+						case 'Event':
1417
+							break;
1418
+						case 'Ticket':
1419
+							$ticket = $item->ticket();
1420
+							// right now we're only handling tickets here.
1421
+							// Cause its expected that only tickets will have attendees right?
1422
+							if (! $ticket instanceof EE_Ticket) {
1423
+								break;
1424
+							}
1425
+							try {
1426
+								$event_name = $ticket->get_event_name();
1427
+							} catch (Exception $e) {
1428
+								EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1429
+								$event_name = esc_html__('Unknown Event', 'event_espresso');
1430
+							}
1431
+							$event_name   .= ' - ' . $item->name();
1432
+							$ticket_price = EEH_Template::format_currency($item->unit_price());
1433
+							// now get all of the registrations for this transaction that use this ticket
1434
+							$registrations = $ticket->registrations(
1435
+								[['TXN_ID' => $this->_transaction->ID()]]
1436
+							);
1437
+							foreach ($registrations as $registration) {
1438
+								if (! $registration instanceof EE_Registration) {
1439
+									break;
1440
+								}
1441
+								$this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1442
+									= $registration->status_ID();
1443
+								$this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1444
+									= $registration->count();
1445
+								$this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1446
+									= $event_name;
1447
+								$this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1448
+									= $ticket_price;
1449
+								// attendee info
1450
+								$attendee = $registration->get_first_related('Attendee');
1451
+								if ($attendee instanceof EE_Attendee) {
1452
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1453
+										= $attendee->ID();
1454
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1455
+										= $attendee->full_name();
1456
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']
1457
+										= '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1458
+										  . esc_html__(
1459
+											  ' Event',
1460
+											  'event_espresso'
1461
+										  )
1462
+										  . '">' . $attendee->email() . '</a>';
1463
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']
1464
+										= EEH_Address::format($attendee, 'inline', false, false);
1465
+								} else {
1466
+									$this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1467
+									$this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1468
+									$this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1469
+									$this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1470
+								}
1471
+							}
1472
+							break;
1473
+					}
1474
+				}
1475
+			}
1476
+
1477
+			$this->_template_args['transaction_form_url'] = add_query_arg(
1478
+				[
1479
+					'action'  => 'edit_transaction',
1480
+					'process' => 'attendees',
1481
+				],
1482
+				TXN_ADMIN_URL
1483
+			);
1484
+			echo EEH_Template::display_template(
1485
+				TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1486
+				$this->_template_args,
1487
+				true
1488
+			);
1489
+		} else {
1490
+			printf(
1491
+				esc_html__(
1492
+					'%1$sFor some reason, there are no attendees registered for this transaction. Likely the registration was abandoned in process.%2$s',
1493
+					'event_espresso'
1494
+				),
1495
+				'<p class="important-notice">',
1496
+				'</p>'
1497
+			);
1498
+		}
1499
+	}
1500
+
1501
+
1502
+	/**
1503
+	 * txn_registrant_side_meta_box
1504
+	 * generates HTML for the Edit Transaction side meta box
1505
+	 *
1506
+	 * @access public
1507
+	 * @return void
1508
+	 * @throws DomainException
1509
+	 * @throws EE_Error
1510
+	 * @throws InvalidArgumentException
1511
+	 * @throws InvalidDataTypeException
1512
+	 * @throws InvalidInterfaceException
1513
+	 * @throws ReflectionException
1514
+	 */
1515
+	public function txn_registrant_side_meta_box()
1516
+	{
1517
+		$primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1518
+			? $this->_transaction->primary_registration()->get_first_related('Attendee')
1519
+			: null;
1520
+		if (! $primary_att instanceof EE_Attendee) {
1521
+			$this->_template_args['no_attendee_message'] = esc_html__(
1522
+				'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1523
+				'event_espresso'
1524
+			);
1525
+			$primary_att                                 = EEM_Attendee::instance()->create_default_object();
1526
+		}
1527
+		$this->_template_args['ATT_ID']            = $primary_att->ID();
1528
+		$this->_template_args['prime_reg_fname']   = $primary_att->fname();
1529
+		$this->_template_args['prime_reg_lname']   = $primary_att->lname();
1530
+		$this->_template_args['prime_reg_email']   = $primary_att->email();
1531
+		$this->_template_args['prime_reg_phone']   = $primary_att->phone();
1532
+		$this->_template_args['edit_attendee_url'] = EE_Admin_Page::add_query_args_and_nonce(
1533
+			[
1534
+				'action' => 'edit_attendee',
1535
+				'post'   => $primary_att->ID(),
1536
+			],
1537
+			REG_ADMIN_URL
1538
+		);
1539
+		// get formatted address for registrant
1540
+		$formatted_address                         = EEH_Address::format($primary_att);
1541
+		$formatted_address                         =
1542
+			$formatted_address !== '<div class="espresso-address-dv"><div></div></div>'
1543
+				? $formatted_address
1544
+				: '';
1545
+		$this->_template_args['formatted_address'] = $formatted_address;
1546
+		echo EEH_Template::display_template(
1547
+			TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1548
+			$this->_template_args,
1549
+			true
1550
+		);
1551
+	}
1552
+
1553
+
1554
+	/**
1555
+	 * txn_billing_info_side_meta_box
1556
+	 *    generates HTML for the Edit Transaction side meta box
1557
+	 *
1558
+	 * @access public
1559
+	 * @return void
1560
+	 * @throws DomainException
1561
+	 * @throws EE_Error
1562
+	 * @throws ReflectionException
1563
+	 */
1564
+	public function txn_billing_info_side_meta_box()
1565
+	{
1566
+		$this->_template_args['billing_form']     = $this->_transaction->billing_info();
1567
+		$this->_template_args['billing_form_url'] = add_query_arg(
1568
+			['action' => 'edit_transaction', 'process' => 'billing'],
1569
+			TXN_ADMIN_URL
1570
+		);
1571
+
1572
+		$template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1573
+		echo EEH_Template::display_template($template_path, $this->_template_args, true);
1574
+	}
1575
+
1576
+
1577
+	/**
1578
+	 * apply_payments_or_refunds
1579
+	 *    registers a payment or refund made towards a transaction
1580
+	 *
1581
+	 * @access public
1582
+	 * @return void
1583
+	 * @throws EE_Error
1584
+	 * @throws InvalidArgumentException
1585
+	 * @throws ReflectionException
1586
+	 * @throws RuntimeException
1587
+	 * @throws InvalidDataTypeException
1588
+	 * @throws InvalidInterfaceException
1589
+	 */
1590
+	public function apply_payments_or_refunds()
1591
+	{
1592
+		$valid_data = $this->_validate_payment_request_data();
1593
+		$has_access = $this->capabilities->current_user_can(
1594
+			'ee_edit_payments',
1595
+			'apply_payment_or_refund_from_registration_details'
1596
+		);
1597
+		$TXD_ID     = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1598
+		$amount     = 0;
1599
+		if (! empty($valid_data) && $has_access) {
1600
+			$PAY_ID = $valid_data['PAY_ID'];
1601
+			// save  the new payment
1602
+			$payment = $this->_create_payment_from_request_data($valid_data);
1603
+			$amount  = $payment->amount();
1604
+			// get the TXN for this payment
1605
+			$transaction = $payment->transaction();
1606
+			// verify transaction
1607
+			if ($transaction instanceof EE_Transaction) {
1608
+				// calculate_total_payments_and_update_status
1609
+				$this->_process_transaction_payments($transaction);
1610
+				$REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1611
+				$this->_remove_existing_registration_payments($payment, $PAY_ID);
1612
+				// apply payment to registrations (if applicable)
1613
+				if (! empty($REG_IDs)) {
1614
+					$this->_update_registration_payments($transaction, $payment, $REG_IDs);
1615
+					$this->_maybe_send_notifications();
1616
+					// now process status changes for the same registrations
1617
+					$this->_process_registration_status_change($transaction, $REG_IDs);
1618
+				}
1619
+				$this->_maybe_send_notifications($payment);
1620
+				// prepare to render page
1621
+				do_action(
1622
+					'AHEE__Transactions_Admin_Page__apply_payments_or_refund__after_recording',
1623
+					$transaction,
1624
+					$payment
1625
+				);
1626
+			} else {
1627
+				EE_Error::add_error(
1628
+					esc_html__(
1629
+						'A valid Transaction for this payment could not be retrieved.',
1630
+						'event_espresso'
1631
+					),
1632
+					__FILE__,
1633
+					__FUNCTION__,
1634
+					__LINE__
1635
+				);
1636
+			}
1637
+		} elseif ($has_access) {
1638
+			EE_Error::add_error(
1639
+				esc_html__(
1640
+					'The payment form data could not be processed. Please try again.',
1641
+					'event_espresso'
1642
+				),
1643
+				__FILE__,
1644
+				__FUNCTION__,
1645
+				__LINE__
1646
+			);
1647
+		} else {
1648
+			EE_Error::add_error(
1649
+				esc_html__(
1650
+					'You do not have access to apply payments or refunds to a registration.',
1651
+					'event_espresso'
1652
+				),
1653
+				__FILE__,
1654
+				__FUNCTION__,
1655
+				__LINE__
1656
+			);
1657
+		}
1658
+		$query_args = [
1659
+			'page'   => 'espresso_transactions',
1660
+			'action' => 'view_transaction',
1661
+			'TXN_ID' => $TXD_ID,
1662
+		];
1663
+
1664
+		$this->_redirect_after_action(
1665
+			! EE_Error::has_error(),
1666
+			$amount > 0
1667
+				? esc_html__('payment', 'event_espresso')
1668
+				: esc_html__('refund', 'event_espresso'),
1669
+			esc_html__('processed', 'event_espresso'),
1670
+			$query_args
1671
+		);
1672
+	}
1673
+
1674
+
1675
+	/**
1676
+	 * _validate_payment_request_data
1677
+	 *
1678
+	 * @return array
1679
+	 * @throws EE_Error
1680
+	 * @throws InvalidArgumentException
1681
+	 * @throws InvalidDataTypeException
1682
+	 * @throws InvalidInterfaceException
1683
+	 */
1684
+	protected function _validate_payment_request_data()
1685
+	{
1686
+		if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1687
+			return [];
1688
+		}
1689
+		$payment_form = $this->_generate_payment_form_section();
1690
+		try {
1691
+			if ($payment_form->was_submitted()) {
1692
+				$payment_form->receive_form_submission();
1693
+				if (! $payment_form->is_valid()) {
1694
+					$submission_error_messages = [];
1695
+					foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1696
+						if ($validation_error instanceof EE_Validation_Error) {
1697
+							$form_input                  = $validation_error->get_form_section();
1698
+							$submission_error_messages[] = sprintf(
1699
+								_x('%s : %s', 'Form Section Name : Form Validation Error', 'event_espresso'),
1700
+								$form_input instanceof EE_Form_Input_Base
1701
+									? $form_input->html_label_text()
1702
+									: '',
1703
+								$validation_error->getMessage()
1704
+							);
1705
+						}
1706
+					}
1707
+					EE_Error::add_error(
1708
+						implode('<br />', $submission_error_messages),
1709
+						__FILE__,
1710
+						__FUNCTION__,
1711
+						__LINE__
1712
+					);
1713
+					return [];
1714
+				}
1715
+			}
1716
+		} catch (EE_Error $e) {
1717
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1718
+			return [];
1719
+		}
1720
+
1721
+		return $payment_form->valid_data();
1722
+	}
1723
+
1724
+
1725
+	/**
1726
+	 * _generate_payment_form_section
1727
+	 *
1728
+	 * @return EE_Form_Section_Proper
1729
+	 * @throws EE_Error
1730
+	 */
1731
+	protected function _generate_payment_form_section()
1732
+	{
1733
+		return new EE_Form_Section_Proper(
1734
+			[
1735
+				'name'        => 'txn_admin_payment',
1736
+				'subsections' => [
1737
+					'PAY_ID'          => new EE_Text_Input(
1738
+						[
1739
+							'default'               => 0,
1740
+							'required'              => false,
1741
+							'html_label_text'       => esc_html__('Payment ID', 'event_espresso'),
1742
+							'validation_strategies' => [new EE_Int_Normalization()],
1743
+						]
1744
+					),
1745
+					'TXN_ID'          => new EE_Text_Input(
1746
+						[
1747
+							'default'               => 0,
1748
+							'required'              => true,
1749
+							'html_label_text'       => esc_html__('Transaction ID', 'event_espresso'),
1750
+							'validation_strategies' => [new EE_Int_Normalization()],
1751
+						]
1752
+					),
1753
+					'type'            => new EE_Text_Input(
1754
+						[
1755
+							'default'               => 1,
1756
+							'required'              => true,
1757
+							'html_label_text'       => esc_html__('Payment or Refund', 'event_espresso'),
1758
+							'validation_strategies' => [new EE_Int_Normalization()],
1759
+						]
1760
+					),
1761
+					'amount'          => new EE_Text_Input(
1762
+						[
1763
+							'default'               => 0,
1764
+							'required'              => true,
1765
+							'html_label_text'       => esc_html__('Payment amount', 'event_espresso'),
1766
+							'validation_strategies' => [new EE_Float_Normalization()],
1767
+						]
1768
+					),
1769
+					'status'          => new EE_Text_Input(
1770
+						[
1771
+							'default'         => EEM_Payment::status_id_approved,
1772
+							'required'        => true,
1773
+							'html_label_text' => esc_html__('Payment status', 'event_espresso'),
1774
+						]
1775
+					),
1776
+					'PMD_ID'          => new EE_Text_Input(
1777
+						[
1778
+							'default'               => 2,
1779
+							'required'              => true,
1780
+							'html_label_text'       => esc_html__('Payment Method', 'event_espresso'),
1781
+							'validation_strategies' => [new EE_Int_Normalization()],
1782
+						]
1783
+					),
1784
+					'date'            => new EE_Text_Input(
1785
+						[
1786
+							'default'         => time(),
1787
+							'required'        => true,
1788
+							'html_label_text' => esc_html__('Payment date', 'event_espresso'),
1789
+						]
1790
+					),
1791
+					'txn_id_chq_nmbr' => new EE_Text_Input(
1792
+						[
1793
+							'default'               => '',
1794
+							'required'              => false,
1795
+							'html_label_text'       => esc_html__('Transaction or Cheque Number', 'event_espresso'),
1796
+							'validation_strategies' => [
1797
+								new EE_Max_Length_Validation_Strategy(
1798
+									esc_html__('Input too long', 'event_espresso'),
1799
+									100
1800
+								),
1801
+							],
1802
+						]
1803
+					),
1804
+					'po_number'       => new EE_Text_Input(
1805
+						[
1806
+							'default'               => '',
1807
+							'required'              => false,
1808
+							'html_label_text'       => esc_html__('Purchase Order Number', 'event_espresso'),
1809
+							'validation_strategies' => [
1810
+								new EE_Max_Length_Validation_Strategy(
1811
+									esc_html__('Input too long', 'event_espresso'),
1812
+									100
1813
+								),
1814
+							],
1815
+						]
1816
+					),
1817
+					'accounting'      => new EE_Text_Input(
1818
+						[
1819
+							'default'               => '',
1820
+							'required'              => false,
1821
+							'html_label_text'       => esc_html__('Extra Field for Accounting', 'event_espresso'),
1822
+							'validation_strategies' => [
1823
+								new EE_Max_Length_Validation_Strategy(
1824
+									esc_html__('Input too long', 'event_espresso'),
1825
+									100
1826
+								),
1827
+							],
1828
+						]
1829
+					),
1830
+				],
1831
+			]
1832
+		);
1833
+	}
1834
+
1835
+
1836
+	/**
1837
+	 * _create_payment_from_request_data
1838
+	 *
1839
+	 * @param array $valid_data
1840
+	 * @return EE_Payment
1841
+	 * @throws EE_Error
1842
+	 * @throws InvalidArgumentException
1843
+	 * @throws InvalidDataTypeException
1844
+	 * @throws InvalidInterfaceException
1845
+	 * @throws ReflectionException
1846
+	 */
1847
+	protected function _create_payment_from_request_data($valid_data)
1848
+	{
1849
+		$PAY_ID = $valid_data['PAY_ID'];
1850
+		// get payment amount
1851
+		$amount = $valid_data['amount']
1852
+			? EEH_Money::strip_localized_money_formatting($valid_data['amount'])
1853
+			: 0;
1854
+		// payments have a type value of 1 and refunds have a type value of -1
1855
+		// so multiplying amount by type will give a positive value for payments, and negative values for refunds
1856
+		$amount = $valid_data['type'] < 0
1857
+			? $amount * -1
1858
+			: $amount;
1859
+		// for some reason the date string coming in has extra spaces between the date and time.  This fixes that.
1860
+		$date    = $valid_data['date']
1861
+			? preg_replace('/\s+/', ' ', $valid_data['date'])
1862
+			: date('Y-m-d g:i a', current_time('timestamp'));
1863
+		$payment = EE_Payment::new_instance(
1864
+			[
1865
+				'TXN_ID'              => $valid_data['TXN_ID'],
1866
+				'STS_ID'              => $valid_data['status'],
1867
+				'PAY_timestamp'       => $date,
1868
+				'PAY_source'          => EEM_Payment_Method::scope_admin,
1869
+				'PMD_ID'              => $valid_data['PMD_ID'],
1870
+				'PAY_amount'          => $amount,
1871
+				'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'],
1872
+				'PAY_po_number'       => $valid_data['po_number'],
1873
+				'PAY_extra_accntng'   => $valid_data['accounting'],
1874
+				'PAY_details'         => $valid_data,
1875
+				'PAY_ID'              => $PAY_ID,
1876
+			],
1877
+			'',
1878
+			['Y-m-d', 'g:i a']
1879
+		);
1880
+
1881
+		if (! $payment->save()) {
1882
+			EE_Error::add_error(
1883
+				sprintf(
1884
+					esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
1885
+					$payment->ID()
1886
+				),
1887
+				__FILE__,
1888
+				__FUNCTION__,
1889
+				__LINE__
1890
+			);
1891
+		}
1892
+
1893
+		return $payment;
1894
+	}
1895
+
1896
+
1897
+	/**
1898
+	 * _process_transaction_payments
1899
+	 *
1900
+	 * @param EE_Transaction $transaction
1901
+	 * @return void
1902
+	 * @throws EE_Error
1903
+	 * @throws InvalidArgumentException
1904
+	 * @throws ReflectionException
1905
+	 * @throws InvalidDataTypeException
1906
+	 * @throws InvalidInterfaceException
1907
+	 */
1908
+	protected function _process_transaction_payments(EE_Transaction $transaction)
1909
+	{
1910
+		/** @type EE_Transaction_Payments $transaction_payments */
1911
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
1912
+		// update the transaction with this payment
1913
+		if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) {
1914
+			EE_Error::add_success(
1915
+				esc_html__(
1916
+					'The payment has been processed successfully.',
1917
+					'event_espresso'
1918
+				),
1919
+				__FILE__,
1920
+				__FUNCTION__,
1921
+				__LINE__
1922
+			);
1923
+		} else {
1924
+			EE_Error::add_error(
1925
+				esc_html__(
1926
+					'The payment was processed successfully but the amount paid for the transaction was not updated.',
1927
+					'event_espresso'
1928
+				),
1929
+				__FILE__,
1930
+				__FUNCTION__,
1931
+				__LINE__
1932
+			);
1933
+		}
1934
+	}
1935
+
1936
+
1937
+	/**
1938
+	 * _get_REG_IDs_to_apply_payment_to
1939
+	 * returns a list of registration IDs that the payment will apply to
1940
+	 *
1941
+	 * @param EE_Payment $payment
1942
+	 * @return array
1943
+	 * @throws EE_Error
1944
+	 * @throws InvalidArgumentException
1945
+	 * @throws InvalidDataTypeException
1946
+	 * @throws InvalidInterfaceException
1947
+	 * @throws ReflectionException
1948
+	 */
1949
+	protected function _get_REG_IDs_to_apply_payment_to(EE_Payment $payment)
1950
+	{
1951
+		// grab array of IDs for specific registrations to apply changes to
1952
+		$apply_to_all = $this->request->getRequestParam(
1953
+			'txn_admin_payment[apply_to_all_registrations]',
1954
+			false,
1955
+			DataType::BOOL
1956
+		);
1957
+		$REG_IDs      = ! $apply_to_all
1958
+			? $this->request->getRequestParam(
1959
+				'txn_admin_payment[registrations]',
1960
+				[],
1961
+				DataType::INT,
1962
+				true
1963
+			)
1964
+			: [];
1965
+		// nothing specified ? then get all reg IDs
1966
+		if ($apply_to_all || empty($REG_IDs)) {
1967
+			$registrations = $payment->transaction()->registrations(
1968
+				[
1969
+					[
1970
+						'STS_ID' => [
1971
+							'NOT_IN', [ RegStatus::CANCELLED ]
1972
+						]
1973
+					]
1974
+				]
1975
+			);
1976
+			$REG_IDs       = ! empty($registrations)
1977
+				? array_keys($registrations)
1978
+				: $this->_get_existing_reg_payment_REG_IDs($payment);
1979
+		}
1980
+		// ensure that REG_IDs are integers and NOT strings
1981
+		return array_map('absint', $REG_IDs);
1982
+	}
1983
+
1984
+
1985
+	/**
1986
+	 * @return array
1987
+	 */
1988
+	public function existing_reg_payment_REG_IDs()
1989
+	{
1990
+		return $this->_existing_reg_payment_REG_IDs;
1991
+	}
1992
+
1993
+
1994
+	/**
1995
+	 * @param array $existing_reg_payment_REG_IDs
1996
+	 */
1997
+	public function set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs = null)
1998
+	{
1999
+		$this->_existing_reg_payment_REG_IDs = $existing_reg_payment_REG_IDs;
2000
+	}
2001
+
2002
+
2003
+	/**
2004
+	 * _get_existing_reg_payment_REG_IDs
2005
+	 * returns a list of registration IDs that the payment is currently related to
2006
+	 * as recorded in the database
2007
+	 *
2008
+	 * @param EE_Payment $payment
2009
+	 * @return array
2010
+	 * @throws EE_Error
2011
+	 * @throws InvalidArgumentException
2012
+	 * @throws InvalidDataTypeException
2013
+	 * @throws InvalidInterfaceException
2014
+	 * @throws ReflectionException
2015
+	 */
2016
+	protected function _get_existing_reg_payment_REG_IDs(EE_Payment $payment)
2017
+	{
2018
+		if ($this->existing_reg_payment_REG_IDs() === null) {
2019
+			// let's get any existing reg payment records for this payment
2020
+			$existing_reg_payment_REG_IDs = $payment->get_many_related('Registration');
2021
+			// but we only want the REG IDs, so grab the array keys
2022
+			$existing_reg_payment_REG_IDs = ! empty($existing_reg_payment_REG_IDs)
2023
+				? array_keys($existing_reg_payment_REG_IDs)
2024
+				: [];
2025
+			$this->set_existing_reg_payment_REG_IDs($existing_reg_payment_REG_IDs);
2026
+		}
2027
+
2028
+		return $this->existing_reg_payment_REG_IDs();
2029
+	}
2030
+
2031
+
2032
+	/**
2033
+	 * _remove_existing_registration_payments
2034
+	 * this calculates the difference between existing relations
2035
+	 * to the supplied payment and the new list registration IDs,
2036
+	 * removes any related registrations that no longer apply,
2037
+	 * and then updates the registration paid fields
2038
+	 *
2039
+	 * @param EE_Payment $payment
2040
+	 * @param int        $PAY_ID
2041
+	 * @return bool;
2042
+	 * @throws EE_Error
2043
+	 * @throws InvalidArgumentException
2044
+	 * @throws ReflectionException
2045
+	 * @throws InvalidDataTypeException
2046
+	 * @throws InvalidInterfaceException
2047
+	 */
2048
+	protected function _remove_existing_registration_payments(EE_Payment $payment, $PAY_ID = 0)
2049
+	{
2050
+		// newly created payments will have nothing recorded for $PAY_ID
2051
+		if (absint($PAY_ID) === 0) {
2052
+			return false;
2053
+		}
2054
+		$existing_reg_payment_REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2055
+		if (empty($existing_reg_payment_REG_IDs)) {
2056
+			return false;
2057
+		}
2058
+		/** @type EE_Transaction_Payments $transaction_payments */
2059
+		$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2060
+
2061
+		return $transaction_payments->delete_registration_payments_and_update_registrations(
2062
+			$payment,
2063
+			[
2064
+				[
2065
+					'PAY_ID' => $payment->ID(),
2066
+					'REG_ID' => ['IN', $existing_reg_payment_REG_IDs],
2067
+				],
2068
+			]
2069
+		);
2070
+	}
2071
+
2072
+
2073
+	/**
2074
+	 * _update_registration_payments
2075
+	 * this applies the payments to the selected registrations
2076
+	 * but only if they have not already been paid for
2077
+	 *
2078
+	 * @param EE_Transaction $transaction
2079
+	 * @param EE_Payment     $payment
2080
+	 * @param array          $REG_IDs
2081
+	 * @return void
2082
+	 * @throws EE_Error
2083
+	 * @throws InvalidArgumentException
2084
+	 * @throws ReflectionException
2085
+	 * @throws RuntimeException
2086
+	 * @throws InvalidDataTypeException
2087
+	 * @throws InvalidInterfaceException
2088
+	 */
2089
+	protected function _update_registration_payments(
2090
+		EE_Transaction $transaction,
2091
+		EE_Payment $payment,
2092
+		$REG_IDs = []
2093
+	) {
2094
+		// we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
2095
+		// so let's do that using our set of REG_IDs from the form
2096
+		$registration_query_where_params = [
2097
+			'REG_ID' => ['IN', $REG_IDs],
2098
+		];
2099
+		// but add in some conditions regarding payment,
2100
+		// so that we don't apply payments to registrations that are free or have already been paid for
2101
+		// but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2102
+		if (! $payment->is_a_refund()) {
2103
+			$registration_query_where_params['REG_final_price']  = ['!=', 0];
2104
+			$registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2105
+		}
2106
+		$registrations = $transaction->registrations([$registration_query_where_params]);
2107
+		if (! empty($registrations)) {
2108
+			/** @type EE_Payment_Processor $payment_processor */
2109
+			$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2110
+			$payment_processor->process_registration_payments($transaction, $payment, $registrations);
2111
+		}
2112
+	}
2113
+
2114
+
2115
+	/**
2116
+	 * _process_registration_status_change
2117
+	 * This processes requested registration status changes for all the registrations
2118
+	 * on a given transaction and (optionally) sends out notifications for the changes.
2119
+	 *
2120
+	 * @param EE_Transaction $transaction
2121
+	 * @param array          $REG_IDs
2122
+	 * @return bool
2123
+	 * @throws EE_Error
2124
+	 * @throws InvalidArgumentException
2125
+	 * @throws ReflectionException
2126
+	 * @throws InvalidDataTypeException
2127
+	 * @throws InvalidInterfaceException
2128
+	 */
2129
+	protected function _process_registration_status_change(EE_Transaction $transaction, $REG_IDs = [], $reg_status = '')
2130
+	{
2131
+		// first if there is no change in status then we get out.
2132
+		$reg_status = $reg_status
2133
+			?: $this->request->getRequestParam('txn_reg_status_change[reg_status]', 'NAN');
2134
+		if ($reg_status === 'NAN') {
2135
+			// no error message, no change requested, just nothing to do man.
2136
+			return false;
2137
+		}
2138
+		/** @type EE_Transaction_Processor $transaction_processor */
2139
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
2140
+
2141
+		// made it here dude?  Oh WOW.  K, let's take care of changing the statuses
2142
+		return $transaction_processor->manually_update_registration_statuses(
2143
+			$transaction,
2144
+			$reg_status,
2145
+			[['REG_ID' => ['IN', $REG_IDs]]]
2146
+		);
2147
+	}
2148
+
2149
+
2150
+	/**
2151
+	 * _build_payment_json_response
2152
+	 *
2153
+	 * @access public
2154
+	 * @param EE_Payment  $payment
2155
+	 * @param array       $REG_IDs
2156
+	 * @param bool | null $delete_txn_reg_status_change
2157
+	 * @return array
2158
+	 * @throws EE_Error
2159
+	 * @throws InvalidArgumentException
2160
+	 * @throws InvalidDataTypeException
2161
+	 * @throws InvalidInterfaceException
2162
+	 * @throws ReflectionException
2163
+	 */
2164
+	protected function _build_payment_json_response(
2165
+		EE_Payment $payment,
2166
+		$REG_IDs = [],
2167
+		$delete_txn_reg_status_change = null
2168
+	) {
2169
+		// was the payment deleted ?
2170
+		if (is_bool($delete_txn_reg_status_change)) {
2171
+			return [
2172
+				'PAY_ID'                       => $payment->ID(),
2173
+				'amount'                       => $payment->amount(),
2174
+				'total_paid'                   => $payment->transaction()->paid(),
2175
+				'txn_status'                   => $payment->transaction()->status_ID(),
2176
+				'pay_status'                   => $payment->STS_ID(),
2177
+				'registrations'                => $this->_registration_payment_data_array($REG_IDs),
2178
+				'delete_txn_reg_status_change' => $delete_txn_reg_status_change,
2179
+			];
2180
+		}
2181
+
2182
+		$this->_get_payment_status_array();
2183
+		$payment_method = $payment->payment_method();
2184
+		return [
2185
+			'amount'           => $payment->amount(),
2186
+			'total_paid'       => $payment->transaction()->paid(),
2187
+			'txn_status'       => $payment->transaction()->status_ID(),
2188
+			'pay_status'       => $payment->STS_ID(),
2189
+			'PAY_ID'           => $payment->ID(),
2190
+			'STS_ID'           => $payment->STS_ID(),
2191
+			'status'           => self::$_pay_status[ $payment->STS_ID() ],
2192
+			'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2193
+			'method'           => strtoupper($payment->source()),
2194
+			'PM_ID'            => $payment_method instanceof EE_Payment_Method
2195
+				? $payment_method->ID()
2196
+				: 1,
2197
+			'gateway'          => $payment_method instanceof EE_Payment_Method
2198
+				? $payment_method->admin_name()
2199
+				: esc_html__('Unknown', 'event_espresso'),
2200
+			'gateway_response' => $payment->gateway_response(),
2201
+			'txn_id_chq_nmbr'  => $payment->txn_id_chq_nmbr(),
2202
+			'po_number'        => $payment->po_number(),
2203
+			'extra_accntng'    => $payment->extra_accntng(),
2204
+			'registrations'    => $this->_registration_payment_data_array($REG_IDs),
2205
+		];
2206
+	}
2207
+
2208
+
2209
+	/**
2210
+	 * delete_payment
2211
+	 *    delete a payment or refund made towards a transaction
2212
+	 *
2213
+	 * @access public
2214
+	 * @return void
2215
+	 * @throws EE_Error
2216
+	 * @throws InvalidArgumentException
2217
+	 * @throws ReflectionException
2218
+	 * @throws InvalidDataTypeException
2219
+	 * @throws InvalidInterfaceException
2220
+	 */
2221
+	public function delete_payment()
2222
+	{
2223
+		$TXD_ID = $this->request->getRequestParam('delete_txn_admin_payment[TXN_ID]', 0, 'int');
2224
+		// $json_response_data = ['return_data' => false];
2225
+		$PAY_ID     = $this->request->getRequestParam('delete_txn_admin_payment[PAY_ID]', 0, 'int');
2226
+		$amount     = 0;
2227
+		$can_delete = $this->capabilities->current_user_can(
2228
+			'ee_delete_payments',
2229
+			'delete_payment_from_registration_details'
2230
+		);
2231
+		if ($PAY_ID && $can_delete) {
2232
+			$delete_txn_reg_status_change = $this->request->getRequestParam('delete_txn_reg_status_change[reg_status]');
2233
+			$payment                      = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
2234
+			if ($payment instanceof EE_Payment) {
2235
+				$amount  = $payment->amount();
2236
+				$REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
2237
+				/** @type EE_Transaction_Payments $transaction_payments */
2238
+				$transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
2239
+				if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
2240
+					if ($delete_txn_reg_status_change) {
2241
+						$this->_maybe_send_notifications();
2242
+						$this->_process_registration_status_change(
2243
+							$payment->transaction(),
2244
+							$REG_IDs,
2245
+							$delete_txn_reg_status_change
2246
+						);
2247
+					}
2248
+				}
2249
+			} else {
2250
+				EE_Error::add_error(
2251
+					esc_html__('Valid Payment data could not be retrieved from the database.', 'event_espresso'),
2252
+					__FILE__,
2253
+					__FUNCTION__,
2254
+					__LINE__
2255
+				);
2256
+			}
2257
+		} elseif ($can_delete) {
2258
+			EE_Error::add_error(
2259
+				esc_html__(
2260
+					'A valid Payment ID was not received, therefore payment form data could not be loaded.',
2261
+					'event_espresso'
2262
+				),
2263
+				__FILE__,
2264
+				__FUNCTION__,
2265
+				__LINE__
2266
+			);
2267
+		} else {
2268
+			EE_Error::add_error(
2269
+				esc_html__(
2270
+					'You do not have access to delete a payment.',
2271
+					'event_espresso'
2272
+				),
2273
+				__FILE__,
2274
+				__FUNCTION__,
2275
+				__LINE__
2276
+			);
2277
+		}
2278
+		$query_args = [
2279
+			'page'   => 'espresso_transactions',
2280
+			'action' => 'view_transaction',
2281
+			'TXN_ID' => $TXD_ID,
2282
+		];
2283
+		$this->_redirect_after_action(
2284
+			! EE_Error::has_error(),
2285
+			$amount > 0
2286
+				? esc_html__('payment', 'event_espresso')
2287
+				: esc_html__('refund', 'event_espresso'),
2288
+			esc_html__('deleted', 'event_espresso'),
2289
+			$query_args
2290
+		);
2291
+	}
2292
+
2293
+
2294
+	/**
2295
+	 * _registration_payment_data_array
2296
+	 * adds info for 'owing' and 'paid' for each registration to the json response
2297
+	 *
2298
+	 * @access protected
2299
+	 * @param array $REG_IDs
2300
+	 * @return array
2301
+	 * @throws EE_Error
2302
+	 * @throws InvalidArgumentException
2303
+	 * @throws InvalidDataTypeException
2304
+	 * @throws InvalidInterfaceException
2305
+	 * @throws ReflectionException
2306
+	 */
2307
+	protected function _registration_payment_data_array($REG_IDs)
2308
+	{
2309
+		$registration_payment_data = [];
2310
+		// if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2311
+		if (! empty($REG_IDs)) {
2312
+			$registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2313
+			foreach ($registrations as $registration) {
2314
+				if ($registration instanceof EE_Registration) {
2315
+					$registration_payment_data[ $registration->ID() ] = [
2316
+						'paid'  => $registration->pretty_paid(),
2317
+						'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2318
+					];
2319
+				}
2320
+			}
2321
+		}
2322
+
2323
+		return $registration_payment_data;
2324
+	}
2325
+
2326
+
2327
+	/**
2328
+	 * _maybe_send_notifications
2329
+	 * determines whether or not the admin has indicated that notifications should be sent.
2330
+	 * If so, will toggle a filter switch for delivering registration notices.
2331
+	 * If passed an EE_Payment object, then it will trigger payment notifications instead.
2332
+	 *
2333
+	 * @access protected
2334
+	 * @param EE_Payment | null $payment
2335
+	 */
2336
+	protected function _maybe_send_notifications($payment = null)
2337
+	{
2338
+		switch ($payment instanceof EE_Payment) {
2339
+			// payment notifications
2340
+			case true:
2341
+				if ($this->request->getRequestParam('txn_payments[send_notifications]', false, 'bool')) {
2342
+					$this->_process_payment_notification($payment);
2343
+				}
2344
+				break;
2345
+			// registration notifications
2346
+			case false:
2347
+				if ($this->request->getRequestParam('txn_reg_status_change[send_notifications]', false, 'bool')) {
2348
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
2349
+				}
2350
+				break;
2351
+		}
2352
+	}
2353
+
2354
+
2355
+	/**
2356
+	 * _send_payment_reminder
2357
+	 *    generates HTML for the View Transaction Details Admin page
2358
+	 *
2359
+	 * @access protected
2360
+	 * @return void
2361
+	 * @throws EE_Error
2362
+	 * @throws InvalidArgumentException
2363
+	 * @throws InvalidDataTypeException
2364
+	 * @throws InvalidInterfaceException
2365
+	 */
2366
+	protected function _send_payment_reminder()
2367
+	{
2368
+		$TXN_ID      = $this->request->getRequestParam('TXN_ID', 0, 'int');
2369
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2370
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2371
+		$query_args  = $redirect_to
2372
+			? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2373
+			: [];
2374
+		do_action(
2375
+			'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
2376
+			$transaction
2377
+		);
2378
+		$this->_redirect_after_action(
2379
+			false,
2380
+			esc_html__('payment reminder', 'event_espresso'),
2381
+			esc_html__('sent', 'event_espresso'),
2382
+			$query_args,
2383
+			true
2384
+		);
2385
+	}
2386
+
2387
+
2388
+	/**
2389
+	 *  get_transactions
2390
+	 *    get transactions for given parameters (used by list table)
2391
+	 *
2392
+	 * @param int     $per_page how many transactions displayed per page
2393
+	 * @param boolean $count    return the count or objects
2394
+	 * @param string  $view
2395
+	 * @return EE_Transaction[]|int int = count || array of transaction objects
2396
+	 * @throws EE_Error
2397
+	 * @throws InvalidArgumentException
2398
+	 * @throws InvalidDataTypeException
2399
+	 * @throws InvalidInterfaceException
2400
+	 * @throws ReflectionException
2401
+	 */
2402
+	public function get_transactions($per_page, $count = false, $view = '')
2403
+	{
2404
+		$start_date = wp_strip_all_tags(
2405
+			$this->request->getRequestParam('txn-filter-start-date', date('m/d/Y', strtotime('-10 year')))
2406
+		);
2407
+		$end_date   = wp_strip_all_tags(
2408
+			$this->request->getRequestParam('txn-filter-end-date', date('m/d/Y'))
2409
+		);
2410
+
2411
+		// make sure our timestamps start and end right at the boundaries for each day
2412
+		$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2413
+		$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2414
+
2415
+
2416
+		// convert to timestamps
2417
+		$start_date = strtotime($start_date);
2418
+		$end_date   = strtotime($end_date);
2419
+
2420
+		// makes sure start date is the lowest value and vice versa
2421
+		$start_date = min($start_date, $end_date);
2422
+		$end_date   = max($start_date, $end_date);
2423
+
2424
+		// convert to correct format for query
2425
+		$start_date = EEM_Transaction::instance()->convert_datetime_for_query(
2426
+			'TXN_timestamp',
2427
+			date('Y-m-d H:i:s', $start_date),
2428
+			'Y-m-d H:i:s'
2429
+		);
2430
+		$end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2431
+			'TXN_timestamp',
2432
+			date('Y-m-d H:i:s', $end_date),
2433
+			'Y-m-d H:i:s'
2434
+		);
2435
+
2436
+
2437
+		// set orderby
2438
+		$orderby = $this->request->getRequestParam('orderby');
2439
+
2440
+		switch ($orderby) {
2441
+			case 'TXN_ID':
2442
+				break;
2443
+			case 'ATT_fname':
2444
+				$orderby = 'Registration.Attendee.ATT_fname';
2445
+				break;
2446
+			case 'event_name':
2447
+				$orderby = 'Registration.Event.EVT_name';
2448
+				break;
2449
+			default: // 'TXN_timestamp'
2450
+				$orderby = 'TXN_timestamp';
2451
+		}
2452
+
2453
+		$sort         = $this->request->getRequestParam('order', 'DESC');
2454
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
2455
+
2456
+		$per_page = absint($per_page)
2457
+			? $per_page
2458
+			: 10;
2459
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
2460
+
2461
+		$offset = ($current_page - 1) * $per_page;
2462
+		$limit  = [$offset, $per_page];
2463
+
2464
+		$_where = [
2465
+			'TXN_timestamp'          => ['BETWEEN', [$start_date, $end_date]],
2466
+			'Registration.REG_count' => 1,
2467
+		];
2468
+
2469
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', 0, 'int');
2470
+		if ($EVT_ID) {
2471
+			$_where['Registration.EVT_ID'] = $EVT_ID;
2472
+		}
2473
+
2474
+		$search_term = $this->request->getRequestParam('s');
2475
+		if ($search_term) {
2476
+			$search_term  = '%' . $search_term . '%';
2477
+			$_where['OR'] = [
2478
+				'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2479
+				'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
2480
+				'Registration.Event.EVT_short_desc'   => ['LIKE', $search_term],
2481
+				'Registration.Attendee.ATT_full_name' => ['LIKE', $search_term],
2482
+				'Registration.Attendee.ATT_fname'     => ['LIKE', $search_term],
2483
+				'Registration.Attendee.ATT_lname'     => ['LIKE', $search_term],
2484
+				'Registration.Attendee.ATT_short_bio' => ['LIKE', $search_term],
2485
+				'Registration.Attendee.ATT_email'     => ['LIKE', $search_term],
2486
+				'Registration.Attendee.ATT_address'   => ['LIKE', $search_term],
2487
+				'Registration.Attendee.ATT_address2'  => ['LIKE', $search_term],
2488
+				'Registration.Attendee.ATT_city'      => ['LIKE', $search_term],
2489
+				'Registration.REG_final_price'        => ['LIKE', $search_term],
2490
+				'Registration.REG_code'               => ['LIKE', $search_term],
2491
+				'Registration.REG_count'              => ['LIKE', $search_term],
2492
+				'Registration.REG_group_size'         => ['LIKE', $search_term],
2493
+				'Registration.Ticket.TKT_name'        => ['LIKE', $search_term],
2494
+				'Registration.Ticket.TKT_description' => ['LIKE', $search_term],
2495
+				'Payment.PAY_source'                  => ['LIKE', $search_term],
2496
+				'Payment.Payment_Method.PMD_name'     => ['LIKE', $search_term],
2497
+				'TXN_session_data'                    => ['LIKE', $search_term],
2498
+				'Payment.PAY_txn_id_chq_nmbr'         => ['LIKE', $search_term],
2499
+			];
2500
+		}
2501
+
2502
+		$status = $this->request->getRequestParam('status');
2503
+		// failed transactions
2504
+		$failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2505
+		$abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2506
+		$incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2507
+
2508
+		if ($failed) {
2509
+			$_where['STS_ID'] = EEM_Transaction::failed_status_code;
2510
+		} elseif ($abandoned) {
2511
+			$_where['STS_ID'] = EEM_Transaction::abandoned_status_code;
2512
+		} elseif ($incomplete) {
2513
+			$_where['STS_ID'] = EEM_Transaction::incomplete_status_code;
2514
+		} else {
2515
+			$_where['STS_ID']  = ['!=', EEM_Transaction::failed_status_code];
2516
+			$_where['STS_ID*'] = ['!=', EEM_Transaction::abandoned_status_code];
2517
+		}
2518
+
2519
+		$query_params = apply_filters(
2520
+			'FHEE__Transactions_Admin_Page___get_transactions_query_params',
2521
+			[
2522
+				$_where,
2523
+				'order_by'                 => [$orderby => $sort],
2524
+				'limit'                    => $limit,
2525
+				'default_where_conditions' => EEM_Base::default_where_conditions_this_only,
2526
+			],
2527
+			$this->request->requestParams(),
2528
+			$view,
2529
+			$count
2530
+		);
2531
+
2532
+		return $count
2533
+			? EEM_Transaction::instance()->count([$query_params[0]], 'TXN_ID', true)
2534
+			: EEM_Transaction::instance()->get_all($query_params);
2535
+	}
2536
+
2537
+
2538
+	/**
2539
+	 * @throws EE_Error
2540
+	 * @throws InvalidArgumentException
2541
+	 * @throws InvalidDataTypeException
2542
+	 * @throws InvalidInterfaceException
2543
+	 * @throws ReflectionException
2544
+	 * @throws RuntimeException
2545
+	 * @since 4.9.79.p
2546
+	 */
2547
+	public function recalculateLineItems()
2548
+	{
2549
+		$TXN_ID = $this->request->getRequestParam('TXN_ID', 0, 'int');
2550
+		/** @var EE_Transaction $transaction */
2551
+		$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2552
+		$success     = $transaction->recalculateLineItems();
2553
+		$redirect_to = $this->request->getRequestParam('redirect_to');
2554
+		$query_args  = $redirect_to
2555
+			? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2556
+			: [];
2557
+		$this->_redirect_after_action(
2558
+			$success,
2559
+			esc_html__('Transaction taxes and totals', 'event_espresso'),
2560
+			esc_html__('recalculated', 'event_espresso'),
2561
+			$query_args,
2562
+			true
2563
+		);
2564
+	}
2565 2565
 }
Please login to merge, or discard this patch.
Spacing   +103 added lines, -103 removed lines patch added patch discarded remove patch
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
             '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.',
245 245
             'event_espresso'
246 246
         );
247
-        EE_Registry::$i18n_js_strings['error_occurred']          = esc_html__(
247
+        EE_Registry::$i18n_js_strings['error_occurred'] = esc_html__(
248 248
             'An error occurred! Please refresh the page and try again.',
249 249
             'event_espresso'
250 250
         );
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
         // enqueue style
346 346
         wp_register_style(
347 347
             'espresso_txn',
348
-            TXN_ASSETS_URL . 'espresso_transactions_admin.css',
348
+            TXN_ASSETS_URL.'espresso_transactions_admin.css',
349 349
             [],
350 350
             EVENT_ESPRESSO_VERSION
351 351
         );
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
         // scripts
354 354
         wp_register_script(
355 355
             'espresso_txn',
356
-            TXN_ASSETS_URL . 'espresso_transactions_admin.js',
356
+            TXN_ASSETS_URL.'espresso_transactions_admin.js',
357 357
             [
358 358
                 'ee_admin_js',
359 359
                 'ee-datepicker',
@@ -480,7 +480,7 @@  discard block
 block discarded – undo
480 480
             $this->_transaction->verify_abandoned_transaction_status();
481 481
         }
482 482
 
483
-        if (! $this->_transaction instanceof EE_Transaction) {
483
+        if ( ! $this->_transaction instanceof EE_Transaction) {
484 484
             $error_msg = sprintf(
485 485
                 esc_html__(
486 486
                     'An error occurred and the details for the transaction with the ID # %d could not be retrieved.',
@@ -577,7 +577,7 @@  discard block
 block discarded – undo
577 577
             'FHEE__Transactions_Admin_Page___transaction_legend_items__more_items',
578 578
             [
579 579
                 'overpaid'   => [
580
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::overpaid_status_code,
580
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::overpaid_status_code,
581 581
                     'desc'  => EEH_Template::pretty_status(
582 582
                         EEM_Transaction::overpaid_status_code,
583 583
                         false,
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
                     ),
586 586
                 ],
587 587
                 'complete'   => [
588
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::complete_status_code,
588
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::complete_status_code,
589 589
                     'desc'  => EEH_Template::pretty_status(
590 590
                         EEM_Transaction::complete_status_code,
591 591
                         false,
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
                     ),
594 594
                 ],
595 595
                 'incomplete' => [
596
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::incomplete_status_code,
596
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::incomplete_status_code,
597 597
                     'desc'  => EEH_Template::pretty_status(
598 598
                         EEM_Transaction::incomplete_status_code,
599 599
                         false,
@@ -601,7 +601,7 @@  discard block
 block discarded – undo
601 601
                     ),
602 602
                 ],
603 603
                 'abandoned'  => [
604
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::abandoned_status_code,
604
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::abandoned_status_code,
605 605
                     'desc'  => EEH_Template::pretty_status(
606 606
                         EEM_Transaction::abandoned_status_code,
607 607
                         false,
@@ -609,7 +609,7 @@  discard block
 block discarded – undo
609 609
                     ),
610 610
                 ],
611 611
                 'failed'     => [
612
-                    'class' => 'ee-status-legend ee-status-bg--' . EEM_Transaction::failed_status_code,
612
+                    'class' => 'ee-status-legend ee-status-bg--'.EEM_Transaction::failed_status_code,
613 613
                     'desc'  => EEH_Template::pretty_status(
614 614
                         EEM_Transaction::failed_status_code,
615 615
                         false,
@@ -652,11 +652,11 @@  discard block
 block discarded – undo
652 652
                 )
653 653
                 . '" aria-label="'
654 654
                 . esc_attr__('Click to Edit event', 'event_espresso')
655
-                . '">' . $event->name() . '</a>',
655
+                . '">'.$event->name().'</a>',
656 656
                 '</h3>'
657 657
             )
658 658
             : '';
659
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_transaction_legend_items());
659
+        $this->_template_args['after_list_table'] = $this->_display_legend($this->_transaction_legend_items());
660 660
         $this->display_admin_list_table_page_with_no_sidebar();
661 661
     }
662 662
 
@@ -686,7 +686,7 @@  discard block
 block discarded – undo
686 686
 
687 687
         $this->_set_transaction_object();
688 688
 
689
-        if (! $this->_transaction instanceof EE_Transaction) {
689
+        if ( ! $this->_transaction instanceof EE_Transaction) {
690 690
             return;
691 691
         }
692 692
 
@@ -696,7 +696,7 @@  discard block
 block discarded – undo
696 696
         $this->_template_args['txn_datetime']['value'] = $this->_transaction->get_i18n_datetime('TXN_timestamp');
697 697
         $this->_template_args['txn_datetime']['label'] = esc_html__('Date', 'event_espresso');
698 698
 
699
-        $this->_template_args['txn_status']['value'] = self::$_txn_status[ $this->_transaction->status_ID() ];
699
+        $this->_template_args['txn_status']['value'] = self::$_txn_status[$this->_transaction->status_ID()];
700 700
         $this->_template_args['txn_status']['label'] = esc_html__('Transaction Status', 'event_espresso');
701 701
         $this->_template_args['txn_status']['class'] = $this->_transaction->status_ID();
702 702
 
@@ -741,7 +741,7 @@  discard block
 block discarded – undo
741 741
 
742 742
 
743 743
         // next link
744
-        $next_txn                                 = $this->_transaction->next(
744
+        $next_txn = $this->_transaction->next(
745 745
             null,
746 746
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
747 747
             'TXN_ID'
@@ -756,7 +756,7 @@  discard block
 block discarded – undo
756 756
             )
757 757
             : '';
758 758
         // previous link
759
-        $previous_txn                                 = $this->_transaction->previous(
759
+        $previous_txn = $this->_transaction->previous(
760 760
             null,
761 761
             [['STS_ID' => ['!=', EEM_Transaction::failed_status_code]]],
762 762
             'TXN_ID'
@@ -808,7 +808,7 @@  discard block
 block discarded – undo
808 808
         // grab messages at the last second
809 809
         $this->_template_args['notices'] = EE_Error::get_notices();
810 810
         // path to template
811
-        $template_path                             = TXN_TEMPLATE_PATH . 'txn_admin_details_header.template.php';
811
+        $template_path                             = TXN_TEMPLATE_PATH.'txn_admin_details_header.template.php';
812 812
         $this->_template_args['admin_page_header'] = EEH_Template::display_template(
813 813
             $template_path,
814 814
             $this->_template_args,
@@ -836,19 +836,19 @@  discard block
 block discarded – undo
836 836
     {
837 837
         $this->_set_transaction_object();
838 838
 
839
-        if (! $this->_transaction instanceof EE_Transaction) {
839
+        if ( ! $this->_transaction instanceof EE_Transaction) {
840 840
             return;
841 841
         }
842 842
         $this->addMetaBox(
843 843
             'edit-txn-details-mbox',
844
-            '<span>' . esc_html__('Transaction Details', 'event_espresso')
844
+            '<span>'.esc_html__('Transaction Details', 'event_espresso')
845 845
             . '&nbsp;<span class="dashicons dashicons-cart" ></span></span>',
846 846
             [$this, 'txn_details_meta_box'],
847 847
             $this->_wp_page_slug
848 848
         );
849 849
         $this->addMetaBox(
850 850
             'edit-txn-attendees-mbox',
851
-            '<span>' . esc_html__('Attendees Registered in this Transaction', 'event_espresso')
851
+            '<span>'.esc_html__('Attendees Registered in this Transaction', 'event_espresso')
852 852
             . '&nbsp;<span class="dashicons dashicons-groups" ></span></span>',
853 853
             [$this, 'txn_attendees_meta_box'],
854 854
             $this->_wp_page_slug,
@@ -890,7 +890,7 @@  discard block
 block discarded – undo
890 890
     {
891 891
         $content = '';
892 892
         $actions = [];
893
-        if (! $transaction instanceof EE_Transaction) {
893
+        if ( ! $transaction instanceof EE_Transaction) {
894 894
             return $content;
895 895
         }
896 896
         /** @var EE_Registration $primary_registration */
@@ -1001,7 +1001,7 @@  discard block
 block discarded – undo
1001 1001
             $this->_transaction->primary_registration() instanceof EE_Registration
1002 1002
                 ? $this->_transaction->primary_registration()->attendee()
1003 1003
                 : null;
1004
-        $this->_template_args['can_edit_payments']   = $this->capabilities->current_user_can(
1004
+        $this->_template_args['can_edit_payments'] = $this->capabilities->current_user_can(
1005 1005
             'ee_edit_payments',
1006 1006
             'apply_payment_or_refund_from_registration_details'
1007 1007
         );
@@ -1012,7 +1012,7 @@  discard block
 block discarded – undo
1012 1012
 
1013 1013
         // get line table
1014 1014
         EEH_Autoloader::register_line_item_display_autoloaders();
1015
-        $Line_Item_Display                       = new EE_Line_Item_Display(
1015
+        $Line_Item_Display = new EE_Line_Item_Display(
1016 1016
             'admin_table',
1017 1017
             'EE_Admin_Table_Line_Item_Display_Strategy'
1018 1018
         );
@@ -1029,7 +1029,7 @@  discard block
 block discarded – undo
1029 1029
             ? $taxes
1030 1030
             : false;
1031 1031
 
1032
-        $this->_template_args['grand_total']     = EEH_Template::format_currency(
1032
+        $this->_template_args['grand_total'] = EEH_Template::format_currency(
1033 1033
             $this->_transaction->total(),
1034 1034
             false,
1035 1035
             false
@@ -1039,7 +1039,7 @@  discard block
 block discarded – undo
1039 1039
 
1040 1040
         // process payment details
1041 1041
         $payments = $this->_transaction->payments();
1042
-        if (! empty($payments)) {
1042
+        if ( ! empty($payments)) {
1043 1043
             $this->_template_args['payments']              = $payments;
1044 1044
             $this->_template_args['existing_reg_payments'] = $this->_get_registration_payment_IDs($payments);
1045 1045
         } else {
@@ -1097,7 +1097,7 @@  discard block
 block discarded – undo
1097 1097
                                   esc_html__('%1$s : Initiated %2$s', 'event_espresso'),
1098 1098
                                   ucwords(str_replace('_', ' ', $reg_step)),
1099 1099
                                   date(
1100
-                                      get_option('date_format') . ' ' . get_option('time_format'),
1100
+                                      get_option('date_format').' '.get_option('time_format'),
1101 1101
                                       $reg_step_status + (get_option('gmt_offset') * HOUR_IN_SECONDS)
1102 1102
                                   )
1103 1103
                               )
@@ -1111,7 +1111,7 @@  discard block
 block discarded – undo
1111 1111
                               . '</div>';
1112 1112
             }
1113 1113
         }
1114
-        $reg_steps                                                 .= '</ul>';
1114
+        $reg_steps .= '</ul>';
1115 1115
         $this->_template_args['txn_details']['reg_steps']['value'] = $reg_steps;
1116 1116
         $this->_template_args['txn_details']['reg_steps']['label'] = esc_html__(
1117 1117
             'Registration Step Progress',
@@ -1124,14 +1124,14 @@  discard block
 block discarded – undo
1124 1124
         $this->_get_payment_status_array();
1125 1125
         $this->_get_reg_status_selection(); // sets up the template args for the reg status array for the transaction.
1126 1126
 
1127
-        $this->_template_args['transaction_form_url']    = add_query_arg(
1127
+        $this->_template_args['transaction_form_url'] = add_query_arg(
1128 1128
             [
1129 1129
                 'action'  => 'edit_transaction',
1130 1130
                 'process' => 'transaction',
1131 1131
             ],
1132 1132
             TXN_ADMIN_URL
1133 1133
         );
1134
-        $this->_template_args['apply_payment_form_url']  = add_query_arg(
1134
+        $this->_template_args['apply_payment_form_url'] = add_query_arg(
1135 1135
             [
1136 1136
                 'page'   => 'espresso_transactions',
1137 1137
                 'action' => 'espresso_apply_payment',
@@ -1150,7 +1150,7 @@  discard block
 block discarded – undo
1150 1150
 
1151 1151
         // 'espresso_delete_payment_nonce'
1152 1152
 
1153
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_txn_details.template.php';
1153
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_txn_details.template.php';
1154 1154
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1155 1155
     }
1156 1156
 
@@ -1182,19 +1182,19 @@  discard block
 block discarded – undo
1182 1182
                 ],
1183 1183
             ]
1184 1184
         );
1185
-        if (! empty($reg_payments)) {
1185
+        if ( ! empty($reg_payments)) {
1186 1186
             foreach ($payments as $payment) {
1187
-                if (! $payment instanceof EE_Payment) {
1187
+                if ( ! $payment instanceof EE_Payment) {
1188 1188
                     continue;
1189
-                } elseif (! isset($existing_reg_payments[ $payment->ID() ])) {
1190
-                    $existing_reg_payments[ $payment->ID() ] = [];
1189
+                } elseif ( ! isset($existing_reg_payments[$payment->ID()])) {
1190
+                    $existing_reg_payments[$payment->ID()] = [];
1191 1191
                 }
1192 1192
                 foreach ($reg_payments as $reg_payment) {
1193 1193
                     if (
1194 1194
                         $reg_payment instanceof EE_Registration_Payment
1195 1195
                         && $reg_payment->payment_ID() === $payment->ID()
1196 1196
                     ) {
1197
-                        $existing_reg_payments[ $payment->ID() ][] = $reg_payment->registration_ID();
1197
+                        $existing_reg_payments[$payment->ID()][] = $reg_payment->registration_ID();
1198 1198
                     }
1199 1199
                 }
1200 1200
             }
@@ -1220,7 +1220,7 @@  discard block
 block discarded – undo
1220 1220
     protected function _get_registrations_to_apply_payment_to()
1221 1221
     {
1222 1222
         // we want any registration with an active status (ie: not deleted or cancelled)
1223
-        $query_params                      = [
1223
+        $query_params = [
1224 1224
             [
1225 1225
                 'STS_ID' => [
1226 1226
                     'IN',
@@ -1232,22 +1232,22 @@  discard block
 block discarded – undo
1232 1232
                 ],
1233 1233
             ],
1234 1234
         ];
1235
-        $registrations_to_apply_payment_to = EEH_HTML::br() . EEH_HTML::div(
1235
+        $registrations_to_apply_payment_to = EEH_HTML::br().EEH_HTML::div(
1236 1236
                 '',
1237 1237
                 'txn-admin-apply-payment-to-registrations-dv',
1238 1238
                 '',
1239 1239
                 'clear: both; margin: 1.5em 0 0; display: none;'
1240 1240
             );
1241
-        $registrations_to_apply_payment_to .= EEH_HTML::br() . EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1241
+        $registrations_to_apply_payment_to .= EEH_HTML::br().EEH_HTML::div('', '', 'admin-primary-mbox-tbl-wrap');
1242 1242
         $registrations_to_apply_payment_to .= EEH_HTML::table('', '', 'admin-primary-mbox-tbl striped');
1243 1243
         $registrations_to_apply_payment_to .= EEH_HTML::thead(
1244 1244
             EEH_HTML::tr(
1245
-                EEH_HTML::th(esc_html__('ID', 'event_espresso')) .
1246
-                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')) .
1247
-                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')) .
1248
-                EEH_HTML::th(esc_html__('Event', 'event_espresso')) .
1249
-                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr') .
1250
-                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr') .
1245
+                EEH_HTML::th(esc_html__('ID', 'event_espresso')).
1246
+                EEH_HTML::th(esc_html__('Registrant', 'event_espresso')).
1247
+                EEH_HTML::th(esc_html__('Ticket', 'event_espresso')).
1248
+                EEH_HTML::th(esc_html__('Event', 'event_espresso')).
1249
+                EEH_HTML::th(esc_html__('Paid', 'event_espresso'), '', 'txn-admin-payment-paid-td jst-cntr').
1250
+                EEH_HTML::th(esc_html__('Owing', 'event_espresso'), '', 'txn-admin-payment-owing-td jst-cntr').
1251 1251
                 EEH_HTML::th(esc_html__('Apply', 'event_espresso'), '', 'jst-cntr')
1252 1252
             )
1253 1253
         );
@@ -1262,36 +1262,36 @@  discard block
 block discarded – undo
1262 1262
                     : esc_html__('Unknown Attendee', 'event_espresso');
1263 1263
                 $owing                             = $registration->final_price() - $registration->paid();
1264 1264
                 $taxable                           = $registration->ticket()->taxable()
1265
-                    ? ' <span class="smaller-text lt-grey-text"> ' . esc_html__('+ tax', 'event_espresso') . '</span>'
1265
+                    ? ' <span class="smaller-text lt-grey-text"> '.esc_html__('+ tax', 'event_espresso').'</span>'
1266 1266
                     : '';
1267 1267
                 $checked                           = empty($existing_reg_payments)
1268 1268
                                                      || in_array($registration->ID(), $existing_reg_payments, true)
1269 1269
                     ? ' checked'
1270 1270
                     : '';
1271
-                $disabled                          = $registration->final_price() > 0
1271
+                $disabled = $registration->final_price() > 0
1272 1272
                     ? ''
1273 1273
                     : ' disabled';
1274 1274
                 $registrations_to_apply_payment_to .= EEH_HTML::tr(
1275
-                    EEH_HTML::td($registration->ID()) .
1276
-                    EEH_HTML::td($attendee_name) .
1275
+                    EEH_HTML::td($registration->ID()).
1276
+                    EEH_HTML::td($attendee_name).
1277 1277
                     EEH_HTML::td(
1278
-                        $registration->ticket()->name() . ' : ' . $registration->ticket()->pretty_price() . $taxable
1279
-                    ) .
1280
-                    EEH_HTML::td($registration->event_name()) .
1281
-                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr') .
1278
+                        $registration->ticket()->name().' : '.$registration->ticket()->pretty_price().$taxable
1279
+                    ).
1280
+                    EEH_HTML::td($registration->event_name()).
1281
+                    EEH_HTML::td($registration->pretty_paid(), '', 'txn-admin-payment-paid-td jst-cntr').
1282 1282
                     EEH_HTML::td(
1283 1283
                         EEH_Template::format_currency($owing),
1284 1284
                         '',
1285 1285
                         'txn-admin-payment-owing-td jst-cntr'
1286
-                    ) .
1286
+                    ).
1287 1287
                     EEH_HTML::td(
1288
-                        '<input type="checkbox" value="' . $registration->ID()
1288
+                        '<input type="checkbox" value="'.$registration->ID()
1289 1289
                         . '" name="txn_admin_payment[registrations]"'
1290
-                        . $checked . $disabled . '>',
1290
+                        . $checked.$disabled.'>',
1291 1291
                         '',
1292 1292
                         'jst-cntr'
1293 1293
                     ),
1294
-                    'apply-payment-registration-row-' . $registration->ID()
1294
+                    'apply-payment-registration-row-'.$registration->ID()
1295 1295
                 );
1296 1296
             }
1297 1297
         }
@@ -1306,7 +1306,7 @@  discard block
 block discarded – undo
1306 1306
             '',
1307 1307
             'clear description'
1308 1308
         );
1309
-        $registrations_to_apply_payment_to                         .= EEH_HTML::divx();
1309
+        $registrations_to_apply_payment_to .= EEH_HTML::divx();
1310 1310
         $this->_template_args['registrations_to_apply_payment_to'] = $registrations_to_apply_payment_to;
1311 1311
     }
1312 1312
 
@@ -1372,12 +1372,12 @@  discard block
 block discarded – undo
1372 1372
                 [
1373 1373
                     'OR*payment_method_for_payment' => [
1374 1374
                         'PMD_ID'    => ['IN', $payment_methods_of_payments],
1375
-                        'PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%'],
1375
+                        'PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%'],
1376 1376
                     ],
1377 1377
                 ],
1378 1378
             ];
1379 1379
         } else {
1380
-            $query_args = [['PMD_scope' => ['LIKE', '%' . EEM_Payment_Method::scope_admin . '%']]];
1380
+            $query_args = [['PMD_scope' => ['LIKE', '%'.EEM_Payment_Method::scope_admin.'%']]];
1381 1381
         }
1382 1382
         $this->_template_args['payment_methods'] = EEM_Payment_Method::instance()->get_all($query_args);
1383 1383
     }
@@ -1409,7 +1409,7 @@  discard block
 block discarded – undo
1409 1409
             'Line_Item',
1410 1410
             [['LIN_type' => 'line-item']]
1411 1411
         );
1412
-        if (! empty($line_items)) {
1412
+        if ( ! empty($line_items)) {
1413 1413
             foreach ($line_items as $item) {
1414 1414
                 if ($item instanceof EE_Line_Item) {
1415 1415
                     switch ($item->OBJ_type()) {
@@ -1419,7 +1419,7 @@  discard block
 block discarded – undo
1419 1419
                             $ticket = $item->ticket();
1420 1420
                             // right now we're only handling tickets here.
1421 1421
                             // Cause its expected that only tickets will have attendees right?
1422
-                            if (! $ticket instanceof EE_Ticket) {
1422
+                            if ( ! $ticket instanceof EE_Ticket) {
1423 1423
                                 break;
1424 1424
                             }
1425 1425
                             try {
@@ -1428,45 +1428,45 @@  discard block
 block discarded – undo
1428 1428
                                 EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
1429 1429
                                 $event_name = esc_html__('Unknown Event', 'event_espresso');
1430 1430
                             }
1431
-                            $event_name   .= ' - ' . $item->name();
1431
+                            $event_name   .= ' - '.$item->name();
1432 1432
                             $ticket_price = EEH_Template::format_currency($item->unit_price());
1433 1433
                             // now get all of the registrations for this transaction that use this ticket
1434 1434
                             $registrations = $ticket->registrations(
1435 1435
                                 [['TXN_ID' => $this->_transaction->ID()]]
1436 1436
                             );
1437 1437
                             foreach ($registrations as $registration) {
1438
-                                if (! $registration instanceof EE_Registration) {
1438
+                                if ( ! $registration instanceof EE_Registration) {
1439 1439
                                     break;
1440 1440
                                 }
1441
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['STS_ID']
1441
+                                $this->_template_args['event_attendees'][$registration->ID()]['STS_ID']
1442 1442
                                     = $registration->status_ID();
1443
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['att_num']
1443
+                                $this->_template_args['event_attendees'][$registration->ID()]['att_num']
1444 1444
                                     = $registration->count();
1445
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['event_ticket_name']
1445
+                                $this->_template_args['event_attendees'][$registration->ID()]['event_ticket_name']
1446 1446
                                     = $event_name;
1447
-                                $this->_template_args['event_attendees'][ $registration->ID() ]['ticket_price']
1447
+                                $this->_template_args['event_attendees'][$registration->ID()]['ticket_price']
1448 1448
                                     = $ticket_price;
1449 1449
                                 // attendee info
1450 1450
                                 $attendee = $registration->get_first_related('Attendee');
1451 1451
                                 if ($attendee instanceof EE_Attendee) {
1452
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']
1452
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']
1453 1453
                                         = $attendee->ID();
1454
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee']
1454
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee']
1455 1455
                                         = $attendee->full_name();
1456
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']
1457
-                                        = '<a href="mailto:' . $attendee->email() . '?subject=' . $event_name
1456
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']
1457
+                                        = '<a href="mailto:'.$attendee->email().'?subject='.$event_name
1458 1458
                                           . esc_html__(
1459 1459
                                               ' Event',
1460 1460
                                               'event_espresso'
1461 1461
                                           )
1462
-                                          . '">' . $attendee->email() . '</a>';
1463
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']
1462
+                                          . '">'.$attendee->email().'</a>';
1463
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']
1464 1464
                                         = EEH_Address::format($attendee, 'inline', false, false);
1465 1465
                                 } else {
1466
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['att_id']   = '';
1467
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['attendee'] = '';
1468
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['email']    = '';
1469
-                                    $this->_template_args['event_attendees'][ $registration->ID() ]['address']  = '';
1466
+                                    $this->_template_args['event_attendees'][$registration->ID()]['att_id']   = '';
1467
+                                    $this->_template_args['event_attendees'][$registration->ID()]['attendee'] = '';
1468
+                                    $this->_template_args['event_attendees'][$registration->ID()]['email']    = '';
1469
+                                    $this->_template_args['event_attendees'][$registration->ID()]['address']  = '';
1470 1470
                                 }
1471 1471
                             }
1472 1472
                             break;
@@ -1482,7 +1482,7 @@  discard block
 block discarded – undo
1482 1482
                 TXN_ADMIN_URL
1483 1483
             );
1484 1484
             echo EEH_Template::display_template(
1485
-                TXN_TEMPLATE_PATH . 'txn_admin_details_main_meta_box_attendees.template.php',
1485
+                TXN_TEMPLATE_PATH.'txn_admin_details_main_meta_box_attendees.template.php',
1486 1486
                 $this->_template_args,
1487 1487
                 true
1488 1488
             );
@@ -1517,12 +1517,12 @@  discard block
 block discarded – undo
1517 1517
         $primary_att = $this->_transaction->primary_registration() instanceof EE_Registration
1518 1518
             ? $this->_transaction->primary_registration()->get_first_related('Attendee')
1519 1519
             : null;
1520
-        if (! $primary_att instanceof EE_Attendee) {
1520
+        if ( ! $primary_att instanceof EE_Attendee) {
1521 1521
             $this->_template_args['no_attendee_message'] = esc_html__(
1522 1522
                 'There is no attached contact for this transaction.  The transaction either failed due to an error or was abandoned.',
1523 1523
                 'event_espresso'
1524 1524
             );
1525
-            $primary_att                                 = EEM_Attendee::instance()->create_default_object();
1525
+            $primary_att = EEM_Attendee::instance()->create_default_object();
1526 1526
         }
1527 1527
         $this->_template_args['ATT_ID']            = $primary_att->ID();
1528 1528
         $this->_template_args['prime_reg_fname']   = $primary_att->fname();
@@ -1544,7 +1544,7 @@  discard block
 block discarded – undo
1544 1544
                 : '';
1545 1545
         $this->_template_args['formatted_address'] = $formatted_address;
1546 1546
         echo EEH_Template::display_template(
1547
-            TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_registrant.template.php',
1547
+            TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_registrant.template.php',
1548 1548
             $this->_template_args,
1549 1549
             true
1550 1550
         );
@@ -1569,7 +1569,7 @@  discard block
 block discarded – undo
1569 1569
             TXN_ADMIN_URL
1570 1570
         );
1571 1571
 
1572
-        $template_path = TXN_TEMPLATE_PATH . 'txn_admin_details_side_meta_box_billing_info.template.php';
1572
+        $template_path = TXN_TEMPLATE_PATH.'txn_admin_details_side_meta_box_billing_info.template.php';
1573 1573
         echo EEH_Template::display_template($template_path, $this->_template_args, true);
1574 1574
     }
1575 1575
 
@@ -1596,7 +1596,7 @@  discard block
 block discarded – undo
1596 1596
         );
1597 1597
         $TXD_ID     = $this->request->getRequestParam('txn_admin_payment[TXN_ID]', 0, 'int');
1598 1598
         $amount     = 0;
1599
-        if (! empty($valid_data) && $has_access) {
1599
+        if ( ! empty($valid_data) && $has_access) {
1600 1600
             $PAY_ID = $valid_data['PAY_ID'];
1601 1601
             // save  the new payment
1602 1602
             $payment = $this->_create_payment_from_request_data($valid_data);
@@ -1610,7 +1610,7 @@  discard block
 block discarded – undo
1610 1610
                 $REG_IDs = $this->_get_REG_IDs_to_apply_payment_to($payment);
1611 1611
                 $this->_remove_existing_registration_payments($payment, $PAY_ID);
1612 1612
                 // apply payment to registrations (if applicable)
1613
-                if (! empty($REG_IDs)) {
1613
+                if ( ! empty($REG_IDs)) {
1614 1614
                     $this->_update_registration_payments($transaction, $payment, $REG_IDs);
1615 1615
                     $this->_maybe_send_notifications();
1616 1616
                     // now process status changes for the same registrations
@@ -1683,14 +1683,14 @@  discard block
 block discarded – undo
1683 1683
      */
1684 1684
     protected function _validate_payment_request_data()
1685 1685
     {
1686
-        if (! $this->request->requestParamIsSet('txn_admin_payment')) {
1686
+        if ( ! $this->request->requestParamIsSet('txn_admin_payment')) {
1687 1687
             return [];
1688 1688
         }
1689 1689
         $payment_form = $this->_generate_payment_form_section();
1690 1690
         try {
1691 1691
             if ($payment_form->was_submitted()) {
1692 1692
                 $payment_form->receive_form_submission();
1693
-                if (! $payment_form->is_valid()) {
1693
+                if ( ! $payment_form->is_valid()) {
1694 1694
                     $submission_error_messages = [];
1695 1695
                     foreach ($payment_form->get_validation_errors_accumulated() as $validation_error) {
1696 1696
                         if ($validation_error instanceof EE_Validation_Error) {
@@ -1878,7 +1878,7 @@  discard block
 block discarded – undo
1878 1878
             ['Y-m-d', 'g:i a']
1879 1879
         );
1880 1880
 
1881
-        if (! $payment->save()) {
1881
+        if ( ! $payment->save()) {
1882 1882
             EE_Error::add_error(
1883 1883
                 sprintf(
1884 1884
                     esc_html__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'),
@@ -1954,7 +1954,7 @@  discard block
 block discarded – undo
1954 1954
             false,
1955 1955
             DataType::BOOL
1956 1956
         );
1957
-        $REG_IDs      = ! $apply_to_all
1957
+        $REG_IDs = ! $apply_to_all
1958 1958
             ? $this->request->getRequestParam(
1959 1959
                 'txn_admin_payment[registrations]',
1960 1960
                 [],
@@ -1968,12 +1968,12 @@  discard block
 block discarded – undo
1968 1968
                 [
1969 1969
                     [
1970 1970
                         'STS_ID' => [
1971
-                            'NOT_IN', [ RegStatus::CANCELLED ]
1971
+                            'NOT_IN', [RegStatus::CANCELLED]
1972 1972
                         ]
1973 1973
                     ]
1974 1974
                 ]
1975 1975
             );
1976
-            $REG_IDs       = ! empty($registrations)
1976
+            $REG_IDs = ! empty($registrations)
1977 1977
                 ? array_keys($registrations)
1978 1978
                 : $this->_get_existing_reg_payment_REG_IDs($payment);
1979 1979
         }
@@ -2099,12 +2099,12 @@  discard block
 block discarded – undo
2099 2099
         // but add in some conditions regarding payment,
2100 2100
         // so that we don't apply payments to registrations that are free or have already been paid for
2101 2101
         // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
2102
-        if (! $payment->is_a_refund()) {
2102
+        if ( ! $payment->is_a_refund()) {
2103 2103
             $registration_query_where_params['REG_final_price']  = ['!=', 0];
2104 2104
             $registration_query_where_params['REG_final_price*'] = ['!=', 'REG_paid', true];
2105 2105
         }
2106 2106
         $registrations = $transaction->registrations([$registration_query_where_params]);
2107
-        if (! empty($registrations)) {
2107
+        if ( ! empty($registrations)) {
2108 2108
             /** @type EE_Payment_Processor $payment_processor */
2109 2109
             $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2110 2110
             $payment_processor->process_registration_payments($transaction, $payment, $registrations);
@@ -2188,7 +2188,7 @@  discard block
 block discarded – undo
2188 2188
             'pay_status'       => $payment->STS_ID(),
2189 2189
             'PAY_ID'           => $payment->ID(),
2190 2190
             'STS_ID'           => $payment->STS_ID(),
2191
-            'status'           => self::$_pay_status[ $payment->STS_ID() ],
2191
+            'status'           => self::$_pay_status[$payment->STS_ID()],
2192 2192
             'date'             => $payment->timestamp('Y-m-d', 'h:i a'),
2193 2193
             'method'           => strtoupper($payment->source()),
2194 2194
             'PM_ID'            => $payment_method instanceof EE_Payment_Method
@@ -2308,11 +2308,11 @@  discard block
 block discarded – undo
2308 2308
     {
2309 2309
         $registration_payment_data = [];
2310 2310
         // if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
2311
-        if (! empty($REG_IDs)) {
2311
+        if ( ! empty($REG_IDs)) {
2312 2312
             $registrations = EEM_Registration::instance()->get_all([['REG_ID' => ['IN', $REG_IDs]]]);
2313 2313
             foreach ($registrations as $registration) {
2314 2314
                 if ($registration instanceof EE_Registration) {
2315
-                    $registration_payment_data[ $registration->ID() ] = [
2315
+                    $registration_payment_data[$registration->ID()] = [
2316 2316
                         'paid'  => $registration->pretty_paid(),
2317 2317
                         'owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()),
2318 2318
                     ];
@@ -2369,7 +2369,7 @@  discard block
 block discarded – undo
2369 2369
         $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2370 2370
         $redirect_to = $this->request->getRequestParam('redirect_to');
2371 2371
         $query_args  = $redirect_to
2372
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2372
+            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ]
2373 2373
             : [];
2374 2374
         do_action(
2375 2375
             'AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
@@ -2409,8 +2409,8 @@  discard block
 block discarded – undo
2409 2409
         );
2410 2410
 
2411 2411
         // make sure our timestamps start and end right at the boundaries for each day
2412
-        $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
2413
-        $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
2412
+        $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
2413
+        $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
2414 2414
 
2415 2415
 
2416 2416
         // convert to timestamps
@@ -2427,7 +2427,7 @@  discard block
 block discarded – undo
2427 2427
             date('Y-m-d H:i:s', $start_date),
2428 2428
             'Y-m-d H:i:s'
2429 2429
         );
2430
-        $end_date   = EEM_Transaction::instance()->convert_datetime_for_query(
2430
+        $end_date = EEM_Transaction::instance()->convert_datetime_for_query(
2431 2431
             'TXN_timestamp',
2432 2432
             date('Y-m-d H:i:s', $end_date),
2433 2433
             'Y-m-d H:i:s'
@@ -2473,7 +2473,7 @@  discard block
 block discarded – undo
2473 2473
 
2474 2474
         $search_term = $this->request->getRequestParam('s');
2475 2475
         if ($search_term) {
2476
-            $search_term  = '%' . $search_term . '%';
2476
+            $search_term  = '%'.$search_term.'%';
2477 2477
             $_where['OR'] = [
2478 2478
                 'Registration.Event.EVT_name'         => ['LIKE', $search_term],
2479 2479
                 'Registration.Event.EVT_desc'         => ['LIKE', $search_term],
@@ -2501,9 +2501,9 @@  discard block
 block discarded – undo
2501 2501
 
2502 2502
         $status = $this->request->getRequestParam('status');
2503 2503
         // failed transactions
2504
-        $failed     = (! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2505
-        $abandoned  = (! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2506
-        $incomplete = (! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2504
+        $failed     = ( ! empty($status) && $status === 'failed' && ! $count) || ($count && $view === 'failed');
2505
+        $abandoned  = ( ! empty($status) && $status === 'abandoned' && ! $count) || ($count && $view === 'abandoned');
2506
+        $incomplete = ( ! empty($status) && $status === 'incomplete' && ! $count) || ($count && $view === 'incomplete');
2507 2507
 
2508 2508
         if ($failed) {
2509 2509
             $_where['STS_ID'] = EEM_Transaction::failed_status_code;
@@ -2552,7 +2552,7 @@  discard block
 block discarded – undo
2552 2552
         $success     = $transaction->recalculateLineItems();
2553 2553
         $redirect_to = $this->request->getRequestParam('redirect_to');
2554 2554
         $query_args  = $redirect_to
2555
-            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID,]
2555
+            ? ['action' => $redirect_to, 'TXN_ID' => $TXN_ID, ]
2556 2556
             : [];
2557 2557
         $this->_redirect_after_action(
2558 2558
             $success,
Please login to merge, or discard this patch.
registration_form/templates/questions_main_meta_box.template.php 2 patches
Indentation   +184 added lines, -184 removed lines patch added patch discarded remove patch
@@ -12,58 +12,58 @@  discard block
 block discarded – undo
12 12
 
13 13
 try {
14 14
 
15
-    // the following are already escaped
16
-    echo wp_kses(
17
-        EEH_Form_Fields::hidden_input(
18
-            'QST_system',
19
-            $question->system_ID()
20
-        ),
21
-        AllowedTags::getWithFormTags()
22
-    );
23
-    echo wp_kses(
24
-        EEH_Form_Fields::hidden_input(
25
-            'QST_wp_user',
26
-            $question->wp_user()
27
-        ),
28
-        AllowedTags::getWithFormTags()
29
-    );
30
-    echo wp_kses(
31
-        EEH_Form_Fields::hidden_input(
32
-            'QST_deleted',
33
-            $question->deleted()
34
-        ),
35
-        AllowedTags::getWithFormTags()
36
-    );
15
+	// the following are already escaped
16
+	echo wp_kses(
17
+		EEH_Form_Fields::hidden_input(
18
+			'QST_system',
19
+			$question->system_ID()
20
+		),
21
+		AllowedTags::getWithFormTags()
22
+	);
23
+	echo wp_kses(
24
+		EEH_Form_Fields::hidden_input(
25
+			'QST_wp_user',
26
+			$question->wp_user()
27
+		),
28
+		AllowedTags::getWithFormTags()
29
+	);
30
+	echo wp_kses(
31
+		EEH_Form_Fields::hidden_input(
32
+			'QST_deleted',
33
+			$question->deleted()
34
+		),
35
+		AllowedTags::getWithFormTags()
36
+	);
37 37
 
38
-    $QST_system = $question->system_ID();
39
-    $fields     = $question->get_model()->field_settings();
38
+	$QST_system = $question->system_ID();
39
+	$fields     = $question->get_model()->field_settings();
40 40
 
41
-    do_action('AHEE__questions_main_meta_box__template__before_admin_page_content', $question);
41
+	do_action('AHEE__questions_main_meta_box__template__before_admin_page_content', $question);
42 42
 
43
-    // does question have any answers? cause if it does then we have to disable type
44
-    $has_answers = $question->has_answers();
45
-    global $allowedposttags;
46
-    $info_box = '';
47
-    if ($QST_system === 'country') {
48
-        // already escaped
49
-        $info_box = EEH_HTML::div(
50
-            EEH_HTML::h3(
51
-                '<span class="dashicons dashicons-info"></span> '
52
-                . esc_html__('Did you know...', 'event_espresso'),
53
-                '',
54
-                'ee-status--info'
55
-            ) .
56
-            EEH_HTML::p(
57
-                esc_html__(
58
-                    'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
59
-                    'event_espresso'
60
-                )
61
-            ),
62
-            '',
63
-            'ee-info-box'
64
-        );
65
-    }
66
-    ?>
43
+	// does question have any answers? cause if it does then we have to disable type
44
+	$has_answers = $question->has_answers();
45
+	global $allowedposttags;
46
+	$info_box = '';
47
+	if ($QST_system === 'country') {
48
+		// already escaped
49
+		$info_box = EEH_HTML::div(
50
+			EEH_HTML::h3(
51
+				'<span class="dashicons dashicons-info"></span> '
52
+				. esc_html__('Did you know...', 'event_espresso'),
53
+				'',
54
+				'ee-status--info'
55
+			) .
56
+			EEH_HTML::p(
57
+				esc_html__(
58
+					'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
59
+					'event_espresso'
60
+				)
61
+			),
62
+			'',
63
+			'ee-info-box'
64
+		);
65
+	}
66
+	?>
67 67
 
68 68
     <?php do_action('AHEE__questions_main_meta_box__template__inner_admin_page_content', $question); ?>
69 69
 
@@ -90,9 +90,9 @@  discard block
 block discarded – undo
90 90
             </tr>
91 91
 
92 92
             <?php
93
-            $id            = ! empty($QST_system) ? '_disabled' : '';
94
-            $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
95
-            ?>
93
+			$id            = ! empty($QST_system) ? '_disabled' : '';
94
+			$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
95
+			?>
96 96
             <tr>
97 97
                 <th>
98 98
                     <label for="QST_admin_label<?php esc_attr_e($id); ?>">
@@ -132,11 +132,11 @@  discard block
 block discarded – undo
132 132
             </tr>
133 133
 
134 134
             <?php
135
-            $id            = ! empty($QST_system) ? '_disabled' : '';
136
-            $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
137
-            $admin_only    = $question->get('QST_admin_only');
138
-            $checked       = ! empty($admin_only) ? ' checked' : '';
139
-            ?>
135
+			$id            = ! empty($QST_system) ? '_disabled' : '';
136
+			$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
137
+			$admin_only    = $question->get('QST_admin_only');
138
+			$checked       = ! empty($admin_only) ? ' checked' : '';
139
+			?>
140 140
             <tr>
141 141
                 <th>
142 142
                     <label for="QST_admin_only<?php esc_attr_e($id); ?>">
@@ -151,18 +151,18 @@  discard block
 block discarded – undo
151 151
                            type="checkbox"
152 152
                            value="1"
153 153
                         <?php
154
-                        esc_attr_e($disabled_attr);
155
-                        esc_attr_e($checked);
156
-                        ?>
154
+						esc_attr_e($disabled_attr);
155
+						esc_attr_e($checked);
156
+						?>
157 157
                     />
158 158
                     <br />
159 159
                         <?php
160
-                        if (! empty($QST_system)) { ?>
160
+						if (! empty($QST_system)) { ?>
161 161
                             <p class="description ee-system-question" >
162 162
                                 <?php esc_html_e(
163
-                                    'System question! This field cannot be changed.',
164
-                                    'event_espresso'
165
-                                ); ?>
163
+									'System question! This field cannot be changed.',
164
+									'event_espresso'
165
+								); ?>
166 166
                             </p>
167 167
                         <?php } ?>
168 168
                 </td>
@@ -177,40 +177,40 @@  discard block
 block discarded – undo
177 177
                 </th>
178 178
                 <td>
179 179
                     <?php
180
-                    $disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
181
-                    $id       = $disabled ? '_disabled' : '';
180
+					$disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
181
+					$id       = $disabled ? '_disabled' : '';
182 182
 
183
-                    if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
184
-                        unset($question_types[ EEM_Question::QST_type_email_confirm ]);
185
-                    }
183
+					if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
184
+						unset($question_types[ EEM_Question::QST_type_email_confirm ]);
185
+					}
186 186
 
187
-                    echo wp_kses(
188
-                        EEH_Form_Fields::select_input(
189
-                            'QST_type' . $id,
190
-                            $question_types,
191
-                            $question->type(),
192
-                            'id="QST_type' . $id . '" ' . $disabled_attr
193
-                        ),
194
-                        AllowedTags::getWithFormTags()
195
-                    );
196
-                    if ($disabled) { ?>
187
+					echo wp_kses(
188
+						EEH_Form_Fields::select_input(
189
+							'QST_type' . $id,
190
+							$question_types,
191
+							$question->type(),
192
+							'id="QST_type' . $id . '" ' . $disabled_attr
193
+						),
194
+						AllowedTags::getWithFormTags()
195
+					);
196
+					if ($disabled) { ?>
197 197
                         <input id='QST_type'
198 198
                                name="QST_type"
199 199
                                type="hidden"
200 200
                                value="<?php esc_attr_e($question->type()); ?>"
201 201
                         />
202 202
                         <?php
203
-                        $explanatory_text = esc_html__(
204
-                            'System question! This field cannot be changed.',
205
-                            'event_espresso'
206
-                        );
207
-                    } else {
208
-                        $explanatory_text = esc_html__(
209
-                            'Because there are currently answers for this question in the database, your options to change the question type have been limited to similar question-types.',
210
-                            'event_espresso'
211
-                        );
212
-                    }
213
-                    if ($disabled || $has_answers) { ?>
203
+						$explanatory_text = esc_html__(
204
+							'System question! This field cannot be changed.',
205
+							'event_espresso'
206
+						);
207
+					} else {
208
+						$explanatory_text = esc_html__(
209
+							'Because there are currently answers for this question in the database, your options to change the question type have been limited to similar question-types.',
210
+							'event_espresso'
211
+						);
212
+					}
213
+					if ($disabled || $has_answers) { ?>
214 214
                         <p class="description ee-system-question" >
215 215
                                 <?php echo esc_html($explanatory_text); ?>
216 216
                         </p>
@@ -240,19 +240,19 @@  discard block
 block discarded – undo
240 240
                     />
241 241
                     <p class="description">
242 242
                         <?php esc_html_e(
243
-                            'Maximum number of characters allowed when answering this question',
244
-                            'event_espresso'
245
-                        ); ?>
243
+							'Maximum number of characters allowed when answering this question',
244
+							'event_espresso'
245
+						); ?>
246 246
                     </p>
247 247
                     <?php if ($QST_system) { ?>
248 248
                     <p class="description ee-system-question" >
249 249
                         <?php printf(
250
-                            esc_html__(
251
-                                'System question! The maximum number of characters that can be used for this question is %1$s',
252
-                                'event_espresso'
253
-                            ),
254
-                            $max_max
255
-                        ); ?>
250
+							esc_html__(
251
+								'System question! The maximum number of characters that can be used for this question is %1$s',
252
+								'event_espresso'
253
+							),
254
+							$max_max
255
+						); ?>
256 256
                     </p>
257 257
                     <?php } ?>
258 258
                 </td>
@@ -276,9 +276,9 @@  discard block
 block discarded – undo
276 276
                                 <th class="option-desc-header">
277 277
                                     <label>
278 278
                                     <?php esc_html_e(
279
-                                        'Description (optional, only shown on registration form)',
280
-                                        'event_espresso'
281
-                                    ) ?>
279
+										'Description (optional, only shown on registration form)',
280
+										'event_espresso'
281
+									) ?>
282 282
                                     </label>
283 283
                                 </th>
284 284
                                 <th class="option-actions-header">
@@ -321,9 +321,9 @@  discard block
 block discarded – undo
321 321
                                     </a>
322 322
                                     <a class="button button--icon-only sortable-drag-handle ee-aria-tooltip"
323 323
                                         aria-label="<?php esc_html_e(
324
-                                            'click and drag to change the order of this option',
325
-                                            'event_espresso'
326
-                                        ) ?>"
324
+											'click and drag to change the order of this option',
325
+											'event_espresso'
326
+										) ?>"
327 327
                                     >
328 328
                                         <span class='dashicons dashicons-image-flip-vertical '></span>
329 329
                                     </a>
@@ -331,14 +331,14 @@  discard block
 block discarded – undo
331 331
                             </tr>
332 332
 
333 333
                             <?php
334
-                            $count            = 0;
335
-                            $question_options = $question->options();
336
-                            if (! empty($question_options)) {
337
-                                foreach ($question_options as $option_id => $option) {
338
-                                    $disabled_attr = $has_answers || $option->get('QSO_system')
339
-                                        ? 'disabled'
340
-                                        : '';
341
-                                    ?>
334
+							$count            = 0;
335
+							$question_options = $question->options();
336
+							if (! empty($question_options)) {
337
+								foreach ($question_options as $option_id => $option) {
338
+									$disabled_attr = $has_answers || $option->get('QSO_system')
339
+										? 'disabled'
340
+										: '';
341
+									?>
342 342
                                     <tr class="question-option ee-options-sortable">
343 343
                                         <td class="option-value-cell">
344 344
                                             <label class='screen-reader-text'
@@ -388,35 +388,35 @@  discard block
 block discarded – undo
388 388
                                         <?php } ?>
389 389
                                             <a class='button button--icon-only sortable-drag-handle ee-aria-tooltip'
390 390
                                                aria-label="<?php esc_html_e(
391
-                                                   'click and drag to change the order of this option',
392
-                                                   'event_espresso'
393
-                                               ) ?>"
391
+												   'click and drag to change the order of this option',
392
+												   'event_espresso'
393
+											   ) ?>"
394 394
                                             >
395 395
                                                 <span class='dashicons dashicons-image-flip-vertical '></span>
396 396
                                             </a>
397 397
                                         <?php
398
-                                        echo wp_kses(
399
-                                            EEH_Form_Fields::hidden_input(
400
-                                                "question_options[$count][QST_ID])",
401
-                                                $option->question_ID()
402
-                                            ),
403
-                                            AllowedTags::getWithFormTags()
404
-                                        );
405
-                                        echo wp_kses(
406
-                                            EEH_Form_Fields::hidden_input(
407
-                                                "question_options[$count][QSO_ID])",
408
-                                                $option->ID()
409
-                                            ),
410
-                                            AllowedTags::getWithFormTags()
411
-                                        );
412
-                                        $count++;
413
-                                        ?>
398
+										echo wp_kses(
399
+											EEH_Form_Fields::hidden_input(
400
+												"question_options[$count][QST_ID])",
401
+												$option->question_ID()
402
+											),
403
+											AllowedTags::getWithFormTags()
404
+										);
405
+										echo wp_kses(
406
+											EEH_Form_Fields::hidden_input(
407
+												"question_options[$count][QSO_ID])",
408
+												$option->ID()
409
+											),
410
+											AllowedTags::getWithFormTags()
411
+										);
412
+										$count++;
413
+										?>
414 414
                                         </td>
415 415
                                     </tr>
416 416
                                     <?php
417
-                                }
418
-                            } else {
419
-                                ?>
417
+								}
418
+							} else {
419
+								?>
420 420
                                 <tr class="question-option ee-options-sortable">
421 421
                                     <td class="option-value-cell">
422 422
                                         <label class='screen-reader-text' for='question_options-0-QSO_value'>
@@ -445,14 +445,14 @@  discard block
 block discarded – undo
445 445
                                     </td>
446 446
                                     <td class="option-actions-cell">
447 447
                                         <?php echo wp_kses(
448
-                                            EEH_Form_Fields::hidden_input("question_options_count", 0),
449
-                                            AllowedTags::getWithFormTags()
450
-                                        ); ?>
448
+											EEH_Form_Fields::hidden_input("question_options_count", 0),
449
+											AllowedTags::getWithFormTags()
450
+										); ?>
451 451
                                     </td>
452 452
                                 </tr>
453 453
                                 <?php
454
-                            }
455
-                            ?>
454
+							}
455
+							?>
456 456
                         </tbody>
457 457
                     </table>
458 458
                     <div class="ee-admin-button-row">
@@ -460,27 +460,27 @@  discard block
 block discarded – undo
460 460
                             <?php esc_html_e('Add Another Answer Option', 'event_espresso') ?>
461 461
                         </a>
462 462
                         <?php echo wp_kses(
463
-                            EEH_Form_Fields::hidden_input(
464
-                                "question_options_count",
465
-                                $count
466
-                            ),
467
-                            AllowedTags::getWithFormTags()
468
-                        ); ?>
463
+							EEH_Form_Fields::hidden_input(
464
+								"question_options_count",
465
+								$count
466
+							),
467
+							AllowedTags::getWithFormTags()
468
+						); ?>
469 469
                     </div>
470 470
                     <br />
471 471
 
472 472
                     <p class="description">
473 473
                         <?php esc_html_e(
474
-                            'Answer Options are the choices that you give people to select from for RADIO_BTN, CHECKBOX or DROPDOWN questions. The Value is a simple key that will be saved to the database and the description is optional. Note that values CANNOT contain any HTML, but descriptions can.',
475
-                            'event_espresso'
476
-                        ) ?>
474
+							'Answer Options are the choices that you give people to select from for RADIO_BTN, CHECKBOX or DROPDOWN questions. The Value is a simple key that will be saved to the database and the description is optional. Note that values CANNOT contain any HTML, but descriptions can.',
475
+							'event_espresso'
476
+						) ?>
477 477
                     </p>
478 478
                     <?php if ($has_answers) : ?>
479 479
                         <p class="description ee-system-question" >
480 480
                             <?php esc_html_e(
481
-                                'Answer values that are not editable are this way because there are registrations in the database that have answers for this question.  If you need to correct a mistake, or edit an existing option value, then trash the existing one and create a new option with the changes.  This will ensure that the existing registrations that chose the original answer will preserve that answer.',
482
-                                'event_espresso'
483
-                            ); ?>
481
+								'Answer values that are not editable are this way because there are registrations in the database that have answers for this question.  If you need to correct a mistake, or edit an existing option value, then trash the existing one and create a new option with the changes.  This will ensure that the existing registrations that chose the original answer will preserve that answer.',
482
+								'event_espresso'
483
+							); ?>
484 484
                         </p>
485 485
                     <?php endif; ?>
486 486
                 </td>
@@ -495,41 +495,41 @@  discard block
 block discarded – undo
495 495
                 </th>
496 496
                 <td>
497 497
                     <?php
498
-                    $system_required   = ['fname', 'email'];
499
-                    $disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
500
-                    $required_on       = $question->get('QST_admin_only');
501
-                    $show_required_class = $admin_only && $required_on ? '' : ' hidden';
502
-                    $disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
503
-                    $id                =
504
-                        ! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
505
-                    $requiredOptions   = [
506
-                        ['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
507
-                        ['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
508
-                    ];
509
-                    echo wp_kses(
510
-                        EEH_Form_Fields::select_input(
511
-                            'QST_required' . $id,
512
-                            $requiredOptions,
513
-                            $question->required(),
514
-                            'id="QST_required' . $id . '"' . $disabled_attr,
515
-                            'ee-input-width--small'
516
-                        ),
517
-                        AllowedTags::getWithFormTags()
518
-                    );
519
-                    ?>
498
+					$system_required   = ['fname', 'email'];
499
+					$disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
500
+					$required_on       = $question->get('QST_admin_only');
501
+					$show_required_class = $admin_only && $required_on ? '' : ' hidden';
502
+					$disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
503
+					$id                =
504
+						! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
505
+					$requiredOptions   = [
506
+						['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
507
+						['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
508
+					];
509
+					echo wp_kses(
510
+						EEH_Form_Fields::select_input(
511
+							'QST_required' . $id,
512
+							$requiredOptions,
513
+							$question->required(),
514
+							'id="QST_required' . $id . '"' . $disabled_attr,
515
+							'ee-input-width--small'
516
+						),
517
+						AllowedTags::getWithFormTags()
518
+					);
519
+					?>
520 520
                     <p id="required_toggled_on"
521 521
                        class="description<?php esc_attr_e($show_required_class); ?>"
522 522
                     >
523 523
                         <?php esc_html_e(
524
-                            'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
525
-                            'event_espresso'
526
-                        ) ?>
524
+							'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
525
+							'event_espresso'
526
+						) ?>
527 527
                     </p>
528 528
                     <p id="required_toggled_off" class="description ee-system-question" style="color:#D54E21; display: none;">
529 529
                             <?php esc_html_e(
530
-                                'Required option field is no longer disabled because the question is not Admin-Only',
531
-                                'event_espresso'
532
-                            ) ?>
530
+								'Required option field is no longer disabled because the question is not Admin-Only',
531
+								'event_espresso'
532
+							) ?>
533 533
                     </p>
534 534
                     <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
535 535
                         <input id="QST_required"
@@ -563,8 +563,8 @@  discard block
 block discarded – undo
563 563
                 </td>
564 564
             </tr>
565 565
             <?php
566
-            do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
567
-            ?>
566
+			do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
567
+			?>
568 568
         </tbody>
569 569
     </table>
570 570
 
@@ -572,8 +572,8 @@  discard block
 block discarded – undo
572 572
 </div>
573 573
 
574 574
     <?php
575
-    do_action('AHEE__questions_main_meta_box__template__after_admin_page_content', $question);
575
+	do_action('AHEE__questions_main_meta_box__template__after_admin_page_content', $question);
576 576
 
577 577
 } catch (Exception $e) {
578
-    EE_Error::add_error($e->getMessage(), __FILE__, __LINE__, __METHOD__);
578
+	EE_Error::add_error($e->getMessage(), __FILE__, __LINE__, __METHOD__);
579 579
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -52,7 +52,7 @@  discard block
 block discarded – undo
52 52
                 . esc_html__('Did you know...', 'event_espresso'),
53 53
                 '',
54 54
                 'ee-status--info'
55
-            ) .
55
+            ).
56 56
             EEH_HTML::p(
57 57
                 esc_html__(
58 58
                     'If you add a State/Province Select input immediately after this Country Select input when building your registration form, then the State/Province Select input options will change to correspond with the choice made in this input. So for example, choosing "United States" in this Country Select input will populate the State/Province Select input with just the state options for the United States.',
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
                            value="<?php esc_attr_e($question->get_f('QST_admin_label')); ?>"
109 109
                            <?php esc_attr_e($disabled_attr); ?>
110 110
                     />
111
-                    <?php if (! empty($QST_system)) { ?>
111
+                    <?php if ( ! empty($QST_system)) { ?>
112 112
                         <input class="ee-input-width--reg"
113 113
                                id='QST_admin_label'
114 114
                                name="QST_admin_label"
@@ -117,7 +117,7 @@  discard block
 block discarded – undo
117 117
                         />
118 118
                     <?php } ?>
119 119
                     <br />
120
-                    <?php if (! empty($QST_system)) { ?>
120
+                    <?php if ( ! empty($QST_system)) { ?>
121 121
                         <p class="description ee-system-question" >
122 122
                             <?php esc_html_e('System question! This field cannot be changed.', 'event_espresso') ?>
123 123
                         </p>
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
                     />
158 158
                     <br />
159 159
                         <?php
160
-                        if (! empty($QST_system)) { ?>
160
+                        if ( ! empty($QST_system)) { ?>
161 161
                             <p class="description ee-system-question" >
162 162
                                 <?php esc_html_e(
163 163
                                     'System question! This field cannot be changed.',
@@ -181,15 +181,15 @@  discard block
 block discarded – undo
181 181
                     $id       = $disabled ? '_disabled' : '';
182 182
 
183 183
                     if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
184
-                        unset($question_types[ EEM_Question::QST_type_email_confirm ]);
184
+                        unset($question_types[EEM_Question::QST_type_email_confirm]);
185 185
                     }
186 186
 
187 187
                     echo wp_kses(
188 188
                         EEH_Form_Fields::select_input(
189
-                            'QST_type' . $id,
189
+                            'QST_type'.$id,
190 190
                             $question_types,
191 191
                             $question->type(),
192
-                            'id="QST_type' . $id . '" ' . $disabled_attr
192
+                            'id="QST_type'.$id.'" '.$disabled_attr
193 193
                         ),
194 194
                         AllowedTags::getWithFormTags()
195 195
                     );
@@ -230,7 +230,7 @@  discard block
 block discarded – undo
230 230
                     <input id="QST_max<?php esc_attr_e($id); ?>"
231 231
                         class="ee-input-width--tiny"
232 232
                     <?php if ($max_max !== EE_INF) :?>
233
-                        max="<?php esc_attr_e($max_max);?>"
233
+                        max="<?php esc_attr_e($max_max); ?>"
234 234
                     <?php  endif; ?>
235 235
                         min="1"
236 236
                         name="QST_max"
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
                             <?php
334 334
                             $count            = 0;
335 335
                             $question_options = $question->options();
336
-                            if (! empty($question_options)) {
336
+                            if ( ! empty($question_options)) {
337 337
                                 foreach ($question_options as $option_id => $option) {
338 338
                                     $disabled_attr = $has_answers || $option->get('QSO_system')
339 339
                                         ? 'disabled'
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
                                             />
380 380
                                         </td>
381 381
                                         <td class="option-actions-cell">
382
-                                        <?php if (! $option->system()) { ?>
382
+                                        <?php if ( ! $option->system()) { ?>
383 383
                                             <a class='button button--icon-only remove-option remove-item ee-aria-tooltip'
384 384
                                                aria-label="<?php esc_html_e('click to delete this option', 'event_espresso') ?>"
385 385
                                             >
@@ -508,10 +508,10 @@  discard block
 block discarded – undo
508 508
                     ];
509 509
                     echo wp_kses(
510 510
                         EEH_Form_Fields::select_input(
511
-                            'QST_required' . $id,
511
+                            'QST_required'.$id,
512 512
                             $requiredOptions,
513 513
                             $question->required(),
514
-                            'id="QST_required' . $id . '"' . $disabled_attr,
514
+                            'id="QST_required'.$id.'"'.$disabled_attr,
515 515
                             'ee-input-width--small'
516 516
                         ),
517 517
                         AllowedTags::getWithFormTags()
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
                                 'event_espresso'
532 532
                             ) ?>
533 533
                     </p>
534
-                    <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
534
+                    <?php if ( ! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
535 535
                         <input id="QST_required"
536 536
                                name="QST_required"
537 537
                                type='hidden'
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_List_Table.class.php 1 patch
Indentation   +568 added lines, -568 removed lines patch added patch discarded remove patch
@@ -16,168 +16,168 @@  discard block
 block discarded – undo
16 16
  */
17 17
 class Events_Admin_List_Table extends EE_Admin_List_Table
18 18
 {
19
-    private ?EE_Datetime $_dtt = null;
20
-
21
-
22
-    /**
23
-     * Initial setup of data properties for the list table.
24
-     *
25
-     * @throws Exception
26
-     */
27
-    protected function _setup_data()
28
-    {
29
-        $this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
30
-        $this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
31
-    }
32
-
33
-
34
-    /**
35
-     * Set up of additional properties for the list table.
36
-     *
37
-     * @throws EE_Error
38
-     * @throws ReflectionException
39
-     */
40
-    protected function _set_properties()
41
-    {
42
-        $this->_wp_list_args    = [
43
-            'singular' => esc_html__('event', 'event_espresso'),
44
-            'plural'   => esc_html__('events', 'event_espresso'),
45
-            'ajax'     => true, // for now
46
-            'screen'   => $this->_admin_page->get_current_screen()->id,
47
-        ];
48
-        $approved_registrations = esc_html__('Approved Registrations', 'event_espresso');
49
-        $this->_columns         = [
50
-            'cb'              => '<input type="checkbox" />',
51
-            'id'              => esc_html__('ID', 'event_espresso'),
52
-            'name'            => esc_html__('Name', 'event_espresso'),
53
-            'author'          => esc_html__('Author', 'event_espresso'),
54
-            'venue'           => esc_html__('Venue', 'event_espresso'),
55
-            'start_date_time' => esc_html__('Event Start', 'event_espresso'),
56
-            'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
57
-            'attendees'       => '
19
+	private ?EE_Datetime $_dtt = null;
20
+
21
+
22
+	/**
23
+	 * Initial setup of data properties for the list table.
24
+	 *
25
+	 * @throws Exception
26
+	 */
27
+	protected function _setup_data()
28
+	{
29
+		$this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
30
+		$this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Set up of additional properties for the list table.
36
+	 *
37
+	 * @throws EE_Error
38
+	 * @throws ReflectionException
39
+	 */
40
+	protected function _set_properties()
41
+	{
42
+		$this->_wp_list_args    = [
43
+			'singular' => esc_html__('event', 'event_espresso'),
44
+			'plural'   => esc_html__('events', 'event_espresso'),
45
+			'ajax'     => true, // for now
46
+			'screen'   => $this->_admin_page->get_current_screen()->id,
47
+		];
48
+		$approved_registrations = esc_html__('Approved Registrations', 'event_espresso');
49
+		$this->_columns         = [
50
+			'cb'              => '<input type="checkbox" />',
51
+			'id'              => esc_html__('ID', 'event_espresso'),
52
+			'name'            => esc_html__('Name', 'event_espresso'),
53
+			'author'          => esc_html__('Author', 'event_espresso'),
54
+			'venue'           => esc_html__('Venue', 'event_espresso'),
55
+			'start_date_time' => esc_html__('Event Start', 'event_espresso'),
56
+			'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
57
+			'attendees'       => '
58 58
                 <span class="dashicons dashicons-groups ee-status-color--RAP ee-aria-tooltip"
59 59
                     aria-label="' . $approved_registrations . '"></span>
60 60
                 <span class="screen-reader-text">' . $approved_registrations . '</span>',
61
-            'actions'         => $this->actionsColumnHeader(),
62
-        ];
63
-        $this->addConditionalColumns();
64
-        $this->_sortable_columns = [
65
-            'id'              => ['EVT_ID' => true],
66
-            'name'            => ['EVT_name' => false],
67
-            'author'          => ['EVT_wp_user' => false],
68
-            'venue'           => ['Venue.VNU_name' => false],
69
-            'start_date_time' => ['Datetime.DTT_EVT_start' => false],
70
-            'reg_begins'      => ['Datetime.Ticket.TKT_start_date' => false],
71
-        ];
72
-
73
-        $this->_primary_column = 'id';
74
-        $this->_hidden_columns = ['author', 'event_category'];
75
-    }
76
-
77
-
78
-    /**
79
-     * @return array
80
-     */
81
-    protected function _get_table_filters()
82
-    {
83
-        return []; // no filters with decaf
84
-    }
85
-
86
-
87
-    /**
88
-     * Setup of views properties.
89
-     *
90
-     * @throws InvalidDataTypeException
91
-     * @throws InvalidInterfaceException
92
-     * @throws InvalidArgumentException
93
-     * @throws EE_Error
94
-     * @throws ReflectionException
95
-     */
96
-    protected function _add_view_counts()
97
-    {
98
-        $this->_views['all']['count']   = $this->_admin_page->total_events();
99
-        $this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
100
-        if (
101
-            EE_Registry::instance()->CAP->current_user_can(
102
-                'ee_delete_events',
103
-                'espresso_events_trash_events'
104
-            )
105
-        ) {
106
-            $this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
107
-        }
108
-    }
109
-
110
-
111
-    /**
112
-     * @param EE_Event $item
113
-     * @return string
114
-     */
115
-    protected function _get_row_class($item): string
116
-    {
117
-        $class = parent::_get_row_class($item);
118
-        if ($this->_has_checkbox_column) {
119
-            $class .= ' has-checkbox-column';
120
-        }
121
-        return $class;
122
-    }
123
-
124
-
125
-    /**
126
-     * @param EE_Event $item
127
-     * @return string
128
-     * @throws EE_Error
129
-     * @throws ReflectionException
130
-     */
131
-    public function column_cb($item): string
132
-    {
133
-        if (! $item instanceof EE_Event) {
134
-            return '';
135
-        }
136
-        $this->_dtt = $item->primary_datetime(); // set this for use in other columns
137
-        $content    = sprintf(
138
-            '<input type="checkbox" name="EVT_IDs[]" value="%s" />',
139
-            $item->ID()
140
-        );
141
-        return $this->columnContent('cb', $content, 'center');
142
-    }
143
-
144
-
145
-    /**
146
-     * @param EE_Event $event
147
-     * @return string
148
-     * @throws EE_Error
149
-     * @throws ReflectionException
150
-     */
151
-    public function column_id(EE_Event $event): string
152
-    {
153
-        $content = '<span class="ee-entity-id">' . $event->ID() . '</span>';
154
-        $content .= '<span class="show-on-mobile-view-only">';
155
-        $content .= $this->column_name($event, false);
156
-        $content .= '</span>';
157
-        return $this->columnContent('id', $content, 'end');
158
-    }
159
-
160
-
161
-    /**
162
-     * @param EE_Event $event
163
-     * @param bool     $prep_content
164
-     * @return string
165
-     * @throws EE_Error
166
-     * @throws ReflectionException
167
-     */
168
-    public function column_name(EE_Event $event, bool $prep_content = true): string
169
-    {
170
-        $edit_query_args = [
171
-            'action' => 'edit',
172
-            'post'   => $event->ID(),
173
-        ];
174
-        $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
175
-        $actions         = $this->_column_name_action_setup($event);
176
-        $status          = esc_attr($event->get_active_status());
177
-        $pretty_status   = EEH_Template::pretty_status($status, false, 'sentence');
178
-        $status_dot      = '<span class="ee-status-dot ee-status-bg--' . $status . '"></span>';
179
-        $visibility      = $event->get_visibility_status();
180
-        $content         = '
61
+			'actions'         => $this->actionsColumnHeader(),
62
+		];
63
+		$this->addConditionalColumns();
64
+		$this->_sortable_columns = [
65
+			'id'              => ['EVT_ID' => true],
66
+			'name'            => ['EVT_name' => false],
67
+			'author'          => ['EVT_wp_user' => false],
68
+			'venue'           => ['Venue.VNU_name' => false],
69
+			'start_date_time' => ['Datetime.DTT_EVT_start' => false],
70
+			'reg_begins'      => ['Datetime.Ticket.TKT_start_date' => false],
71
+		];
72
+
73
+		$this->_primary_column = 'id';
74
+		$this->_hidden_columns = ['author', 'event_category'];
75
+	}
76
+
77
+
78
+	/**
79
+	 * @return array
80
+	 */
81
+	protected function _get_table_filters()
82
+	{
83
+		return []; // no filters with decaf
84
+	}
85
+
86
+
87
+	/**
88
+	 * Setup of views properties.
89
+	 *
90
+	 * @throws InvalidDataTypeException
91
+	 * @throws InvalidInterfaceException
92
+	 * @throws InvalidArgumentException
93
+	 * @throws EE_Error
94
+	 * @throws ReflectionException
95
+	 */
96
+	protected function _add_view_counts()
97
+	{
98
+		$this->_views['all']['count']   = $this->_admin_page->total_events();
99
+		$this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
100
+		if (
101
+			EE_Registry::instance()->CAP->current_user_can(
102
+				'ee_delete_events',
103
+				'espresso_events_trash_events'
104
+			)
105
+		) {
106
+			$this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
107
+		}
108
+	}
109
+
110
+
111
+	/**
112
+	 * @param EE_Event $item
113
+	 * @return string
114
+	 */
115
+	protected function _get_row_class($item): string
116
+	{
117
+		$class = parent::_get_row_class($item);
118
+		if ($this->_has_checkbox_column) {
119
+			$class .= ' has-checkbox-column';
120
+		}
121
+		return $class;
122
+	}
123
+
124
+
125
+	/**
126
+	 * @param EE_Event $item
127
+	 * @return string
128
+	 * @throws EE_Error
129
+	 * @throws ReflectionException
130
+	 */
131
+	public function column_cb($item): string
132
+	{
133
+		if (! $item instanceof EE_Event) {
134
+			return '';
135
+		}
136
+		$this->_dtt = $item->primary_datetime(); // set this for use in other columns
137
+		$content    = sprintf(
138
+			'<input type="checkbox" name="EVT_IDs[]" value="%s" />',
139
+			$item->ID()
140
+		);
141
+		return $this->columnContent('cb', $content, 'center');
142
+	}
143
+
144
+
145
+	/**
146
+	 * @param EE_Event $event
147
+	 * @return string
148
+	 * @throws EE_Error
149
+	 * @throws ReflectionException
150
+	 */
151
+	public function column_id(EE_Event $event): string
152
+	{
153
+		$content = '<span class="ee-entity-id">' . $event->ID() . '</span>';
154
+		$content .= '<span class="show-on-mobile-view-only">';
155
+		$content .= $this->column_name($event, false);
156
+		$content .= '</span>';
157
+		return $this->columnContent('id', $content, 'end');
158
+	}
159
+
160
+
161
+	/**
162
+	 * @param EE_Event $event
163
+	 * @param bool     $prep_content
164
+	 * @return string
165
+	 * @throws EE_Error
166
+	 * @throws ReflectionException
167
+	 */
168
+	public function column_name(EE_Event $event, bool $prep_content = true): string
169
+	{
170
+		$edit_query_args = [
171
+			'action' => 'edit',
172
+			'post'   => $event->ID(),
173
+		];
174
+		$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
175
+		$actions         = $this->_column_name_action_setup($event);
176
+		$status          = esc_attr($event->get_active_status());
177
+		$pretty_status   = EEH_Template::pretty_status($status, false, 'sentence');
178
+		$status_dot      = '<span class="ee-status-dot ee-status-bg--' . $status . '"></span>';
179
+		$visibility      = $event->get_visibility_status();
180
+		$content         = '
181 181
             <div class="ee-layout-row ee-layout-row--fixed">
182 182
                 <a  class="row-title ee-status-color--' . $status . ' ee-aria-tooltip"
183 183
                     aria-label="' . $pretty_status . '"
@@ -186,416 +186,416 @@  discard block
 block discarded – undo
186 186
                     ' . $status_dot . $event->name() . '
187 187
                 </a>
188 188
                 ' . (
189
-                    $visibility
190
-                    ? '<span class="ee-event-visibility-status ee-status-text-small">(' . esc_html($visibility) . ')</span>'
191
-                    : ''
192
-                ) . '
189
+					$visibility
190
+					? '<span class="ee-event-visibility-status ee-status-text-small">(' . esc_html($visibility) . ')</span>'
191
+					: ''
192
+				) . '
193 193
             </div>';
194 194
 
195
-        $content .= $this->row_actions($actions);
196
-
197
-        return $prep_content ? $this->columnContent('name', $content) : $content;
198
-    }
199
-
200
-
201
-    /**
202
-     * Just a method for setting up the actions for the name column
203
-     *
204
-     * @param EE_Event $event
205
-     * @return array array of actions
206
-     * @throws EE_Error
207
-     * @throws InvalidArgumentException
208
-     * @throws InvalidDataTypeException
209
-     * @throws InvalidInterfaceException
210
-     * @throws ReflectionException
211
-     */
212
-    protected function _column_name_action_setup(EE_Event $event): array
213
-    {
214
-        // todo: remove when attendees is active
215
-        if (! defined('REG_ADMIN_URL')) {
216
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
217
-        }
218
-        $actions            = [];
219
-        $restore_event_link = '';
220
-        $delete_event_link  = '';
221
-        $trash_event_link   = '';
222
-        if (
223
-            EE_Registry::instance()->CAP->current_user_can(
224
-                'ee_edit_event',
225
-                'espresso_events_edit',
226
-                $event->ID()
227
-            )
228
-        ) {
229
-            $edit_query_args = [
230
-                'action' => 'edit',
231
-                'post'   => $event->ID(),
232
-            ];
233
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
234
-            $actions['edit'] = '<a href="' . $edit_link . '" class="ee-aria-tooltip" '
235
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
236
-                               . esc_html__('Edit', 'event_espresso')
237
-                               . '</a>';
238
-        }
239
-        if (
240
-            EE_Registry::instance()->CAP->current_user_can(
241
-                'ee_read_registrations',
242
-                'espresso_registrations_view_registration'
243
-            )
244
-            && EE_Registry::instance()->CAP->current_user_can(
245
-                'ee_read_event',
246
-                'espresso_registrations_view_registration',
247
-                $event->ID()
248
-            )
249
-        ) {
250
-            $attendees_query_args = [
251
-                'action'   => 'default',
252
-                'event_id' => $event->ID(),
253
-            ];
254
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
255
-            $actions['attendees'] = '<a href="' . $attendees_link . '" class="ee-aria-tooltip"'
256
-                                    . ' aria-label="' . esc_attr__('View Registrations', 'event_espresso') . '">'
257
-                                    . esc_html__('Registrations', 'event_espresso')
258
-                                    . '</a>';
259
-        }
260
-        if (
261
-            EE_Registry::instance()->CAP->current_user_can(
262
-                'ee_delete_event',
263
-                'espresso_events_trash_event',
264
-                $event->ID()
265
-            )
266
-        ) {
267
-            $trash_event_query_args = [
268
-                'action' => 'trash_event',
269
-                'EVT_ID' => $event->ID(),
270
-            ];
271
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
272
-                $trash_event_query_args,
273
-                EVENTS_ADMIN_URL
274
-            );
275
-        }
276
-        if (
277
-            EE_Registry::instance()->CAP->current_user_can(
278
-                'ee_delete_event',
279
-                'espresso_events_restore_event',
280
-                $event->ID()
281
-            )
282
-        ) {
283
-            $restore_event_query_args = [
284
-                'action' => 'restore_event',
285
-                'EVT_ID' => $event->ID(),
286
-            ];
287
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
288
-                $restore_event_query_args,
289
-                EVENTS_ADMIN_URL
290
-            );
291
-        }
292
-        if (
293
-            EE_Registry::instance()->CAP->current_user_can(
294
-                'ee_delete_event',
295
-                'espresso_events_delete_event',
296
-                $event->ID()
297
-            )
298
-        ) {
299
-            $delete_event_query_args = [
300
-                'action' => 'delete_event',
301
-                'EVT_ID' => $event->ID(),
302
-            ];
303
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
304
-                $delete_event_query_args,
305
-                EVENTS_ADMIN_URL
306
-            );
307
-        }
308
-        $view_link       = get_permalink($event->ID());
309
-        $actions['view'] = '<a href="' . $view_link . '" class="ee-aria-tooltip"'
310
-                           . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '">'
311
-                           . esc_html__('View', 'event_espresso')
312
-                           . '</a>';
313
-        if ($event->get('status') === 'trash') {
314
-            if (
315
-                EE_Registry::instance()->CAP->current_user_can(
316
-                    'ee_delete_event',
317
-                    'espresso_events_restore_event',
318
-                    $event->ID()
319
-                )
320
-            ) {
321
-                $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" class="ee-aria-tooltip"'
322
-                                                 . ' aria-label="' . esc_attr__('Restore from Trash', 'event_espresso')
323
-                                                 . '">'
324
-                                                 . esc_html__('Restore from Trash', 'event_espresso')
325
-                                                 . '</a>';
326
-            }
327
-            if (
328
-                EE_Registry::instance()->CAP->current_user_can(
329
-                    'ee_delete_event',
330
-                    'espresso_events_delete_event',
331
-                    $event->ID()
332
-                )
333
-            ) {
334
-                $actions['delete'] = '<a href="' . $delete_event_link . '" class="ee-aria-tooltip"'
335
-                                     . ' aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
336
-                                     . esc_html__('Delete Permanently', 'event_espresso')
337
-                                     . '</a>';
338
-            }
339
-        } else {
340
-            if (
341
-                EE_Registry::instance()->CAP->current_user_can(
342
-                    'ee_delete_event',
343
-                    'espresso_events_trash_event',
344
-                    $event->ID()
345
-                )
346
-            ) {
347
-                $actions['move to trash'] = '<a href="' . $trash_event_link . '" class="ee-aria-tooltip"'
348
-                                            . ' aria-label="' . esc_attr__('Trash Event', 'event_espresso') . '">'
349
-                                            . esc_html__('Trash', 'event_espresso')
350
-                                            . '</a>';
351
-            }
352
-        }
353
-        return $actions;
354
-    }
355
-
356
-
357
-    /**
358
-     * @param EE_Event $event
359
-     * @return string
360
-     * @throws EE_Error
361
-     * @throws ReflectionException
362
-     */
363
-    public function column_author(EE_Event $event): string
364
-    {
365
-        // user author info
366
-        $event_author = get_userdata($event->wp_user());
367
-        $gravatar     = get_avatar($event->wp_user(), '24');
368
-        // filter link
369
-        $query_args = [
370
-            'action'      => 'default',
371
-            'EVT_wp_user' => $event->wp_user(),
372
-        ];
373
-        $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
374
-        $content    = '<div class="ee-layout-row ee-layout-row--fixed">';
375
-        $content    .= '  <a href="' . $filter_url . '" class="ee-event-author ee-aria-tooltip"'
376
-                       . ' aria-label="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
377
-                       . $gravatar . $event_author->display_name
378
-                       . '</a>';
379
-        $content    .= '</div>';
380
-        return $this->columnContent('author', $content);
381
-    }
382
-
383
-
384
-    /**
385
-     * @param EE_Event $event
386
-     * @return string
387
-     * @throws EE_Error
388
-     * @throws ReflectionException
389
-     */
390
-    public function column_event_category(EE_Event $event): string
391
-    {
392
-        $event_categories = $event->get_all_event_categories();
393
-        $content          = implode(
394
-            ', ',
395
-            array_map(
396
-                function (EE_Term $category) {
397
-                    return $category->name();
398
-                },
399
-                $event_categories
400
-            )
401
-        );
402
-        return $this->columnContent('event_category', $content);
403
-    }
404
-
405
-
406
-    /**
407
-     * @param EE_Event $event
408
-     * @return string
409
-     * @throws EE_Error
410
-     * @throws ReflectionException
411
-     */
412
-    public function column_venue(EE_Event $event): string
413
-    {
414
-        $venue   = $event->get_first_related('Venue');
415
-        $content = ! empty($venue)
416
-            ? $venue->name()
417
-            : '';
418
-        return $this->columnContent('venue', $content);
419
-    }
420
-
421
-
422
-    /**
423
-     * @param EE_Event $event
424
-     * @return string
425
-     * @throws EE_Error
426
-     * @throws ReflectionException
427
-     */
428
-    public function column_start_date_time(EE_Event $event): string
429
-    {
430
-        $content = $this->_dtt instanceof EE_Datetime
431
-            ? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
432
-            : esc_html__('No Date was saved for this Event', 'event_espresso');
433
-        return $this->columnContent('start_date_time', $content);
434
-    }
435
-
436
-
437
-    /**
438
-     * @param EE_Event $event
439
-     * @return string
440
-     * @throws EE_Error
441
-     * @throws ReflectionException
442
-     */
443
-    public function column_reg_begins(EE_Event $event): string
444
-    {
445
-        $reg_start = $event->get_ticket_with_earliest_start_time();
446
-        $content   = $reg_start instanceof EE_Ticket
447
-            ? $reg_start->get_i18n_datetime('TKT_start_date')
448
-            : esc_html__('No Tickets have been setup for this Event', 'event_espresso');
449
-        return $this->columnContent('reg_begins', $content);
450
-    }
451
-
452
-
453
-    /**
454
-     * @param EE_Event $event
455
-     * @return string
456
-     * @throws EE_Error
457
-     * @throws InvalidArgumentException
458
-     * @throws InvalidDataTypeException
459
-     * @throws InvalidInterfaceException
460
-     * @throws ReflectionException
461
-     */
462
-    public function column_attendees(EE_Event $event): string
463
-    {
464
-        $attendees_query_args = [
465
-            'action'   => 'default',
466
-            'event_id' => $event->ID(),
467
-            '_reg_status' => RegStatus::APPROVED,
468
-        ];
469
-        $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
470
-        $registered_attendees = EEM_Registration::instance()->get_event_registration_count($event->ID());
471
-
472
-        $content              = EE_Registry::instance()->CAP->current_user_can(
473
-            'ee_read_event',
474
-            'espresso_registrations_view_registration',
475
-            $event->ID()
476
-        ) && EE_Registry::instance()->CAP->current_user_can(
477
-            'ee_read_registrations',
478
-            'espresso_registrations_view_registration'
479
-        )
480
-            ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
481
-            : $registered_attendees;
482
-        return $this->columnContent('attendees', $content, 'center');
483
-    }
484
-
485
-
486
-    /**
487
-     * @param EE_Event $event
488
-     * @return float
489
-     * @throws EE_Error
490
-     * @throws InvalidArgumentException
491
-     * @throws InvalidDataTypeException
492
-     * @throws InvalidInterfaceException
493
-     * @throws ReflectionException
494
-     */
495
-    public function column_tkts_sold(EE_Event $event): float
496
-    {
497
-        $content = EEM_Ticket::instance()->sum([['Datetime.EVT_ID' => $event->ID()]], 'TKT_sold');
498
-        return $this->columnContent('tkts_sold', $content);
499
-    }
500
-
501
-
502
-    /**
503
-     * @param EE_Event $event
504
-     * @return string
505
-     * @throws EE_Error
506
-     * @throws InvalidArgumentException
507
-     * @throws InvalidDataTypeException
508
-     * @throws InvalidInterfaceException
509
-     * @throws ReflectionException
510
-     */
511
-    public function column_actions(EE_Event $event): string
512
-    {
513
-        // todo: remove when attendees is active
514
-        if (! defined('REG_ADMIN_URL')) {
515
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
516
-        }
517
-        $action_links   = [];
518
-        $view_link      = get_permalink($event->ID());
519
-        $action_links[] = '<a href="' . $view_link . '" class="ee-aria-tooltip button button--icon-only"'
520
-                          . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">
195
+		$content .= $this->row_actions($actions);
196
+
197
+		return $prep_content ? $this->columnContent('name', $content) : $content;
198
+	}
199
+
200
+
201
+	/**
202
+	 * Just a method for setting up the actions for the name column
203
+	 *
204
+	 * @param EE_Event $event
205
+	 * @return array array of actions
206
+	 * @throws EE_Error
207
+	 * @throws InvalidArgumentException
208
+	 * @throws InvalidDataTypeException
209
+	 * @throws InvalidInterfaceException
210
+	 * @throws ReflectionException
211
+	 */
212
+	protected function _column_name_action_setup(EE_Event $event): array
213
+	{
214
+		// todo: remove when attendees is active
215
+		if (! defined('REG_ADMIN_URL')) {
216
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
217
+		}
218
+		$actions            = [];
219
+		$restore_event_link = '';
220
+		$delete_event_link  = '';
221
+		$trash_event_link   = '';
222
+		if (
223
+			EE_Registry::instance()->CAP->current_user_can(
224
+				'ee_edit_event',
225
+				'espresso_events_edit',
226
+				$event->ID()
227
+			)
228
+		) {
229
+			$edit_query_args = [
230
+				'action' => 'edit',
231
+				'post'   => $event->ID(),
232
+			];
233
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
234
+			$actions['edit'] = '<a href="' . $edit_link . '" class="ee-aria-tooltip" '
235
+							   . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
236
+							   . esc_html__('Edit', 'event_espresso')
237
+							   . '</a>';
238
+		}
239
+		if (
240
+			EE_Registry::instance()->CAP->current_user_can(
241
+				'ee_read_registrations',
242
+				'espresso_registrations_view_registration'
243
+			)
244
+			&& EE_Registry::instance()->CAP->current_user_can(
245
+				'ee_read_event',
246
+				'espresso_registrations_view_registration',
247
+				$event->ID()
248
+			)
249
+		) {
250
+			$attendees_query_args = [
251
+				'action'   => 'default',
252
+				'event_id' => $event->ID(),
253
+			];
254
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
255
+			$actions['attendees'] = '<a href="' . $attendees_link . '" class="ee-aria-tooltip"'
256
+									. ' aria-label="' . esc_attr__('View Registrations', 'event_espresso') . '">'
257
+									. esc_html__('Registrations', 'event_espresso')
258
+									. '</a>';
259
+		}
260
+		if (
261
+			EE_Registry::instance()->CAP->current_user_can(
262
+				'ee_delete_event',
263
+				'espresso_events_trash_event',
264
+				$event->ID()
265
+			)
266
+		) {
267
+			$trash_event_query_args = [
268
+				'action' => 'trash_event',
269
+				'EVT_ID' => $event->ID(),
270
+			];
271
+			$trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
272
+				$trash_event_query_args,
273
+				EVENTS_ADMIN_URL
274
+			);
275
+		}
276
+		if (
277
+			EE_Registry::instance()->CAP->current_user_can(
278
+				'ee_delete_event',
279
+				'espresso_events_restore_event',
280
+				$event->ID()
281
+			)
282
+		) {
283
+			$restore_event_query_args = [
284
+				'action' => 'restore_event',
285
+				'EVT_ID' => $event->ID(),
286
+			];
287
+			$restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
288
+				$restore_event_query_args,
289
+				EVENTS_ADMIN_URL
290
+			);
291
+		}
292
+		if (
293
+			EE_Registry::instance()->CAP->current_user_can(
294
+				'ee_delete_event',
295
+				'espresso_events_delete_event',
296
+				$event->ID()
297
+			)
298
+		) {
299
+			$delete_event_query_args = [
300
+				'action' => 'delete_event',
301
+				'EVT_ID' => $event->ID(),
302
+			];
303
+			$delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
304
+				$delete_event_query_args,
305
+				EVENTS_ADMIN_URL
306
+			);
307
+		}
308
+		$view_link       = get_permalink($event->ID());
309
+		$actions['view'] = '<a href="' . $view_link . '" class="ee-aria-tooltip"'
310
+						   . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '">'
311
+						   . esc_html__('View', 'event_espresso')
312
+						   . '</a>';
313
+		if ($event->get('status') === 'trash') {
314
+			if (
315
+				EE_Registry::instance()->CAP->current_user_can(
316
+					'ee_delete_event',
317
+					'espresso_events_restore_event',
318
+					$event->ID()
319
+				)
320
+			) {
321
+				$actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" class="ee-aria-tooltip"'
322
+												 . ' aria-label="' . esc_attr__('Restore from Trash', 'event_espresso')
323
+												 . '">'
324
+												 . esc_html__('Restore from Trash', 'event_espresso')
325
+												 . '</a>';
326
+			}
327
+			if (
328
+				EE_Registry::instance()->CAP->current_user_can(
329
+					'ee_delete_event',
330
+					'espresso_events_delete_event',
331
+					$event->ID()
332
+				)
333
+			) {
334
+				$actions['delete'] = '<a href="' . $delete_event_link . '" class="ee-aria-tooltip"'
335
+									 . ' aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
336
+									 . esc_html__('Delete Permanently', 'event_espresso')
337
+									 . '</a>';
338
+			}
339
+		} else {
340
+			if (
341
+				EE_Registry::instance()->CAP->current_user_can(
342
+					'ee_delete_event',
343
+					'espresso_events_trash_event',
344
+					$event->ID()
345
+				)
346
+			) {
347
+				$actions['move to trash'] = '<a href="' . $trash_event_link . '" class="ee-aria-tooltip"'
348
+											. ' aria-label="' . esc_attr__('Trash Event', 'event_espresso') . '">'
349
+											. esc_html__('Trash', 'event_espresso')
350
+											. '</a>';
351
+			}
352
+		}
353
+		return $actions;
354
+	}
355
+
356
+
357
+	/**
358
+	 * @param EE_Event $event
359
+	 * @return string
360
+	 * @throws EE_Error
361
+	 * @throws ReflectionException
362
+	 */
363
+	public function column_author(EE_Event $event): string
364
+	{
365
+		// user author info
366
+		$event_author = get_userdata($event->wp_user());
367
+		$gravatar     = get_avatar($event->wp_user(), '24');
368
+		// filter link
369
+		$query_args = [
370
+			'action'      => 'default',
371
+			'EVT_wp_user' => $event->wp_user(),
372
+		];
373
+		$filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
374
+		$content    = '<div class="ee-layout-row ee-layout-row--fixed">';
375
+		$content    .= '  <a href="' . $filter_url . '" class="ee-event-author ee-aria-tooltip"'
376
+					   . ' aria-label="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
377
+					   . $gravatar . $event_author->display_name
378
+					   . '</a>';
379
+		$content    .= '</div>';
380
+		return $this->columnContent('author', $content);
381
+	}
382
+
383
+
384
+	/**
385
+	 * @param EE_Event $event
386
+	 * @return string
387
+	 * @throws EE_Error
388
+	 * @throws ReflectionException
389
+	 */
390
+	public function column_event_category(EE_Event $event): string
391
+	{
392
+		$event_categories = $event->get_all_event_categories();
393
+		$content          = implode(
394
+			', ',
395
+			array_map(
396
+				function (EE_Term $category) {
397
+					return $category->name();
398
+				},
399
+				$event_categories
400
+			)
401
+		);
402
+		return $this->columnContent('event_category', $content);
403
+	}
404
+
405
+
406
+	/**
407
+	 * @param EE_Event $event
408
+	 * @return string
409
+	 * @throws EE_Error
410
+	 * @throws ReflectionException
411
+	 */
412
+	public function column_venue(EE_Event $event): string
413
+	{
414
+		$venue   = $event->get_first_related('Venue');
415
+		$content = ! empty($venue)
416
+			? $venue->name()
417
+			: '';
418
+		return $this->columnContent('venue', $content);
419
+	}
420
+
421
+
422
+	/**
423
+	 * @param EE_Event $event
424
+	 * @return string
425
+	 * @throws EE_Error
426
+	 * @throws ReflectionException
427
+	 */
428
+	public function column_start_date_time(EE_Event $event): string
429
+	{
430
+		$content = $this->_dtt instanceof EE_Datetime
431
+			? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
432
+			: esc_html__('No Date was saved for this Event', 'event_espresso');
433
+		return $this->columnContent('start_date_time', $content);
434
+	}
435
+
436
+
437
+	/**
438
+	 * @param EE_Event $event
439
+	 * @return string
440
+	 * @throws EE_Error
441
+	 * @throws ReflectionException
442
+	 */
443
+	public function column_reg_begins(EE_Event $event): string
444
+	{
445
+		$reg_start = $event->get_ticket_with_earliest_start_time();
446
+		$content   = $reg_start instanceof EE_Ticket
447
+			? $reg_start->get_i18n_datetime('TKT_start_date')
448
+			: esc_html__('No Tickets have been setup for this Event', 'event_espresso');
449
+		return $this->columnContent('reg_begins', $content);
450
+	}
451
+
452
+
453
+	/**
454
+	 * @param EE_Event $event
455
+	 * @return string
456
+	 * @throws EE_Error
457
+	 * @throws InvalidArgumentException
458
+	 * @throws InvalidDataTypeException
459
+	 * @throws InvalidInterfaceException
460
+	 * @throws ReflectionException
461
+	 */
462
+	public function column_attendees(EE_Event $event): string
463
+	{
464
+		$attendees_query_args = [
465
+			'action'   => 'default',
466
+			'event_id' => $event->ID(),
467
+			'_reg_status' => RegStatus::APPROVED,
468
+		];
469
+		$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
470
+		$registered_attendees = EEM_Registration::instance()->get_event_registration_count($event->ID());
471
+
472
+		$content              = EE_Registry::instance()->CAP->current_user_can(
473
+			'ee_read_event',
474
+			'espresso_registrations_view_registration',
475
+			$event->ID()
476
+		) && EE_Registry::instance()->CAP->current_user_can(
477
+			'ee_read_registrations',
478
+			'espresso_registrations_view_registration'
479
+		)
480
+			? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
481
+			: $registered_attendees;
482
+		return $this->columnContent('attendees', $content, 'center');
483
+	}
484
+
485
+
486
+	/**
487
+	 * @param EE_Event $event
488
+	 * @return float
489
+	 * @throws EE_Error
490
+	 * @throws InvalidArgumentException
491
+	 * @throws InvalidDataTypeException
492
+	 * @throws InvalidInterfaceException
493
+	 * @throws ReflectionException
494
+	 */
495
+	public function column_tkts_sold(EE_Event $event): float
496
+	{
497
+		$content = EEM_Ticket::instance()->sum([['Datetime.EVT_ID' => $event->ID()]], 'TKT_sold');
498
+		return $this->columnContent('tkts_sold', $content);
499
+	}
500
+
501
+
502
+	/**
503
+	 * @param EE_Event $event
504
+	 * @return string
505
+	 * @throws EE_Error
506
+	 * @throws InvalidArgumentException
507
+	 * @throws InvalidDataTypeException
508
+	 * @throws InvalidInterfaceException
509
+	 * @throws ReflectionException
510
+	 */
511
+	public function column_actions(EE_Event $event): string
512
+	{
513
+		// todo: remove when attendees is active
514
+		if (! defined('REG_ADMIN_URL')) {
515
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
516
+		}
517
+		$action_links   = [];
518
+		$view_link      = get_permalink($event->ID());
519
+		$action_links[] = '<a href="' . $view_link . '" class="ee-aria-tooltip button button--icon-only"'
520
+						  . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">
521 521
                           <span class="dashicons dashicons-visibility"></span></a>';
522
-        if (
523
-            EE_Registry::instance()->CAP->current_user_can(
524
-                'ee_edit_event',
525
-                'espresso_events_edit',
526
-                $event->ID()
527
-            )
528
-        ) {
529
-            $edit_query_args = [
530
-                'action' => 'edit',
531
-                'post'   => $event->ID(),
532
-            ];
533
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
534
-            $action_links[]  = '<a href="' . $edit_link . '" class="ee-aria-tooltip button button--icon-only"'
535
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
536
-                               . '<span class="dashicons dashicons-calendar-alt"></span>'
537
-                               . '</a>';
538
-        }
539
-        if (
540
-            EE_Registry::instance()->CAP->current_user_can(
541
-                'ee_read_registrations',
542
-                'espresso_registrations_view_registration'
543
-            )
544
-            && EE_Registry::instance()->CAP->current_user_can(
545
-                'ee_read_event',
546
-                'espresso_registrations_view_registration',
547
-                $event->ID()
548
-            )
549
-        ) {
550
-            $attendees_query_args = [
551
-                'action'   => 'default',
552
-                'event_id' => $event->ID(),
553
-            ];
554
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
555
-            $action_links[]       = '<a href="' . $attendees_link . '" class="ee-aria-tooltip button button--icon-only"'
556
-                                    . ' aria-label="' . esc_attr__('View Registrants', 'event_espresso') . '">'
557
-                                    . '<span class="dashicons dashicons-groups"></span>'
558
-                                    . '</a>';
559
-        }
560
-        $action_links = apply_filters(
561
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
562
-            $action_links,
563
-            $event
564
-        );
565
-        $content      = $this->_action_string(
566
-            implode("\n\t", $action_links),
567
-            $event,
568
-            'div',
569
-            'event-overview-actions ee-list-table-actions'
570
-        );
571
-        return $this->columnContent('actions', $this->actionsModalMenu($content));
572
-    }
573
-
574
-
575
-    /**
576
-     * Helper for adding columns conditionally
577
-     *
578
-     * @throws EE_Error
579
-     * @throws InvalidArgumentException
580
-     * @throws InvalidDataTypeException
581
-     * @throws InvalidInterfaceException
582
-     * @throws ReflectionException
583
-     */
584
-    private function addConditionalColumns()
585
-    {
586
-        $event_category_count = EEM_Term::instance()->count(
587
-            [['Term_Taxonomy.taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY]]
588
-        );
589
-        if ($event_category_count === 0) {
590
-            return;
591
-        }
592
-        $column_array = [];
593
-        foreach ($this->_columns as $column => $column_label) {
594
-            $column_array[ $column ] = $column_label;
595
-            if ($column === 'venue') {
596
-                $column_array['event_category'] = esc_html__('Event Category', 'event_espresso');
597
-            }
598
-        }
599
-        $this->_columns = $column_array;
600
-    }
522
+		if (
523
+			EE_Registry::instance()->CAP->current_user_can(
524
+				'ee_edit_event',
525
+				'espresso_events_edit',
526
+				$event->ID()
527
+			)
528
+		) {
529
+			$edit_query_args = [
530
+				'action' => 'edit',
531
+				'post'   => $event->ID(),
532
+			];
533
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
534
+			$action_links[]  = '<a href="' . $edit_link . '" class="ee-aria-tooltip button button--icon-only"'
535
+							   . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
536
+							   . '<span class="dashicons dashicons-calendar-alt"></span>'
537
+							   . '</a>';
538
+		}
539
+		if (
540
+			EE_Registry::instance()->CAP->current_user_can(
541
+				'ee_read_registrations',
542
+				'espresso_registrations_view_registration'
543
+			)
544
+			&& EE_Registry::instance()->CAP->current_user_can(
545
+				'ee_read_event',
546
+				'espresso_registrations_view_registration',
547
+				$event->ID()
548
+			)
549
+		) {
550
+			$attendees_query_args = [
551
+				'action'   => 'default',
552
+				'event_id' => $event->ID(),
553
+			];
554
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
555
+			$action_links[]       = '<a href="' . $attendees_link . '" class="ee-aria-tooltip button button--icon-only"'
556
+									. ' aria-label="' . esc_attr__('View Registrants', 'event_espresso') . '">'
557
+									. '<span class="dashicons dashicons-groups"></span>'
558
+									. '</a>';
559
+		}
560
+		$action_links = apply_filters(
561
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
562
+			$action_links,
563
+			$event
564
+		);
565
+		$content      = $this->_action_string(
566
+			implode("\n\t", $action_links),
567
+			$event,
568
+			'div',
569
+			'event-overview-actions ee-list-table-actions'
570
+		);
571
+		return $this->columnContent('actions', $this->actionsModalMenu($content));
572
+	}
573
+
574
+
575
+	/**
576
+	 * Helper for adding columns conditionally
577
+	 *
578
+	 * @throws EE_Error
579
+	 * @throws InvalidArgumentException
580
+	 * @throws InvalidDataTypeException
581
+	 * @throws InvalidInterfaceException
582
+	 * @throws ReflectionException
583
+	 */
584
+	private function addConditionalColumns()
585
+	{
586
+		$event_category_count = EEM_Term::instance()->count(
587
+			[['Term_Taxonomy.taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY]]
588
+		);
589
+		if ($event_category_count === 0) {
590
+			return;
591
+		}
592
+		$column_array = [];
593
+		foreach ($this->_columns as $column => $column_label) {
594
+			$column_array[ $column ] = $column_label;
595
+			if ($column === 'venue') {
596
+				$column_array['event_category'] = esc_html__('Event Category', 'event_espresso');
597
+			}
598
+		}
599
+		$this->_columns = $column_array;
600
+	}
601 601
 }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2949 added lines, -2949 removed lines patch added patch discarded remove patch
@@ -20,2956 +20,2956 @@
 block discarded – undo
20 20
  */
21 21
 class Events_Admin_Page extends EE_Admin_Page_CPT
22 22
 {
23
-    /**
24
-     * primary key for the event model
25
-     */
26
-    private int $EVT_ID = 0;
27
-
28
-    /**
29
-     * This will hold the event object for event_details screen.
30
-     *
31
-     * @var EE_Event|null $_event
32
-     */
33
-    protected ?EE_Event $_event = null;
34
-
35
-    /**
36
-     * This will hold the category object for category_details screen.
37
-     */
38
-    protected ?stdClass $_category = null;
39
-
40
-    protected ?EEM_Event $_event_model = null;
41
-
42
-    /**
43
-     * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
44
-     */
45
-    protected $_cpt_model_obj;
46
-
47
-    protected ?NodeGroupDao $model_obj_node_group_persister = null;
48
-
49
-    protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
50
-
51
-
52
-    /**
53
-     * Initialize page props for this admin page group.
54
-     */
55
-    protected function _init_page_props()
56
-    {
57
-        // is there a evt_id in the request?
58
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
59
-        $this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
60
-        $this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
61
-
62
-        $this->page_slug        = EVENTS_PG_SLUG;
63
-        $this->page_label       = EVENTS_LABEL;
64
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
65
-        $this->_admin_base_path = EVENTS_ADMIN;
66
-        $this->_cpt_model_names = [
67
-            'create_new' => 'EEM_Event',
68
-            'edit'       => 'EEM_Event',
69
-        ];
70
-        $this->_cpt_edit_routes = [
71
-            'espresso_events' => 'edit',
72
-        ];
73
-        add_action(
74
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
75
-            [$this, 'verify_event_edit'],
76
-            10,
77
-            2
78
-        );
79
-    }
80
-
81
-
82
-    /**
83
-     * Sets the ajax hooks used for this admin page group.
84
-     */
85
-    protected function _ajax_hooks()
86
-    {
87
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
88
-    }
89
-
90
-
91
-    /**
92
-     * Sets the page properties for this admin page group.
93
-     */
94
-    protected function _define_page_props()
95
-    {
96
-        $this->_admin_page_title = EVENTS_LABEL;
97
-        $this->_labels           = [
98
-            'buttons'      => [
99
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
100
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
101
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
102
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
103
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
104
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
105
-            ],
106
-            'editor_title' => [
107
-                'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
108
-            ],
109
-            'publishbox'   => [
110
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
111
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
112
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
113
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
114
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
115
-            ],
116
-        ];
117
-    }
118
-
119
-
120
-    /**
121
-     * Sets the page routes property for this admin page group.
122
-     */
123
-    protected function _set_page_routes()
124
-    {
125
-        $this->_page_routes = [
126
-            'default'                       => [
127
-                'func'       => [$this, '_events_overview_list_table'],
128
-                'capability' => 'ee_read_events',
129
-            ],
130
-            'create_new'                    => [
131
-                'func'       => [$this, '_create_new_cpt_item'],
132
-                'capability' => 'ee_edit_events',
133
-            ],
134
-            'edit'                          => [
135
-                'func'       => [$this, '_edit_cpt_item'],
136
-                'capability' => 'ee_edit_event',
137
-                'obj_id'     => $this->EVT_ID,
138
-            ],
139
-            'copy_event'                    => [
140
-                'func'       => [$this, '_copy_events'],
141
-                'capability' => 'ee_edit_event',
142
-                'obj_id'     => $this->EVT_ID,
143
-                'noheader'   => true,
144
-            ],
145
-            'trash_event'                   => [
146
-                'func'       => [$this, '_trash_or_restore_event'],
147
-                'args'       => ['event_status' => 'trash'],
148
-                'capability' => 'ee_delete_event',
149
-                'obj_id'     => $this->EVT_ID,
150
-                'noheader'   => true,
151
-            ],
152
-            'trash_events'                  => [
153
-                'func'       => [$this, '_trash_or_restore_events'],
154
-                'args'       => ['event_status' => 'trash'],
155
-                'capability' => 'ee_delete_events',
156
-                'noheader'   => true,
157
-            ],
158
-            'restore_event'                 => [
159
-                'func'       => [$this, '_trash_or_restore_event'],
160
-                'args'       => ['event_status' => 'draft'],
161
-                'capability' => 'ee_delete_event',
162
-                'obj_id'     => $this->EVT_ID,
163
-                'noheader'   => true,
164
-            ],
165
-            'restore_events'                => [
166
-                'func'       => [$this, '_trash_or_restore_events'],
167
-                'args'       => ['event_status' => 'draft'],
168
-                'capability' => 'ee_delete_events',
169
-                'noheader'   => true,
170
-            ],
171
-            'delete_event'                  => [
172
-                'func'       => [$this, '_delete_event'],
173
-                'capability' => 'ee_delete_event',
174
-                'obj_id'     => $this->EVT_ID,
175
-                'noheader'   => true,
176
-            ],
177
-            'delete_events'                 => [
178
-                'func'       => [$this, '_delete_events'],
179
-                'capability' => 'ee_delete_events',
180
-                'noheader'   => true,
181
-            ],
182
-            'view_report'                   => [
183
-                'func'       => [$this, '_view_report'],
184
-                'capability' => 'ee_edit_events',
185
-            ],
186
-            'default_event_settings'        => [
187
-                'func'       => [$this, '_default_event_settings'],
188
-                'capability' => 'manage_options',
189
-            ],
190
-            'update_default_event_settings' => [
191
-                'func'       => [$this, '_update_default_event_settings'],
192
-                'capability' => 'manage_options',
193
-                'noheader'   => true,
194
-            ],
195
-            'template_settings'             => [
196
-                'func'       => [$this, '_template_settings'],
197
-                'capability' => 'manage_options',
198
-            ],
199
-            // event category tab related
200
-            'add_category'                  => [
201
-                'func'       => [$this, '_category_details'],
202
-                'capability' => 'ee_edit_event_category',
203
-                'args'       => ['view' => 'add'],
204
-            ],
205
-            'edit_category'                 => [
206
-                'func'       => [$this, '_category_details'],
207
-                'capability' => 'ee_edit_event_category',
208
-                'args'       => ['view' => 'edit'],
209
-            ],
210
-            'delete_categories'             => [
211
-                'func'       => [$this, '_delete_categories'],
212
-                'capability' => 'ee_delete_event_category',
213
-                'noheader'   => true,
214
-            ],
215
-            'delete_category'               => [
216
-                'func'       => [$this, '_delete_categories'],
217
-                'capability' => 'ee_delete_event_category',
218
-                'noheader'   => true,
219
-            ],
220
-            'insert_category'               => [
221
-                'func'       => [$this, '_insert_or_update_category'],
222
-                'args'       => ['new_category' => true],
223
-                'capability' => 'ee_edit_event_category',
224
-                'noheader'   => true,
225
-            ],
226
-            'update_category'               => [
227
-                'func'       => [$this, '_insert_or_update_category'],
228
-                'args'       => ['new_category' => false],
229
-                'capability' => 'ee_edit_event_category',
230
-                'noheader'   => true,
231
-            ],
232
-            'category_list'                 => [
233
-                'func'       => [$this, '_category_list_table'],
234
-                'capability' => 'ee_manage_event_categories',
235
-            ],
236
-            'preview_deletion'              => [
237
-                'func'       => [$this, 'previewDeletion'],
238
-                'capability' => 'ee_delete_events',
239
-            ],
240
-            'confirm_deletion'              => [
241
-                'func'       => [$this, 'confirmDeletion'],
242
-                'capability' => 'ee_delete_events',
243
-                'noheader'   => true,
244
-            ],
245
-        ];
246
-    }
247
-
248
-
249
-    /**
250
-     * Set the _page_config property for this admin page group.
251
-     */
252
-    protected function _set_page_config()
253
-    {
254
-        $post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
255
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
256
-        $this->_page_config = [
257
-            'default'                => [
258
-                'nav'           => [
259
-                    'label' => esc_html__('Overview', 'event_espresso'),
260
-                    'icon'  => 'dashicons-list-view',
261
-                    'order' => 10,
262
-                ],
263
-                'list_table'    => 'Events_Admin_List_Table',
264
-                'help_tabs'     => [
265
-                    'events_overview_help_tab'                       => [
266
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
267
-                        'filename' => 'events_overview',
268
-                    ],
269
-                    'events_overview_table_column_headings_help_tab' => [
270
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
271
-                        'filename' => 'events_overview_table_column_headings',
272
-                    ],
273
-                    'events_overview_filters_help_tab'               => [
274
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
275
-                        'filename' => 'events_overview_filters',
276
-                    ],
277
-                    'events_overview_view_help_tab'                  => [
278
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
279
-                        'filename' => 'events_overview_views',
280
-                    ],
281
-                    'events_overview_other_help_tab'                 => [
282
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
283
-                        'filename' => 'events_overview_other',
284
-                    ],
285
-                ],
286
-                'require_nonce' => false,
287
-            ],
288
-            'create_new'             => [
289
-                'nav'           => [
290
-                    'label'      => esc_html__('Add New Event', 'event_espresso'),
291
-                    'icon'       => 'dashicons-plus-alt',
292
-                    'order'      => 15,
293
-                    'persistent' => false,
294
-                ],
295
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
296
-                'help_tabs'     => [
297
-                    'event_editor_help_tab'                            => [
298
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
299
-                        'filename' => 'event_editor',
300
-                    ],
301
-                    'event_editor_title_richtexteditor_help_tab'       => [
302
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
303
-                        'filename' => 'event_editor_title_richtexteditor',
304
-                    ],
305
-                    'event_editor_venue_details_help_tab'              => [
306
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
307
-                        'filename' => 'event_editor_venue_details',
308
-                    ],
309
-                    'event_editor_event_datetimes_help_tab'            => [
310
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
311
-                        'filename' => 'event_editor_event_datetimes',
312
-                    ],
313
-                    'event_editor_event_tickets_help_tab'              => [
314
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
315
-                        'filename' => 'event_editor_event_tickets',
316
-                    ],
317
-                    'event_editor_event_registration_options_help_tab' => [
318
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
319
-                        'filename' => 'event_editor_event_registration_options',
320
-                    ],
321
-                    'event_editor_tags_categories_help_tab'            => [
322
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
323
-                        'filename' => 'event_editor_tags_categories',
324
-                    ],
325
-                    'event_editor_questions_registrants_help_tab'      => [
326
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
327
-                        'filename' => 'event_editor_questions_registrants',
328
-                    ],
329
-                    'event_editor_save_new_event_help_tab'             => [
330
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
331
-                        'filename' => 'event_editor_save_new_event',
332
-                    ],
333
-                    'event_editor_other_help_tab'                      => [
334
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
335
-                        'filename' => 'event_editor_other',
336
-                    ],
337
-                ],
338
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
339
-                'require_nonce' => false,
340
-            ],
341
-            'edit'                   => [
342
-                'nav'           => [
343
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
344
-                    'icon'       => 'dashicons-edit',
345
-                    'order'      => 15,
346
-                    'persistent' => false,
347
-                    'url'        => $post_id
348
-                        ? EE_Admin_Page::add_query_args_and_nonce(
349
-                            ['post' => $post_id, 'action' => 'edit'],
350
-                            $this->_current_page_view_url
351
-                        )
352
-                        : $this->_admin_base_url,
353
-                ],
354
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
355
-                'help_tabs'     => [
356
-                    'event_editor_help_tab'                            => [
357
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
358
-                        'filename' => 'event_editor',
359
-                    ],
360
-                    'event_editor_title_richtexteditor_help_tab'       => [
361
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
362
-                        'filename' => 'event_editor_title_richtexteditor',
363
-                    ],
364
-                    'event_editor_venue_details_help_tab'              => [
365
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
366
-                        'filename' => 'event_editor_venue_details',
367
-                    ],
368
-                    'event_editor_event_datetimes_help_tab'            => [
369
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
370
-                        'filename' => 'event_editor_event_datetimes',
371
-                    ],
372
-                    'event_editor_event_tickets_help_tab'              => [
373
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
374
-                        'filename' => 'event_editor_event_tickets',
375
-                    ],
376
-                    'event_editor_event_registration_options_help_tab' => [
377
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
378
-                        'filename' => 'event_editor_event_registration_options',
379
-                    ],
380
-                    'event_editor_tags_categories_help_tab'            => [
381
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
382
-                        'filename' => 'event_editor_tags_categories',
383
-                    ],
384
-                    'event_editor_questions_registrants_help_tab'      => [
385
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
386
-                        'filename' => 'event_editor_questions_registrants',
387
-                    ],
388
-                    'event_editor_save_new_event_help_tab'             => [
389
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
390
-                        'filename' => 'event_editor_save_new_event',
391
-                    ],
392
-                    'event_editor_other_help_tab'                      => [
393
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
394
-                        'filename' => 'event_editor_other',
395
-                    ],
396
-                ],
397
-                'require_nonce' => false,
398
-            ],
399
-            'default_event_settings' => [
400
-                'nav'           => [
401
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
402
-                    'icon'  => 'dashicons-admin-generic',
403
-                    'order' => 40,
404
-                ],
405
-                'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
406
-                'labels'        => [
407
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
408
-                ],
409
-                'help_tabs'     => [
410
-                    'default_settings_help_tab'        => [
411
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
412
-                        'filename' => 'events_default_settings',
413
-                    ],
414
-                    'default_settings_status_help_tab' => [
415
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
416
-                        'filename' => 'events_default_settings_status',
417
-                    ],
418
-                    'default_maximum_tickets_help_tab' => [
419
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
420
-                        'filename' => 'events_default_settings_max_tickets',
421
-                    ],
422
-                ],
423
-                'require_nonce' => false,
424
-            ],
425
-            // template settings
426
-            'template_settings'      => [
427
-                'nav'           => [
428
-                    'label' => esc_html__('Templates', 'event_espresso'),
429
-                    'icon'  => 'dashicons-layout',
430
-                    'order' => 30,
431
-                ],
432
-                'metaboxes'     => $this->_default_espresso_metaboxes,
433
-                'help_tabs'     => [
434
-                    'general_settings_templates_help_tab' => [
435
-                        'title'    => esc_html__('Templates', 'event_espresso'),
436
-                        'filename' => 'general_settings_templates',
437
-                    ],
438
-                ],
439
-                'require_nonce' => false,
440
-            ],
441
-            // event category stuff
442
-            'add_category'           => [
443
-                'nav'           => [
444
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
445
-                    'icon'       => 'dashicons-plus-alt',
446
-                    'order'      => 25,
447
-                    'persistent' => false,
448
-                ],
449
-                'help_tabs'     => [
450
-                    'add_category_help_tab' => [
451
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
452
-                        'filename' => 'events_add_category',
453
-                    ],
454
-                ],
455
-                'metaboxes'     => ['_publish_post_box'],
456
-                'require_nonce' => false,
457
-            ],
458
-            'edit_category'          => [
459
-                'nav'           => [
460
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
461
-                    'icon'       => 'dashicons-edit',
462
-                    'order'      => 25,
463
-                    'persistent' => false,
464
-                    'url'        => $EVT_CAT_ID
465
-                        ? add_query_arg(
466
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
467
-                            $this->_current_page_view_url
468
-                        )
469
-                        : $this->_admin_base_url,
470
-                ],
471
-                'help_tabs'     => [
472
-                    'edit_category_help_tab' => [
473
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
474
-                        'filename' => 'events_edit_category',
475
-                    ],
476
-                ],
477
-                'metaboxes'     => ['_publish_post_box'],
478
-                'require_nonce' => false,
479
-            ],
480
-            'category_list'          => [
481
-                'nav'           => [
482
-                    'label' => esc_html__('Categories', 'event_espresso'),
483
-                    'icon'  => 'dashicons-networking',
484
-                    'order' => 20,
485
-                ],
486
-                'list_table'    => 'Event_Categories_Admin_List_Table',
487
-                'help_tabs'     => [
488
-                    'events_categories_help_tab'                       => [
489
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
490
-                        'filename' => 'events_categories',
491
-                    ],
492
-                    'events_categories_table_column_headings_help_tab' => [
493
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
494
-                        'filename' => 'events_categories_table_column_headings',
495
-                    ],
496
-                    'events_categories_view_help_tab'                  => [
497
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
498
-                        'filename' => 'events_categories_views',
499
-                    ],
500
-                    'events_categories_other_help_tab'                 => [
501
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
502
-                        'filename' => 'events_categories_other',
503
-                    ],
504
-                ],
505
-                'metaboxes'     => $this->_default_espresso_metaboxes,
506
-                'require_nonce' => false,
507
-            ],
508
-            'preview_deletion'       => [
509
-                'nav'           => [
510
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
511
-                    'icon'       => 'dashicons-remove',
512
-                    'order'      => 15,
513
-                    'persistent' => false,
514
-                    'url'        => '',
515
-                ],
516
-                'require_nonce' => false,
517
-            ],
518
-        ];
519
-    }
520
-
521
-
522
-    /**
523
-     * Used to register any global screen options if necessary for every route in this admin page group.
524
-     */
525
-    protected function _add_screen_options()
526
-    {
527
-    }
528
-
529
-
530
-    /**
531
-     * Implementing the screen options for the 'default' route.
532
-     *
533
-     * @throws InvalidArgumentException
534
-     * @throws InvalidDataTypeException
535
-     * @throws InvalidInterfaceException
536
-     */
537
-    protected function _add_screen_options_default()
538
-    {
539
-        $this->_per_page_screen_option();
540
-    }
541
-
542
-
543
-    /**
544
-     * Implementing screen options for the category list route.
545
-     *
546
-     * @throws InvalidArgumentException
547
-     * @throws InvalidDataTypeException
548
-     * @throws InvalidInterfaceException
549
-     */
550
-    protected function _add_screen_options_category_list()
551
-    {
552
-        $page_title              = $this->_admin_page_title;
553
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
554
-        $this->_per_page_screen_option();
555
-        $this->_admin_page_title = $page_title;
556
-    }
557
-
558
-
559
-    /**
560
-     * Used to register any global feature pointers for the admin page group.
561
-     */
562
-    protected function _add_feature_pointers()
563
-    {
564
-    }
565
-
566
-
567
-    /**
568
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
569
-     */
570
-    public function load_scripts_styles()
571
-    {
572
-        wp_register_style(
573
-            'events-admin-css',
574
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
575
-            [],
576
-            EVENT_ESPRESSO_VERSION
577
-        );
578
-        wp_register_style(
579
-            'ee-cat-admin',
580
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
581
-            [],
582
-            EVENT_ESPRESSO_VERSION
583
-        );
584
-        wp_enqueue_style('events-admin-css');
585
-        wp_enqueue_style('ee-cat-admin');
586
-        // scripts
587
-        wp_register_script(
588
-            'event_editor_js',
589
-            EVENTS_ASSETS_URL . 'event_editor.js',
590
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
591
-            EVENT_ESPRESSO_VERSION,
592
-            true
593
-        );
594
-    }
595
-
596
-
597
-    /**
598
-     * Enqueuing scripts and styles specific to this view
599
-     */
600
-    public function load_scripts_styles_create_new()
601
-    {
602
-        $this->load_scripts_styles_edit();
603
-    }
604
-
605
-
606
-    /**
607
-     * Enqueuing scripts and styles specific to this view
608
-     */
609
-    public function load_scripts_styles_edit()
610
-    {
611
-        // styles
612
-        wp_enqueue_style('espresso-ui-theme');
613
-        wp_register_style(
614
-            'event-editor-css',
615
-            EVENTS_ASSETS_URL . 'event-editor.css',
616
-            ['ee-admin-css'],
617
-            EVENT_ESPRESSO_VERSION
618
-        );
619
-        wp_enqueue_style('event-editor-css');
620
-        // scripts
621
-        if (! $this->admin_config->useAdvancedEditor()) {
622
-            wp_register_script(
623
-                'event-datetime-metabox',
624
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
625
-                ['event_editor_js', 'ee-datepicker'],
626
-                EVENT_ESPRESSO_VERSION
627
-            );
628
-            wp_enqueue_script('event-datetime-metabox');
629
-        }
630
-    }
631
-
632
-
633
-    /**
634
-     * Populating the _views property for the category list table view.
635
-     */
636
-    protected function _set_list_table_views_category_list()
637
-    {
638
-        $this->_views = [
639
-            'all' => [
640
-                'slug'        => 'all',
641
-                'label'       => esc_html__('All', 'event_espresso'),
642
-                'count'       => 0,
643
-                'bulk_action' => [
644
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
645
-                ],
646
-            ],
647
-        ];
648
-    }
649
-
650
-
651
-    /**
652
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
653
-     */
654
-    public function admin_init()
655
-    {
656
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
657
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
658
-            'event_espresso'
659
-        );
660
-    }
661
-
662
-
663
-    /**
664
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
665
-     * group.
666
-     */
667
-    public function admin_notices()
668
-    {
669
-    }
670
-
671
-
672
-    /**
673
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
674
-     * this admin page group.
675
-     */
676
-    public function admin_footer_scripts()
677
-    {
678
-    }
679
-
680
-
681
-    /**
682
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
683
-     * warning (via EE_Error::add_error());
684
-     *
685
-     * @param EE_Event|null $event Event object
686
-     * @param string        $req_type
687
-     * @return void
688
-     * @throws EE_Error
689
-     * @throws ReflectionException
690
-     */
691
-    public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
692
-    {
693
-        // don't need to do this when processing
694
-        if (! empty($req_type)) {
695
-            return;
696
-        }
697
-        // no event?
698
-        if (! $event instanceof EE_Event) {
699
-            $event = $this->_cpt_model_obj;
700
-        }
701
-        // STILL no event?
702
-        if (! $event instanceof EE_Event) {
703
-            return;
704
-        }
705
-        // don't need to keep calling this
706
-        remove_action(
707
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
708
-            [$this, 'verify_event_edit']
709
-        );
710
-        $orig_status = $event->status();
711
-        // first check if event is active.
712
-        if (
713
-            $orig_status === EEM_Event::cancelled
714
-            || $orig_status === EEM_Event::postponed
715
-            || $event->is_expired()
716
-            || $event->is_inactive()
717
-        ) {
718
-            return;
719
-        }
720
-        // made it here so it IS active... next check that any of the tickets are sold.
721
-        if ($event->is_sold_out(true)) {
722
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
723
-                EE_Error::add_attention(
724
-                    sprintf(
725
-                        esc_html__(
726
-                            '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.',
727
-                            'event_espresso'
728
-                        ),
729
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
730
-                    )
731
-                );
732
-            }
733
-            return;
734
-        }
735
-        if ($orig_status === EEM_Event::sold_out) {
736
-            EE_Error::add_attention(
737
-                sprintf(
738
-                    esc_html__(
739
-                        '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.',
740
-                        'event_espresso'
741
-                    ),
742
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
743
-                )
744
-            );
745
-        }
746
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
747
-        if (! $event->tickets_on_sale()) {
748
-            return;
749
-        }
750
-        // made it here so show warning
751
-        $this->_edit_event_warning();
752
-    }
753
-
754
-
755
-    /**
756
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
757
-     * When needed, hook this into a EE_Error::add_error() notice.
758
-     *
759
-     * @access protected
760
-     * @return void
761
-     */
762
-    protected function _edit_event_warning()
763
-    {
764
-        // we don't want to add warnings during these requests
765
-        if ($this->request->getRequestParam('action') === 'editpost') {
766
-            return;
767
-        }
768
-        EE_Error::add_attention(
769
-            sprintf(
770
-                esc_html__(
771
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
772
-                    'event_espresso'
773
-                ),
774
-                '<a class="espresso-help-tab-lnk ee-help-tab-link">',
775
-                '</a>'
776
-            )
777
-        );
778
-    }
779
-
780
-
781
-    /**
782
-     * When a user is creating a new event, notify them if they haven't set their timezone.
783
-     * Otherwise, do the normal logic
784
-     *
785
-     * @return void
786
-     * @throws EE_Error
787
-     * @throws InvalidArgumentException
788
-     * @throws InvalidDataTypeException
789
-     * @throws InvalidInterfaceException
790
-     * @throws ReflectionException
791
-     */
792
-    protected function _create_new_cpt_item()
793
-    {
794
-        $has_timezone_string = get_option('timezone_string');
795
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
796
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
797
-            EE_Error::add_attention(
798
-                sprintf(
799
-                    esc_html__(
800
-                        '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',
801
-                        'event_espresso'
802
-                    ),
803
-                    '<br>',
804
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
805
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
806
-                    . '</select>',
807
-                    '<button class="button button--secondary timezone-submit">',
808
-                    '</button><span class="spinner"></span>'
809
-                ),
810
-                __FILE__,
811
-                __FUNCTION__,
812
-                __LINE__
813
-            );
814
-        }
815
-        parent::_create_new_cpt_item();
816
-    }
817
-
818
-
819
-    /**
820
-     * Sets the _views property for the default route in this admin page group.
821
-     */
822
-    protected function _set_list_table_views_default()
823
-    {
824
-        $this->_views = [
825
-            'all'   => [
826
-                'slug'        => 'all',
827
-                'label'       => esc_html__('View All Events', 'event_espresso'),
828
-                'count'       => 0,
829
-                'bulk_action' => [
830
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
831
-                ],
832
-            ],
833
-            'draft' => [
834
-                'slug'        => 'draft',
835
-                'label'       => esc_html__('Draft', 'event_espresso'),
836
-                'count'       => 0,
837
-                'bulk_action' => [
838
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
839
-                ],
840
-            ],
841
-        ];
842
-        if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
843
-            $this->_views['trash'] = [
844
-                'slug'        => 'trash',
845
-                'label'       => esc_html__('Trash', 'event_espresso'),
846
-                'count'       => 0,
847
-                'bulk_action' => [
848
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
849
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
850
-                ],
851
-            ];
852
-        }
853
-    }
854
-
855
-
856
-    /**
857
-     * Provides the legend item array for the default list table view.
858
-     *
859
-     * @return array
860
-     * @throws EE_Error
861
-     * @throws EE_Error
862
-     */
863
-    protected function _event_legend_items(): array
864
-    {
865
-        $items    = [
866
-            'view_details'   => [
867
-                'class' => 'dashicons dashicons-visibility',
868
-                'desc'  => esc_html__('View Event', 'event_espresso'),
869
-            ],
870
-            'edit_event'     => [
871
-                'class' => 'dashicons dashicons-calendar-alt',
872
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
873
-            ],
874
-            'view_attendees' => [
875
-                'class' => 'dashicons dashicons-groups',
876
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
877
-            ],
878
-        ];
879
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
880
-        $statuses = [
881
-            'sold_out_status'  => [
882
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
883
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
884
-            ],
885
-            'active_status'    => [
886
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
887
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
888
-            ],
889
-            'upcoming_status'  => [
890
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
891
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
892
-            ],
893
-            'postponed_status' => [
894
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
895
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
896
-            ],
897
-            'cancelled_status' => [
898
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
899
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
900
-            ],
901
-            'expired_status'   => [
902
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
903
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
904
-            ],
905
-            'inactive_status'  => [
906
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
907
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
908
-            ],
909
-        ];
910
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
911
-        return array_merge($items, $statuses);
912
-    }
913
-
914
-
915
-    /**
916
-     * @return EEM_Event
917
-     * @throws EE_Error
918
-     * @throws InvalidArgumentException
919
-     * @throws InvalidDataTypeException
920
-     * @throws InvalidInterfaceException
921
-     * @throws ReflectionException
922
-     */
923
-    private function _event_model(): EEM_Event
924
-    {
925
-        if (! $this->_event_model instanceof EEM_Event) {
926
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
927
-        }
928
-        return $this->_event_model;
929
-    }
930
-
931
-
932
-    /**
933
-     * Adds extra buttons to the WP CPT permalink field row.
934
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
935
-     *
936
-     * @param string      $return    the current html
937
-     * @param int         $id        the post id for the page
938
-     * @param string|null $new_title What the title is
939
-     * @param string|null $new_slug  what the slug is
940
-     * @return string            The new html string for the permalink area
941
-     * @deprecated 5.0.0.p
942
-     * @see        TicketSelectorShortcodeButton::addButton
943
-     */
944
-    public function extra_permalink_field_buttons(
945
-        string $return,
946
-        int $id,
947
-        ?string $new_title,
948
-        ?string $new_slug
949
-    ): string {
950
-        return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
951
-    }
952
-
953
-
954
-    /**
955
-     * _events_overview_list_table
956
-     * This contains the logic for showing the events_overview list
957
-     *
958
-     * @access protected
959
-     * @return void
960
-     * @throws DomainException
961
-     * @throws EE_Error
962
-     * @throws InvalidArgumentException
963
-     * @throws InvalidDataTypeException
964
-     * @throws InvalidInterfaceException
965
-     */
966
-    protected function _events_overview_list_table()
967
-    {
968
-        $after_list_table = [];
969
-        $links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
970
-        $links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
971
-        $links_html       .= EEH_HTML::div(
972
-            EEH_Template::get_button_or_link(
973
-                get_post_type_archive_link(EspressoPostType::EVENTS),
974
-                esc_html__('View Event Archive Page', 'event_espresso'),
975
-                'button button--small button--secondary'
976
-            ),
977
-            '',
978
-            'ee-admin-button-row ee-admin-button-row--align-start'
979
-        );
980
-        $links_html       .= EEH_HTML::divx();
981
-
982
-        $after_list_table['view_event_list_button'] = $links_html;
983
-
984
-        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
985
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
986
-                'create_new',
987
-                'add',
988
-                [],
989
-                'add-new-h2'
990
-            );
991
-
992
-        $this->_template_args['after_list_table'] = array_merge(
993
-            (array) $this->_template_args['after_list_table'],
994
-            $after_list_table
995
-        );
996
-        $this->display_admin_list_table_page_with_no_sidebar();
997
-    }
998
-
999
-
1000
-    /**
1001
-     * this allows for extra misc actions in the default WP publish box
1002
-     *
1003
-     * @return void
1004
-     * @throws DomainException
1005
-     * @throws EE_Error
1006
-     * @throws InvalidArgumentException
1007
-     * @throws InvalidDataTypeException
1008
-     * @throws InvalidInterfaceException
1009
-     * @throws ReflectionException
1010
-     */
1011
-    public function extra_misc_actions_publish_box()
1012
-    {
1013
-        $this->_generate_publish_box_extra_content();
1014
-    }
1015
-
1016
-
1017
-    /**
1018
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1019
-     * saved.
1020
-     * Typically you would use this to save any additional data.
1021
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1022
-     * ALSO very important.  When a post transitions from scheduled to published,
1023
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1024
-     * other meta saves. So MAKE sure that you handle this accordingly.
1025
-     *
1026
-     * @access protected
1027
-     * @abstract
1028
-     * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1029
-     * @param WP_Post $post    The post object of the cpt that was saved.
1030
-     * @return void
1031
-     * @throws EE_Error
1032
-     * @throws InvalidArgumentException
1033
-     * @throws InvalidDataTypeException
1034
-     * @throws InvalidInterfaceException
1035
-     * @throws ReflectionException
1036
-     */
1037
-    protected function _insert_update_cpt_item($post_id, $post)
1038
-    {
1039
-        if ($post instanceof WP_Post && $post->post_type !== EspressoPostType::EVENTS) {
1040
-            // get out we're not processing an event save.
1041
-            return;
1042
-        }
1043
-        $event_values = [
1044
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1045
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1046
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1047
-        ];
1048
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1049
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1050
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1051
-                'display_ticket_selector',
1052
-                false,
1053
-                'bool'
1054
-            );
1055
-            $event_values['EVT_additional_limit']            = min(
1056
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1057
-                $this->request->getRequestParam(
1058
-                    'additional_limit',
1059
-                    EEM_Event::get_default_additional_limit(),
1060
-                    'int'
1061
-                )
1062
-            );
1063
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1064
-                'EVT_default_registration_status',
1065
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1066
-            );
1067
-
1068
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1069
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1070
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1071
-        } elseif ($post instanceof WP_Post) {
1072
-            $event_values['EVT_name'] = $post->post_title;
1073
-            $event_values['EVT_desc'] = $post->post_content;
1074
-        }
1075
-        // update event
1076
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1077
-        // get event_object for other metaboxes...
1078
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1079
-        // i have to set up where conditions to override the filters in the model
1080
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1081
-        /** @var EE_Event $event */
1082
-        $event = $this->_event_model()->get_one(
1083
-            [
1084
-                [
1085
-                    $this->_event_model()->primary_key_name() => $post_id,
1086
-                    'OR'                                      => [
1087
-                        'status'   => $post->post_status,
1088
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1089
-                        // but the returned object here has a status of "publish", so use the original post status as well
1090
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1091
-                    ],
1092
-                    'status' => ['NOT IN', ['auto-draft']],
1093
-                ],
1094
-            ]
1095
-        );
1096
-
1097
-        if (! $event instanceof EE_Event) {
1098
-            return;
1099
-        }
1100
-
1101
-        // the following are default callbacks for event attachment updates
1102
-        // that can be overridden by caffeinated functionality and/or addons.
1103
-        $event_update_callbacks = [];
1104
-        if (! $this->admin_config->useAdvancedEditor()) {
1105
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1106
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1107
-        }
1108
-        $event_update_callbacks = apply_filters(
1109
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1110
-            $event_update_callbacks
1111
-        );
1112
-
1113
-        $att_success = true;
1114
-        foreach ($event_update_callbacks as $e_callback) {
1115
-            $_success = is_callable($e_callback)
1116
-                ? $e_callback($event, $this->request->requestParams())
1117
-                : false;
1118
-            // if ANY of these updates fail then we want the appropriate global error message
1119
-            $att_success = $_success !== false ? $att_success : false;
1120
-        }
1121
-        // any errors?
1122
-        if ($success && $att_success === false) {
1123
-            EE_Error::add_error(
1124
-                esc_html__(
1125
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1126
-                    'event_espresso'
1127
-                ),
1128
-                __FILE__,
1129
-                __FUNCTION__,
1130
-                __LINE__
1131
-            );
1132
-        } elseif ($success === false) {
1133
-            EE_Error::add_error(
1134
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1135
-                __FILE__,
1136
-                __FUNCTION__,
1137
-                __LINE__
1138
-            );
1139
-        }
1140
-    }
1141
-
1142
-
1143
-    /**
1144
-     * @param int $post_id
1145
-     * @param int $revision_id
1146
-     * @throws EE_Error
1147
-     * @throws EE_Error
1148
-     * @throws ReflectionException
1149
-     * @see parent::restore_item()
1150
-     */
1151
-    protected function _restore_cpt_item(int $post_id, int $revision_id)
1152
-    {
1153
-        // copy existing event meta to new post
1154
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1155
-        if ($post_evt instanceof EE_Event) {
1156
-            // meta revision restore
1157
-            $post_evt->restore_revision($revision_id);
1158
-            // related objs restore
1159
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1160
-        }
1161
-    }
1162
-
1163
-
1164
-    /**
1165
-     * Attach the venue to the Event
1166
-     *
1167
-     * @param EE_Event $event Event Object to add the venue to
1168
-     * @param array    $data  The request data from the form
1169
-     * @return bool           Success or fail.
1170
-     * @throws EE_Error
1171
-     * @throws ReflectionException
1172
-     */
1173
-    protected function _default_venue_update(EE_Event $event, array $data): bool
1174
-    {
1175
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1176
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1177
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1178
-        // very important.  If we don't have a venue name...
1179
-        // then we'll get out because not necessary to create empty venue
1180
-        if (empty($data['venue_title'])) {
1181
-            return false;
1182
-        }
1183
-        $venue_array = [
1184
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1185
-            'VNU_name'            => $data['venue_title'],
1186
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1187
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1188
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1189
-                ? $data['venue_short_description']
1190
-                : null,
1191
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1192
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1193
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1194
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1195
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1196
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1197
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1198
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1199
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1200
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1201
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1202
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1203
-            'status'              => 'publish',
1204
-        ];
1205
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1206
-        if (! empty($venue_id)) {
1207
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1208
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1209
-            // we've gotta make sure that the venue is always attached to a revision..
1210
-            // add_relation_to should take care of making sure that the relation is already present.
1211
-            $event->_add_relation_to($venue_id, 'Venue');
1212
-            return $rows_affected > 0;
1213
-        }
1214
-        // we insert the venue
1215
-        $venue_id = $venue_model->insert($venue_array);
1216
-        $event->_add_relation_to($venue_id, 'Venue');
1217
-        return ! empty($venue_id);
1218
-        // when we have the ancestor come in it's already been handled by the revision save.
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1224
-     *
1225
-     * @param EE_Event $event The Event object we're attaching data to
1226
-     * @param array    $data  The request data from the form
1227
-     * @return array
1228
-     * @throws EE_Error
1229
-     * @throws ReflectionException
1230
-     * @throws Exception
1231
-     */
1232
-    protected function _default_tickets_update(EE_Event $event, array $data): array
1233
-    {
1234
-        if ($this->admin_config->useAdvancedEditor()) {
1235
-            return [];
1236
-        }
1237
-        $datetime       = null;
1238
-        $saved_tickets  = [];
1239
-        $event_timezone = $event->get_timezone();
1240
-        $date_formats   = ['Y-m-d', 'h:i a'];
1241
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1242
-            // trim all values to ensure any excess whitespace is removed.
1243
-            $datetime_data                = array_map('trim', $datetime_data);
1244
-            $datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1245
-                    ? $datetime_data['DTT_EVT_end']
1246
-                    : $datetime_data['DTT_EVT_start'];
1247
-            $datetime_values              = [
1248
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1249
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1250
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1251
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1252
-                'DTT_order'     => $row,
1253
-            ];
1254
-            // if we have an id then let's get existing object first and then set the new values.
1255
-            //  Otherwise we instantiate a new object for save.
1256
-            if (! empty($datetime_data['DTT_ID'])) {
1257
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1258
-                if (! $datetime instanceof EE_Datetime) {
1259
-                    throw new RuntimeException(
1260
-                        sprintf(
1261
-                            esc_html__(
1262
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1263
-                                'event_espresso'
1264
-                            ),
1265
-                            $datetime_data['DTT_ID']
1266
-                        )
1267
-                    );
1268
-                }
1269
-                $datetime->set_date_format($date_formats[0]);
1270
-                $datetime->set_time_format($date_formats[1]);
1271
-                foreach ($datetime_values as $field => $value) {
1272
-                    $datetime->set($field, $value);
1273
-                }
1274
-            } else {
1275
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1276
-            }
1277
-            if (! $datetime instanceof EE_Datetime) {
1278
-                throw new RuntimeException(
1279
-                    sprintf(
1280
-                        esc_html__(
1281
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1282
-                            'event_espresso'
1283
-                        ),
1284
-                        print_r($datetime_values, true)
1285
-                    )
1286
-                );
1287
-            }
1288
-            // before going any further make sure our dates are setup correctly
1289
-            // so that the end date is always equal or greater than the start date.
1290
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1291
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1292
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1293
-            }
1294
-            $datetime->save();
1295
-            $event->_add_relation_to($datetime, 'Datetime');
1296
-        }
1297
-        // no datetimes get deleted so we don't do any of that logic here.
1298
-        // update tickets next
1299
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1300
-
1301
-        // set up some default start and end dates in case those are not present in the incoming data
1302
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1303
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1304
-        // use the start date of the first datetime for the end date
1305
-        $first_datetime   = $event->first_datetime();
1306
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1307
-
1308
-        // now process the incoming data
1309
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1310
-            $update_prices = false;
1311
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1312
-            // trim inputs to ensure any excess whitespace is removed.
1313
-            $ticket_data   = array_map('trim', $ticket_data);
1314
-            $ticket_values = [
1315
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1316
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1317
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1318
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1319
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1320
-                    ? $ticket_data['TKT_start_date']
1321
-                    : $default_start_date,
1322
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1323
-                    ? $ticket_data['TKT_end_date']
1324
-                    : $default_end_date,
1325
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1326
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1327
-                    ? $ticket_data['TKT_qty']
1328
-                    : EE_INF,
1329
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1330
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1331
-                    ? $ticket_data['TKT_uses']
1332
-                    : EE_INF,
1333
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1334
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1335
-                'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1336
-                'TKT_price'       => $ticket_price,
1337
-                'TKT_row'         => $row,
1338
-            ];
1339
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1340
-            // which means in turn that the prices will become new prices as well.
1341
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1342
-                $ticket_values['TKT_ID']         = 0;
1343
-                $ticket_values['TKT_is_default'] = 0;
1344
-                $update_prices                   = true;
1345
-            }
1346
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1347
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1348
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1349
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1350
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1351
-            if (! empty($ticket_data['TKT_ID'])) {
1352
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1353
-                if (! $existing_ticket instanceof EE_Ticket) {
1354
-                    throw new RuntimeException(
1355
-                        sprintf(
1356
-                            esc_html__(
1357
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1358
-                                'event_espresso'
1359
-                            ),
1360
-                            $ticket_data['TKT_ID']
1361
-                        )
1362
-                    );
1363
-                }
1364
-                $ticket_sold = $existing_ticket->count_related(
1365
-                        'Registration',
1366
-                        [
1367
-                            [
1368
-                                'STS_ID' => [
1369
-                                    'NOT IN',
1370
-                                    [RegStatus::INCOMPLETE],
1371
-                                ],
1372
-                            ],
1373
-                        ]
1374
-                    ) > 0;
1375
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1376
-                // if they are different then we create a new ticket (if $ticket_sold)
1377
-                // if they aren't different then we go ahead and modify existing ticket.
1378
-                $create_new_ticket = $ticket_sold
1379
-                                     && $ticket_price !== $existing_ticket->price()
1380
-                                     && ! $existing_ticket->deleted();
1381
-                $existing_ticket->set_date_format($date_formats[0]);
1382
-                $existing_ticket->set_time_format($date_formats[1]);
1383
-                // set new values
1384
-                foreach ($ticket_values as $field => $value) {
1385
-                    if ($field == 'TKT_qty') {
1386
-                        $existing_ticket->set_qty($value);
1387
-                    } elseif ($field == 'TKT_price') {
1388
-                        $existing_ticket->set('TKT_price', $ticket_price);
1389
-                    } else {
1390
-                        $existing_ticket->set($field, $value);
1391
-                    }
1392
-                }
1393
-                $ticket = $existing_ticket;
1394
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1395
-                //  Otherwise we have to create a new ticket.
1396
-                if ($create_new_ticket) {
1397
-                    // archive the old ticket first
1398
-                    $existing_ticket->set('TKT_deleted', 1);
1399
-                    $existing_ticket->save();
1400
-                    // make sure this ticket is still recorded in our $saved_tickets
1401
-                    // so we don't run it through the regular trash routine.
1402
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1403
-                    // create new ticket that's a copy of the existing except,
1404
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1405
-                    $new_ticket = clone $existing_ticket;
1406
-                    $new_ticket->set('TKT_ID', 0);
1407
-                    $new_ticket->set('TKT_deleted', 0);
1408
-                    $new_ticket->set('TKT_sold', 0);
1409
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1410
-                    $update_prices = true;
1411
-                    $ticket        = $new_ticket;
1412
-                }
1413
-            } else {
1414
-                // no TKT_id so a new ticket
1415
-                $ticket_values['TKT_price'] = $ticket_price;
1416
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1417
-                $update_prices              = true;
1418
-            }
1419
-            if (! $ticket instanceof EE_Ticket) {
1420
-                throw new RuntimeException(
1421
-                    sprintf(
1422
-                        esc_html__(
1423
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1424
-                            'event_espresso'
1425
-                        ),
1426
-                        print_r($ticket_values, true)
1427
-                    )
1428
-                );
1429
-            }
1430
-            // cap ticket qty by datetime reg limits
1431
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1432
-            // update ticket.
1433
-            $ticket->save();
1434
-            // before going any further make sure our dates are setup correctly
1435
-            // so that the end date is always equal or greater than the start date.
1436
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1437
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1438
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1439
-                $ticket->save();
1440
-            }
1441
-            // initially let's add the ticket to the datetime
1442
-            $datetime->_add_relation_to($ticket, 'Ticket');
1443
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1444
-            // add prices to ticket
1445
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1446
-                ? $data['edit_prices'][ $row ]
1447
-                : [];
1448
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1449
-        }
1450
-        // however now we need to handle permanently deleting tickets via the ui.
1451
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1452
-        // However, it does allow for deleting tickets that have no tickets sold,
1453
-        // in which case we want to get rid of permanently because there is no need to save in db.
1454
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1455
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1456
-        foreach ($tickets_removed as $id) {
1457
-            $id = absint($id);
1458
-            // get the ticket for this id
1459
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1460
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1461
-                continue;
1462
-            }
1463
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1464
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1465
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1466
-            foreach ($related_datetimes as $related_datetime) {
1467
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1468
-            }
1469
-            // need to do the same for prices (except these prices can also be deleted because again,
1470
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1471
-            $ticket_to_remove->delete_related_permanently('Price');
1472
-            // finally let's delete this ticket
1473
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1474
-            $ticket_to_remove->delete_permanently();
1475
-        }
1476
-        return [$datetime, $saved_tickets];
1477
-    }
1478
-
1479
-
1480
-    /**
1481
-     * This attaches a list of given prices to a ticket.
1482
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1483
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1484
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1485
-     *
1486
-     * @access  private
1487
-     * @param array     $prices_data Array of prices from the form.
1488
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1489
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1490
-     * @return  void
1491
-     * @throws EE_Error
1492
-     * @throws ReflectionException
1493
-     */
1494
-    private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1495
-    {
1496
-        $timezone = $ticket->get_timezone();
1497
-        foreach ($prices_data as $row => $price_data) {
1498
-            $price_values = [
1499
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1500
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1501
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1502
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1503
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1504
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1505
-                'PRC_order'      => $row,
1506
-            ];
1507
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1508
-                $price_values['PRC_ID'] = 0;
1509
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1510
-            } else {
1511
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1512
-                // update this price with new values
1513
-                foreach ($price_values as $field => $new_price) {
1514
-                    $price->set($field, $new_price);
1515
-                }
1516
-            }
1517
-            if (! $price instanceof EE_Price) {
1518
-                throw new RuntimeException(
1519
-                    sprintf(
1520
-                        esc_html__(
1521
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1522
-                            'event_espresso'
1523
-                        ),
1524
-                        print_r($price_values, true)
1525
-                    )
1526
-                );
1527
-            }
1528
-            $price->save();
1529
-            $ticket->_add_relation_to($price, 'Price');
1530
-        }
1531
-    }
1532
-
1533
-
1534
-    /**
1535
-     * Add in our autosave ajax handlers
1536
-     */
1537
-    protected function _ee_autosave_create_new()
1538
-    {
1539
-    }
1540
-
1541
-
1542
-    /**
1543
-     * More autosave handlers.
1544
-     */
1545
-    protected function _ee_autosave_edit()
1546
-    {
1547
-    }
1548
-
1549
-
1550
-    /**
1551
-     * @throws EE_Error
1552
-     * @throws ReflectionException
1553
-     */
1554
-    private function _generate_publish_box_extra_content()
1555
-    {
1556
-        // load formatter helper
1557
-        // args for getting related registrations
1558
-        $approved_query_args        = [
1559
-            [
1560
-                'REG_deleted' => 0,
1561
-                'STS_ID'      => RegStatus::APPROVED,
1562
-            ],
1563
-        ];
1564
-        $not_approved_query_args    = [
1565
-            [
1566
-                'REG_deleted' => 0,
1567
-                'STS_ID'      => RegStatus::AWAITING_REVIEW,
1568
-            ],
1569
-        ];
1570
-        $pending_payment_query_args = [
1571
-            [
1572
-                'REG_deleted' => 0,
1573
-                'STS_ID'      => RegStatus::PENDING_PAYMENT,
1574
-            ],
1575
-        ];
1576
-        // publish box
1577
-        $publish_box_extra_args = [
1578
-            'view_approved_reg_url'        => add_query_arg(
1579
-                [
1580
-                    'action'      => 'default',
1581
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1582
-                    '_reg_status' => RegStatus::APPROVED,
1583
-                    'use_filters' => true,
1584
-                ],
1585
-                REG_ADMIN_URL
1586
-            ),
1587
-            'view_not_approved_reg_url'    => add_query_arg(
1588
-                [
1589
-                    'action'      => 'default',
1590
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1591
-                    '_reg_status' => RegStatus::AWAITING_REVIEW,
1592
-                    'use_filters' => true,
1593
-                ],
1594
-                REG_ADMIN_URL
1595
-            ),
1596
-            'view_pending_payment_reg_url' => add_query_arg(
1597
-                [
1598
-                    'action'      => 'default',
1599
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1600
-                    '_reg_status' => RegStatus::PENDING_PAYMENT,
1601
-                    'use_filters' => true,
1602
-                ],
1603
-                REG_ADMIN_URL
1604
-            ),
1605
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1606
-                'Registration',
1607
-                $approved_query_args
1608
-            ),
1609
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1610
-                'Registration',
1611
-                $not_approved_query_args
1612
-            ),
1613
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1614
-                'Registration',
1615
-                $pending_payment_query_args
1616
-            ),
1617
-            'misc_pub_section_class'       => apply_filters(
1618
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1619
-                'misc-pub-section'
1620
-            ),
1621
-        ];
1622
-        ob_start();
1623
-        do_action(
1624
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1625
-            $this->_cpt_model_obj
1626
-        );
1627
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1628
-        // load template
1629
-        EEH_Template::display_template(
1630
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1631
-            $publish_box_extra_args
1632
-        );
1633
-    }
1634
-
1635
-
1636
-    /**
1637
-     * @return EE_Event
1638
-     */
1639
-    public function get_event_object()
1640
-    {
1641
-        return $this->_cpt_model_obj;
1642
-    }
1643
-
1644
-
1645
-
1646
-
1647
-    /** METABOXES * */
1648
-    /**
1649
-     * _register_event_editor_meta_boxes
1650
-     * add all metaboxes related to the event_editor
1651
-     *
1652
-     * @return void
1653
-     * @throws EE_Error
1654
-     * @throws ReflectionException
1655
-     */
1656
-    protected function _register_event_editor_meta_boxes()
1657
-    {
1658
-        $this->verify_cpt_object();
1659
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1660
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1661
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1662
-            $this->addMetaBox(
1663
-                'espresso_event_editor_event_options',
1664
-                esc_html__('Event Registration Options', 'event_espresso'),
1665
-                [$this, 'registration_options_meta_box'],
1666
-                $this->page_slug,
1667
-                'side'
1668
-            );
1669
-        }
1670
-        if (! $use_advanced_editor) {
1671
-            $this->addMetaBox(
1672
-                'espresso_event_editor_tickets',
1673
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1674
-                [$this, 'ticket_metabox'],
1675
-                $this->page_slug,
1676
-                'normal',
1677
-                'high'
1678
-            );
1679
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1680
-            add_action(
1681
-                'add_meta_boxes_espresso_events',
1682
-                function () {
1683
-                    global $current_screen;
1684
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1685
-                },
1686
-                99
1687
-            );
1688
-        }
1689
-        // NOTE: if you're looking for other metaboxes in here,
1690
-        // where a metabox has a related management page in the admin
1691
-        // you will find it setup in the related management page's "_Hooks" file.
1692
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1693
-    }
1694
-
1695
-
1696
-    /**
1697
-     * @throws DomainException
1698
-     * @throws EE_Error
1699
-     * @throws ReflectionException
1700
-     */
1701
-    public function ticket_metabox()
1702
-    {
1703
-        $existing_datetime_ids = $existing_ticket_ids = [];
1704
-        // defaults for template args
1705
-        $template_args = [
1706
-            'ticket_rows'       => '',
1707
-            'total_ticket_rows' => 1,
1708
-            'trash_icon'        => 'dashicons dashicons-lock',
1709
-            'disabled'          => '',
1710
-        ];
1711
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1712
-        /**
1713
-         * 1. Start with retrieving Datetimes
1714
-         * 2. Fore each datetime get related tickets
1715
-         * 3. For each ticket get related prices
1716
-         */
1717
-        /** @var EEM_Datetime $datetime_model */
1718
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1719
-        /** @var EEM_Ticket $datetime_model */
1720
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1721
-        $times        = $datetime_model->get_all_event_dates($event_id);
1722
-        /** @type EE_Datetime $first_datetime */
1723
-        $first_datetime = reset($times);
1724
-        // do we get related tickets?
1725
-        if (
1726
-            $first_datetime instanceof EE_Datetime
1727
-            && $first_datetime->ID() !== 0
1728
-        ) {
1729
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1730
-            $template_args['time']   = $first_datetime;
1731
-            $related_tickets         = $first_datetime->tickets(
1732
-                [
1733
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1734
-                    'default_where_conditions' => 'none',
1735
-                ]
1736
-            );
1737
-            if (! empty($related_tickets)) {
1738
-                $template_args['total_ticket_rows'] = count($related_tickets);
1739
-                $row                                = 0;
1740
-                foreach ($related_tickets as $ticket) {
1741
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1742
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1743
-                    $row++;
1744
-                }
1745
-            } else {
1746
-                $template_args['total_ticket_rows'] = 1;
1747
-                /** @type EE_Ticket $ticket */
1748
-                $ticket                       = $ticket_model->create_default_object();
1749
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1750
-            }
1751
-        } else {
1752
-            $template_args['time'] = $times[0];
1753
-            /** @type EE_Ticket[] $tickets */
1754
-            $tickets                      = $ticket_model->get_all_default_tickets();
1755
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1756
-            // NOTE: we're just sending the first default row
1757
-            // (decaf can't manage default tickets so this should be sufficient);
1758
-        }
1759
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1760
-            'event_editor_event_datetimes_help_tab'
1761
-        );
1762
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1763
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1764
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1765
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1766
-            $ticket_model->create_default_object(),
1767
-            true
1768
-        );
1769
-        $template                                  = apply_filters(
1770
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1771
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1772
-        );
1773
-        EEH_Template::display_template($template, $template_args);
1774
-    }
1775
-
1776
-
1777
-    /**
1778
-     * Setup an individual ticket form for the decaf event editor page
23
+	/**
24
+	 * primary key for the event model
25
+	 */
26
+	private int $EVT_ID = 0;
27
+
28
+	/**
29
+	 * This will hold the event object for event_details screen.
30
+	 *
31
+	 * @var EE_Event|null $_event
32
+	 */
33
+	protected ?EE_Event $_event = null;
34
+
35
+	/**
36
+	 * This will hold the category object for category_details screen.
37
+	 */
38
+	protected ?stdClass $_category = null;
39
+
40
+	protected ?EEM_Event $_event_model = null;
41
+
42
+	/**
43
+	 * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
44
+	 */
45
+	protected $_cpt_model_obj;
46
+
47
+	protected ?NodeGroupDao $model_obj_node_group_persister = null;
48
+
49
+	protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
50
+
51
+
52
+	/**
53
+	 * Initialize page props for this admin page group.
54
+	 */
55
+	protected function _init_page_props()
56
+	{
57
+		// is there a evt_id in the request?
58
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
59
+		$this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
60
+		$this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
61
+
62
+		$this->page_slug        = EVENTS_PG_SLUG;
63
+		$this->page_label       = EVENTS_LABEL;
64
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
65
+		$this->_admin_base_path = EVENTS_ADMIN;
66
+		$this->_cpt_model_names = [
67
+			'create_new' => 'EEM_Event',
68
+			'edit'       => 'EEM_Event',
69
+		];
70
+		$this->_cpt_edit_routes = [
71
+			'espresso_events' => 'edit',
72
+		];
73
+		add_action(
74
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
75
+			[$this, 'verify_event_edit'],
76
+			10,
77
+			2
78
+		);
79
+	}
80
+
81
+
82
+	/**
83
+	 * Sets the ajax hooks used for this admin page group.
84
+	 */
85
+	protected function _ajax_hooks()
86
+	{
87
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
88
+	}
89
+
90
+
91
+	/**
92
+	 * Sets the page properties for this admin page group.
93
+	 */
94
+	protected function _define_page_props()
95
+	{
96
+		$this->_admin_page_title = EVENTS_LABEL;
97
+		$this->_labels           = [
98
+			'buttons'      => [
99
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
100
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
101
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
102
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
103
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
104
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
105
+			],
106
+			'editor_title' => [
107
+				'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
108
+			],
109
+			'publishbox'   => [
110
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
111
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
112
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
113
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
114
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
115
+			],
116
+		];
117
+	}
118
+
119
+
120
+	/**
121
+	 * Sets the page routes property for this admin page group.
122
+	 */
123
+	protected function _set_page_routes()
124
+	{
125
+		$this->_page_routes = [
126
+			'default'                       => [
127
+				'func'       => [$this, '_events_overview_list_table'],
128
+				'capability' => 'ee_read_events',
129
+			],
130
+			'create_new'                    => [
131
+				'func'       => [$this, '_create_new_cpt_item'],
132
+				'capability' => 'ee_edit_events',
133
+			],
134
+			'edit'                          => [
135
+				'func'       => [$this, '_edit_cpt_item'],
136
+				'capability' => 'ee_edit_event',
137
+				'obj_id'     => $this->EVT_ID,
138
+			],
139
+			'copy_event'                    => [
140
+				'func'       => [$this, '_copy_events'],
141
+				'capability' => 'ee_edit_event',
142
+				'obj_id'     => $this->EVT_ID,
143
+				'noheader'   => true,
144
+			],
145
+			'trash_event'                   => [
146
+				'func'       => [$this, '_trash_or_restore_event'],
147
+				'args'       => ['event_status' => 'trash'],
148
+				'capability' => 'ee_delete_event',
149
+				'obj_id'     => $this->EVT_ID,
150
+				'noheader'   => true,
151
+			],
152
+			'trash_events'                  => [
153
+				'func'       => [$this, '_trash_or_restore_events'],
154
+				'args'       => ['event_status' => 'trash'],
155
+				'capability' => 'ee_delete_events',
156
+				'noheader'   => true,
157
+			],
158
+			'restore_event'                 => [
159
+				'func'       => [$this, '_trash_or_restore_event'],
160
+				'args'       => ['event_status' => 'draft'],
161
+				'capability' => 'ee_delete_event',
162
+				'obj_id'     => $this->EVT_ID,
163
+				'noheader'   => true,
164
+			],
165
+			'restore_events'                => [
166
+				'func'       => [$this, '_trash_or_restore_events'],
167
+				'args'       => ['event_status' => 'draft'],
168
+				'capability' => 'ee_delete_events',
169
+				'noheader'   => true,
170
+			],
171
+			'delete_event'                  => [
172
+				'func'       => [$this, '_delete_event'],
173
+				'capability' => 'ee_delete_event',
174
+				'obj_id'     => $this->EVT_ID,
175
+				'noheader'   => true,
176
+			],
177
+			'delete_events'                 => [
178
+				'func'       => [$this, '_delete_events'],
179
+				'capability' => 'ee_delete_events',
180
+				'noheader'   => true,
181
+			],
182
+			'view_report'                   => [
183
+				'func'       => [$this, '_view_report'],
184
+				'capability' => 'ee_edit_events',
185
+			],
186
+			'default_event_settings'        => [
187
+				'func'       => [$this, '_default_event_settings'],
188
+				'capability' => 'manage_options',
189
+			],
190
+			'update_default_event_settings' => [
191
+				'func'       => [$this, '_update_default_event_settings'],
192
+				'capability' => 'manage_options',
193
+				'noheader'   => true,
194
+			],
195
+			'template_settings'             => [
196
+				'func'       => [$this, '_template_settings'],
197
+				'capability' => 'manage_options',
198
+			],
199
+			// event category tab related
200
+			'add_category'                  => [
201
+				'func'       => [$this, '_category_details'],
202
+				'capability' => 'ee_edit_event_category',
203
+				'args'       => ['view' => 'add'],
204
+			],
205
+			'edit_category'                 => [
206
+				'func'       => [$this, '_category_details'],
207
+				'capability' => 'ee_edit_event_category',
208
+				'args'       => ['view' => 'edit'],
209
+			],
210
+			'delete_categories'             => [
211
+				'func'       => [$this, '_delete_categories'],
212
+				'capability' => 'ee_delete_event_category',
213
+				'noheader'   => true,
214
+			],
215
+			'delete_category'               => [
216
+				'func'       => [$this, '_delete_categories'],
217
+				'capability' => 'ee_delete_event_category',
218
+				'noheader'   => true,
219
+			],
220
+			'insert_category'               => [
221
+				'func'       => [$this, '_insert_or_update_category'],
222
+				'args'       => ['new_category' => true],
223
+				'capability' => 'ee_edit_event_category',
224
+				'noheader'   => true,
225
+			],
226
+			'update_category'               => [
227
+				'func'       => [$this, '_insert_or_update_category'],
228
+				'args'       => ['new_category' => false],
229
+				'capability' => 'ee_edit_event_category',
230
+				'noheader'   => true,
231
+			],
232
+			'category_list'                 => [
233
+				'func'       => [$this, '_category_list_table'],
234
+				'capability' => 'ee_manage_event_categories',
235
+			],
236
+			'preview_deletion'              => [
237
+				'func'       => [$this, 'previewDeletion'],
238
+				'capability' => 'ee_delete_events',
239
+			],
240
+			'confirm_deletion'              => [
241
+				'func'       => [$this, 'confirmDeletion'],
242
+				'capability' => 'ee_delete_events',
243
+				'noheader'   => true,
244
+			],
245
+		];
246
+	}
247
+
248
+
249
+	/**
250
+	 * Set the _page_config property for this admin page group.
251
+	 */
252
+	protected function _set_page_config()
253
+	{
254
+		$post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
255
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
256
+		$this->_page_config = [
257
+			'default'                => [
258
+				'nav'           => [
259
+					'label' => esc_html__('Overview', 'event_espresso'),
260
+					'icon'  => 'dashicons-list-view',
261
+					'order' => 10,
262
+				],
263
+				'list_table'    => 'Events_Admin_List_Table',
264
+				'help_tabs'     => [
265
+					'events_overview_help_tab'                       => [
266
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
267
+						'filename' => 'events_overview',
268
+					],
269
+					'events_overview_table_column_headings_help_tab' => [
270
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
271
+						'filename' => 'events_overview_table_column_headings',
272
+					],
273
+					'events_overview_filters_help_tab'               => [
274
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
275
+						'filename' => 'events_overview_filters',
276
+					],
277
+					'events_overview_view_help_tab'                  => [
278
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
279
+						'filename' => 'events_overview_views',
280
+					],
281
+					'events_overview_other_help_tab'                 => [
282
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
283
+						'filename' => 'events_overview_other',
284
+					],
285
+				],
286
+				'require_nonce' => false,
287
+			],
288
+			'create_new'             => [
289
+				'nav'           => [
290
+					'label'      => esc_html__('Add New Event', 'event_espresso'),
291
+					'icon'       => 'dashicons-plus-alt',
292
+					'order'      => 15,
293
+					'persistent' => false,
294
+				],
295
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
296
+				'help_tabs'     => [
297
+					'event_editor_help_tab'                            => [
298
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
299
+						'filename' => 'event_editor',
300
+					],
301
+					'event_editor_title_richtexteditor_help_tab'       => [
302
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
303
+						'filename' => 'event_editor_title_richtexteditor',
304
+					],
305
+					'event_editor_venue_details_help_tab'              => [
306
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
307
+						'filename' => 'event_editor_venue_details',
308
+					],
309
+					'event_editor_event_datetimes_help_tab'            => [
310
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
311
+						'filename' => 'event_editor_event_datetimes',
312
+					],
313
+					'event_editor_event_tickets_help_tab'              => [
314
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
315
+						'filename' => 'event_editor_event_tickets',
316
+					],
317
+					'event_editor_event_registration_options_help_tab' => [
318
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
319
+						'filename' => 'event_editor_event_registration_options',
320
+					],
321
+					'event_editor_tags_categories_help_tab'            => [
322
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
323
+						'filename' => 'event_editor_tags_categories',
324
+					],
325
+					'event_editor_questions_registrants_help_tab'      => [
326
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
327
+						'filename' => 'event_editor_questions_registrants',
328
+					],
329
+					'event_editor_save_new_event_help_tab'             => [
330
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
331
+						'filename' => 'event_editor_save_new_event',
332
+					],
333
+					'event_editor_other_help_tab'                      => [
334
+						'title'    => esc_html__('Event Other', 'event_espresso'),
335
+						'filename' => 'event_editor_other',
336
+					],
337
+				],
338
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
339
+				'require_nonce' => false,
340
+			],
341
+			'edit'                   => [
342
+				'nav'           => [
343
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
344
+					'icon'       => 'dashicons-edit',
345
+					'order'      => 15,
346
+					'persistent' => false,
347
+					'url'        => $post_id
348
+						? EE_Admin_Page::add_query_args_and_nonce(
349
+							['post' => $post_id, 'action' => 'edit'],
350
+							$this->_current_page_view_url
351
+						)
352
+						: $this->_admin_base_url,
353
+				],
354
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
355
+				'help_tabs'     => [
356
+					'event_editor_help_tab'                            => [
357
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
358
+						'filename' => 'event_editor',
359
+					],
360
+					'event_editor_title_richtexteditor_help_tab'       => [
361
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
362
+						'filename' => 'event_editor_title_richtexteditor',
363
+					],
364
+					'event_editor_venue_details_help_tab'              => [
365
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
366
+						'filename' => 'event_editor_venue_details',
367
+					],
368
+					'event_editor_event_datetimes_help_tab'            => [
369
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
370
+						'filename' => 'event_editor_event_datetimes',
371
+					],
372
+					'event_editor_event_tickets_help_tab'              => [
373
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
374
+						'filename' => 'event_editor_event_tickets',
375
+					],
376
+					'event_editor_event_registration_options_help_tab' => [
377
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
378
+						'filename' => 'event_editor_event_registration_options',
379
+					],
380
+					'event_editor_tags_categories_help_tab'            => [
381
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
382
+						'filename' => 'event_editor_tags_categories',
383
+					],
384
+					'event_editor_questions_registrants_help_tab'      => [
385
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
386
+						'filename' => 'event_editor_questions_registrants',
387
+					],
388
+					'event_editor_save_new_event_help_tab'             => [
389
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
390
+						'filename' => 'event_editor_save_new_event',
391
+					],
392
+					'event_editor_other_help_tab'                      => [
393
+						'title'    => esc_html__('Event Other', 'event_espresso'),
394
+						'filename' => 'event_editor_other',
395
+					],
396
+				],
397
+				'require_nonce' => false,
398
+			],
399
+			'default_event_settings' => [
400
+				'nav'           => [
401
+					'label' => esc_html__('Default Settings', 'event_espresso'),
402
+					'icon'  => 'dashicons-admin-generic',
403
+					'order' => 40,
404
+				],
405
+				'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
406
+				'labels'        => [
407
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
408
+				],
409
+				'help_tabs'     => [
410
+					'default_settings_help_tab'        => [
411
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
412
+						'filename' => 'events_default_settings',
413
+					],
414
+					'default_settings_status_help_tab' => [
415
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
416
+						'filename' => 'events_default_settings_status',
417
+					],
418
+					'default_maximum_tickets_help_tab' => [
419
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
420
+						'filename' => 'events_default_settings_max_tickets',
421
+					],
422
+				],
423
+				'require_nonce' => false,
424
+			],
425
+			// template settings
426
+			'template_settings'      => [
427
+				'nav'           => [
428
+					'label' => esc_html__('Templates', 'event_espresso'),
429
+					'icon'  => 'dashicons-layout',
430
+					'order' => 30,
431
+				],
432
+				'metaboxes'     => $this->_default_espresso_metaboxes,
433
+				'help_tabs'     => [
434
+					'general_settings_templates_help_tab' => [
435
+						'title'    => esc_html__('Templates', 'event_espresso'),
436
+						'filename' => 'general_settings_templates',
437
+					],
438
+				],
439
+				'require_nonce' => false,
440
+			],
441
+			// event category stuff
442
+			'add_category'           => [
443
+				'nav'           => [
444
+					'label'      => esc_html__('Add Category', 'event_espresso'),
445
+					'icon'       => 'dashicons-plus-alt',
446
+					'order'      => 25,
447
+					'persistent' => false,
448
+				],
449
+				'help_tabs'     => [
450
+					'add_category_help_tab' => [
451
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
452
+						'filename' => 'events_add_category',
453
+					],
454
+				],
455
+				'metaboxes'     => ['_publish_post_box'],
456
+				'require_nonce' => false,
457
+			],
458
+			'edit_category'          => [
459
+				'nav'           => [
460
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
461
+					'icon'       => 'dashicons-edit',
462
+					'order'      => 25,
463
+					'persistent' => false,
464
+					'url'        => $EVT_CAT_ID
465
+						? add_query_arg(
466
+							['EVT_CAT_ID' => $EVT_CAT_ID],
467
+							$this->_current_page_view_url
468
+						)
469
+						: $this->_admin_base_url,
470
+				],
471
+				'help_tabs'     => [
472
+					'edit_category_help_tab' => [
473
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
474
+						'filename' => 'events_edit_category',
475
+					],
476
+				],
477
+				'metaboxes'     => ['_publish_post_box'],
478
+				'require_nonce' => false,
479
+			],
480
+			'category_list'          => [
481
+				'nav'           => [
482
+					'label' => esc_html__('Categories', 'event_espresso'),
483
+					'icon'  => 'dashicons-networking',
484
+					'order' => 20,
485
+				],
486
+				'list_table'    => 'Event_Categories_Admin_List_Table',
487
+				'help_tabs'     => [
488
+					'events_categories_help_tab'                       => [
489
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
490
+						'filename' => 'events_categories',
491
+					],
492
+					'events_categories_table_column_headings_help_tab' => [
493
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
494
+						'filename' => 'events_categories_table_column_headings',
495
+					],
496
+					'events_categories_view_help_tab'                  => [
497
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
498
+						'filename' => 'events_categories_views',
499
+					],
500
+					'events_categories_other_help_tab'                 => [
501
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
502
+						'filename' => 'events_categories_other',
503
+					],
504
+				],
505
+				'metaboxes'     => $this->_default_espresso_metaboxes,
506
+				'require_nonce' => false,
507
+			],
508
+			'preview_deletion'       => [
509
+				'nav'           => [
510
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
511
+					'icon'       => 'dashicons-remove',
512
+					'order'      => 15,
513
+					'persistent' => false,
514
+					'url'        => '',
515
+				],
516
+				'require_nonce' => false,
517
+			],
518
+		];
519
+	}
520
+
521
+
522
+	/**
523
+	 * Used to register any global screen options if necessary for every route in this admin page group.
524
+	 */
525
+	protected function _add_screen_options()
526
+	{
527
+	}
528
+
529
+
530
+	/**
531
+	 * Implementing the screen options for the 'default' route.
532
+	 *
533
+	 * @throws InvalidArgumentException
534
+	 * @throws InvalidDataTypeException
535
+	 * @throws InvalidInterfaceException
536
+	 */
537
+	protected function _add_screen_options_default()
538
+	{
539
+		$this->_per_page_screen_option();
540
+	}
541
+
542
+
543
+	/**
544
+	 * Implementing screen options for the category list route.
545
+	 *
546
+	 * @throws InvalidArgumentException
547
+	 * @throws InvalidDataTypeException
548
+	 * @throws InvalidInterfaceException
549
+	 */
550
+	protected function _add_screen_options_category_list()
551
+	{
552
+		$page_title              = $this->_admin_page_title;
553
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
554
+		$this->_per_page_screen_option();
555
+		$this->_admin_page_title = $page_title;
556
+	}
557
+
558
+
559
+	/**
560
+	 * Used to register any global feature pointers for the admin page group.
561
+	 */
562
+	protected function _add_feature_pointers()
563
+	{
564
+	}
565
+
566
+
567
+	/**
568
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
569
+	 */
570
+	public function load_scripts_styles()
571
+	{
572
+		wp_register_style(
573
+			'events-admin-css',
574
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
575
+			[],
576
+			EVENT_ESPRESSO_VERSION
577
+		);
578
+		wp_register_style(
579
+			'ee-cat-admin',
580
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
581
+			[],
582
+			EVENT_ESPRESSO_VERSION
583
+		);
584
+		wp_enqueue_style('events-admin-css');
585
+		wp_enqueue_style('ee-cat-admin');
586
+		// scripts
587
+		wp_register_script(
588
+			'event_editor_js',
589
+			EVENTS_ASSETS_URL . 'event_editor.js',
590
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
591
+			EVENT_ESPRESSO_VERSION,
592
+			true
593
+		);
594
+	}
595
+
596
+
597
+	/**
598
+	 * Enqueuing scripts and styles specific to this view
599
+	 */
600
+	public function load_scripts_styles_create_new()
601
+	{
602
+		$this->load_scripts_styles_edit();
603
+	}
604
+
605
+
606
+	/**
607
+	 * Enqueuing scripts and styles specific to this view
608
+	 */
609
+	public function load_scripts_styles_edit()
610
+	{
611
+		// styles
612
+		wp_enqueue_style('espresso-ui-theme');
613
+		wp_register_style(
614
+			'event-editor-css',
615
+			EVENTS_ASSETS_URL . 'event-editor.css',
616
+			['ee-admin-css'],
617
+			EVENT_ESPRESSO_VERSION
618
+		);
619
+		wp_enqueue_style('event-editor-css');
620
+		// scripts
621
+		if (! $this->admin_config->useAdvancedEditor()) {
622
+			wp_register_script(
623
+				'event-datetime-metabox',
624
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
625
+				['event_editor_js', 'ee-datepicker'],
626
+				EVENT_ESPRESSO_VERSION
627
+			);
628
+			wp_enqueue_script('event-datetime-metabox');
629
+		}
630
+	}
631
+
632
+
633
+	/**
634
+	 * Populating the _views property for the category list table view.
635
+	 */
636
+	protected function _set_list_table_views_category_list()
637
+	{
638
+		$this->_views = [
639
+			'all' => [
640
+				'slug'        => 'all',
641
+				'label'       => esc_html__('All', 'event_espresso'),
642
+				'count'       => 0,
643
+				'bulk_action' => [
644
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
645
+				],
646
+			],
647
+		];
648
+	}
649
+
650
+
651
+	/**
652
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
653
+	 */
654
+	public function admin_init()
655
+	{
656
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
657
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
658
+			'event_espresso'
659
+		);
660
+	}
661
+
662
+
663
+	/**
664
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
665
+	 * group.
666
+	 */
667
+	public function admin_notices()
668
+	{
669
+	}
670
+
671
+
672
+	/**
673
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
674
+	 * this admin page group.
675
+	 */
676
+	public function admin_footer_scripts()
677
+	{
678
+	}
679
+
680
+
681
+	/**
682
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
683
+	 * warning (via EE_Error::add_error());
684
+	 *
685
+	 * @param EE_Event|null $event Event object
686
+	 * @param string        $req_type
687
+	 * @return void
688
+	 * @throws EE_Error
689
+	 * @throws ReflectionException
690
+	 */
691
+	public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
692
+	{
693
+		// don't need to do this when processing
694
+		if (! empty($req_type)) {
695
+			return;
696
+		}
697
+		// no event?
698
+		if (! $event instanceof EE_Event) {
699
+			$event = $this->_cpt_model_obj;
700
+		}
701
+		// STILL no event?
702
+		if (! $event instanceof EE_Event) {
703
+			return;
704
+		}
705
+		// don't need to keep calling this
706
+		remove_action(
707
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
708
+			[$this, 'verify_event_edit']
709
+		);
710
+		$orig_status = $event->status();
711
+		// first check if event is active.
712
+		if (
713
+			$orig_status === EEM_Event::cancelled
714
+			|| $orig_status === EEM_Event::postponed
715
+			|| $event->is_expired()
716
+			|| $event->is_inactive()
717
+		) {
718
+			return;
719
+		}
720
+		// made it here so it IS active... next check that any of the tickets are sold.
721
+		if ($event->is_sold_out(true)) {
722
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
723
+				EE_Error::add_attention(
724
+					sprintf(
725
+						esc_html__(
726
+							'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.',
727
+							'event_espresso'
728
+						),
729
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
730
+					)
731
+				);
732
+			}
733
+			return;
734
+		}
735
+		if ($orig_status === EEM_Event::sold_out) {
736
+			EE_Error::add_attention(
737
+				sprintf(
738
+					esc_html__(
739
+						'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.',
740
+						'event_espresso'
741
+					),
742
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
743
+				)
744
+			);
745
+		}
746
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
747
+		if (! $event->tickets_on_sale()) {
748
+			return;
749
+		}
750
+		// made it here so show warning
751
+		$this->_edit_event_warning();
752
+	}
753
+
754
+
755
+	/**
756
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
757
+	 * When needed, hook this into a EE_Error::add_error() notice.
758
+	 *
759
+	 * @access protected
760
+	 * @return void
761
+	 */
762
+	protected function _edit_event_warning()
763
+	{
764
+		// we don't want to add warnings during these requests
765
+		if ($this->request->getRequestParam('action') === 'editpost') {
766
+			return;
767
+		}
768
+		EE_Error::add_attention(
769
+			sprintf(
770
+				esc_html__(
771
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
772
+					'event_espresso'
773
+				),
774
+				'<a class="espresso-help-tab-lnk ee-help-tab-link">',
775
+				'</a>'
776
+			)
777
+		);
778
+	}
779
+
780
+
781
+	/**
782
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
783
+	 * Otherwise, do the normal logic
784
+	 *
785
+	 * @return void
786
+	 * @throws EE_Error
787
+	 * @throws InvalidArgumentException
788
+	 * @throws InvalidDataTypeException
789
+	 * @throws InvalidInterfaceException
790
+	 * @throws ReflectionException
791
+	 */
792
+	protected function _create_new_cpt_item()
793
+	{
794
+		$has_timezone_string = get_option('timezone_string');
795
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
796
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
797
+			EE_Error::add_attention(
798
+				sprintf(
799
+					esc_html__(
800
+						'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',
801
+						'event_espresso'
802
+					),
803
+					'<br>',
804
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
805
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
806
+					. '</select>',
807
+					'<button class="button button--secondary timezone-submit">',
808
+					'</button><span class="spinner"></span>'
809
+				),
810
+				__FILE__,
811
+				__FUNCTION__,
812
+				__LINE__
813
+			);
814
+		}
815
+		parent::_create_new_cpt_item();
816
+	}
817
+
818
+
819
+	/**
820
+	 * Sets the _views property for the default route in this admin page group.
821
+	 */
822
+	protected function _set_list_table_views_default()
823
+	{
824
+		$this->_views = [
825
+			'all'   => [
826
+				'slug'        => 'all',
827
+				'label'       => esc_html__('View All Events', 'event_espresso'),
828
+				'count'       => 0,
829
+				'bulk_action' => [
830
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
831
+				],
832
+			],
833
+			'draft' => [
834
+				'slug'        => 'draft',
835
+				'label'       => esc_html__('Draft', 'event_espresso'),
836
+				'count'       => 0,
837
+				'bulk_action' => [
838
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
839
+				],
840
+			],
841
+		];
842
+		if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
843
+			$this->_views['trash'] = [
844
+				'slug'        => 'trash',
845
+				'label'       => esc_html__('Trash', 'event_espresso'),
846
+				'count'       => 0,
847
+				'bulk_action' => [
848
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
849
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
850
+				],
851
+			];
852
+		}
853
+	}
854
+
855
+
856
+	/**
857
+	 * Provides the legend item array for the default list table view.
858
+	 *
859
+	 * @return array
860
+	 * @throws EE_Error
861
+	 * @throws EE_Error
862
+	 */
863
+	protected function _event_legend_items(): array
864
+	{
865
+		$items    = [
866
+			'view_details'   => [
867
+				'class' => 'dashicons dashicons-visibility',
868
+				'desc'  => esc_html__('View Event', 'event_espresso'),
869
+			],
870
+			'edit_event'     => [
871
+				'class' => 'dashicons dashicons-calendar-alt',
872
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
873
+			],
874
+			'view_attendees' => [
875
+				'class' => 'dashicons dashicons-groups',
876
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
877
+			],
878
+		];
879
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
880
+		$statuses = [
881
+			'sold_out_status'  => [
882
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
883
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
884
+			],
885
+			'active_status'    => [
886
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
887
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
888
+			],
889
+			'upcoming_status'  => [
890
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
891
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
892
+			],
893
+			'postponed_status' => [
894
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
895
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
896
+			],
897
+			'cancelled_status' => [
898
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
899
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
900
+			],
901
+			'expired_status'   => [
902
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
903
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
904
+			],
905
+			'inactive_status'  => [
906
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
907
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
908
+			],
909
+		];
910
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
911
+		return array_merge($items, $statuses);
912
+	}
913
+
914
+
915
+	/**
916
+	 * @return EEM_Event
917
+	 * @throws EE_Error
918
+	 * @throws InvalidArgumentException
919
+	 * @throws InvalidDataTypeException
920
+	 * @throws InvalidInterfaceException
921
+	 * @throws ReflectionException
922
+	 */
923
+	private function _event_model(): EEM_Event
924
+	{
925
+		if (! $this->_event_model instanceof EEM_Event) {
926
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
927
+		}
928
+		return $this->_event_model;
929
+	}
930
+
931
+
932
+	/**
933
+	 * Adds extra buttons to the WP CPT permalink field row.
934
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
935
+	 *
936
+	 * @param string      $return    the current html
937
+	 * @param int         $id        the post id for the page
938
+	 * @param string|null $new_title What the title is
939
+	 * @param string|null $new_slug  what the slug is
940
+	 * @return string            The new html string for the permalink area
941
+	 * @deprecated 5.0.0.p
942
+	 * @see        TicketSelectorShortcodeButton::addButton
943
+	 */
944
+	public function extra_permalink_field_buttons(
945
+		string $return,
946
+		int $id,
947
+		?string $new_title,
948
+		?string $new_slug
949
+	): string {
950
+		return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
951
+	}
952
+
953
+
954
+	/**
955
+	 * _events_overview_list_table
956
+	 * This contains the logic for showing the events_overview list
957
+	 *
958
+	 * @access protected
959
+	 * @return void
960
+	 * @throws DomainException
961
+	 * @throws EE_Error
962
+	 * @throws InvalidArgumentException
963
+	 * @throws InvalidDataTypeException
964
+	 * @throws InvalidInterfaceException
965
+	 */
966
+	protected function _events_overview_list_table()
967
+	{
968
+		$after_list_table = [];
969
+		$links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
970
+		$links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
971
+		$links_html       .= EEH_HTML::div(
972
+			EEH_Template::get_button_or_link(
973
+				get_post_type_archive_link(EspressoPostType::EVENTS),
974
+				esc_html__('View Event Archive Page', 'event_espresso'),
975
+				'button button--small button--secondary'
976
+			),
977
+			'',
978
+			'ee-admin-button-row ee-admin-button-row--align-start'
979
+		);
980
+		$links_html       .= EEH_HTML::divx();
981
+
982
+		$after_list_table['view_event_list_button'] = $links_html;
983
+
984
+		$after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
985
+		$this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
986
+				'create_new',
987
+				'add',
988
+				[],
989
+				'add-new-h2'
990
+			);
991
+
992
+		$this->_template_args['after_list_table'] = array_merge(
993
+			(array) $this->_template_args['after_list_table'],
994
+			$after_list_table
995
+		);
996
+		$this->display_admin_list_table_page_with_no_sidebar();
997
+	}
998
+
999
+
1000
+	/**
1001
+	 * this allows for extra misc actions in the default WP publish box
1002
+	 *
1003
+	 * @return void
1004
+	 * @throws DomainException
1005
+	 * @throws EE_Error
1006
+	 * @throws InvalidArgumentException
1007
+	 * @throws InvalidDataTypeException
1008
+	 * @throws InvalidInterfaceException
1009
+	 * @throws ReflectionException
1010
+	 */
1011
+	public function extra_misc_actions_publish_box()
1012
+	{
1013
+		$this->_generate_publish_box_extra_content();
1014
+	}
1015
+
1016
+
1017
+	/**
1018
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1019
+	 * saved.
1020
+	 * Typically you would use this to save any additional data.
1021
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1022
+	 * ALSO very important.  When a post transitions from scheduled to published,
1023
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1024
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1025
+	 *
1026
+	 * @access protected
1027
+	 * @abstract
1028
+	 * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1029
+	 * @param WP_Post $post    The post object of the cpt that was saved.
1030
+	 * @return void
1031
+	 * @throws EE_Error
1032
+	 * @throws InvalidArgumentException
1033
+	 * @throws InvalidDataTypeException
1034
+	 * @throws InvalidInterfaceException
1035
+	 * @throws ReflectionException
1036
+	 */
1037
+	protected function _insert_update_cpt_item($post_id, $post)
1038
+	{
1039
+		if ($post instanceof WP_Post && $post->post_type !== EspressoPostType::EVENTS) {
1040
+			// get out we're not processing an event save.
1041
+			return;
1042
+		}
1043
+		$event_values = [
1044
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1045
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1046
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1047
+		];
1048
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1049
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1050
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1051
+				'display_ticket_selector',
1052
+				false,
1053
+				'bool'
1054
+			);
1055
+			$event_values['EVT_additional_limit']            = min(
1056
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1057
+				$this->request->getRequestParam(
1058
+					'additional_limit',
1059
+					EEM_Event::get_default_additional_limit(),
1060
+					'int'
1061
+				)
1062
+			);
1063
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1064
+				'EVT_default_registration_status',
1065
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1066
+			);
1067
+
1068
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1069
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1070
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1071
+		} elseif ($post instanceof WP_Post) {
1072
+			$event_values['EVT_name'] = $post->post_title;
1073
+			$event_values['EVT_desc'] = $post->post_content;
1074
+		}
1075
+		// update event
1076
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1077
+		// get event_object for other metaboxes...
1078
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1079
+		// i have to set up where conditions to override the filters in the model
1080
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1081
+		/** @var EE_Event $event */
1082
+		$event = $this->_event_model()->get_one(
1083
+			[
1084
+				[
1085
+					$this->_event_model()->primary_key_name() => $post_id,
1086
+					'OR'                                      => [
1087
+						'status'   => $post->post_status,
1088
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1089
+						// but the returned object here has a status of "publish", so use the original post status as well
1090
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1091
+					],
1092
+					'status' => ['NOT IN', ['auto-draft']],
1093
+				],
1094
+			]
1095
+		);
1096
+
1097
+		if (! $event instanceof EE_Event) {
1098
+			return;
1099
+		}
1100
+
1101
+		// the following are default callbacks for event attachment updates
1102
+		// that can be overridden by caffeinated functionality and/or addons.
1103
+		$event_update_callbacks = [];
1104
+		if (! $this->admin_config->useAdvancedEditor()) {
1105
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1106
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1107
+		}
1108
+		$event_update_callbacks = apply_filters(
1109
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1110
+			$event_update_callbacks
1111
+		);
1112
+
1113
+		$att_success = true;
1114
+		foreach ($event_update_callbacks as $e_callback) {
1115
+			$_success = is_callable($e_callback)
1116
+				? $e_callback($event, $this->request->requestParams())
1117
+				: false;
1118
+			// if ANY of these updates fail then we want the appropriate global error message
1119
+			$att_success = $_success !== false ? $att_success : false;
1120
+		}
1121
+		// any errors?
1122
+		if ($success && $att_success === false) {
1123
+			EE_Error::add_error(
1124
+				esc_html__(
1125
+					'Event Details saved successfully but something went wrong with saving attachments.',
1126
+					'event_espresso'
1127
+				),
1128
+				__FILE__,
1129
+				__FUNCTION__,
1130
+				__LINE__
1131
+			);
1132
+		} elseif ($success === false) {
1133
+			EE_Error::add_error(
1134
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1135
+				__FILE__,
1136
+				__FUNCTION__,
1137
+				__LINE__
1138
+			);
1139
+		}
1140
+	}
1141
+
1142
+
1143
+	/**
1144
+	 * @param int $post_id
1145
+	 * @param int $revision_id
1146
+	 * @throws EE_Error
1147
+	 * @throws EE_Error
1148
+	 * @throws ReflectionException
1149
+	 * @see parent::restore_item()
1150
+	 */
1151
+	protected function _restore_cpt_item(int $post_id, int $revision_id)
1152
+	{
1153
+		// copy existing event meta to new post
1154
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1155
+		if ($post_evt instanceof EE_Event) {
1156
+			// meta revision restore
1157
+			$post_evt->restore_revision($revision_id);
1158
+			// related objs restore
1159
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1160
+		}
1161
+	}
1162
+
1163
+
1164
+	/**
1165
+	 * Attach the venue to the Event
1166
+	 *
1167
+	 * @param EE_Event $event Event Object to add the venue to
1168
+	 * @param array    $data  The request data from the form
1169
+	 * @return bool           Success or fail.
1170
+	 * @throws EE_Error
1171
+	 * @throws ReflectionException
1172
+	 */
1173
+	protected function _default_venue_update(EE_Event $event, array $data): bool
1174
+	{
1175
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1176
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1177
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1178
+		// very important.  If we don't have a venue name...
1179
+		// then we'll get out because not necessary to create empty venue
1180
+		if (empty($data['venue_title'])) {
1181
+			return false;
1182
+		}
1183
+		$venue_array = [
1184
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1185
+			'VNU_name'            => $data['venue_title'],
1186
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1187
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1188
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1189
+				? $data['venue_short_description']
1190
+				: null,
1191
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1192
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1193
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1194
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1195
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1196
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1197
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1198
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1199
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1200
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1201
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1202
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1203
+			'status'              => 'publish',
1204
+		];
1205
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1206
+		if (! empty($venue_id)) {
1207
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1208
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1209
+			// we've gotta make sure that the venue is always attached to a revision..
1210
+			// add_relation_to should take care of making sure that the relation is already present.
1211
+			$event->_add_relation_to($venue_id, 'Venue');
1212
+			return $rows_affected > 0;
1213
+		}
1214
+		// we insert the venue
1215
+		$venue_id = $venue_model->insert($venue_array);
1216
+		$event->_add_relation_to($venue_id, 'Venue');
1217
+		return ! empty($venue_id);
1218
+		// when we have the ancestor come in it's already been handled by the revision save.
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1224
+	 *
1225
+	 * @param EE_Event $event The Event object we're attaching data to
1226
+	 * @param array    $data  The request data from the form
1227
+	 * @return array
1228
+	 * @throws EE_Error
1229
+	 * @throws ReflectionException
1230
+	 * @throws Exception
1231
+	 */
1232
+	protected function _default_tickets_update(EE_Event $event, array $data): array
1233
+	{
1234
+		if ($this->admin_config->useAdvancedEditor()) {
1235
+			return [];
1236
+		}
1237
+		$datetime       = null;
1238
+		$saved_tickets  = [];
1239
+		$event_timezone = $event->get_timezone();
1240
+		$date_formats   = ['Y-m-d', 'h:i a'];
1241
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1242
+			// trim all values to ensure any excess whitespace is removed.
1243
+			$datetime_data                = array_map('trim', $datetime_data);
1244
+			$datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1245
+					? $datetime_data['DTT_EVT_end']
1246
+					: $datetime_data['DTT_EVT_start'];
1247
+			$datetime_values              = [
1248
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1249
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1250
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1251
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1252
+				'DTT_order'     => $row,
1253
+			];
1254
+			// if we have an id then let's get existing object first and then set the new values.
1255
+			//  Otherwise we instantiate a new object for save.
1256
+			if (! empty($datetime_data['DTT_ID'])) {
1257
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1258
+				if (! $datetime instanceof EE_Datetime) {
1259
+					throw new RuntimeException(
1260
+						sprintf(
1261
+							esc_html__(
1262
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1263
+								'event_espresso'
1264
+							),
1265
+							$datetime_data['DTT_ID']
1266
+						)
1267
+					);
1268
+				}
1269
+				$datetime->set_date_format($date_formats[0]);
1270
+				$datetime->set_time_format($date_formats[1]);
1271
+				foreach ($datetime_values as $field => $value) {
1272
+					$datetime->set($field, $value);
1273
+				}
1274
+			} else {
1275
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1276
+			}
1277
+			if (! $datetime instanceof EE_Datetime) {
1278
+				throw new RuntimeException(
1279
+					sprintf(
1280
+						esc_html__(
1281
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1282
+							'event_espresso'
1283
+						),
1284
+						print_r($datetime_values, true)
1285
+					)
1286
+				);
1287
+			}
1288
+			// before going any further make sure our dates are setup correctly
1289
+			// so that the end date is always equal or greater than the start date.
1290
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1291
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1292
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1293
+			}
1294
+			$datetime->save();
1295
+			$event->_add_relation_to($datetime, 'Datetime');
1296
+		}
1297
+		// no datetimes get deleted so we don't do any of that logic here.
1298
+		// update tickets next
1299
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1300
+
1301
+		// set up some default start and end dates in case those are not present in the incoming data
1302
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1303
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1304
+		// use the start date of the first datetime for the end date
1305
+		$first_datetime   = $event->first_datetime();
1306
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1307
+
1308
+		// now process the incoming data
1309
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1310
+			$update_prices = false;
1311
+			$ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1312
+			// trim inputs to ensure any excess whitespace is removed.
1313
+			$ticket_data   = array_map('trim', $ticket_data);
1314
+			$ticket_values = [
1315
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1316
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1317
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1318
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1319
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1320
+					? $ticket_data['TKT_start_date']
1321
+					: $default_start_date,
1322
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1323
+					? $ticket_data['TKT_end_date']
1324
+					: $default_end_date,
1325
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1326
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1327
+					? $ticket_data['TKT_qty']
1328
+					: EE_INF,
1329
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1330
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1331
+					? $ticket_data['TKT_uses']
1332
+					: EE_INF,
1333
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1334
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1335
+				'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1336
+				'TKT_price'       => $ticket_price,
1337
+				'TKT_row'         => $row,
1338
+			];
1339
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1340
+			// which means in turn that the prices will become new prices as well.
1341
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1342
+				$ticket_values['TKT_ID']         = 0;
1343
+				$ticket_values['TKT_is_default'] = 0;
1344
+				$update_prices                   = true;
1345
+			}
1346
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1347
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1348
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1349
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1350
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1351
+			if (! empty($ticket_data['TKT_ID'])) {
1352
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1353
+				if (! $existing_ticket instanceof EE_Ticket) {
1354
+					throw new RuntimeException(
1355
+						sprintf(
1356
+							esc_html__(
1357
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1358
+								'event_espresso'
1359
+							),
1360
+							$ticket_data['TKT_ID']
1361
+						)
1362
+					);
1363
+				}
1364
+				$ticket_sold = $existing_ticket->count_related(
1365
+						'Registration',
1366
+						[
1367
+							[
1368
+								'STS_ID' => [
1369
+									'NOT IN',
1370
+									[RegStatus::INCOMPLETE],
1371
+								],
1372
+							],
1373
+						]
1374
+					) > 0;
1375
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1376
+				// if they are different then we create a new ticket (if $ticket_sold)
1377
+				// if they aren't different then we go ahead and modify existing ticket.
1378
+				$create_new_ticket = $ticket_sold
1379
+									 && $ticket_price !== $existing_ticket->price()
1380
+									 && ! $existing_ticket->deleted();
1381
+				$existing_ticket->set_date_format($date_formats[0]);
1382
+				$existing_ticket->set_time_format($date_formats[1]);
1383
+				// set new values
1384
+				foreach ($ticket_values as $field => $value) {
1385
+					if ($field == 'TKT_qty') {
1386
+						$existing_ticket->set_qty($value);
1387
+					} elseif ($field == 'TKT_price') {
1388
+						$existing_ticket->set('TKT_price', $ticket_price);
1389
+					} else {
1390
+						$existing_ticket->set($field, $value);
1391
+					}
1392
+				}
1393
+				$ticket = $existing_ticket;
1394
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1395
+				//  Otherwise we have to create a new ticket.
1396
+				if ($create_new_ticket) {
1397
+					// archive the old ticket first
1398
+					$existing_ticket->set('TKT_deleted', 1);
1399
+					$existing_ticket->save();
1400
+					// make sure this ticket is still recorded in our $saved_tickets
1401
+					// so we don't run it through the regular trash routine.
1402
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1403
+					// create new ticket that's a copy of the existing except,
1404
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1405
+					$new_ticket = clone $existing_ticket;
1406
+					$new_ticket->set('TKT_ID', 0);
1407
+					$new_ticket->set('TKT_deleted', 0);
1408
+					$new_ticket->set('TKT_sold', 0);
1409
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1410
+					$update_prices = true;
1411
+					$ticket        = $new_ticket;
1412
+				}
1413
+			} else {
1414
+				// no TKT_id so a new ticket
1415
+				$ticket_values['TKT_price'] = $ticket_price;
1416
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1417
+				$update_prices              = true;
1418
+			}
1419
+			if (! $ticket instanceof EE_Ticket) {
1420
+				throw new RuntimeException(
1421
+					sprintf(
1422
+						esc_html__(
1423
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1424
+							'event_espresso'
1425
+						),
1426
+						print_r($ticket_values, true)
1427
+					)
1428
+				);
1429
+			}
1430
+			// cap ticket qty by datetime reg limits
1431
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1432
+			// update ticket.
1433
+			$ticket->save();
1434
+			// before going any further make sure our dates are setup correctly
1435
+			// so that the end date is always equal or greater than the start date.
1436
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1437
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1438
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1439
+				$ticket->save();
1440
+			}
1441
+			// initially let's add the ticket to the datetime
1442
+			$datetime->_add_relation_to($ticket, 'Ticket');
1443
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1444
+			// add prices to ticket
1445
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1446
+				? $data['edit_prices'][ $row ]
1447
+				: [];
1448
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1449
+		}
1450
+		// however now we need to handle permanently deleting tickets via the ui.
1451
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1452
+		// However, it does allow for deleting tickets that have no tickets sold,
1453
+		// in which case we want to get rid of permanently because there is no need to save in db.
1454
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1455
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1456
+		foreach ($tickets_removed as $id) {
1457
+			$id = absint($id);
1458
+			// get the ticket for this id
1459
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1460
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1461
+				continue;
1462
+			}
1463
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1464
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1465
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1466
+			foreach ($related_datetimes as $related_datetime) {
1467
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1468
+			}
1469
+			// need to do the same for prices (except these prices can also be deleted because again,
1470
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1471
+			$ticket_to_remove->delete_related_permanently('Price');
1472
+			// finally let's delete this ticket
1473
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1474
+			$ticket_to_remove->delete_permanently();
1475
+		}
1476
+		return [$datetime, $saved_tickets];
1477
+	}
1478
+
1479
+
1480
+	/**
1481
+	 * This attaches a list of given prices to a ticket.
1482
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1483
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1484
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1485
+	 *
1486
+	 * @access  private
1487
+	 * @param array     $prices_data Array of prices from the form.
1488
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1489
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1490
+	 * @return  void
1491
+	 * @throws EE_Error
1492
+	 * @throws ReflectionException
1493
+	 */
1494
+	private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1495
+	{
1496
+		$timezone = $ticket->get_timezone();
1497
+		foreach ($prices_data as $row => $price_data) {
1498
+			$price_values = [
1499
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1500
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1501
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1502
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1503
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1504
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1505
+				'PRC_order'      => $row,
1506
+			];
1507
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1508
+				$price_values['PRC_ID'] = 0;
1509
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1510
+			} else {
1511
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1512
+				// update this price with new values
1513
+				foreach ($price_values as $field => $new_price) {
1514
+					$price->set($field, $new_price);
1515
+				}
1516
+			}
1517
+			if (! $price instanceof EE_Price) {
1518
+				throw new RuntimeException(
1519
+					sprintf(
1520
+						esc_html__(
1521
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1522
+							'event_espresso'
1523
+						),
1524
+						print_r($price_values, true)
1525
+					)
1526
+				);
1527
+			}
1528
+			$price->save();
1529
+			$ticket->_add_relation_to($price, 'Price');
1530
+		}
1531
+	}
1532
+
1533
+
1534
+	/**
1535
+	 * Add in our autosave ajax handlers
1536
+	 */
1537
+	protected function _ee_autosave_create_new()
1538
+	{
1539
+	}
1540
+
1541
+
1542
+	/**
1543
+	 * More autosave handlers.
1544
+	 */
1545
+	protected function _ee_autosave_edit()
1546
+	{
1547
+	}
1548
+
1549
+
1550
+	/**
1551
+	 * @throws EE_Error
1552
+	 * @throws ReflectionException
1553
+	 */
1554
+	private function _generate_publish_box_extra_content()
1555
+	{
1556
+		// load formatter helper
1557
+		// args for getting related registrations
1558
+		$approved_query_args        = [
1559
+			[
1560
+				'REG_deleted' => 0,
1561
+				'STS_ID'      => RegStatus::APPROVED,
1562
+			],
1563
+		];
1564
+		$not_approved_query_args    = [
1565
+			[
1566
+				'REG_deleted' => 0,
1567
+				'STS_ID'      => RegStatus::AWAITING_REVIEW,
1568
+			],
1569
+		];
1570
+		$pending_payment_query_args = [
1571
+			[
1572
+				'REG_deleted' => 0,
1573
+				'STS_ID'      => RegStatus::PENDING_PAYMENT,
1574
+			],
1575
+		];
1576
+		// publish box
1577
+		$publish_box_extra_args = [
1578
+			'view_approved_reg_url'        => add_query_arg(
1579
+				[
1580
+					'action'      => 'default',
1581
+					'event_id'    => $this->_cpt_model_obj->ID(),
1582
+					'_reg_status' => RegStatus::APPROVED,
1583
+					'use_filters' => true,
1584
+				],
1585
+				REG_ADMIN_URL
1586
+			),
1587
+			'view_not_approved_reg_url'    => add_query_arg(
1588
+				[
1589
+					'action'      => 'default',
1590
+					'event_id'    => $this->_cpt_model_obj->ID(),
1591
+					'_reg_status' => RegStatus::AWAITING_REVIEW,
1592
+					'use_filters' => true,
1593
+				],
1594
+				REG_ADMIN_URL
1595
+			),
1596
+			'view_pending_payment_reg_url' => add_query_arg(
1597
+				[
1598
+					'action'      => 'default',
1599
+					'event_id'    => $this->_cpt_model_obj->ID(),
1600
+					'_reg_status' => RegStatus::PENDING_PAYMENT,
1601
+					'use_filters' => true,
1602
+				],
1603
+				REG_ADMIN_URL
1604
+			),
1605
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1606
+				'Registration',
1607
+				$approved_query_args
1608
+			),
1609
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1610
+				'Registration',
1611
+				$not_approved_query_args
1612
+			),
1613
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1614
+				'Registration',
1615
+				$pending_payment_query_args
1616
+			),
1617
+			'misc_pub_section_class'       => apply_filters(
1618
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1619
+				'misc-pub-section'
1620
+			),
1621
+		];
1622
+		ob_start();
1623
+		do_action(
1624
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1625
+			$this->_cpt_model_obj
1626
+		);
1627
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1628
+		// load template
1629
+		EEH_Template::display_template(
1630
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1631
+			$publish_box_extra_args
1632
+		);
1633
+	}
1634
+
1635
+
1636
+	/**
1637
+	 * @return EE_Event
1638
+	 */
1639
+	public function get_event_object()
1640
+	{
1641
+		return $this->_cpt_model_obj;
1642
+	}
1643
+
1644
+
1645
+
1646
+
1647
+	/** METABOXES * */
1648
+	/**
1649
+	 * _register_event_editor_meta_boxes
1650
+	 * add all metaboxes related to the event_editor
1651
+	 *
1652
+	 * @return void
1653
+	 * @throws EE_Error
1654
+	 * @throws ReflectionException
1655
+	 */
1656
+	protected function _register_event_editor_meta_boxes()
1657
+	{
1658
+		$this->verify_cpt_object();
1659
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1660
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1661
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1662
+			$this->addMetaBox(
1663
+				'espresso_event_editor_event_options',
1664
+				esc_html__('Event Registration Options', 'event_espresso'),
1665
+				[$this, 'registration_options_meta_box'],
1666
+				$this->page_slug,
1667
+				'side'
1668
+			);
1669
+		}
1670
+		if (! $use_advanced_editor) {
1671
+			$this->addMetaBox(
1672
+				'espresso_event_editor_tickets',
1673
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1674
+				[$this, 'ticket_metabox'],
1675
+				$this->page_slug,
1676
+				'normal',
1677
+				'high'
1678
+			);
1679
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1680
+			add_action(
1681
+				'add_meta_boxes_espresso_events',
1682
+				function () {
1683
+					global $current_screen;
1684
+					remove_meta_box('authordiv', $current_screen, 'normal');
1685
+				},
1686
+				99
1687
+			);
1688
+		}
1689
+		// NOTE: if you're looking for other metaboxes in here,
1690
+		// where a metabox has a related management page in the admin
1691
+		// you will find it setup in the related management page's "_Hooks" file.
1692
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1693
+	}
1694
+
1695
+
1696
+	/**
1697
+	 * @throws DomainException
1698
+	 * @throws EE_Error
1699
+	 * @throws ReflectionException
1700
+	 */
1701
+	public function ticket_metabox()
1702
+	{
1703
+		$existing_datetime_ids = $existing_ticket_ids = [];
1704
+		// defaults for template args
1705
+		$template_args = [
1706
+			'ticket_rows'       => '',
1707
+			'total_ticket_rows' => 1,
1708
+			'trash_icon'        => 'dashicons dashicons-lock',
1709
+			'disabled'          => '',
1710
+		];
1711
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1712
+		/**
1713
+		 * 1. Start with retrieving Datetimes
1714
+		 * 2. Fore each datetime get related tickets
1715
+		 * 3. For each ticket get related prices
1716
+		 */
1717
+		/** @var EEM_Datetime $datetime_model */
1718
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1719
+		/** @var EEM_Ticket $datetime_model */
1720
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1721
+		$times        = $datetime_model->get_all_event_dates($event_id);
1722
+		/** @type EE_Datetime $first_datetime */
1723
+		$first_datetime = reset($times);
1724
+		// do we get related tickets?
1725
+		if (
1726
+			$first_datetime instanceof EE_Datetime
1727
+			&& $first_datetime->ID() !== 0
1728
+		) {
1729
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1730
+			$template_args['time']   = $first_datetime;
1731
+			$related_tickets         = $first_datetime->tickets(
1732
+				[
1733
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1734
+					'default_where_conditions' => 'none',
1735
+				]
1736
+			);
1737
+			if (! empty($related_tickets)) {
1738
+				$template_args['total_ticket_rows'] = count($related_tickets);
1739
+				$row                                = 0;
1740
+				foreach ($related_tickets as $ticket) {
1741
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1742
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1743
+					$row++;
1744
+				}
1745
+			} else {
1746
+				$template_args['total_ticket_rows'] = 1;
1747
+				/** @type EE_Ticket $ticket */
1748
+				$ticket                       = $ticket_model->create_default_object();
1749
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1750
+			}
1751
+		} else {
1752
+			$template_args['time'] = $times[0];
1753
+			/** @type EE_Ticket[] $tickets */
1754
+			$tickets                      = $ticket_model->get_all_default_tickets();
1755
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1756
+			// NOTE: we're just sending the first default row
1757
+			// (decaf can't manage default tickets so this should be sufficient);
1758
+		}
1759
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1760
+			'event_editor_event_datetimes_help_tab'
1761
+		);
1762
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1763
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1764
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1765
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1766
+			$ticket_model->create_default_object(),
1767
+			true
1768
+		);
1769
+		$template                                  = apply_filters(
1770
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1771
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1772
+		);
1773
+		EEH_Template::display_template($template, $template_args);
1774
+	}
1775
+
1776
+
1777
+	/**
1778
+	 * Setup an individual ticket form for the decaf event editor page
1779
+	 *
1780
+	 * @access private
1781
+	 * @param EE_Ticket $ticket   the ticket object
1782
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1783
+	 * @param int       $row
1784
+	 * @return string generated html for the ticket row.
1785
+	 * @throws EE_Error
1786
+	 * @throws ReflectionException
1787
+	 */
1788
+	private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1789
+	{
1790
+		$template_args = [
1791
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1792
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1793
+				: '',
1794
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1795
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1796
+			'TKT_name'            => $ticket->get('TKT_name'),
1797
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1798
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1799
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1800
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1801
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1802
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1803
+			'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1804
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1805
+				? 'dashicons dashicons-post-trash clickable'
1806
+				: 'dashicons dashicons-lock',
1807
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1808
+				: ' disabled=disabled',
1809
+		];
1810
+		$price         = $ticket->ID() !== 0
1811
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1812
+			: null;
1813
+		$price         = $price instanceof EE_Price
1814
+			? $price
1815
+			: EEM_Price::instance()->create_default_object();
1816
+		$price_args    = [
1817
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1818
+			'PRC_amount'            => $price->get('PRC_amount'),
1819
+			'PRT_ID'                => $price->get('PRT_ID'),
1820
+			'PRC_ID'                => $price->get('PRC_ID'),
1821
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1822
+		];
1823
+		// make sure we have default start and end dates if skeleton
1824
+		// handle rows that should NOT be empty
1825
+		if (empty($template_args['TKT_start_date'])) {
1826
+			// if empty then the start date will be now.
1827
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1828
+		}
1829
+		if (empty($template_args['TKT_end_date'])) {
1830
+			// get the earliest datetime (if present);
1831
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1832
+				? $this->_cpt_model_obj->get_first_related(
1833
+					'Datetime',
1834
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1835
+				)
1836
+				: null;
1837
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1838
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1839
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1840
+		}
1841
+		$template_args = array_merge($template_args, $price_args);
1842
+		$template      = apply_filters(
1843
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1844
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1845
+			$ticket
1846
+		);
1847
+		return EEH_Template::display_template($template, $template_args, true);
1848
+	}
1849
+
1850
+
1851
+	/**
1852
+	 * @throws EE_Error
1853
+	 * @throws ReflectionException
1854
+	 */
1855
+	public function registration_options_meta_box()
1856
+	{
1857
+		$yes_no_values             = [
1858
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1859
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1860
+		];
1861
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1862
+			[
1863
+				RegStatus::CANCELLED,
1864
+				RegStatus::DECLINED,
1865
+				RegStatus::INCOMPLETE,
1866
+			],
1867
+			true
1868
+		);
1869
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1870
+		$template_args['_event']                          = $this->_cpt_model_obj;
1871
+		$template_args['event']                           = $this->_cpt_model_obj;
1872
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1873
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1874
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1875
+			'default_reg_status',
1876
+			$default_reg_status_values,
1877
+			$this->_cpt_model_obj->default_registration_status(),
1878
+			'',
1879
+			'ee-input-width--reg',
1880
+			false
1881
+		);
1882
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1883
+			'display_desc',
1884
+			$yes_no_values,
1885
+			$this->_cpt_model_obj->display_description()
1886
+		);
1887
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1888
+			'display_ticket_selector',
1889
+			$yes_no_values,
1890
+			$this->_cpt_model_obj->display_ticket_selector(),
1891
+			'',
1892
+			'ee-input-width--small',
1893
+			false
1894
+		);
1895
+		$template_args['additional_registration_options'] = apply_filters(
1896
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1897
+			'',
1898
+			$template_args,
1899
+			$yes_no_values,
1900
+			$default_reg_status_values
1901
+		);
1902
+		EEH_Template::display_template(
1903
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1904
+			$template_args
1905
+		);
1906
+	}
1907
+
1908
+
1909
+	/**
1910
+	 * _get_events()
1911
+	 * This method simply returns all the events (for the given _view and paging)
1912
+	 *
1913
+	 * @access public
1914
+	 * @param int  $per_page     count of items per page (20 default);
1915
+	 * @param int  $current_page what is the current page being viewed.
1916
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1917
+	 *                           If FALSE then we return an array of event objects
1918
+	 *                           that match the given _view and paging parameters.
1919
+	 * @return array|int         an array of event objects or a count of them.
1920
+	 * @throws Exception
1921
+	 */
1922
+	public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1923
+	{
1924
+		$EEM_Event   = $this->_event_model();
1925
+		$offset      = ($current_page - 1) * $per_page;
1926
+		$limit       = $count ? null : $offset . ',' . $per_page;
1927
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1928
+		$order       = $this->request->getRequestParam('order', 'DESC');
1929
+		$month_range = $this->request->getRequestParam('month_range');
1930
+		if ($month_range) {
1931
+			$pieces = explode(' ', $month_range, 3);
1932
+			// simulate the FIRST day of the month, that fixes issues for months like February
1933
+			// where PHP doesn't know what to assume for date.
1934
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1935
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1936
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1937
+		}
1938
+		$where  = [];
1939
+		$status = $this->request->getRequestParam('status');
1940
+		// determine what post_status our condition will have for the query.
1941
+		switch ($status) {
1942
+			case 'month':
1943
+			case 'today':
1944
+			case null:
1945
+			case 'all':
1946
+				break;
1947
+			case 'draft':
1948
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1949
+				break;
1950
+			default:
1951
+				$where['status'] = $status;
1952
+		}
1953
+		// categories? The default for all categories is -1
1954
+		$category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1955
+		if ($category !== -1) {
1956
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1957
+			$where['Term_Taxonomy.term_id']  = $category;
1958
+		}
1959
+		// date where conditions
1960
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1961
+		if ($month_range) {
1962
+			$DateTime = new DateTime(
1963
+				$year_r . '-' . $month_r . '-01 00:00:00',
1964
+				new DateTimeZone('UTC')
1965
+			);
1966
+			$start    = $DateTime->getTimestamp();
1967
+			// set the datetime to be the end of the month
1968
+			$DateTime->setDate(
1969
+				$year_r,
1970
+				$month_r,
1971
+				$DateTime->format('t')
1972
+			)->setTime(23, 59, 59);
1973
+			$end                             = $DateTime->getTimestamp();
1974
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1975
+		} elseif ($status === 'today') {
1976
+			$DateTime                        = new DateTime(
1977
+				'now',
1978
+				new DateTimeZone(EEM_Event::instance()->get_timezone())
1979
+			);
1980
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1981
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1982
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1983
+		} elseif ($status === 'month') {
1984
+			$now                             = date('Y-m-01');
1985
+			$DateTime                        = new DateTime(
1986
+				$now,
1987
+				new DateTimeZone(EEM_Event::instance()->get_timezone())
1988
+			);
1989
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1990
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1991
+														->setTime(23, 59, 59)
1992
+														->format(implode(' ', $start_formats));
1993
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1994
+		}
1995
+		if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1996
+			$where['EVT_wp_user'] = get_current_user_id();
1997
+		} else {
1998
+			if (! isset($where['status'])) {
1999
+				if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
2000
+					$where['OR'] = [
2001
+						'status*restrict_private' => ['!=', 'private'],
2002
+						'AND'                     => [
2003
+							'status*inclusive' => ['=', 'private'],
2004
+							'EVT_wp_user'      => get_current_user_id(),
2005
+						],
2006
+					];
2007
+				}
2008
+			}
2009
+		}
2010
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2011
+		if (
2012
+			$wp_user
2013
+			&& $wp_user !== get_current_user_id()
2014
+			&& $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2015
+		) {
2016
+			$where['EVT_wp_user'] = $wp_user;
2017
+		}
2018
+		// search query handling
2019
+		$search_term = $this->request->getRequestParam('s');
2020
+		if ($search_term) {
2021
+			$search_term = '%' . $search_term . '%';
2022
+			$where['OR'] = [
2023
+				'EVT_name'       => ['LIKE', $search_term],
2024
+				'EVT_desc'       => ['LIKE', $search_term],
2025
+				'EVT_short_desc' => ['LIKE', $search_term],
2026
+			];
2027
+		}
2028
+		// filter events by venue.
2029
+		$venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2030
+		if ($venue) {
2031
+			$where['Venue.VNU_ID'] = $venue;
2032
+		}
2033
+		$request_params = $this->request->requestParams();
2034
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2035
+		$query_params   = apply_filters(
2036
+			'FHEE__Events_Admin_Page__get_events__query_params',
2037
+			[
2038
+				$where,
2039
+				'limit'    => $limit,
2040
+				'order_by' => $orderby,
2041
+				'order'    => $order,
2042
+				'group_by' => 'EVT_ID',
2043
+			],
2044
+			$request_params
2045
+		);
2046
+
2047
+		// let's first check if we have special requests coming in.
2048
+		$active_status = $this->request->getRequestParam('active_status');
2049
+		if ($active_status) {
2050
+			switch ($active_status) {
2051
+				case 'upcoming':
2052
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2053
+				case 'expired':
2054
+					return $EEM_Event->get_expired_events($query_params, $count);
2055
+				case 'active':
2056
+					return $EEM_Event->get_active_events($query_params, $count);
2057
+				case 'inactive':
2058
+					return $EEM_Event->get_inactive_events($query_params, $count);
2059
+			}
2060
+		}
2061
+
2062
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2063
+	}
2064
+
2065
+
2066
+	/**
2067
+	 * handling for WordPress CPT actions (trash, restore, delete)
2068
+	 *
2069
+	 * @param string $post_id
2070
+	 * @throws EE_Error
2071
+	 * @throws ReflectionException
2072
+	 */
2073
+	public function trash_cpt_item($post_id)
2074
+	{
2075
+		$this->request->setRequestParam('EVT_ID', $post_id);
2076
+		$this->_trash_or_restore_event('trash', false);
2077
+	}
2078
+
2079
+
2080
+	/**
2081
+	 * @param string $post_id
2082
+	 * @throws EE_Error
2083
+	 * @throws ReflectionException
2084
+	 */
2085
+	public function restore_cpt_item($post_id)
2086
+	{
2087
+		$this->request->setRequestParam('EVT_ID', $post_id);
2088
+		$this->_trash_or_restore_event('draft', false);
2089
+	}
2090
+
2091
+
2092
+	/**
2093
+	 * @param string $post_id
2094
+	 * @throws EE_Error
2095
+	 * @throws EE_Error
2096
+	 */
2097
+	public function delete_cpt_item($post_id)
2098
+	{
2099
+		throw new EE_Error(
2100
+			esc_html__(
2101
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2102
+				'event_espresso'
2103
+			)
2104
+		);
2105
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2106
+		// $this->_delete_event();
2107
+	}
2108
+
2109
+
2110
+	/**
2111
+	 * _trash_or_restore_event
2112
+	 *
2113
+	 * @access protected
2114
+	 * @param string $event_status
2115
+	 * @param bool   $redirect_after
2116
+	 * @throws EE_Error
2117
+	 * @throws EE_Error
2118
+	 * @throws ReflectionException
2119
+	 */
2120
+	protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2121
+	{
2122
+		// loop thru events
2123
+		if ($this->EVT_ID) {
2124
+			// clean status
2125
+			$event_status = sanitize_key($event_status);
2126
+			// grab status
2127
+			if (! empty($event_status)) {
2128
+				$success = $this->_change_event_status($this->EVT_ID, $event_status);
2129
+			} else {
2130
+				$success = false;
2131
+				$msg     = esc_html__(
2132
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2133
+					'event_espresso'
2134
+				);
2135
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2136
+			}
2137
+		} else {
2138
+			$success = false;
2139
+			$msg     = esc_html__(
2140
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2141
+				'event_espresso'
2142
+			);
2143
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2144
+		}
2145
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2146
+		if ($redirect_after) {
2147
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2148
+		}
2149
+	}
2150
+
2151
+
2152
+	/**
2153
+	 * _trash_or_restore_events
2154
+	 *
2155
+	 * @access protected
2156
+	 * @param string $event_status
2157
+	 * @return void
2158
+	 * @throws EE_Error
2159
+	 * @throws EE_Error
2160
+	 * @throws ReflectionException
2161
+	 */
2162
+	protected function _trash_or_restore_events(string $event_status = 'trash')
2163
+	{
2164
+		// clean status
2165
+		$event_status = sanitize_key($event_status);
2166
+		// grab status
2167
+		if (! empty($event_status)) {
2168
+			$success = true;
2169
+			// determine the event id and set to array.
2170
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2171
+			// loop thru events
2172
+			foreach ($EVT_IDs as $EVT_ID) {
2173
+				if ($EVT_ID = absint($EVT_ID)) {
2174
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2175
+					$success = $results !== false ? $success : false;
2176
+				} else {
2177
+					$msg = sprintf(
2178
+						esc_html__(
2179
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2180
+							'event_espresso'
2181
+						),
2182
+						$EVT_ID
2183
+					);
2184
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
+					$success = false;
2186
+				}
2187
+			}
2188
+		} else {
2189
+			$success = false;
2190
+			$msg     = esc_html__(
2191
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2192
+				'event_espresso'
2193
+			);
2194
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2195
+		}
2196
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2197
+		$success = $success ? 2 : false;
2198
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2199
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2200
+	}
2201
+
2202
+
2203
+	/**
2204
+	 * @param int    $EVT_ID
2205
+	 * @param string $event_status
2206
+	 * @return bool
2207
+	 * @throws EE_Error
2208
+	 * @throws ReflectionException
2209
+	 */
2210
+	private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2211
+	{
2212
+		// grab event id
2213
+		if (! $EVT_ID) {
2214
+			$msg = esc_html__(
2215
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2216
+				'event_espresso'
2217
+			);
2218
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2219
+			return false;
2220
+		}
2221
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2222
+		// clean status
2223
+		$event_status = sanitize_key($event_status);
2224
+		// grab status
2225
+		if (empty($event_status)) {
2226
+			$msg = esc_html__(
2227
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2228
+				'event_espresso'
2229
+			);
2230
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2231
+			return false;
2232
+		}
2233
+		// was event trashed or restored ?
2234
+		switch ($event_status) {
2235
+			case 'draft':
2236
+				$action = 'restored from the trash';
2237
+				$hook   = 'AHEE_event_restored_from_trash';
2238
+				break;
2239
+			case 'trash':
2240
+				$action = 'moved to the trash';
2241
+				$hook   = 'AHEE_event_moved_to_trash';
2242
+				break;
2243
+			default:
2244
+				$action = 'updated';
2245
+				$hook   = false;
2246
+		}
2247
+		// use class to change status
2248
+		$this->_cpt_model_obj->set_status($event_status);
2249
+		$success = $this->_cpt_model_obj->save();
2250
+		if (! $success) {
2251
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2252
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2253
+			return false;
2254
+		}
2255
+		if ($hook) {
2256
+			do_action($hook);
2257
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2258
+			// because events side step that and it otherwise won't get called
2259
+			do_action(
2260
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2261
+				$this->_cpt_model_obj,
2262
+				$hook === 'AHEE_event_moved_to_trash',
2263
+				$success
2264
+			);
2265
+		}
2266
+		return true;
2267
+	}
2268
+
2269
+
2270
+	/**
2271
+	 * @param array $event_ids
2272
+	 * @return array
2273
+	 * @since   4.10.23.p
2274
+	 */
2275
+	private function cleanEventIds(array $event_ids): array
2276
+	{
2277
+		return array_map('absint', $event_ids);
2278
+	}
2279
+
2280
+
2281
+	/**
2282
+	 * @return array
2283
+	 * @since   4.10.23.p
2284
+	 */
2285
+	private function getEventIdsFromRequest(): array
2286
+	{
2287
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2288
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2289
+		} else {
2290
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2291
+		}
2292
+	}
2293
+
2294
+
2295
+	/**
2296
+	 * @param bool $preview_delete
2297
+	 * @throws EE_Error
2298
+	 * @throws ReflectionException
2299
+	 */
2300
+	protected function _delete_event(bool $preview_delete = true)
2301
+	{
2302
+		$this->_delete_events($preview_delete);
2303
+	}
2304
+
2305
+
2306
+	/**
2307
+	 * Gets the tree traversal batch persister.
2308
+	 *
2309
+	 * @return NodeGroupDao
2310
+	 * @throws InvalidArgumentException
2311
+	 * @throws InvalidDataTypeException
2312
+	 * @throws InvalidInterfaceException
2313
+	 * @since 4.10.12.p
2314
+	 */
2315
+	protected function getModelObjNodeGroupPersister(): NodeGroupDao
2316
+	{
2317
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2318
+			$this->model_obj_node_group_persister =
2319
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2320
+		}
2321
+		return $this->model_obj_node_group_persister;
2322
+	}
2323
+
2324
+
2325
+	/**
2326
+	 * @param bool $preview_delete
2327
+	 * @return void
2328
+	 * @throws EE_Error
2329
+	 * @throws ReflectionException
2330
+	 */
2331
+	protected function _delete_events(bool $preview_delete = true)
2332
+	{
2333
+		$event_ids = $this->getEventIdsFromRequest();
2334
+		if ($preview_delete) {
2335
+			$this->generateDeletionPreview($event_ids);
2336
+		} else {
2337
+			foreach ($event_ids as $event_id) {
2338
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2339
+				if ($event instanceof EE_Event) {
2340
+					$event->delete_permanently();
2341
+				}
2342
+			}
2343
+		}
2344
+	}
2345
+
2346
+
2347
+	/**
2348
+	 * @param array $event_ids
2349
+	 */
2350
+	protected function generateDeletionPreview(array $event_ids)
2351
+	{
2352
+		$event_ids = $this->cleanEventIds($event_ids);
2353
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2354
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2355
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2356
+			[
2357
+				'action'            => 'preview_deletion',
2358
+				'deletion_job_code' => $deletion_job_code,
2359
+			],
2360
+			$this->_admin_base_url
2361
+		);
2362
+		EEH_URL::safeRedirectAndExit(
2363
+			EE_Admin_Page::add_query_args_and_nonce(
2364
+				[
2365
+					'page'              => EED_Batch::PAGE_SLUG,
2366
+					'batch'             => EED_Batch::batch_job,
2367
+					'EVT_IDs'           => $event_ids,
2368
+					'deletion_job_code' => $deletion_job_code,
2369
+					'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2370
+					'return_url'        => urlencode($return_url),
2371
+				],
2372
+				admin_url()
2373
+			)
2374
+		);
2375
+	}
2376
+
2377
+
2378
+	/**
2379
+	 * Checks for a POST submission
2380
+	 *
2381
+	 * @since 4.10.12.p
2382
+	 */
2383
+	protected function confirmDeletion()
2384
+	{
2385
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2386
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2387
+		);
2388
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2389
+	}
2390
+
2391
+
2392
+	/**
2393
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2394
+	 *
2395
+	 * @throws EE_Error
2396
+	 * @since 4.10.12.p
2397
+	 */
2398
+	protected function previewDeletion()
2399
+	{
2400
+		$preview_deletion_logic = $this->getLoader()->getShared(
2401
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2402
+		);
2403
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2404
+		$this->display_admin_page_with_no_sidebar();
2405
+	}
2406
+
2407
+
2408
+	/**
2409
+	 * get total number of events
2410
+	 *
2411
+	 * @access public
2412
+	 * @return int
2413
+	 * @throws EE_Error
2414
+	 * @throws EE_Error
2415
+	 * @throws ReflectionException
2416
+	 */
2417
+	public function total_events(): int
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
+	 * @throws ReflectionException
2435
+	 */
2436
+	public function total_events_draft(): int
2437
+	{
2438
+		return EEM_Event::instance()->count(
2439
+			[
2440
+				['status' => ['IN', ['draft', 'auto-draft']]],
2441
+				'caps' => 'read_admin',
2442
+			],
2443
+			'EVT_ID',
2444
+			true
2445
+		);
2446
+	}
2447
+
2448
+
2449
+	/**
2450
+	 * get total number of trashed events
2451
+	 *
2452
+	 * @access public
2453
+	 * @return int
2454
+	 * @throws EE_Error
2455
+	 * @throws EE_Error
2456
+	 * @throws ReflectionException
2457
+	 */
2458
+	public function total_trashed_events(): int
2459
+	{
2460
+		return EEM_Event::instance()->count(
2461
+			[
2462
+				['status' => 'trash'],
2463
+				'caps' => 'read_admin',
2464
+			],
2465
+			'EVT_ID',
2466
+			true
2467
+		);
2468
+	}
2469
+
2470
+
2471
+	/**
2472
+	 *    _default_event_settings
2473
+	 *    This generates the Default Settings Tab
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
+	protected function _default_event_settings()
2484
+	{
2485
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2486
+		$this->_set_publish_post_box_vars();
2487
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
2488
+			$this->_default_event_settings_form()->get_html(),
2489
+			'',
2490
+			'padding'
2491
+		);
2492
+		$this->display_admin_page_with_sidebar();
2493
+	}
2494
+
2495
+
2496
+	/**
2497
+	 * Return the form for event settings.
2498
+	 *
2499
+	 * @return EE_Form_Section_Proper
2500
+	 * @throws EE_Error
2501
+	 * @throws ReflectionException
2502
+	 */
2503
+	protected function _default_event_settings_form(): EE_Form_Section_Proper
2504
+	{
2505
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2506
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2507
+		// exclude
2508
+			[
2509
+				RegStatus::CANCELLED,
2510
+				RegStatus::DECLINED,
2511
+				RegStatus::INCOMPLETE,
2512
+				RegStatus::WAIT_LIST,
2513
+			],
2514
+			true
2515
+		);
2516
+		// setup Advanced Editor ???
2517
+		if (
2518
+			$this->raw_req_action === 'default_event_settings'
2519
+			|| $this->raw_req_action === 'update_default_event_settings'
2520
+		) {
2521
+			$this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2522
+		}
2523
+		return new EE_Form_Section_Proper(
2524
+			[
2525
+				'name'            => 'update_default_event_settings',
2526
+				'html_id'         => 'update_default_event_settings',
2527
+				'html_class'      => 'form-table',
2528
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2529
+				'subsections'     => apply_filters(
2530
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2531
+					[
2532
+						'defaults_section_header' => new EE_Form_Section_HTML(
2533
+							EEH_HTML::h2(
2534
+								esc_html__('Default Settings', 'event_espresso'),
2535
+								'',
2536
+								'ee-admin-settings-hdr'
2537
+							)
2538
+						),
2539
+						'default_reg_status'      => new EE_Select_Input(
2540
+							$registration_stati_for_selection,
2541
+							[
2542
+								'default'         => isset($registration_config->default_STS_ID)
2543
+													 && array_key_exists(
2544
+														 $registration_config->default_STS_ID,
2545
+														 $registration_stati_for_selection
2546
+													 )
2547
+									? sanitize_text_field($registration_config->default_STS_ID)
2548
+									: RegStatus::PENDING_PAYMENT,
2549
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2550
+													 . EEH_Template::get_help_tab_link(
2551
+										'default_settings_status_help_tab'
2552
+									),
2553
+								'html_help_text'  => esc_html__(
2554
+									'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.',
2555
+									'event_espresso'
2556
+								),
2557
+								'html_class'      => 'ee-input-width--small',
2558
+							]
2559
+						),
2560
+						'default_max_tickets'     => new EE_Integer_Input(
2561
+							[
2562
+								'default'         => $registration_config->default_maximum_number_of_tickets
2563
+													 ?? EEM_Event::get_default_additional_limit(),
2564
+								'html_label_text' => esc_html__(
2565
+														 'Default Maximum Tickets Allowed Per Order:',
2566
+														 'event_espresso'
2567
+													 )
2568
+													 . EEH_Template::get_help_tab_link(
2569
+										'default_maximum_tickets_help_tab"'
2570
+									),
2571
+								'html_help_text'  => esc_html__(
2572
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2573
+									'event_espresso'
2574
+								),
2575
+								'html_class'      => 'ee-input-width--tiny',
2576
+							]
2577
+						),
2578
+					]
2579
+				),
2580
+			]
2581
+		);
2582
+	}
2583
+
2584
+
2585
+	/**
2586
+	 * @return void
2587
+	 * @throws EE_Error
2588
+	 * @throws InvalidArgumentException
2589
+	 * @throws InvalidDataTypeException
2590
+	 * @throws InvalidInterfaceException
2591
+	 * @throws ReflectionException
2592
+	 */
2593
+	protected function _update_default_event_settings()
2594
+	{
2595
+		$form = $this->_default_event_settings_form();
2596
+		if ($form->was_submitted()) {
2597
+			$form->receive_form_submission();
2598
+			if ($form->is_valid()) {
2599
+				$registration_config = EE_Registry::instance()->CFG->registration;
2600
+				$valid_data          = $form->valid_data();
2601
+				if (isset($valid_data['default_reg_status'])) {
2602
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2603
+				}
2604
+				if (isset($valid_data['default_max_tickets'])) {
2605
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2606
+				}
2607
+				do_action(
2608
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2609
+					$valid_data,
2610
+					EE_Registry::instance()->CFG,
2611
+					$this
2612
+				);
2613
+				// update because data was valid!
2614
+				EE_Registry::instance()->CFG->update_espresso_config();
2615
+				EE_Error::overwrite_success();
2616
+				EE_Error::add_success(
2617
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2618
+				);
2619
+			}
2620
+		}
2621
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2622
+	}
2623
+
2624
+
2625
+	/*************        Templates        *************
1779 2626
      *
1780
-     * @access private
1781
-     * @param EE_Ticket $ticket   the ticket object
1782
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1783
-     * @param int       $row
1784
-     * @return string generated html for the ticket row.
1785
-     * @throws EE_Error
1786
-     * @throws ReflectionException
1787
-     */
1788
-    private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1789
-    {
1790
-        $template_args = [
1791
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1792
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1793
-                : '',
1794
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1795
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1796
-            'TKT_name'            => $ticket->get('TKT_name'),
1797
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1798
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1799
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1800
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1801
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1802
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1803
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1804
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1805
-                ? 'dashicons dashicons-post-trash clickable'
1806
-                : 'dashicons dashicons-lock',
1807
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1808
-                : ' disabled=disabled',
1809
-        ];
1810
-        $price         = $ticket->ID() !== 0
1811
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1812
-            : null;
1813
-        $price         = $price instanceof EE_Price
1814
-            ? $price
1815
-            : EEM_Price::instance()->create_default_object();
1816
-        $price_args    = [
1817
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1818
-            'PRC_amount'            => $price->get('PRC_amount'),
1819
-            'PRT_ID'                => $price->get('PRT_ID'),
1820
-            'PRC_ID'                => $price->get('PRC_ID'),
1821
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1822
-        ];
1823
-        // make sure we have default start and end dates if skeleton
1824
-        // handle rows that should NOT be empty
1825
-        if (empty($template_args['TKT_start_date'])) {
1826
-            // if empty then the start date will be now.
1827
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1828
-        }
1829
-        if (empty($template_args['TKT_end_date'])) {
1830
-            // get the earliest datetime (if present);
1831
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1832
-                ? $this->_cpt_model_obj->get_first_related(
1833
-                    'Datetime',
1834
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1835
-                )
1836
-                : null;
1837
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1838
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1839
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1840
-        }
1841
-        $template_args = array_merge($template_args, $price_args);
1842
-        $template      = apply_filters(
1843
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1844
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1845
-            $ticket
1846
-        );
1847
-        return EEH_Template::display_template($template, $template_args, true);
1848
-    }
1849
-
1850
-
1851
-    /**
1852
-     * @throws EE_Error
1853
-     * @throws ReflectionException
1854
-     */
1855
-    public function registration_options_meta_box()
1856
-    {
1857
-        $yes_no_values             = [
1858
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1859
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1860
-        ];
1861
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1862
-            [
1863
-                RegStatus::CANCELLED,
1864
-                RegStatus::DECLINED,
1865
-                RegStatus::INCOMPLETE,
1866
-            ],
1867
-            true
1868
-        );
1869
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1870
-        $template_args['_event']                          = $this->_cpt_model_obj;
1871
-        $template_args['event']                           = $this->_cpt_model_obj;
1872
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1873
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1874
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1875
-            'default_reg_status',
1876
-            $default_reg_status_values,
1877
-            $this->_cpt_model_obj->default_registration_status(),
1878
-            '',
1879
-            'ee-input-width--reg',
1880
-            false
1881
-        );
1882
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1883
-            'display_desc',
1884
-            $yes_no_values,
1885
-            $this->_cpt_model_obj->display_description()
1886
-        );
1887
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1888
-            'display_ticket_selector',
1889
-            $yes_no_values,
1890
-            $this->_cpt_model_obj->display_ticket_selector(),
1891
-            '',
1892
-            'ee-input-width--small',
1893
-            false
1894
-        );
1895
-        $template_args['additional_registration_options'] = apply_filters(
1896
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1897
-            '',
1898
-            $template_args,
1899
-            $yes_no_values,
1900
-            $default_reg_status_values
1901
-        );
1902
-        EEH_Template::display_template(
1903
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1904
-            $template_args
1905
-        );
1906
-    }
1907
-
1908
-
1909
-    /**
1910
-     * _get_events()
1911
-     * This method simply returns all the events (for the given _view and paging)
1912
-     *
1913
-     * @access public
1914
-     * @param int  $per_page     count of items per page (20 default);
1915
-     * @param int  $current_page what is the current page being viewed.
1916
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1917
-     *                           If FALSE then we return an array of event objects
1918
-     *                           that match the given _view and paging parameters.
1919
-     * @return array|int         an array of event objects or a count of them.
1920
-     * @throws Exception
1921
-     */
1922
-    public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1923
-    {
1924
-        $EEM_Event   = $this->_event_model();
1925
-        $offset      = ($current_page - 1) * $per_page;
1926
-        $limit       = $count ? null : $offset . ',' . $per_page;
1927
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1928
-        $order       = $this->request->getRequestParam('order', 'DESC');
1929
-        $month_range = $this->request->getRequestParam('month_range');
1930
-        if ($month_range) {
1931
-            $pieces = explode(' ', $month_range, 3);
1932
-            // simulate the FIRST day of the month, that fixes issues for months like February
1933
-            // where PHP doesn't know what to assume for date.
1934
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1935
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1936
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1937
-        }
1938
-        $where  = [];
1939
-        $status = $this->request->getRequestParam('status');
1940
-        // determine what post_status our condition will have for the query.
1941
-        switch ($status) {
1942
-            case 'month':
1943
-            case 'today':
1944
-            case null:
1945
-            case 'all':
1946
-                break;
1947
-            case 'draft':
1948
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1949
-                break;
1950
-            default:
1951
-                $where['status'] = $status;
1952
-        }
1953
-        // categories? The default for all categories is -1
1954
-        $category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1955
-        if ($category !== -1) {
1956
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1957
-            $where['Term_Taxonomy.term_id']  = $category;
1958
-        }
1959
-        // date where conditions
1960
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1961
-        if ($month_range) {
1962
-            $DateTime = new DateTime(
1963
-                $year_r . '-' . $month_r . '-01 00:00:00',
1964
-                new DateTimeZone('UTC')
1965
-            );
1966
-            $start    = $DateTime->getTimestamp();
1967
-            // set the datetime to be the end of the month
1968
-            $DateTime->setDate(
1969
-                $year_r,
1970
-                $month_r,
1971
-                $DateTime->format('t')
1972
-            )->setTime(23, 59, 59);
1973
-            $end                             = $DateTime->getTimestamp();
1974
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1975
-        } elseif ($status === 'today') {
1976
-            $DateTime                        = new DateTime(
1977
-                'now',
1978
-                new DateTimeZone(EEM_Event::instance()->get_timezone())
1979
-            );
1980
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1981
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1982
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1983
-        } elseif ($status === 'month') {
1984
-            $now                             = date('Y-m-01');
1985
-            $DateTime                        = new DateTime(
1986
-                $now,
1987
-                new DateTimeZone(EEM_Event::instance()->get_timezone())
1988
-            );
1989
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1990
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1991
-                                                        ->setTime(23, 59, 59)
1992
-                                                        ->format(implode(' ', $start_formats));
1993
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1994
-        }
1995
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1996
-            $where['EVT_wp_user'] = get_current_user_id();
1997
-        } else {
1998
-            if (! isset($where['status'])) {
1999
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
2000
-                    $where['OR'] = [
2001
-                        'status*restrict_private' => ['!=', 'private'],
2002
-                        'AND'                     => [
2003
-                            'status*inclusive' => ['=', 'private'],
2004
-                            'EVT_wp_user'      => get_current_user_id(),
2005
-                        ],
2006
-                    ];
2007
-                }
2008
-            }
2009
-        }
2010
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2011
-        if (
2012
-            $wp_user
2013
-            && $wp_user !== get_current_user_id()
2014
-            && $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2015
-        ) {
2016
-            $where['EVT_wp_user'] = $wp_user;
2017
-        }
2018
-        // search query handling
2019
-        $search_term = $this->request->getRequestParam('s');
2020
-        if ($search_term) {
2021
-            $search_term = '%' . $search_term . '%';
2022
-            $where['OR'] = [
2023
-                'EVT_name'       => ['LIKE', $search_term],
2024
-                'EVT_desc'       => ['LIKE', $search_term],
2025
-                'EVT_short_desc' => ['LIKE', $search_term],
2026
-            ];
2027
-        }
2028
-        // filter events by venue.
2029
-        $venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2030
-        if ($venue) {
2031
-            $where['Venue.VNU_ID'] = $venue;
2032
-        }
2033
-        $request_params = $this->request->requestParams();
2034
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2035
-        $query_params   = apply_filters(
2036
-            'FHEE__Events_Admin_Page__get_events__query_params',
2037
-            [
2038
-                $where,
2039
-                'limit'    => $limit,
2040
-                'order_by' => $orderby,
2041
-                'order'    => $order,
2042
-                'group_by' => 'EVT_ID',
2043
-            ],
2044
-            $request_params
2045
-        );
2046
-
2047
-        // let's first check if we have special requests coming in.
2048
-        $active_status = $this->request->getRequestParam('active_status');
2049
-        if ($active_status) {
2050
-            switch ($active_status) {
2051
-                case 'upcoming':
2052
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2053
-                case 'expired':
2054
-                    return $EEM_Event->get_expired_events($query_params, $count);
2055
-                case 'active':
2056
-                    return $EEM_Event->get_active_events($query_params, $count);
2057
-                case 'inactive':
2058
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2059
-            }
2060
-        }
2061
-
2062
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2063
-    }
2064
-
2065
-
2066
-    /**
2067
-     * handling for WordPress CPT actions (trash, restore, delete)
2068
-     *
2069
-     * @param string $post_id
2070
-     * @throws EE_Error
2071
-     * @throws ReflectionException
2072
-     */
2073
-    public function trash_cpt_item($post_id)
2074
-    {
2075
-        $this->request->setRequestParam('EVT_ID', $post_id);
2076
-        $this->_trash_or_restore_event('trash', false);
2077
-    }
2078
-
2079
-
2080
-    /**
2081
-     * @param string $post_id
2082
-     * @throws EE_Error
2083
-     * @throws ReflectionException
2084
-     */
2085
-    public function restore_cpt_item($post_id)
2086
-    {
2087
-        $this->request->setRequestParam('EVT_ID', $post_id);
2088
-        $this->_trash_or_restore_event('draft', false);
2089
-    }
2090
-
2091
-
2092
-    /**
2093
-     * @param string $post_id
2094
-     * @throws EE_Error
2095
-     * @throws EE_Error
2096
-     */
2097
-    public function delete_cpt_item($post_id)
2098
-    {
2099
-        throw new EE_Error(
2100
-            esc_html__(
2101
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2102
-                'event_espresso'
2103
-            )
2104
-        );
2105
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2106
-        // $this->_delete_event();
2107
-    }
2108
-
2109
-
2110
-    /**
2111
-     * _trash_or_restore_event
2112
-     *
2113
-     * @access protected
2114
-     * @param string $event_status
2115
-     * @param bool   $redirect_after
2116
-     * @throws EE_Error
2117
-     * @throws EE_Error
2118
-     * @throws ReflectionException
2119
-     */
2120
-    protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2121
-    {
2122
-        // loop thru events
2123
-        if ($this->EVT_ID) {
2124
-            // clean status
2125
-            $event_status = sanitize_key($event_status);
2126
-            // grab status
2127
-            if (! empty($event_status)) {
2128
-                $success = $this->_change_event_status($this->EVT_ID, $event_status);
2129
-            } else {
2130
-                $success = false;
2131
-                $msg     = esc_html__(
2132
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2133
-                    'event_espresso'
2134
-                );
2135
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2136
-            }
2137
-        } else {
2138
-            $success = false;
2139
-            $msg     = esc_html__(
2140
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2141
-                'event_espresso'
2142
-            );
2143
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2144
-        }
2145
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2146
-        if ($redirect_after) {
2147
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2148
-        }
2149
-    }
2150
-
2151
-
2152
-    /**
2153
-     * _trash_or_restore_events
2154
-     *
2155
-     * @access protected
2156
-     * @param string $event_status
2157
-     * @return void
2158
-     * @throws EE_Error
2159
-     * @throws EE_Error
2160
-     * @throws ReflectionException
2161
-     */
2162
-    protected function _trash_or_restore_events(string $event_status = 'trash')
2163
-    {
2164
-        // clean status
2165
-        $event_status = sanitize_key($event_status);
2166
-        // grab status
2167
-        if (! empty($event_status)) {
2168
-            $success = true;
2169
-            // determine the event id and set to array.
2170
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2171
-            // loop thru events
2172
-            foreach ($EVT_IDs as $EVT_ID) {
2173
-                if ($EVT_ID = absint($EVT_ID)) {
2174
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2175
-                    $success = $results !== false ? $success : false;
2176
-                } else {
2177
-                    $msg = sprintf(
2178
-                        esc_html__(
2179
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2180
-                            'event_espresso'
2181
-                        ),
2182
-                        $EVT_ID
2183
-                    );
2184
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2185
-                    $success = false;
2186
-                }
2187
-            }
2188
-        } else {
2189
-            $success = false;
2190
-            $msg     = esc_html__(
2191
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2192
-                'event_espresso'
2193
-            );
2194
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2195
-        }
2196
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2197
-        $success = $success ? 2 : false;
2198
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2199
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2200
-    }
2201
-
2202
-
2203
-    /**
2204
-     * @param int    $EVT_ID
2205
-     * @param string $event_status
2206
-     * @return bool
2207
-     * @throws EE_Error
2208
-     * @throws ReflectionException
2209
-     */
2210
-    private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2211
-    {
2212
-        // grab event id
2213
-        if (! $EVT_ID) {
2214
-            $msg = esc_html__(
2215
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2216
-                'event_espresso'
2217
-            );
2218
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2219
-            return false;
2220
-        }
2221
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2222
-        // clean status
2223
-        $event_status = sanitize_key($event_status);
2224
-        // grab status
2225
-        if (empty($event_status)) {
2226
-            $msg = esc_html__(
2227
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2228
-                'event_espresso'
2229
-            );
2230
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2231
-            return false;
2232
-        }
2233
-        // was event trashed or restored ?
2234
-        switch ($event_status) {
2235
-            case 'draft':
2236
-                $action = 'restored from the trash';
2237
-                $hook   = 'AHEE_event_restored_from_trash';
2238
-                break;
2239
-            case 'trash':
2240
-                $action = 'moved to the trash';
2241
-                $hook   = 'AHEE_event_moved_to_trash';
2242
-                break;
2243
-            default:
2244
-                $action = 'updated';
2245
-                $hook   = false;
2246
-        }
2247
-        // use class to change status
2248
-        $this->_cpt_model_obj->set_status($event_status);
2249
-        $success = $this->_cpt_model_obj->save();
2250
-        if (! $success) {
2251
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2252
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2253
-            return false;
2254
-        }
2255
-        if ($hook) {
2256
-            do_action($hook);
2257
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2258
-            // because events side step that and it otherwise won't get called
2259
-            do_action(
2260
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2261
-                $this->_cpt_model_obj,
2262
-                $hook === 'AHEE_event_moved_to_trash',
2263
-                $success
2264
-            );
2265
-        }
2266
-        return true;
2267
-    }
2268
-
2269
-
2270
-    /**
2271
-     * @param array $event_ids
2272
-     * @return array
2273
-     * @since   4.10.23.p
2274
-     */
2275
-    private function cleanEventIds(array $event_ids): array
2276
-    {
2277
-        return array_map('absint', $event_ids);
2278
-    }
2279
-
2280
-
2281
-    /**
2282
-     * @return array
2283
-     * @since   4.10.23.p
2284
-     */
2285
-    private function getEventIdsFromRequest(): array
2286
-    {
2287
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2288
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2289
-        } else {
2290
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2291
-        }
2292
-    }
2293
-
2294
-
2295
-    /**
2296
-     * @param bool $preview_delete
2297
-     * @throws EE_Error
2298
-     * @throws ReflectionException
2299
-     */
2300
-    protected function _delete_event(bool $preview_delete = true)
2301
-    {
2302
-        $this->_delete_events($preview_delete);
2303
-    }
2304
-
2305
-
2306
-    /**
2307
-     * Gets the tree traversal batch persister.
2308
-     *
2309
-     * @return NodeGroupDao
2310
-     * @throws InvalidArgumentException
2311
-     * @throws InvalidDataTypeException
2312
-     * @throws InvalidInterfaceException
2313
-     * @since 4.10.12.p
2314
-     */
2315
-    protected function getModelObjNodeGroupPersister(): NodeGroupDao
2316
-    {
2317
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2318
-            $this->model_obj_node_group_persister =
2319
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2320
-        }
2321
-        return $this->model_obj_node_group_persister;
2322
-    }
2323
-
2324
-
2325
-    /**
2326
-     * @param bool $preview_delete
2327
-     * @return void
2328
-     * @throws EE_Error
2329
-     * @throws ReflectionException
2330
-     */
2331
-    protected function _delete_events(bool $preview_delete = true)
2332
-    {
2333
-        $event_ids = $this->getEventIdsFromRequest();
2334
-        if ($preview_delete) {
2335
-            $this->generateDeletionPreview($event_ids);
2336
-        } else {
2337
-            foreach ($event_ids as $event_id) {
2338
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2339
-                if ($event instanceof EE_Event) {
2340
-                    $event->delete_permanently();
2341
-                }
2342
-            }
2343
-        }
2344
-    }
2345
-
2346
-
2347
-    /**
2348
-     * @param array $event_ids
2349
-     */
2350
-    protected function generateDeletionPreview(array $event_ids)
2351
-    {
2352
-        $event_ids = $this->cleanEventIds($event_ids);
2353
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2354
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2355
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2356
-            [
2357
-                'action'            => 'preview_deletion',
2358
-                'deletion_job_code' => $deletion_job_code,
2359
-            ],
2360
-            $this->_admin_base_url
2361
-        );
2362
-        EEH_URL::safeRedirectAndExit(
2363
-            EE_Admin_Page::add_query_args_and_nonce(
2364
-                [
2365
-                    'page'              => EED_Batch::PAGE_SLUG,
2366
-                    'batch'             => EED_Batch::batch_job,
2367
-                    'EVT_IDs'           => $event_ids,
2368
-                    'deletion_job_code' => $deletion_job_code,
2369
-                    'job_handler'       => urlencode('EventEspresso\core\libraries\batch\JobHandlers\PreviewEventDeletion'),
2370
-                    'return_url'        => urlencode($return_url),
2371
-                ],
2372
-                admin_url()
2373
-            )
2374
-        );
2375
-    }
2376
-
2377
-
2378
-    /**
2379
-     * Checks for a POST submission
2380
-     *
2381
-     * @since 4.10.12.p
2382
-     */
2383
-    protected function confirmDeletion()
2384
-    {
2385
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2386
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2387
-        );
2388
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2389
-    }
2390
-
2391
-
2392
-    /**
2393
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2394
-     *
2395
-     * @throws EE_Error
2396
-     * @since 4.10.12.p
2397
-     */
2398
-    protected function previewDeletion()
2399
-    {
2400
-        $preview_deletion_logic = $this->getLoader()->getShared(
2401
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2402
-        );
2403
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2404
-        $this->display_admin_page_with_no_sidebar();
2405
-    }
2406
-
2407
-
2408
-    /**
2409
-     * get total number of events
2410
-     *
2411
-     * @access public
2412
-     * @return int
2413
-     * @throws EE_Error
2414
-     * @throws EE_Error
2415
-     * @throws ReflectionException
2416
-     */
2417
-    public function total_events(): int
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
-     * @throws ReflectionException
2435
-     */
2436
-    public function total_events_draft(): int
2437
-    {
2438
-        return EEM_Event::instance()->count(
2439
-            [
2440
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2441
-                'caps' => 'read_admin',
2442
-            ],
2443
-            'EVT_ID',
2444
-            true
2445
-        );
2446
-    }
2447
-
2448
-
2449
-    /**
2450
-     * get total number of trashed events
2451
-     *
2452
-     * @access public
2453
-     * @return int
2454
-     * @throws EE_Error
2455
-     * @throws EE_Error
2456
-     * @throws ReflectionException
2457
-     */
2458
-    public function total_trashed_events(): int
2459
-    {
2460
-        return EEM_Event::instance()->count(
2461
-            [
2462
-                ['status' => 'trash'],
2463
-                'caps' => 'read_admin',
2464
-            ],
2465
-            'EVT_ID',
2466
-            true
2467
-        );
2468
-    }
2469
-
2470
-
2471
-    /**
2472
-     *    _default_event_settings
2473
-     *    This generates the Default Settings Tab
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
-    protected function _default_event_settings()
2484
-    {
2485
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2486
-        $this->_set_publish_post_box_vars();
2487
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
2488
-            $this->_default_event_settings_form()->get_html(),
2489
-            '',
2490
-            'padding'
2491
-        );
2492
-        $this->display_admin_page_with_sidebar();
2493
-    }
2494
-
2495
-
2496
-    /**
2497
-     * Return the form for event settings.
2498
-     *
2499
-     * @return EE_Form_Section_Proper
2500
-     * @throws EE_Error
2501
-     * @throws ReflectionException
2502
-     */
2503
-    protected function _default_event_settings_form(): EE_Form_Section_Proper
2504
-    {
2505
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2506
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2507
-        // exclude
2508
-            [
2509
-                RegStatus::CANCELLED,
2510
-                RegStatus::DECLINED,
2511
-                RegStatus::INCOMPLETE,
2512
-                RegStatus::WAIT_LIST,
2513
-            ],
2514
-            true
2515
-        );
2516
-        // setup Advanced Editor ???
2517
-        if (
2518
-            $this->raw_req_action === 'default_event_settings'
2519
-            || $this->raw_req_action === 'update_default_event_settings'
2520
-        ) {
2521
-            $this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2522
-        }
2523
-        return new EE_Form_Section_Proper(
2524
-            [
2525
-                'name'            => 'update_default_event_settings',
2526
-                'html_id'         => 'update_default_event_settings',
2527
-                'html_class'      => 'form-table',
2528
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2529
-                'subsections'     => apply_filters(
2530
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2531
-                    [
2532
-                        'defaults_section_header' => new EE_Form_Section_HTML(
2533
-                            EEH_HTML::h2(
2534
-                                esc_html__('Default Settings', 'event_espresso'),
2535
-                                '',
2536
-                                'ee-admin-settings-hdr'
2537
-                            )
2538
-                        ),
2539
-                        'default_reg_status'      => new EE_Select_Input(
2540
-                            $registration_stati_for_selection,
2541
-                            [
2542
-                                'default'         => isset($registration_config->default_STS_ID)
2543
-                                                     && array_key_exists(
2544
-                                                         $registration_config->default_STS_ID,
2545
-                                                         $registration_stati_for_selection
2546
-                                                     )
2547
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2548
-                                    : RegStatus::PENDING_PAYMENT,
2549
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2550
-                                                     . EEH_Template::get_help_tab_link(
2551
-                                        'default_settings_status_help_tab'
2552
-                                    ),
2553
-                                'html_help_text'  => esc_html__(
2554
-                                    '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.',
2555
-                                    'event_espresso'
2556
-                                ),
2557
-                                'html_class'      => 'ee-input-width--small',
2558
-                            ]
2559
-                        ),
2560
-                        'default_max_tickets'     => new EE_Integer_Input(
2561
-                            [
2562
-                                'default'         => $registration_config->default_maximum_number_of_tickets
2563
-                                                     ?? EEM_Event::get_default_additional_limit(),
2564
-                                'html_label_text' => esc_html__(
2565
-                                                         'Default Maximum Tickets Allowed Per Order:',
2566
-                                                         'event_espresso'
2567
-                                                     )
2568
-                                                     . EEH_Template::get_help_tab_link(
2569
-                                        'default_maximum_tickets_help_tab"'
2570
-                                    ),
2571
-                                'html_help_text'  => esc_html__(
2572
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2573
-                                    'event_espresso'
2574
-                                ),
2575
-                                'html_class'      => 'ee-input-width--tiny',
2576
-                            ]
2577
-                        ),
2578
-                    ]
2579
-                ),
2580
-            ]
2581
-        );
2582
-    }
2583
-
2584
-
2585
-    /**
2586
-     * @return void
2587
-     * @throws EE_Error
2588
-     * @throws InvalidArgumentException
2589
-     * @throws InvalidDataTypeException
2590
-     * @throws InvalidInterfaceException
2591
-     * @throws ReflectionException
2592
-     */
2593
-    protected function _update_default_event_settings()
2594
-    {
2595
-        $form = $this->_default_event_settings_form();
2596
-        if ($form->was_submitted()) {
2597
-            $form->receive_form_submission();
2598
-            if ($form->is_valid()) {
2599
-                $registration_config = EE_Registry::instance()->CFG->registration;
2600
-                $valid_data          = $form->valid_data();
2601
-                if (isset($valid_data['default_reg_status'])) {
2602
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2603
-                }
2604
-                if (isset($valid_data['default_max_tickets'])) {
2605
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2606
-                }
2607
-                do_action(
2608
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2609
-                    $valid_data,
2610
-                    EE_Registry::instance()->CFG,
2611
-                    $this
2612
-                );
2613
-                // update because data was valid!
2614
-                EE_Registry::instance()->CFG->update_espresso_config();
2615
-                EE_Error::overwrite_success();
2616
-                EE_Error::add_success(
2617
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2618
-                );
2619
-            }
2620
-        }
2621
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2622
-    }
2623
-
2624
-
2625
-    /*************        Templates        *************
2626
-     *
2627
-     * @throws EE_Error
2628
-     */
2629
-    protected function _template_settings()
2630
-    {
2631
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2632
-        $this->_template_args['preview_img']  = '<img src="'
2633
-                                                . EVENTS_ASSETS_URL
2634
-                                                . '/images/'
2635
-                                                . 'caffeinated_template_features.jpg" alt="'
2636
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2637
-                                                . '" />';
2638
-        $this->_template_args['preview_text'] = '<strong>'
2639
-                                                . esc_html__(
2640
-                                                    '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.',
2641
-                                                    'event_espresso'
2642
-                                                ) . '</strong>';
2643
-        $this->display_admin_caf_preview_page('template_settings_tab');
2644
-    }
2645
-
2646
-
2647
-    /** Event Category Stuff **/
2648
-    /**
2649
-     * set the _category property with the category object for the loaded page.
2650
-     *
2651
-     * @access private
2652
-     * @return void
2653
-     */
2654
-    private function _set_category_object()
2655
-    {
2656
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2657
-            return;
2658
-        } //already have the category object so get out.
2659
-        // set default category object
2660
-        $this->_set_empty_category_object();
2661
-        // only set if we've got an id
2662
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2663
-        if (! $category_ID) {
2664
-            return;
2665
-        }
2666
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2667
-        if (! empty($term)) {
2668
-            $this->_category->category_name       = $term->name;
2669
-            $this->_category->category_identifier = $term->slug;
2670
-            $this->_category->category_desc       = $term->description;
2671
-            $this->_category->id                  = $term->term_id;
2672
-            $this->_category->parent              = $term->parent;
2673
-        }
2674
-    }
2675
-
2676
-
2677
-    /**
2678
-     * Clears out category properties.
2679
-     */
2680
-    private function _set_empty_category_object()
2681
-    {
2682
-        $this->_category                = new stdClass();
2683
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2684
-        $this->_category->id            = $this->_category->parent = 0;
2685
-    }
2686
-
2687
-
2688
-    /**
2689
-     * @throws DomainException
2690
-     * @throws EE_Error
2691
-     * @throws InvalidArgumentException
2692
-     * @throws InvalidDataTypeException
2693
-     * @throws InvalidInterfaceException
2694
-     */
2695
-    protected function _category_list_table()
2696
-    {
2697
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2698
-        $this->_admin_page_title .= ' ';
2699
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2700
-            'add_category',
2701
-            'add_category',
2702
-            [],
2703
-            'add-new-h2'
2704
-        );
2705
-        $this->display_admin_list_table_page_with_sidebar();
2706
-    }
2707
-
2708
-
2709
-    /**
2710
-     * Output category details view.
2711
-     *
2712
-     * @throws EE_Error
2713
-     * @throws EE_Error
2714
-     */
2715
-    protected function _category_details($view)
2716
-    {
2717
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2718
-        $this->_set_add_edit_form_tags($route);
2719
-        $this->_set_category_object();
2720
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2721
-        $delete_action = 'delete_category';
2722
-        // custom redirect
2723
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2724
-            ['action' => 'category_list'],
2725
-            $this->_admin_base_url
2726
-        );
2727
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2728
-        // take care of contents
2729
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2730
-        $this->display_admin_page_with_sidebar();
2731
-    }
2732
-
2733
-
2734
-    /**
2735
-     * Output category details content.
2736
-     *
2737
-     * @throws DomainException
2738
-     */
2739
-    protected function _category_details_content(): string
2740
-    {
2741
-        $editor_args['category_desc'] = [
2742
-            'type'          => 'wp_editor',
2743
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2744
-            'class'         => 'my_editor_custom',
2745
-            'wpeditor_args' => ['media_buttons' => false],
2746
-        ];
2747
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2748
-        $all_terms                    = get_terms(
2749
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2750
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2751
-        );
2752
-        // setup category select for term parents.
2753
-        $category_select_values[] = [
2754
-            'text' => esc_html__('No Parent', 'event_espresso'),
2755
-            'id'   => 0,
2756
-        ];
2757
-        foreach ($all_terms as $term) {
2758
-            $category_select_values[] = [
2759
-                'text' => $term->name,
2760
-                'id'   => $term->term_id,
2761
-            ];
2762
-        }
2763
-        $category_select = EEH_Form_Fields::select_input(
2764
-            'category_parent',
2765
-            $category_select_values,
2766
-            $this->_category->parent
2767
-        );
2768
-        $template_args   = [
2769
-            'category'                 => $this->_category,
2770
-            'category_select'          => $category_select,
2771
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2772
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2773
-            'disable'                  => '',
2774
-            'disabled_message'         => false,
2775
-        ];
2776
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2777
-        return EEH_Template::display_template($template, $template_args, true);
2778
-    }
2779
-
2780
-
2781
-    /**
2782
-     * Handles deleting categories.
2783
-     *
2784
-     * @throws EE_Error
2785
-     */
2786
-    protected function _delete_categories()
2787
-    {
2788
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2789
-        foreach ($category_IDs as $category_ID) {
2790
-            $this->_delete_category($category_ID);
2791
-        }
2792
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2793
-        $query_args = [
2794
-            'action' => 'category_list',
2795
-        ];
2796
-        $this->_redirect_after_action(0, '', '', $query_args);
2797
-    }
2798
-
2799
-
2800
-    /**
2801
-     * Handles deleting specific category.
2802
-     *
2803
-     * @param int $cat_id
2804
-     */
2805
-    protected function _delete_category(int $cat_id)
2806
-    {
2807
-        $cat_id = absint($cat_id);
2808
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2809
-    }
2810
-
2811
-
2812
-    /**
2813
-     * Handles triggering the update or insertion of a new category.
2814
-     *
2815
-     * @param bool $new_category true means we're triggering the insert of a new category.
2816
-     * @throws EE_Error
2817
-     * @throws EE_Error
2818
-     */
2819
-    protected function _insert_or_update_category(bool $new_category)
2820
-    {
2821
-        $cat_id  = $this->_insert_category($new_category);
2822
-        $success = 0; // we already have a success message so lets not send another.
2823
-        if ($cat_id) {
2824
-            $query_args = [
2825
-                'action'     => 'edit_category',
2826
-                'EVT_CAT_ID' => $cat_id,
2827
-            ];
2828
-        } else {
2829
-            $query_args = ['action' => 'add_category'];
2830
-        }
2831
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2832
-    }
2833
-
2834
-
2835
-    /**
2836
-     * Inserts or updates category
2837
-     *
2838
-     * @param bool $new_category (true indicates we're updating a category).
2839
-     * @return bool|mixed|string
2840
-     */
2841
-    private function _insert_category(bool $new_category)
2842
-    {
2843
-        $category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2844
-        $category_name       = $this->request->getRequestParam('category_name', '');
2845
-        $category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2846
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2847
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2848
-
2849
-        if (empty($category_name)) {
2850
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2851
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2852
-            return 0;
2853
-        }
2854
-        $term_args = [
2855
-            'name'        => $category_name,
2856
-            'description' => $category_desc,
2857
-            'parent'      => $category_parent,
2858
-        ];
2859
-        // was the category_identifier input disabled?
2860
-        if ($category_identifier) {
2861
-            $term_args['slug'] = $category_identifier;
2862
-        }
2863
-        $insert_ids = $new_category
2864
-            ? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2865
-            : wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2866
-
2867
-        if ($insert_ids instanceof WP_Error) {
2868
-            EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2869
-            return 0;
2870
-        }
2871
-        $category_ID = $insert_ids['term_id'] ?? 0;
2872
-        if (! $category_ID) {
2873
-            EE_Error::add_error(
2874
-                esc_html__(
2875
-                    'An error occurred and the category has not been saved to the database.',
2876
-                    'event_espresso'
2877
-                ),
2878
-                __FILE__,
2879
-                __FUNCTION__,
2880
-                __LINE__
2881
-            );
2882
-            return 0;
2883
-        }
2884
-        EE_Error::add_success(
2885
-            sprintf(
2886
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2887
-                $category_name
2888
-            )
2889
-        );
2890
-        return $category_ID;
2891
-    }
2892
-
2893
-
2894
-    /**
2895
-     * Gets categories or count of categories matching the arguments in the request.
2896
-     *
2897
-     * @param int  $per_page
2898
-     * @param int  $current_page
2899
-     * @param bool $count
2900
-     * @return EE_Term_Taxonomy[]|int
2901
-     * @throws EE_Error
2902
-     * @throws ReflectionException
2903
-     */
2904
-    public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2905
-    {
2906
-        // testing term stuff
2907
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2908
-        $order       = $this->request->getRequestParam('order', 'DESC');
2909
-        $limit       = ($current_page - 1) * $per_page;
2910
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2911
-        $search_term = $this->request->getRequestParam('s');
2912
-        if ($search_term) {
2913
-            $search_term = '%' . $search_term . '%';
2914
-            $where['OR'] = [
2915
-                'Term.name'   => ['LIKE', $search_term],
2916
-                'description' => ['LIKE', $search_term],
2917
-            ];
2918
-        }
2919
-        $query_params = [
2920
-            $where,
2921
-            'order_by'   => [$orderby => $order],
2922
-            'limit'      => $limit . ',' . $per_page,
2923
-            'force_join' => ['Term'],
2924
-        ];
2925
-        return $count
2926
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2927
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2928
-    }
2929
-
2930
-    /* end category stuff */
2931
-
2932
-
2933
-    /**************/
2934
-
2935
-
2936
-    /**
2937
-     * Callback for the `ee_save_timezone_setting` ajax action.
2938
-     *
2939
-     * @throws EE_Error
2940
-     * @throws InvalidArgumentException
2941
-     * @throws InvalidDataTypeException
2942
-     * @throws InvalidInterfaceException
2943
-     */
2944
-    public function saveTimezoneString()
2945
-    {
2946
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2947
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2948
-            EE_Error::add_error(
2949
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2950
-                __FILE__,
2951
-                __FUNCTION__,
2952
-                __LINE__
2953
-            );
2954
-            $this->_template_args['error'] = true;
2955
-            $this->_return_json();
2956
-        }
2957
-
2958
-        update_option('timezone_string', $timezone_string);
2959
-        EE_Error::add_success(
2960
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2961
-        );
2962
-        $this->_template_args['success'] = true;
2963
-        $this->_return_json(true, ['action' => 'create_new']);
2964
-    }
2965
-
2966
-
2967
-    /**
2968 2627
      * @throws EE_Error
2969
-     * @deprecated 4.10.25.p
2970 2628
      */
2971
-    public function save_timezonestring_setting()
2972
-    {
2973
-        $this->saveTimezoneString();
2974
-    }
2629
+	protected function _template_settings()
2630
+	{
2631
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2632
+		$this->_template_args['preview_img']  = '<img src="'
2633
+												. EVENTS_ASSETS_URL
2634
+												. '/images/'
2635
+												. 'caffeinated_template_features.jpg" alt="'
2636
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2637
+												. '" />';
2638
+		$this->_template_args['preview_text'] = '<strong>'
2639
+												. esc_html__(
2640
+													'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.',
2641
+													'event_espresso'
2642
+												) . '</strong>';
2643
+		$this->display_admin_caf_preview_page('template_settings_tab');
2644
+	}
2645
+
2646
+
2647
+	/** Event Category Stuff **/
2648
+	/**
2649
+	 * set the _category property with the category object for the loaded page.
2650
+	 *
2651
+	 * @access private
2652
+	 * @return void
2653
+	 */
2654
+	private function _set_category_object()
2655
+	{
2656
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2657
+			return;
2658
+		} //already have the category object so get out.
2659
+		// set default category object
2660
+		$this->_set_empty_category_object();
2661
+		// only set if we've got an id
2662
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2663
+		if (! $category_ID) {
2664
+			return;
2665
+		}
2666
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2667
+		if (! empty($term)) {
2668
+			$this->_category->category_name       = $term->name;
2669
+			$this->_category->category_identifier = $term->slug;
2670
+			$this->_category->category_desc       = $term->description;
2671
+			$this->_category->id                  = $term->term_id;
2672
+			$this->_category->parent              = $term->parent;
2673
+		}
2674
+	}
2675
+
2676
+
2677
+	/**
2678
+	 * Clears out category properties.
2679
+	 */
2680
+	private function _set_empty_category_object()
2681
+	{
2682
+		$this->_category                = new stdClass();
2683
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2684
+		$this->_category->id            = $this->_category->parent = 0;
2685
+	}
2686
+
2687
+
2688
+	/**
2689
+	 * @throws DomainException
2690
+	 * @throws EE_Error
2691
+	 * @throws InvalidArgumentException
2692
+	 * @throws InvalidDataTypeException
2693
+	 * @throws InvalidInterfaceException
2694
+	 */
2695
+	protected function _category_list_table()
2696
+	{
2697
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2698
+		$this->_admin_page_title .= ' ';
2699
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2700
+			'add_category',
2701
+			'add_category',
2702
+			[],
2703
+			'add-new-h2'
2704
+		);
2705
+		$this->display_admin_list_table_page_with_sidebar();
2706
+	}
2707
+
2708
+
2709
+	/**
2710
+	 * Output category details view.
2711
+	 *
2712
+	 * @throws EE_Error
2713
+	 * @throws EE_Error
2714
+	 */
2715
+	protected function _category_details($view)
2716
+	{
2717
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2718
+		$this->_set_add_edit_form_tags($route);
2719
+		$this->_set_category_object();
2720
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2721
+		$delete_action = 'delete_category';
2722
+		// custom redirect
2723
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2724
+			['action' => 'category_list'],
2725
+			$this->_admin_base_url
2726
+		);
2727
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2728
+		// take care of contents
2729
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2730
+		$this->display_admin_page_with_sidebar();
2731
+	}
2732
+
2733
+
2734
+	/**
2735
+	 * Output category details content.
2736
+	 *
2737
+	 * @throws DomainException
2738
+	 */
2739
+	protected function _category_details_content(): string
2740
+	{
2741
+		$editor_args['category_desc'] = [
2742
+			'type'          => 'wp_editor',
2743
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2744
+			'class'         => 'my_editor_custom',
2745
+			'wpeditor_args' => ['media_buttons' => false],
2746
+		];
2747
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2748
+		$all_terms                    = get_terms(
2749
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2750
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2751
+		);
2752
+		// setup category select for term parents.
2753
+		$category_select_values[] = [
2754
+			'text' => esc_html__('No Parent', 'event_espresso'),
2755
+			'id'   => 0,
2756
+		];
2757
+		foreach ($all_terms as $term) {
2758
+			$category_select_values[] = [
2759
+				'text' => $term->name,
2760
+				'id'   => $term->term_id,
2761
+			];
2762
+		}
2763
+		$category_select = EEH_Form_Fields::select_input(
2764
+			'category_parent',
2765
+			$category_select_values,
2766
+			$this->_category->parent
2767
+		);
2768
+		$template_args   = [
2769
+			'category'                 => $this->_category,
2770
+			'category_select'          => $category_select,
2771
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2772
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2773
+			'disable'                  => '',
2774
+			'disabled_message'         => false,
2775
+		];
2776
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2777
+		return EEH_Template::display_template($template, $template_args, true);
2778
+	}
2779
+
2780
+
2781
+	/**
2782
+	 * Handles deleting categories.
2783
+	 *
2784
+	 * @throws EE_Error
2785
+	 */
2786
+	protected function _delete_categories()
2787
+	{
2788
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2789
+		foreach ($category_IDs as $category_ID) {
2790
+			$this->_delete_category($category_ID);
2791
+		}
2792
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2793
+		$query_args = [
2794
+			'action' => 'category_list',
2795
+		];
2796
+		$this->_redirect_after_action(0, '', '', $query_args);
2797
+	}
2798
+
2799
+
2800
+	/**
2801
+	 * Handles deleting specific category.
2802
+	 *
2803
+	 * @param int $cat_id
2804
+	 */
2805
+	protected function _delete_category(int $cat_id)
2806
+	{
2807
+		$cat_id = absint($cat_id);
2808
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2809
+	}
2810
+
2811
+
2812
+	/**
2813
+	 * Handles triggering the update or insertion of a new category.
2814
+	 *
2815
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2816
+	 * @throws EE_Error
2817
+	 * @throws EE_Error
2818
+	 */
2819
+	protected function _insert_or_update_category(bool $new_category)
2820
+	{
2821
+		$cat_id  = $this->_insert_category($new_category);
2822
+		$success = 0; // we already have a success message so lets not send another.
2823
+		if ($cat_id) {
2824
+			$query_args = [
2825
+				'action'     => 'edit_category',
2826
+				'EVT_CAT_ID' => $cat_id,
2827
+			];
2828
+		} else {
2829
+			$query_args = ['action' => 'add_category'];
2830
+		}
2831
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2832
+	}
2833
+
2834
+
2835
+	/**
2836
+	 * Inserts or updates category
2837
+	 *
2838
+	 * @param bool $new_category (true indicates we're updating a category).
2839
+	 * @return bool|mixed|string
2840
+	 */
2841
+	private function _insert_category(bool $new_category)
2842
+	{
2843
+		$category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2844
+		$category_name       = $this->request->getRequestParam('category_name', '');
2845
+		$category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2846
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2847
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2848
+
2849
+		if (empty($category_name)) {
2850
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2851
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2852
+			return 0;
2853
+		}
2854
+		$term_args = [
2855
+			'name'        => $category_name,
2856
+			'description' => $category_desc,
2857
+			'parent'      => $category_parent,
2858
+		];
2859
+		// was the category_identifier input disabled?
2860
+		if ($category_identifier) {
2861
+			$term_args['slug'] = $category_identifier;
2862
+		}
2863
+		$insert_ids = $new_category
2864
+			? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2865
+			: wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2866
+
2867
+		if ($insert_ids instanceof WP_Error) {
2868
+			EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2869
+			return 0;
2870
+		}
2871
+		$category_ID = $insert_ids['term_id'] ?? 0;
2872
+		if (! $category_ID) {
2873
+			EE_Error::add_error(
2874
+				esc_html__(
2875
+					'An error occurred and the category has not been saved to the database.',
2876
+					'event_espresso'
2877
+				),
2878
+				__FILE__,
2879
+				__FUNCTION__,
2880
+				__LINE__
2881
+			);
2882
+			return 0;
2883
+		}
2884
+		EE_Error::add_success(
2885
+			sprintf(
2886
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2887
+				$category_name
2888
+			)
2889
+		);
2890
+		return $category_ID;
2891
+	}
2892
+
2893
+
2894
+	/**
2895
+	 * Gets categories or count of categories matching the arguments in the request.
2896
+	 *
2897
+	 * @param int  $per_page
2898
+	 * @param int  $current_page
2899
+	 * @param bool $count
2900
+	 * @return EE_Term_Taxonomy[]|int
2901
+	 * @throws EE_Error
2902
+	 * @throws ReflectionException
2903
+	 */
2904
+	public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2905
+	{
2906
+		// testing term stuff
2907
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2908
+		$order       = $this->request->getRequestParam('order', 'DESC');
2909
+		$limit       = ($current_page - 1) * $per_page;
2910
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2911
+		$search_term = $this->request->getRequestParam('s');
2912
+		if ($search_term) {
2913
+			$search_term = '%' . $search_term . '%';
2914
+			$where['OR'] = [
2915
+				'Term.name'   => ['LIKE', $search_term],
2916
+				'description' => ['LIKE', $search_term],
2917
+			];
2918
+		}
2919
+		$query_params = [
2920
+			$where,
2921
+			'order_by'   => [$orderby => $order],
2922
+			'limit'      => $limit . ',' . $per_page,
2923
+			'force_join' => ['Term'],
2924
+		];
2925
+		return $count
2926
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2927
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2928
+	}
2929
+
2930
+	/* end category stuff */
2931
+
2932
+
2933
+	/**************/
2934
+
2935
+
2936
+	/**
2937
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2938
+	 *
2939
+	 * @throws EE_Error
2940
+	 * @throws InvalidArgumentException
2941
+	 * @throws InvalidDataTypeException
2942
+	 * @throws InvalidInterfaceException
2943
+	 */
2944
+	public function saveTimezoneString()
2945
+	{
2946
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2947
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2948
+			EE_Error::add_error(
2949
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2950
+				__FILE__,
2951
+				__FUNCTION__,
2952
+				__LINE__
2953
+			);
2954
+			$this->_template_args['error'] = true;
2955
+			$this->_return_json();
2956
+		}
2957
+
2958
+		update_option('timezone_string', $timezone_string);
2959
+		EE_Error::add_success(
2960
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2961
+		);
2962
+		$this->_template_args['success'] = true;
2963
+		$this->_return_json(true, ['action' => 'create_new']);
2964
+	}
2965
+
2966
+
2967
+	/**
2968
+	 * @throws EE_Error
2969
+	 * @deprecated 4.10.25.p
2970
+	 */
2971
+	public function save_timezonestring_setting()
2972
+	{
2973
+		$this->saveTimezoneString();
2974
+	}
2975 2975
 }
Please login to merge, or discard this patch.
Spacing   +86 added lines, -86 removed lines patch added patch discarded remove patch
@@ -571,13 +571,13 @@  discard block
 block discarded – undo
571 571
     {
572 572
         wp_register_style(
573 573
             'events-admin-css',
574
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
574
+            EVENTS_ASSETS_URL.'events-admin-page.css',
575 575
             [],
576 576
             EVENT_ESPRESSO_VERSION
577 577
         );
578 578
         wp_register_style(
579 579
             'ee-cat-admin',
580
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
580
+            EVENTS_ASSETS_URL.'ee-cat-admin.css',
581 581
             [],
582 582
             EVENT_ESPRESSO_VERSION
583 583
         );
@@ -586,7 +586,7 @@  discard block
 block discarded – undo
586 586
         // scripts
587 587
         wp_register_script(
588 588
             'event_editor_js',
589
-            EVENTS_ASSETS_URL . 'event_editor.js',
589
+            EVENTS_ASSETS_URL.'event_editor.js',
590 590
             ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
591 591
             EVENT_ESPRESSO_VERSION,
592 592
             true
@@ -612,16 +612,16 @@  discard block
 block discarded – undo
612 612
         wp_enqueue_style('espresso-ui-theme');
613 613
         wp_register_style(
614 614
             'event-editor-css',
615
-            EVENTS_ASSETS_URL . 'event-editor.css',
615
+            EVENTS_ASSETS_URL.'event-editor.css',
616 616
             ['ee-admin-css'],
617 617
             EVENT_ESPRESSO_VERSION
618 618
         );
619 619
         wp_enqueue_style('event-editor-css');
620 620
         // scripts
621
-        if (! $this->admin_config->useAdvancedEditor()) {
621
+        if ( ! $this->admin_config->useAdvancedEditor()) {
622 622
             wp_register_script(
623 623
                 'event-datetime-metabox',
624
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
624
+                EVENTS_ASSETS_URL.'event-datetime-metabox.js',
625 625
                 ['event_editor_js', 'ee-datepicker'],
626 626
                 EVENT_ESPRESSO_VERSION
627 627
             );
@@ -691,15 +691,15 @@  discard block
 block discarded – undo
691 691
     public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
692 692
     {
693 693
         // don't need to do this when processing
694
-        if (! empty($req_type)) {
694
+        if ( ! empty($req_type)) {
695 695
             return;
696 696
         }
697 697
         // no event?
698
-        if (! $event instanceof EE_Event) {
698
+        if ( ! $event instanceof EE_Event) {
699 699
             $event = $this->_cpt_model_obj;
700 700
         }
701 701
         // STILL no event?
702
-        if (! $event instanceof EE_Event) {
702
+        if ( ! $event instanceof EE_Event) {
703 703
             return;
704 704
         }
705 705
         // don't need to keep calling this
@@ -744,7 +744,7 @@  discard block
 block discarded – undo
744 744
             );
745 745
         }
746 746
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
747
-        if (! $event->tickets_on_sale()) {
747
+        if ( ! $event->tickets_on_sale()) {
748 748
             return;
749 749
         }
750 750
         // made it here so show warning
@@ -793,7 +793,7 @@  discard block
 block discarded – undo
793 793
     {
794 794
         $has_timezone_string = get_option('timezone_string');
795 795
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
796
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
796
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
797 797
             EE_Error::add_attention(
798 798
                 sprintf(
799 799
                     esc_html__(
@@ -862,7 +862,7 @@  discard block
 block discarded – undo
862 862
      */
863 863
     protected function _event_legend_items(): array
864 864
     {
865
-        $items    = [
865
+        $items = [
866 866
             'view_details'   => [
867 867
                 'class' => 'dashicons dashicons-visibility',
868 868
                 'desc'  => esc_html__('View Event', 'event_espresso'),
@@ -879,31 +879,31 @@  discard block
 block discarded – undo
879 879
         $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
880 880
         $statuses = [
881 881
             'sold_out_status'  => [
882
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
882
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::sold_out,
883 883
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
884 884
             ],
885 885
             'active_status'    => [
886
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
886
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::active,
887 887
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
888 888
             ],
889 889
             'upcoming_status'  => [
890
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
890
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::upcoming,
891 891
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
892 892
             ],
893 893
             'postponed_status' => [
894
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
894
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::postponed,
895 895
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
896 896
             ],
897 897
             'cancelled_status' => [
898
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
898
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::cancelled,
899 899
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
900 900
             ],
901 901
             'expired_status'   => [
902
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
902
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::expired,
903 903
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
904 904
             ],
905 905
             'inactive_status'  => [
906
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
906
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::inactive,
907 907
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
908 908
             ],
909 909
         ];
@@ -922,7 +922,7 @@  discard block
 block discarded – undo
922 922
      */
923 923
     private function _event_model(): EEM_Event
924 924
     {
925
-        if (! $this->_event_model instanceof EEM_Event) {
925
+        if ( ! $this->_event_model instanceof EEM_Event) {
926 926
             $this->_event_model = EE_Registry::instance()->load_model('Event');
927 927
         }
928 928
         return $this->_event_model;
@@ -977,12 +977,12 @@  discard block
 block discarded – undo
977 977
             '',
978 978
             'ee-admin-button-row ee-admin-button-row--align-start'
979 979
         );
980
-        $links_html       .= EEH_HTML::divx();
980
+        $links_html .= EEH_HTML::divx();
981 981
 
982 982
         $after_list_table['view_event_list_button'] = $links_html;
983 983
 
984 984
         $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
985
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
985
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
986 986
                 'create_new',
987 987
                 'add',
988 988
                 [],
@@ -1046,13 +1046,13 @@  discard block
 block discarded – undo
1046 1046
             'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1047 1047
         ];
1048 1048
         // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1049
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1050
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1049
+        if ( ! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1050
+            $event_values['EVT_display_ticket_selector'] = $this->request->getRequestParam(
1051 1051
                 'display_ticket_selector',
1052 1052
                 false,
1053 1053
                 'bool'
1054 1054
             );
1055
-            $event_values['EVT_additional_limit']            = min(
1055
+            $event_values['EVT_additional_limit'] = min(
1056 1056
                 apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1057 1057
                 $this->request->getRequestParam(
1058 1058
                     'additional_limit',
@@ -1094,14 +1094,14 @@  discard block
 block discarded – undo
1094 1094
             ]
1095 1095
         );
1096 1096
 
1097
-        if (! $event instanceof EE_Event) {
1097
+        if ( ! $event instanceof EE_Event) {
1098 1098
             return;
1099 1099
         }
1100 1100
 
1101 1101
         // the following are default callbacks for event attachment updates
1102 1102
         // that can be overridden by caffeinated functionality and/or addons.
1103 1103
         $event_update_callbacks = [];
1104
-        if (! $this->admin_config->useAdvancedEditor()) {
1104
+        if ( ! $this->admin_config->useAdvancedEditor()) {
1105 1105
             $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1106 1106
             $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1107 1107
         }
@@ -1172,7 +1172,7 @@  discard block
 block discarded – undo
1172 1172
      */
1173 1173
     protected function _default_venue_update(EE_Event $event, array $data): bool
1174 1174
     {
1175
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1175
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1176 1176
         $venue_model = EE_Registry::instance()->load_model('Venue');
1177 1177
         $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1178 1178
         // very important.  If we don't have a venue name...
@@ -1203,7 +1203,7 @@  discard block
 block discarded – undo
1203 1203
             'status'              => 'publish',
1204 1204
         ];
1205 1205
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1206
-        if (! empty($venue_id)) {
1206
+        if ( ! empty($venue_id)) {
1207 1207
             $update_where  = [$venue_model->primary_key_name() => $venue_id];
1208 1208
             $rows_affected = $venue_model->update($venue_array, [$update_where]);
1209 1209
             // we've gotta make sure that the venue is always attached to a revision..
@@ -1253,9 +1253,9 @@  discard block
 block discarded – undo
1253 1253
             ];
1254 1254
             // if we have an id then let's get existing object first and then set the new values.
1255 1255
             //  Otherwise we instantiate a new object for save.
1256
-            if (! empty($datetime_data['DTT_ID'])) {
1256
+            if ( ! empty($datetime_data['DTT_ID'])) {
1257 1257
                 $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1258
-                if (! $datetime instanceof EE_Datetime) {
1258
+                if ( ! $datetime instanceof EE_Datetime) {
1259 1259
                     throw new RuntimeException(
1260 1260
                         sprintf(
1261 1261
                             esc_html__(
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
             } else {
1275 1275
                 $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1276 1276
             }
1277
-            if (! $datetime instanceof EE_Datetime) {
1277
+            if ( ! $datetime instanceof EE_Datetime) {
1278 1278
                 throw new RuntimeException(
1279 1279
                     sprintf(
1280 1280
                         esc_html__(
@@ -1300,7 +1300,7 @@  discard block
 block discarded – undo
1300 1300
 
1301 1301
         // set up some default start and end dates in case those are not present in the incoming data
1302 1302
         $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1303
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1303
+        $default_start_date = $default_start_date->format($date_formats[0].' '.$date_formats[1]);
1304 1304
         // use the start date of the first datetime for the end date
1305 1305
         $first_datetime   = $event->first_datetime();
1306 1306
         $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
@@ -1308,7 +1308,7 @@  discard block
 block discarded – undo
1308 1308
         // now process the incoming data
1309 1309
         foreach ($data['edit_tickets'] as $row => $ticket_data) {
1310 1310
             $update_prices = false;
1311
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1311
+            $ticket_price  = $data['edit_prices'][$row][1]['PRC_amount'] ?? 0;
1312 1312
             // trim inputs to ensure any excess whitespace is removed.
1313 1313
             $ticket_data   = array_map('trim', $ticket_data);
1314 1314
             $ticket_values = [
@@ -1348,9 +1348,9 @@  discard block
 block discarded – undo
1348 1348
             // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1349 1349
             // keep in mind that if the ticket has been sold (and we have changed pricing information),
1350 1350
             // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1351
-            if (! empty($ticket_data['TKT_ID'])) {
1351
+            if ( ! empty($ticket_data['TKT_ID'])) {
1352 1352
                 $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1353
-                if (! $existing_ticket instanceof EE_Ticket) {
1353
+                if ( ! $existing_ticket instanceof EE_Ticket) {
1354 1354
                     throw new RuntimeException(
1355 1355
                         sprintf(
1356 1356
                             esc_html__(
@@ -1399,7 +1399,7 @@  discard block
 block discarded – undo
1399 1399
                     $existing_ticket->save();
1400 1400
                     // make sure this ticket is still recorded in our $saved_tickets
1401 1401
                     // so we don't run it through the regular trash routine.
1402
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1402
+                    $saved_tickets[$existing_ticket->ID()] = $existing_ticket;
1403 1403
                     // create new ticket that's a copy of the existing except,
1404 1404
                     // (a new id of course and not archived) AND has the new TKT_price associated with it.
1405 1405
                     $new_ticket = clone $existing_ticket;
@@ -1416,7 +1416,7 @@  discard block
 block discarded – undo
1416 1416
                 $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1417 1417
                 $update_prices              = true;
1418 1418
             }
1419
-            if (! $ticket instanceof EE_Ticket) {
1419
+            if ( ! $ticket instanceof EE_Ticket) {
1420 1420
                 throw new RuntimeException(
1421 1421
                     sprintf(
1422 1422
                         esc_html__(
@@ -1440,10 +1440,10 @@  discard block
 block discarded – undo
1440 1440
             }
1441 1441
             // initially let's add the ticket to the datetime
1442 1442
             $datetime->_add_relation_to($ticket, 'Ticket');
1443
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1443
+            $saved_tickets[$ticket->ID()] = $ticket;
1444 1444
             // add prices to ticket
1445
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1446
-                ? $data['edit_prices'][ $row ]
1445
+            $prices_data = isset($data['edit_prices'][$row]) && is_array($data['edit_prices'][$row])
1446
+                ? $data['edit_prices'][$row]
1447 1447
                 : [];
1448 1448
             $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1449 1449
         }
@@ -1457,7 +1457,7 @@  discard block
 block discarded – undo
1457 1457
             $id = absint($id);
1458 1458
             // get the ticket for this id
1459 1459
             $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1460
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1460
+            if ( ! $ticket_to_remove instanceof EE_Ticket) {
1461 1461
                 continue;
1462 1462
             }
1463 1463
             // need to get all the related datetimes on this ticket and remove from every single one of them
@@ -1514,7 +1514,7 @@  discard block
 block discarded – undo
1514 1514
                     $price->set($field, $new_price);
1515 1515
                 }
1516 1516
             }
1517
-            if (! $price instanceof EE_Price) {
1517
+            if ( ! $price instanceof EE_Price) {
1518 1518
                 throw new RuntimeException(
1519 1519
                     sprintf(
1520 1520
                         esc_html__(
@@ -1555,13 +1555,13 @@  discard block
 block discarded – undo
1555 1555
     {
1556 1556
         // load formatter helper
1557 1557
         // args for getting related registrations
1558
-        $approved_query_args        = [
1558
+        $approved_query_args = [
1559 1559
             [
1560 1560
                 'REG_deleted' => 0,
1561 1561
                 'STS_ID'      => RegStatus::APPROVED,
1562 1562
             ],
1563 1563
         ];
1564
-        $not_approved_query_args    = [
1564
+        $not_approved_query_args = [
1565 1565
             [
1566 1566
                 'REG_deleted' => 0,
1567 1567
                 'STS_ID'      => RegStatus::AWAITING_REVIEW,
@@ -1627,7 +1627,7 @@  discard block
 block discarded – undo
1627 1627
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1628 1628
         // load template
1629 1629
         EEH_Template::display_template(
1630
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1630
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1631 1631
             $publish_box_extra_args
1632 1632
         );
1633 1633
     }
@@ -1658,7 +1658,7 @@  discard block
 block discarded – undo
1658 1658
         $this->verify_cpt_object();
1659 1659
         $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1660 1660
         // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1661
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1661
+        if ( ! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1662 1662
             $this->addMetaBox(
1663 1663
                 'espresso_event_editor_event_options',
1664 1664
                 esc_html__('Event Registration Options', 'event_espresso'),
@@ -1667,7 +1667,7 @@  discard block
 block discarded – undo
1667 1667
                 'side'
1668 1668
             );
1669 1669
         }
1670
-        if (! $use_advanced_editor) {
1670
+        if ( ! $use_advanced_editor) {
1671 1671
             $this->addMetaBox(
1672 1672
                 'espresso_event_editor_tickets',
1673 1673
                 esc_html__('Event Datetime & Ticket', 'event_espresso'),
@@ -1679,7 +1679,7 @@  discard block
 block discarded – undo
1679 1679
         } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1680 1680
             add_action(
1681 1681
                 'add_meta_boxes_espresso_events',
1682
-                function () {
1682
+                function() {
1683 1683
                     global $current_screen;
1684 1684
                     remove_meta_box('authordiv', $current_screen, 'normal');
1685 1685
                 },
@@ -1708,7 +1708,7 @@  discard block
 block discarded – undo
1708 1708
             'trash_icon'        => 'dashicons dashicons-lock',
1709 1709
             'disabled'          => '',
1710 1710
         ];
1711
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1711
+        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1712 1712
         /**
1713 1713
          * 1. Start with retrieving Datetimes
1714 1714
          * 2. Fore each datetime get related tickets
@@ -1734,24 +1734,24 @@  discard block
 block discarded – undo
1734 1734
                     'default_where_conditions' => 'none',
1735 1735
                 ]
1736 1736
             );
1737
-            if (! empty($related_tickets)) {
1737
+            if ( ! empty($related_tickets)) {
1738 1738
                 $template_args['total_ticket_rows'] = count($related_tickets);
1739 1739
                 $row                                = 0;
1740 1740
                 foreach ($related_tickets as $ticket) {
1741
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1741
+                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1742 1742
                     $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1743 1743
                     $row++;
1744 1744
                 }
1745 1745
             } else {
1746 1746
                 $template_args['total_ticket_rows'] = 1;
1747 1747
                 /** @type EE_Ticket $ticket */
1748
-                $ticket                       = $ticket_model->create_default_object();
1748
+                $ticket = $ticket_model->create_default_object();
1749 1749
                 $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1750 1750
             }
1751 1751
         } else {
1752 1752
             $template_args['time'] = $times[0];
1753 1753
             /** @type EE_Ticket[] $tickets */
1754
-            $tickets                      = $ticket_model->get_all_default_tickets();
1754
+            $tickets = $ticket_model->get_all_default_tickets();
1755 1755
             $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1756 1756
             // NOTE: we're just sending the first default row
1757 1757
             // (decaf can't manage default tickets so this should be sufficient);
@@ -1766,9 +1766,9 @@  discard block
 block discarded – undo
1766 1766
             $ticket_model->create_default_object(),
1767 1767
             true
1768 1768
         );
1769
-        $template                                  = apply_filters(
1769
+        $template = apply_filters(
1770 1770
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1771
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1771
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1772 1772
         );
1773 1773
         EEH_Template::display_template($template, $template_args);
1774 1774
     }
@@ -1788,7 +1788,7 @@  discard block
 block discarded – undo
1788 1788
     private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1789 1789
     {
1790 1790
         $template_args = [
1791
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1791
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1792 1792
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1793 1793
                 : '',
1794 1794
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1800,11 +1800,11 @@  discard block
 block discarded – undo
1800 1800
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1801 1801
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1802 1802
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1803
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1804
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1803
+            'trash_icon'          => ($skeleton || ( ! $ticket->get('TKT_deleted')))
1804
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1805 1805
                 ? 'dashicons dashicons-post-trash clickable'
1806 1806
                 : 'dashicons dashicons-lock',
1807
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1807
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1808 1808
                 : ' disabled=disabled',
1809 1809
         ];
1810 1810
         $price         = $ticket->ID() !== 0
@@ -1828,7 +1828,7 @@  discard block
 block discarded – undo
1828 1828
         }
1829 1829
         if (empty($template_args['TKT_end_date'])) {
1830 1830
             // get the earliest datetime (if present);
1831
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1831
+            $earliest_datetime = $this->_cpt_model_obj->ID() > 0
1832 1832
                 ? $this->_cpt_model_obj->get_first_related(
1833 1833
                     'Datetime',
1834 1834
                     ['order_by' => ['DTT_EVT_start' => 'ASC']]
@@ -1841,7 +1841,7 @@  discard block
 block discarded – undo
1841 1841
         $template_args = array_merge($template_args, $price_args);
1842 1842
         $template      = apply_filters(
1843 1843
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1844
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1844
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1845 1845
             $ticket
1846 1846
         );
1847 1847
         return EEH_Template::display_template($template, $template_args, true);
@@ -1854,7 +1854,7 @@  discard block
 block discarded – undo
1854 1854
      */
1855 1855
     public function registration_options_meta_box()
1856 1856
     {
1857
-        $yes_no_values             = [
1857
+        $yes_no_values = [
1858 1858
             ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1859 1859
             ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1860 1860
         ];
@@ -1879,12 +1879,12 @@  discard block
 block discarded – undo
1879 1879
             'ee-input-width--reg',
1880 1880
             false
1881 1881
         );
1882
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1882
+        $template_args['display_description'] = EEH_Form_Fields::select_input(
1883 1883
             'display_desc',
1884 1884
             $yes_no_values,
1885 1885
             $this->_cpt_model_obj->display_description()
1886 1886
         );
1887
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1887
+        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1888 1888
             'display_ticket_selector',
1889 1889
             $yes_no_values,
1890 1890
             $this->_cpt_model_obj->display_ticket_selector(),
@@ -1900,7 +1900,7 @@  discard block
 block discarded – undo
1900 1900
             $default_reg_status_values
1901 1901
         );
1902 1902
         EEH_Template::display_template(
1903
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1903
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1904 1904
             $template_args
1905 1905
         );
1906 1906
     }
@@ -1923,7 +1923,7 @@  discard block
 block discarded – undo
1923 1923
     {
1924 1924
         $EEM_Event   = $this->_event_model();
1925 1925
         $offset      = ($current_page - 1) * $per_page;
1926
-        $limit       = $count ? null : $offset . ',' . $per_page;
1926
+        $limit       = $count ? null : $offset.','.$per_page;
1927 1927
         $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1928 1928
         $order       = $this->request->getRequestParam('order', 'DESC');
1929 1929
         $month_range = $this->request->getRequestParam('month_range');
@@ -1960,10 +1960,10 @@  discard block
 block discarded – undo
1960 1960
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1961 1961
         if ($month_range) {
1962 1962
             $DateTime = new DateTime(
1963
-                $year_r . '-' . $month_r . '-01 00:00:00',
1963
+                $year_r.'-'.$month_r.'-01 00:00:00',
1964 1964
                 new DateTimeZone('UTC')
1965 1965
             );
1966
-            $start    = $DateTime->getTimestamp();
1966
+            $start = $DateTime->getTimestamp();
1967 1967
             // set the datetime to be the end of the month
1968 1968
             $DateTime->setDate(
1969 1969
                 $year_r,
@@ -1992,11 +1992,11 @@  discard block
 block discarded – undo
1992 1992
                                                         ->format(implode(' ', $start_formats));
1993 1993
             $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1994 1994
         }
1995
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1995
+        if ( ! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1996 1996
             $where['EVT_wp_user'] = get_current_user_id();
1997 1997
         } else {
1998
-            if (! isset($where['status'])) {
1999
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1998
+            if ( ! isset($where['status'])) {
1999
+                if ( ! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
2000 2000
                     $where['OR'] = [
2001 2001
                         'status*restrict_private' => ['!=', 'private'],
2002 2002
                         'AND'                     => [
@@ -2018,7 +2018,7 @@  discard block
 block discarded – undo
2018 2018
         // search query handling
2019 2019
         $search_term = $this->request->getRequestParam('s');
2020 2020
         if ($search_term) {
2021
-            $search_term = '%' . $search_term . '%';
2021
+            $search_term = '%'.$search_term.'%';
2022 2022
             $where['OR'] = [
2023 2023
                 'EVT_name'       => ['LIKE', $search_term],
2024 2024
                 'EVT_desc'       => ['LIKE', $search_term],
@@ -2124,7 +2124,7 @@  discard block
 block discarded – undo
2124 2124
             // clean status
2125 2125
             $event_status = sanitize_key($event_status);
2126 2126
             // grab status
2127
-            if (! empty($event_status)) {
2127
+            if ( ! empty($event_status)) {
2128 2128
                 $success = $this->_change_event_status($this->EVT_ID, $event_status);
2129 2129
             } else {
2130 2130
                 $success = false;
@@ -2164,7 +2164,7 @@  discard block
 block discarded – undo
2164 2164
         // clean status
2165 2165
         $event_status = sanitize_key($event_status);
2166 2166
         // grab status
2167
-        if (! empty($event_status)) {
2167
+        if ( ! empty($event_status)) {
2168 2168
             $success = true;
2169 2169
             // determine the event id and set to array.
2170 2170
             $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
@@ -2210,7 +2210,7 @@  discard block
 block discarded – undo
2210 2210
     private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2211 2211
     {
2212 2212
         // grab event id
2213
-        if (! $EVT_ID) {
2213
+        if ( ! $EVT_ID) {
2214 2214
             $msg = esc_html__(
2215 2215
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2216 2216
                 'event_espresso'
@@ -2247,7 +2247,7 @@  discard block
 block discarded – undo
2247 2247
         // use class to change status
2248 2248
         $this->_cpt_model_obj->set_status($event_status);
2249 2249
         $success = $this->_cpt_model_obj->save();
2250
-        if (! $success) {
2250
+        if ( ! $success) {
2251 2251
             $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2252 2252
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2253 2253
             return false;
@@ -2314,7 +2314,7 @@  discard block
 block discarded – undo
2314 2314
      */
2315 2315
     protected function getModelObjNodeGroupPersister(): NodeGroupDao
2316 2316
     {
2317
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2317
+        if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2318 2318
             $this->model_obj_node_group_persister =
2319 2319
                 $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2320 2320
         }
@@ -2639,7 +2639,7 @@  discard block
 block discarded – undo
2639 2639
                                                 . esc_html__(
2640 2640
                                                     '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.',
2641 2641
                                                     'event_espresso'
2642
-                                                ) . '</strong>';
2642
+                                                ).'</strong>';
2643 2643
         $this->display_admin_caf_preview_page('template_settings_tab');
2644 2644
     }
2645 2645
 
@@ -2660,11 +2660,11 @@  discard block
 block discarded – undo
2660 2660
         $this->_set_empty_category_object();
2661 2661
         // only set if we've got an id
2662 2662
         $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2663
-        if (! $category_ID) {
2663
+        if ( ! $category_ID) {
2664 2664
             return;
2665 2665
         }
2666 2666
         $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2667
-        if (! empty($term)) {
2667
+        if ( ! empty($term)) {
2668 2668
             $this->_category->category_name       = $term->name;
2669 2669
             $this->_category->category_identifier = $term->slug;
2670 2670
             $this->_category->category_desc       = $term->description;
@@ -2765,7 +2765,7 @@  discard block
 block discarded – undo
2765 2765
             $category_select_values,
2766 2766
             $this->_category->parent
2767 2767
         );
2768
-        $template_args   = [
2768
+        $template_args = [
2769 2769
             'category'                 => $this->_category,
2770 2770
             'category_select'          => $category_select,
2771 2771
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -2773,7 +2773,7 @@  discard block
 block discarded – undo
2773 2773
             'disable'                  => '',
2774 2774
             'disabled_message'         => false,
2775 2775
         ];
2776
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2776
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2777 2777
         return EEH_Template::display_template($template, $template_args, true);
2778 2778
     }
2779 2779
 
@@ -2869,7 +2869,7 @@  discard block
 block discarded – undo
2869 2869
             return 0;
2870 2870
         }
2871 2871
         $category_ID = $insert_ids['term_id'] ?? 0;
2872
-        if (! $category_ID) {
2872
+        if ( ! $category_ID) {
2873 2873
             EE_Error::add_error(
2874 2874
                 esc_html__(
2875 2875
                     'An error occurred and the category has not been saved to the database.',
@@ -2910,7 +2910,7 @@  discard block
 block discarded – undo
2910 2910
         $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2911 2911
         $search_term = $this->request->getRequestParam('s');
2912 2912
         if ($search_term) {
2913
-            $search_term = '%' . $search_term . '%';
2913
+            $search_term = '%'.$search_term.'%';
2914 2914
             $where['OR'] = [
2915 2915
                 'Term.name'   => ['LIKE', $search_term],
2916 2916
                 'description' => ['LIKE', $search_term],
@@ -2919,7 +2919,7 @@  discard block
 block discarded – undo
2919 2919
         $query_params = [
2920 2920
             $where,
2921 2921
             'order_by'   => [$orderby => $order],
2922
-            'limit'      => $limit . ',' . $per_page,
2922
+            'limit'      => $limit.','.$per_page,
2923 2923
             'force_join' => ['Term'],
2924 2924
         ];
2925 2925
         return $count
Please login to merge, or discard this patch.
admin_pages/events/qtips/EE_Event_List_Table_Tips.lib.php 1 patch
Indentation   +48 added lines, -48 removed lines patch added patch discarded remove patch
@@ -15,33 +15,33 @@  discard block
 block discarded – undo
15 15
  */
16 16
 class EE_Event_List_Table_Tips extends EE_Qtip_Config
17 17
 {
18
-    protected function _set_tips_array()
19
-    {
20
-        $this->_qtipsa = array(
21
-            0 => array(
22
-                'content_id' => 'attendee-column-tip',
23
-                'target'     => '.column-attendees .dashicons-groups',
24
-                'content'    => sprintf(
25
-                    esc_html__('%s Registrations', 'event_espresso'),
26
-                    EEH_Template::pretty_status(
27
-                        RegStatus::APPROVED,
28
-                        false,
29
-                        'sentence'
30
-                    )
31
-                ),
32
-                'options'    => array(
33
-                    'position' => array(
34
-                        'my'     => 'bottom left',
35
-                        'at'     => 'top right',
36
-                        'adjust' => array(
37
-                            'x' => 0,
38
-                            'y' => 0,
39
-                        ),
40
-                    ),
41
-                ),
42
-            ),
43
-            /** temporarily remove status qtips for for list table */
44
-            /**1 => array(
18
+	protected function _set_tips_array()
19
+	{
20
+		$this->_qtipsa = array(
21
+			0 => array(
22
+				'content_id' => 'attendee-column-tip',
23
+				'target'     => '.column-attendees .dashicons-groups',
24
+				'content'    => sprintf(
25
+					esc_html__('%s Registrations', 'event_espresso'),
26
+					EEH_Template::pretty_status(
27
+						RegStatus::APPROVED,
28
+						false,
29
+						'sentence'
30
+					)
31
+				),
32
+				'options'    => array(
33
+					'position' => array(
34
+						'my'     => 'bottom left',
35
+						'at'     => 'top right',
36
+						'adjust' => array(
37
+							'x' => 0,
38
+							'y' => 0,
39
+						),
40
+					),
41
+				),
42
+			),
43
+			/** temporarily remove status qtips for for list table */
44
+			/**1 => array(
45 45
              * 'content_id' => 'ee-event-status-' . EE_Datetime::active,
46 46
              * 'target' => '.event-status-' . EE_Datetime::active,
47 47
              * 'content' => $this->_event_status_legend(EE_Datetime::active),
@@ -111,28 +111,28 @@  discard block
 block discarded – undo
111 111
              * )
112 112
              * )
113 113
              * ),/**/
114
-        );
115
-    }
114
+		);
115
+	}
116 116
 
117
-    /**
118
-     * output the relevant ee-status-legend with the designated status highlighted.
119
-     *
120
-     * @param  EE_Datetime constant $status What status is set (by class)
121
-     * @return string         The status legend with the related status highlighted
122
-     */
123
-    private function _event_status_legend($status)
124
-    {
117
+	/**
118
+	 * output the relevant ee-status-legend with the designated status highlighted.
119
+	 *
120
+	 * @param  EE_Datetime constant $status What status is set (by class)
121
+	 * @return string         The status legend with the related status highlighted
122
+	 */
123
+	private function _event_status_legend($status)
124
+	{
125 125
 
126
-        $status_array = array(
127
-            'active_status'    => EE_Datetime::active,
128
-            'upcoming_status'  => EE_Datetime::upcoming,
129
-            'postponed_status' => EE_Datetime::postponed,
130
-            'sold_out_status'  => EE_Datetime::sold_out,
131
-            'cancelled_status' => EE_Datetime::cancelled,
132
-            'expired_status'   => EE_Datetime::expired,
133
-            'inactive_status'  => EE_Datetime::inactive,
134
-        );
126
+		$status_array = array(
127
+			'active_status'    => EE_Datetime::active,
128
+			'upcoming_status'  => EE_Datetime::upcoming,
129
+			'postponed_status' => EE_Datetime::postponed,
130
+			'sold_out_status'  => EE_Datetime::sold_out,
131
+			'cancelled_status' => EE_Datetime::cancelled,
132
+			'expired_status'   => EE_Datetime::expired,
133
+			'inactive_status'  => EE_Datetime::inactive,
134
+		);
135 135
 
136
-        return EEH_Template::status_legend($status_array, $status);
137
-    }
136
+		return EEH_Template::status_legend($status_array, $status);
137
+	}
138 138
 }
Please login to merge, or discard this patch.
admin_pages/events/help_tabs/event_editor_save_new_event.help_tab.php 1 patch
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -5,62 +5,62 @@
 block discarded – undo
5 5
 </p>
6 6
 <p class="ee-attention">
7 7
     <?php printf(
8
-        esc_html__(
9
-            'Notice: Due to a %1$scurrent bug in the WordPress core%2$s, your event should always have at least a title or description or excerpt. Saving an event without at least one of these fields filled out with information will result in your event not saving correctly. You will then need to recreate your event by clicking on the Add Event button.',
10
-            'event_espresso'
11
-        ),
12
-        '<a href="https://core.trac.wordpress.org/ticket/17115#comment:15">',
13
-        '</a>'
14
-    ); ?>
8
+		esc_html__(
9
+			'Notice: Due to a %1$scurrent bug in the WordPress core%2$s, your event should always have at least a title or description or excerpt. Saving an event without at least one of these fields filled out with information will result in your event not saving correctly. You will then need to recreate your event by clicking on the Add Event button.',
10
+			'event_espresso'
11
+		),
12
+		'<a href="https://core.trac.wordpress.org/ticket/17115#comment:15">',
13
+		'</a>'
14
+	); ?>
15 15
 </p>
16 16
 <ul>
17 17
     <li>
18 18
         <strong><?php esc_html_e('Status', 'event_espresso'); ?></strong><br />
19 19
         <?php esc_html_e(
20
-            'The following statuses are available: Pending Review, Draft, Cancelled, Postponed, and Sold Out. A status of pending review will set an event to draft until an event administrator has approved the event. A status of draft will save an event but it will be unpublished. A status of cancelled means that an event will no longer take place. A status of postponed means that an event is not currently scheduled but may be in the future. A status of sold out means that tickets are no longer available for an event.',
21
-            'event_espresso'
22
-        ); ?>
20
+			'The following statuses are available: Pending Review, Draft, Cancelled, Postponed, and Sold Out. A status of pending review will set an event to draft until an event administrator has approved the event. A status of draft will save an event but it will be unpublished. A status of cancelled means that an event will no longer take place. A status of postponed means that an event is not currently scheduled but may be in the future. A status of sold out means that tickets are no longer available for an event.',
21
+			'event_espresso'
22
+		); ?>
23 23
     </li>
24 24
     <li>
25 25
         <strong><?php esc_html_e('Visibility', 'event_espresso'); ?></strong><br />
26 26
         <?php esc_html_e(
27
-            'The following visibility options are available: Public, Password Protected, and Private. An event that is set to public will be accessible by anyone. An event that is set to password protected will only be available to event administrators and individuals who know the password to access the event registration. An event that is set to private will completely be hidden from public view.',
28
-            'event_espresso'
29
-        ); ?>
27
+			'The following visibility options are available: Public, Password Protected, and Private. An event that is set to public will be accessible by anyone. An event that is set to password protected will only be available to event administrators and individuals who know the password to access the event registration. An event that is set to private will completely be hidden from public view.',
28
+			'event_espresso'
29
+		); ?>
30 30
     </li>
31 31
     <li>
32 32
         <strong><?php esc_html_e('Publish', 'event_espresso'); ?></strong><br />
33 33
         <?php esc_html_e(
34
-            'An event can be published immediately or you can schedule it to be published at a later date in the future.',
35
-            'event_espresso'
36
-        ); ?>
34
+			'An event can be published immediately or you can schedule it to be published at a later date in the future.',
35
+			'event_espresso'
36
+		); ?>
37 37
     </li>
38 38
     <li>
39 39
         <strong><?php esc_html_e('Approved Registrations', 'event_espresso'); ?></strong><br />
40 40
         <?php esc_html_e(
41
-            'Shows number of registrants who are attending event. Click on the Approved Registrations link to be brought to a page where you can be a list of registrants who are attending the event.',
42
-            'event_espresso'
43
-        ); ?>
41
+			'Shows number of registrants who are attending event. Click on the Approved Registrations link to be brought to a page where you can be a list of registrants who are attending the event.',
42
+			'event_espresso'
43
+		); ?>
44 44
     </li>
45 45
     <li>
46 46
         <strong><?php esc_html_e('Pending Payment Registrations', 'event_espresso'); ?></strong><br />
47 47
         <?php esc_html_e(
48
-            'Shows number of registrants who need to pay to attend the event. Click on the Pending Payment Registrations link to be brought to a page where you can be a list of registrants who need to pay for this event.',
49
-            'event_espresso'
50
-        ); ?>
48
+			'Shows number of registrants who need to pay to attend the event. Click on the Pending Payment Registrations link to be brought to a page where you can be a list of registrants who need to pay for this event.',
49
+			'event_espresso'
50
+		); ?>
51 51
     </li>
52 52
     <li>
53 53
         <strong><?php esc_html_e('Not Approved / Awaiting Review Registrations', 'event_espresso'); ?></strong><br />
54 54
         <?php esc_html_e(
55
-            'Shows number of registrants who cannot attend the event because they are awaiting review. Click on the Not Approved / Awaiting Review Registrations link to be brought to a page where you can see a list of registrants who cannot attend the event.',
56
-            'event_espresso'
57
-        ); ?>
55
+			'Shows number of registrants who cannot attend the event because they are awaiting review. Click on the Not Approved / Awaiting Review Registrations link to be brought to a page where you can see a list of registrants who cannot attend the event.',
56
+			'event_espresso'
57
+		); ?>
58 58
     </li>
59 59
     <li>
60 60
         <strong><?php esc_html_e('Move to Trash', 'event_espresso'); ?></strong><br />
61 61
         <?php esc_html_e(
62
-            'Click the Move to Trash link to move an event to the trash. Note: an event can only be deleted after associated payments have been removed and registrations have been removed.',
63
-            'event_espresso'
64
-        ); ?>
62
+			'Click the Move to Trash link to move an event to the trash. Note: an event can only be deleted after associated payments have been removed and registrations have been removed.',
63
+			'event_espresso'
64
+		); ?>
65 65
     </li>
66 66
 </ul>
Please login to merge, or discard this patch.
admin_pages/events/help_tabs/events_default_settings_status.help_tab.php 1 patch
Indentation   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -13,12 +13,12 @@  discard block
 block discarded – undo
13 13
     </strong>
14 14
     <br />
15 15
     <?php sprintf(
16
-        esc_html__(
17
-            'A status of %s means that a registration has been accepted as complete. The registration will count towards the registration limit, remaining tickets, and calculations for available seats. Payments (if necessary) can also be made by primary registrants with this status.',
18
-            'event_espresso'
19
-        ),
20
-        EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
21
-    );
16
+		esc_html__(
17
+			'A status of %s means that a registration has been accepted as complete. The registration will count towards the registration limit, remaining tickets, and calculations for available seats. Payments (if necessary) can also be made by primary registrants with this status.',
18
+			'event_espresso'
19
+		),
20
+		EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
21
+	);
22 22
 ?>
23 23
 </p>
24 24
 <p>
@@ -27,14 +27,14 @@  discard block
 block discarded – undo
27 27
     </strong>
28 28
     <br />
29 29
     <?php printf(
30
-        esc_html__(
31
-            'A status of %1$s means that a registration has not paid but they ARE able to make payments (if necessary).  %2$s registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  If registration for a free event occurs, then registrations are automatically set to %3$s. For paid tickets, %1$s registrations are set to %3$s when full payment is recorded.',
32
-            'event_espresso'
33
-        ),
34
-        EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
35
-        EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
36
-        EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
37
-    );
30
+		esc_html__(
31
+			'A status of %1$s means that a registration has not paid but they ARE able to make payments (if necessary).  %2$s registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  If registration for a free event occurs, then registrations are automatically set to %3$s. For paid tickets, %1$s registrations are set to %3$s when full payment is recorded.',
32
+			'event_espresso'
33
+		),
34
+		EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
35
+		EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
36
+		EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
37
+	);
38 38
 ?>
39 39
 </p>
40 40
 <p>
@@ -43,12 +43,12 @@  discard block
 block discarded – undo
43 43
     </strong>
44 44
     <br />
45 45
     <?php printf(
46
-        esc_html__(
47
-            'A status of %1$s means that a registration has not paid and they cannot make payments for towards an event.  Un-approved registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  This setting differs from the "%2$s" default in that free ticket registrations and paid in full ticket registrations do NOT automatically switch the Registration to %3$s.  Instead, the event admin must manually set the registration to either "%2$s" for registrations requiring payments, or "%3$s" for free events.',
48
-            'event_espresso'
49
-        ),
50
-        EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
51
-        EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'upper'),
52
-        EEH_Template::pretty_status(RegStatus::APPROVED, false, 'upper')
53
-    ); ?>
46
+		esc_html__(
47
+			'A status of %1$s means that a registration has not paid and they cannot make payments for towards an event.  Un-approved registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  This setting differs from the "%2$s" default in that free ticket registrations and paid in full ticket registrations do NOT automatically switch the Registration to %3$s.  Instead, the event admin must manually set the registration to either "%2$s" for registrations requiring payments, or "%3$s" for free events.',
48
+			'event_espresso'
49
+		),
50
+		EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
51
+		EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'upper'),
52
+		EEH_Template::pretty_status(RegStatus::APPROVED, false, 'upper')
53
+	); ?>
54 54
 </p>
Please login to merge, or discard this patch.
events/help_tabs/event_editor_event_registration_options.help_tab.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -13,35 +13,35 @@  discard block
 block discarded – undo
13 13
         <h5><?php esc_html_e('Active Status', 'event_espresso'); ?></h5>
14 14
         <p>
15 15
         <?php esc_html_e(
16
-            'Shows the current status for an event. The status indicator will show Expired (past), Active (present), Upcoming (future) based on the date of the event. There are also special, custom statuses that can be selected. These include Postponed, Sold Out, and Cancelled.',
17
-            'event_espresso'
18
-        ); ?>
16
+			'Shows the current status for an event. The status indicator will show Expired (past), Active (present), Upcoming (future) based on the date of the event. There are also special, custom statuses that can be selected. These include Postponed, Sold Out, and Cancelled.',
17
+			'event_espresso'
18
+		); ?>
19 19
         </p>
20 20
     </li>
21 21
     <li>
22 22
         <h5>
23 23
             <?php esc_html_e(
24
-                'Maximum number of tickets allowed per order for this event',
25
-                'event_espresso'
26
-            ); ?>
24
+				'Maximum number of tickets allowed per order for this event',
25
+				'event_espresso'
26
+			); ?>
27 27
         </h5>
28 28
         <p>
29 29
         <?php esc_html_e('Control how many tickets can be purchased in a single order.', 'event_espresso'); ?>
30 30
         </p>
31 31
         <div class="ee-attention">
32 32
             <?php esc_html_e(
33
-                'Notice: Allowing too many registrations to be processed with a single order can cause transactions to fail. The decision of how many tickets you allow to be purchased per order should be influenced by your web hosting, how much traffic you get to your website, and the complexity of your registration forms. A more powerful web server will reduce the likelihood of transactions failing.',
34
-                'event_espresso'
35
-            ); ?>
33
+				'Notice: Allowing too many registrations to be processed with a single order can cause transactions to fail. The decision of how many tickets you allow to be purchased per order should be influenced by your web hosting, how much traffic you get to your website, and the complexity of your registration forms. A more powerful web server will reduce the likelihood of transactions failing.',
34
+				'event_espresso'
35
+			); ?>
36 36
         </div>
37 37
     </li>
38 38
     <li>
39 39
         <h5><?php esc_html_e('Alternative Registration Page', 'event_espresso'); ?></h5>
40 40
         <p>
41 41
         <?php esc_html_e(
42
-            'Enter another registration URL (website address). This field is optional.',
43
-            'event_espresso'
44
-        ); ?>
42
+			'Enter another registration URL (website address). This field is optional.',
43
+			'event_espresso'
44
+		); ?>
45 45
         </p>
46 46
     </li>
47 47
     <li>
@@ -55,66 +55,66 @@  discard block
 block discarded – undo
55 55
         <p>
56 56
             <strong>
57 57
                 <?php echo esc_html(
58
-                    EEH_Template::pretty_status(
59
-                        RegStatus::APPROVED,
60
-                        false,
61
-                        'sentence'
62
-                    )
63
-                ); ?>
58
+					EEH_Template::pretty_status(
59
+						RegStatus::APPROVED,
60
+						false,
61
+						'sentence'
62
+					)
63
+				); ?>
64 64
             </strong>
65 65
             <br />
66 66
             <?php printf(
67
-                /* translators: Approved Registration status */
68
-                esc_html__(
69
-                    'A status of %s means that a registration has been accepted as complete. The registration will count towards the registration limit, remaining tickets, and calculations for available seats. Payments (if necessary) can also be made by primary registrants with this status.',
70
-                    'event_espresso'
71
-                ),
72
-                EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
73
-            ); ?>
67
+				/* translators: Approved Registration status */
68
+				esc_html__(
69
+					'A status of %s means that a registration has been accepted as complete. The registration will count towards the registration limit, remaining tickets, and calculations for available seats. Payments (if necessary) can also be made by primary registrants with this status.',
70
+					'event_espresso'
71
+				),
72
+				EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
73
+			); ?>
74 74
         </p>
75 75
         <p>
76 76
             <strong>
77 77
                 <?php echo esc_html(
78
-                    EEH_Template::pretty_status(
79
-                        RegStatus::PENDING_PAYMENT,
80
-                        false,
81
-                        'sentence'
82
-                    )
83
-                ); ?>
78
+					EEH_Template::pretty_status(
79
+						RegStatus::PENDING_PAYMENT,
80
+						false,
81
+						'sentence'
82
+					)
83
+				); ?>
84 84
             </strong>
85 85
             <br />
86 86
             <?php printf(
87
-                /* translators: 1: Pending Payment, 2: Pending Payment, 3: Approved */
88
-                esc_html__(
89
-                    'A status of %1$s means that a registration has not paid but they ARE able to make payments (if necessary).  %2$s registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  If registration for a free event occurs, then registrations are automatically set to %3$s. For paid tickets, %1$s registrations are set to %3$s when full payment is recorded.',
90
-                    'event_espresso'
91
-                ),
92
-                EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
93
-                EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
94
-                EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
95
-            ); ?>
87
+				/* translators: 1: Pending Payment, 2: Pending Payment, 3: Approved */
88
+				esc_html__(
89
+					'A status of %1$s means that a registration has not paid but they ARE able to make payments (if necessary).  %2$s registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  If registration for a free event occurs, then registrations are automatically set to %3$s. For paid tickets, %1$s registrations are set to %3$s when full payment is recorded.',
90
+					'event_espresso'
91
+				),
92
+				EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
93
+				EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'),
94
+				EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
95
+			); ?>
96 96
         </p>
97 97
         <p>
98 98
             <strong>
99 99
                 <?php echo esc_html(
100
-                    EEH_Template::pretty_status(
101
-                        RegStatus::AWAITING_REVIEW,
102
-                        false,
103
-                        'sentence'
104
-                    )
105
-                ); ?>
100
+					EEH_Template::pretty_status(
101
+						RegStatus::AWAITING_REVIEW,
102
+						false,
103
+						'sentence'
104
+					)
105
+				); ?>
106 106
             </strong>
107 107
             <br />
108 108
             <?php printf(
109
-            /* translators: 1: Not Approved, 2: Pending Payment, 3: Approved */
110
-                esc_html__(
111
-                    'A status of %1$s means that a registration has not paid and they cannot make payments for towards an event.  Un-approved registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  This setting differs from the "%2$s" default in that free ticket registrations and paid in full ticket registrations do NOT automatically switch the Registration to %3$s.  Instead, the event admin must manually set the registration to either "%2$s" for registrations requiring payments, or "%3$s" for free events.',
112
-                    'event_espresso'
113
-                ),
114
-                EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
115
-                EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT),
116
-                EEH_Template::pretty_status(RegStatus::APPROVED)
117
-            ); ?>
109
+			/* translators: 1: Not Approved, 2: Pending Payment, 3: Approved */
110
+				esc_html__(
111
+					'A status of %1$s means that a registration has not paid and they cannot make payments for towards an event.  Un-approved registrations do NOT count towards registration limits, remaining tickets, and calculations for available seats.  This setting differs from the "%2$s" default in that free ticket registrations and paid in full ticket registrations do NOT automatically switch the Registration to %3$s.  Instead, the event admin must manually set the registration to either "%2$s" for registrations requiring payments, or "%3$s" for free events.',
112
+					'event_espresso'
113
+				),
114
+				EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'),
115
+				EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT),
116
+				EEH_Template::pretty_status(RegStatus::APPROVED)
117
+			); ?>
118 118
         </p>
119 119
     </li>
120 120
 </ul>
Please login to merge, or discard this patch.
admin_pages/events/templates/event_publish_box_extras.template.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -21,9 +21,9 @@  discard block
 block discarded – undo
21 21
     >
22 22
         <span class='ee-reg-list-link__reg-count'><?php echo absint($approved_regs); ?></span>
23 23
         <?php printf(
24
-            esc_html__('%s Registrations', 'event_espresso'),
25
-            EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
26
-        ); ?>
24
+			esc_html__('%s Registrations', 'event_espresso'),
25
+			EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence')
26
+		); ?>
27 27
         <span class='dashicons dashicons-external'></span>
28 28
     </a>
29 29
 </div>
@@ -35,9 +35,9 @@  discard block
 block discarded – undo
35 35
     >
36 36
         <span class='ee-reg-list-link__reg-count'><?php echo absint($pending_payment_regs); ?></span>
37 37
         <?php printf(
38
-            esc_html__('%s Registrations', 'event_espresso'),
39
-            EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence')
40
-        ); ?>
38
+			esc_html__('%s Registrations', 'event_espresso'),
39
+			EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence')
40
+		); ?>
41 41
         <span class='dashicons dashicons-external'></span>
42 42
     </a>
43 43
 </div>
@@ -49,9 +49,9 @@  discard block
 block discarded – undo
49 49
     >
50 50
         <span class='ee-reg-list-link__reg-count'><?php echo absint($not_approved_regs); ?></span>
51 51
         <?php printf(
52
-            esc_html__('%s Registrations', 'event_espresso'),
53
-            EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence')
54
-        ); ?>
52
+			esc_html__('%s Registrations', 'event_espresso'),
53
+			EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence')
54
+		); ?>
55 55
         <span class='dashicons dashicons-external'></span>
56 56
     </a>
57 57
 
Please login to merge, or discard this patch.