Completed
Branch master (8de7dd)
by
unknown
06:29
created
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Indentation   +3844 added lines, -3844 removed lines patch added patch discarded remove patch
@@ -25,2286 +25,2286 @@  discard block
 block discarded – undo
25 25
  */
26 26
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
27 27
 {
28
-    private ?EE_Registration $_registration = null;
29
-
30
-    private ?EE_Event $_reg_event = null;
31
-
32
-    private array $session_data = [];
33
-
34
-    private static array $_reg_status = [];
35
-
36
-    /**
37
-     * Form for displaying the custom questions for this registration.
38
-     * This gets used a few times throughout the request so it's best to cache it
39
-     */
40
-    protected ?EE_Registration_Custom_Questions_Form $_reg_custom_questions_form = null;
41
-
42
-    private ?EEM_Registration $registration_model = null;
43
-
44
-    private ?EEM_Attendee $attendee_model = null;
45
-
46
-    private ?EEM_Event $event_model = null;
47
-
48
-    private ?EEM_Status $status_model = null;
49
-
50
-    /**
51
-     * @var EE_Attendee|null
52
-     */
53
-    protected $_cpt_model_obj;
54
-
55
-
56
-    /**
57
-     * @param bool $routing
58
-     * @throws InvalidArgumentException
59
-     * @throws InvalidDataTypeException
60
-     * @throws InvalidInterfaceException
61
-     * @throws ReflectionException
62
-     */
63
-    public function __construct($routing = true)
64
-    {
65
-        parent::__construct($routing);
66
-        $this->cpt_editpost_route = 'edit_attendee';
67
-        add_action('wp_loaded', [$this, 'wp_loaded']);
68
-    }
69
-
70
-
71
-    /**
72
-     * @return EEM_Registration
73
-     * @throws InvalidArgumentException
74
-     * @throws InvalidDataTypeException
75
-     * @throws InvalidInterfaceException
76
-     * @since 4.10.2.p
77
-     */
78
-    protected function getRegistrationModel(): EEM_Registration
79
-    {
80
-        if (! $this->registration_model instanceof EEM_Registration) {
81
-            $this->registration_model = $this->loader->getShared('EEM_Registration');
82
-        }
83
-        return $this->registration_model;
84
-    }
85
-
86
-
87
-    /**
88
-     * @return EEM_Attendee
89
-     * @throws InvalidArgumentException
90
-     * @throws InvalidDataTypeException
91
-     * @throws InvalidInterfaceException
92
-     * @since 4.10.2.p
93
-     */
94
-    protected function getAttendeeModel(): EEM_Attendee
95
-    {
96
-        if (! $this->attendee_model instanceof EEM_Attendee) {
97
-            $this->attendee_model = $this->loader->getShared('EEM_Attendee');
98
-        }
99
-        return $this->attendee_model;
100
-    }
101
-
102
-
103
-    /**
104
-     * @return EEM_Event
105
-     * @throws InvalidArgumentException
106
-     * @throws InvalidDataTypeException
107
-     * @throws InvalidInterfaceException
108
-     * @since 4.10.2.p
109
-     */
110
-    protected function getEventModel(): EEM_Event
111
-    {
112
-        if (! $this->event_model instanceof EEM_Event) {
113
-            $this->event_model = $this->loader->getShared('EEM_Event');
114
-        }
115
-        return $this->event_model;
116
-    }
117
-
118
-
119
-    /**
120
-     * @return EEM_Status
121
-     * @throws InvalidArgumentException
122
-     * @throws InvalidDataTypeException
123
-     * @throws InvalidInterfaceException
124
-     * @since 4.10.2.p
125
-     */
126
-    protected function getStatusModel(): EEM_Status
127
-    {
128
-        if (! $this->status_model instanceof EEM_Status) {
129
-            $this->status_model = $this->loader->getShared('EEM_Status');
130
-        }
131
-        return $this->status_model;
132
-    }
133
-
134
-
135
-    public function wp_loaded()
136
-    {
137
-        // when adding a new registration...
138
-        $action = $this->request->getRequestParam('action');
139
-        if ($action === 'new_registration') {
140
-            EE_System::do_not_cache();
141
-            if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
142
-                // and it's NOT the attendee information reg step
143
-                // force cookie expiration by setting time to last week
144
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
145
-                // and update the global
146
-                $_COOKIE['ee_registration_added'] = 0;
147
-            }
148
-        }
149
-    }
150
-
151
-
152
-    protected function _init_page_props()
153
-    {
154
-        $this->page_slug        = REG_PG_SLUG;
155
-        $this->_admin_base_url  = REG_ADMIN_URL;
156
-        $this->_admin_base_path = REG_ADMIN;
157
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
158
-        $this->_cpt_routes      = [
159
-            'add_new_attendee' => 'espresso_attendees',
160
-            'edit_attendee'    => 'espresso_attendees',
161
-            'insert_attendee'  => 'espresso_attendees',
162
-            'update_attendee'  => 'espresso_attendees',
163
-        ];
164
-        $this->_cpt_model_names = [
165
-            'add_new_attendee' => 'EEM_Attendee',
166
-            'edit_attendee'    => 'EEM_Attendee',
167
-        ];
168
-        $this->_cpt_edit_routes = [
169
-            'espresso_attendees' => 'edit_attendee',
170
-        ];
171
-        $this->_pagenow_map     = [
172
-            'add_new_attendee' => 'post-new.php',
173
-            'edit_attendee'    => 'post.php',
174
-            'trash'            => 'post.php',
175
-        ];
176
-        add_action('edit_form_after_title', [$this, 'after_title_form_fields']);
177
-        // add filters so that the comment urls don't take users to a confusing 404 page
178
-        add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
179
-    }
180
-
181
-
182
-    /**
183
-     * @param string     $link    The comment permalink with '#comment-$id' appended.
184
-     * @param WP_Comment $comment The current comment object.
185
-     * @return string
186
-     */
187
-    public function clear_comment_link(string $link, WP_Comment $comment): string
188
-    {
189
-        // gotta make sure this only happens on this route
190
-        $post_type = get_post_type($comment->comment_post_ID);
191
-        if ($post_type === EspressoPostType::ATTENDEES) {
192
-            return '#commentsdiv';
193
-        }
194
-        return $link;
195
-    }
196
-
197
-
198
-    protected function _ajax_hooks()
199
-    {
200
-    }
201
-
202
-
203
-    protected function _define_page_props()
204
-    {
205
-        $this->_admin_page_title = $this->page_label;
206
-        $this->_labels           = [
207
-            'buttons'                      => [
208
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
209
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
210
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
211
-                'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
212
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
213
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
214
-            ],
215
-            'publishbox'                   => [
216
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
217
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
218
-            ],
219
-            'hide_add_button_on_cpt_route' => [
220
-                'edit_attendee' => true,
221
-            ],
222
-        ];
223
-    }
224
-
225
-
226
-    /**
227
-     * grab url requests and route them
228
-     *
229
-     * @return void
230
-     * @throws EE_Error
231
-     * @throws ReflectionException
232
-     */
233
-    public function _set_page_routes()
234
-    {
235
-        $this->_get_registration_status_array();
236
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
237
-        $REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
238
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
239
-        $ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
240
-        $this->_page_routes = [
241
-            'default'                             => [
242
-                'func'       => [$this, '_registrations_overview_list_table'],
243
-                'capability' => 'ee_read_registrations',
244
-            ],
245
-            'view_registration'                   => [
246
-                'func'       => [$this, '_registration_details'],
247
-                'capability' => 'ee_read_registration',
248
-                'obj_id'     => $REG_ID,
249
-            ],
250
-            'edit_registration'                   => [
251
-                'func'       => [$this, '_update_attendee_registration_form'],
252
-                'noheader'           => true,
253
-                'headers_sent_route' => 'view_registration',
254
-                'capability'         => 'ee_edit_registration',
255
-                'obj_id'             => $REG_ID,
256
-                '_REG_ID'            => $REG_ID,
257
-            ],
258
-            'trash_registrations'                 => [
259
-                'func'       => [$this, '_trash_or_restore_registrations'],
260
-                'args'       => ['trash' => true],
261
-                'noheader'   => true,
262
-                'capability' => 'ee_delete_registrations',
263
-            ],
264
-            'restore_registrations'               => [
265
-                'func'       => [$this, '_trash_or_restore_registrations'],
266
-                'args'       => ['trash' => false],
267
-                'noheader'   => true,
268
-                'capability' => 'ee_delete_registrations',
269
-            ],
270
-            'delete_registrations'                => [
271
-                'func'       => [$this, '_delete_registrations'],
272
-                'noheader'   => true,
273
-                'capability' => 'ee_delete_registrations',
274
-            ],
275
-            'new_registration'                    => [
276
-                'func'       => [$this, 'new_registration'],
277
-                'capability' => 'ee_edit_registrations',
278
-            ],
279
-            'process_reg_step'                    => [
280
-                'func'       => [$this, 'process_reg_step'],
281
-                'noheader'   => true,
282
-                'capability' => 'ee_edit_registrations',
283
-            ],
284
-            'redirect_to_txn'                     => [
285
-                'func'       => [$this, 'redirect_to_txn'],
286
-                'noheader'   => true,
287
-                'capability' => 'ee_edit_registrations',
288
-            ],
289
-            'change_reg_status'                   => [
290
-                'func'       => [$this, '_change_reg_status'],
291
-                'noheader'   => true,
292
-                'capability' => 'ee_edit_registration',
293
-                'obj_id'     => $REG_ID,
294
-            ],
295
-            'approve_registration'                => [
296
-                'func'       => [$this, 'approve_registration'],
297
-                'noheader'   => true,
298
-                'capability' => 'ee_edit_registration',
299
-                'obj_id'     => $REG_ID,
300
-            ],
301
-            'approve_and_notify_registration'     => [
302
-                'func'       => [$this, 'approve_registration'],
303
-                'noheader'   => true,
304
-                'args'       => [true],
305
-                'capability' => 'ee_edit_registration',
306
-                'obj_id'     => $REG_ID,
307
-            ],
308
-            'approve_registrations'               => [
309
-                'func'       => [$this, 'bulk_action_on_registrations'],
310
-                'noheader'   => true,
311
-                'capability' => 'ee_edit_registrations',
312
-                'args'       => ['approve'],
313
-            ],
314
-            'approve_and_notify_registrations'    => [
315
-                'func'       => [$this, 'bulk_action_on_registrations'],
316
-                'noheader'   => true,
317
-                'capability' => 'ee_edit_registrations',
318
-                'args'       => ['approve', true],
319
-            ],
320
-            'decline_registration'                => [
321
-                'func'       => [$this, 'decline_registration'],
322
-                'noheader'   => true,
323
-                'capability' => 'ee_edit_registration',
324
-                'obj_id'     => $REG_ID,
325
-            ],
326
-            'decline_and_notify_registration'     => [
327
-                'func'       => [$this, 'decline_registration'],
328
-                'noheader'   => true,
329
-                'args'       => [true],
330
-                'capability' => 'ee_edit_registration',
331
-                'obj_id'     => $REG_ID,
332
-            ],
333
-            'decline_registrations'               => [
334
-                'func'       => [$this, 'bulk_action_on_registrations'],
335
-                'noheader'   => true,
336
-                'capability' => 'ee_edit_registrations',
337
-                'args'       => ['decline'],
338
-            ],
339
-            'decline_and_notify_registrations'    => [
340
-                'func'       => [$this, 'bulk_action_on_registrations'],
341
-                'noheader'   => true,
342
-                'capability' => 'ee_edit_registrations',
343
-                'args'       => ['decline', true],
344
-            ],
345
-            'pending_registration'                => [
346
-                'func'       => [$this, 'pending_registration'],
347
-                'noheader'   => true,
348
-                'capability' => 'ee_edit_registration',
349
-                'obj_id'     => $REG_ID,
350
-            ],
351
-            'pending_and_notify_registration'     => [
352
-                'func'       => [$this, 'pending_registration'],
353
-                'noheader'   => true,
354
-                'args'       => [true],
355
-                'capability' => 'ee_edit_registration',
356
-                'obj_id'     => $REG_ID,
357
-            ],
358
-            'pending_registrations'               => [
359
-                'func'       => [$this, 'bulk_action_on_registrations'],
360
-                'noheader'   => true,
361
-                'capability' => 'ee_edit_registrations',
362
-                'args'       => ['pending'],
363
-            ],
364
-            'pending_and_notify_registrations'    => [
365
-                'func'       => [$this, 'bulk_action_on_registrations'],
366
-                'noheader'   => true,
367
-                'capability' => 'ee_edit_registrations',
368
-                'args'       => ['pending', true],
369
-            ],
370
-            'no_approve_registration'             => [
371
-                'func'       => [$this, 'not_approve_registration'],
372
-                'noheader'   => true,
373
-                'capability' => 'ee_edit_registration',
374
-                'obj_id'     => $REG_ID,
375
-            ],
376
-            'no_approve_and_notify_registration'  => [
377
-                'func'       => [$this, 'not_approve_registration'],
378
-                'noheader'   => true,
379
-                'args'       => [true],
380
-                'capability' => 'ee_edit_registration',
381
-                'obj_id'     => $REG_ID,
382
-            ],
383
-            'no_approve_registrations'            => [
384
-                'func'       => [$this, 'bulk_action_on_registrations'],
385
-                'noheader'   => true,
386
-                'capability' => 'ee_edit_registrations',
387
-                'args'       => ['not_approve'],
388
-            ],
389
-            'no_approve_and_notify_registrations' => [
390
-                'func'       => [$this, 'bulk_action_on_registrations'],
391
-                'noheader'   => true,
392
-                'capability' => 'ee_edit_registrations',
393
-                'args'       => ['not_approve', true],
394
-            ],
395
-            'cancel_registration'                 => [
396
-                'func'       => [$this, 'cancel_registration'],
397
-                'noheader'   => true,
398
-                'capability' => 'ee_edit_registration',
399
-                'obj_id'     => $REG_ID,
400
-            ],
401
-            'cancel_and_notify_registration'      => [
402
-                'func'       => [$this, 'cancel_registration'],
403
-                'noheader'   => true,
404
-                'args'       => [true],
405
-                'capability' => 'ee_edit_registration',
406
-                'obj_id'     => $REG_ID,
407
-            ],
408
-            'cancel_registrations'                => [
409
-                'func'       => [$this, 'bulk_action_on_registrations'],
410
-                'noheader'   => true,
411
-                'capability' => 'ee_edit_registrations',
412
-                'args'       => ['cancel'],
413
-            ],
414
-            'cancel_and_notify_registrations'     => [
415
-                'func'       => [$this, 'bulk_action_on_registrations'],
416
-                'noheader'   => true,
417
-                'capability' => 'ee_edit_registrations',
418
-                'args'       => ['cancel', true],
419
-            ],
420
-            'wait_list_registration'              => [
421
-                'func'       => [$this, 'wait_list_registration'],
422
-                'noheader'   => true,
423
-                'capability' => 'ee_edit_registration',
424
-                'obj_id'     => $REG_ID,
425
-            ],
426
-            'wait_list_and_notify_registration'   => [
427
-                'func'       => [$this, 'wait_list_registration'],
428
-                'noheader'   => true,
429
-                'args'       => [true],
430
-                'capability' => 'ee_edit_registration',
431
-                'obj_id'     => $REG_ID,
432
-            ],
433
-            'contact_list'                        => [
434
-                'func'       => [$this, '_attendee_contact_list_table'],
435
-                'capability' => 'ee_read_contacts',
436
-            ],
437
-            'add_new_attendee'                    => [
438
-                'func'       => [$this, '_create_new_cpt_item'],
439
-                'args' => [
440
-                    'new_attendee' => true,
441
-                    'capability'   => 'ee_edit_contacts',
442
-                ],
443
-            ],
444
-            'edit_attendee'                       => [
445
-                'func'       => [$this, '_edit_cpt_item'],
446
-                'capability' => 'ee_edit_contacts',
447
-                'obj_id'     => $ATT_ID,
448
-            ],
449
-            'duplicate_attendee'                  => [
450
-                'func'       => [$this, '_duplicate_attendee'],
451
-                'noheader'   => true,
452
-                'capability' => 'ee_edit_contacts',
453
-                'obj_id'     => $ATT_ID,
454
-            ],
455
-            'insert_attendee'                     => [
456
-                'func'       => [$this, '_insert_or_update_attendee'],
457
-                'args'       => [
458
-                    'new_attendee' => true,
459
-                ],
460
-                'noheader'   => true,
461
-                'capability' => 'ee_edit_contacts',
462
-            ],
463
-            'update_attendee'                     => [
464
-                'func'       => [$this, '_insert_or_update_attendee'],
465
-                'args'       => [
466
-                    'new_attendee' => false,
467
-                ],
468
-                'noheader'   => true,
469
-                'capability' => 'ee_edit_contacts',
470
-                'obj_id'     => $ATT_ID,
471
-            ],
472
-            'trash_attendees'                     => [
473
-                'func'       => [$this, '_trash_or_restore_attendees'],
474
-                'args'       => [
475
-                    'trash' => 'true',
476
-                ],
477
-                'noheader'   => true,
478
-                'capability' => 'ee_delete_contacts',
479
-            ],
480
-            'trash_attendee'                      => [
481
-                'func'       => [$this, '_trash_or_restore_attendees'],
482
-                'args'       => [
483
-                    'trash' => true,
484
-                ],
485
-                'noheader'   => true,
486
-                'capability' => 'ee_delete_contacts',
487
-                'obj_id'     => $ATT_ID,
488
-            ],
489
-            'restore_attendees'                   => [
490
-                'func'       => [$this, '_trash_or_restore_attendees'],
491
-                'args'       => [
492
-                    'trash' => false,
493
-                ],
494
-                'noheader'   => true,
495
-                'capability' => 'ee_delete_contacts',
496
-                'obj_id'     => $ATT_ID,
497
-            ],
498
-            'delete_attendee'                     => [
499
-                'func'       => [$this, 'deleteAttendees'],
500
-                'capability' => 'ee_delete_contacts',
501
-                'obj_id'     => $ATT_ID,
502
-                'noheader'   => true,
503
-            ],
504
-            'delete_attendees'                    => [
505
-                'func'       => [$this, 'deleteAttendees'],
506
-                'capability' => 'ee_delete_contacts',
507
-                'noheader'   => true,
508
-            ],
509
-            'resend_registration'                 => [
510
-                'func'       => [$this, '_resend_registration'],
511
-                'noheader'   => true,
512
-                'capability' => 'ee_send_message',
513
-            ],
514
-            'registrations_report'                => [
515
-                'func'       => [$this, '_registrations_report'],
516
-                'noheader'   => true,
517
-                'capability' => 'ee_read_registrations',
518
-            ],
519
-            'contact_list_export'                 => [
520
-                'func'       => [$this, '_contact_list_export'],
521
-                'noheader'   => true,
522
-                'capability' => 'export',
523
-            ],
524
-            'contact_list_report'                 => [
525
-                'func'       => [$this, '_contact_list_report'],
526
-                'noheader'   => true,
527
-                'capability' => 'ee_read_contacts',
528
-            ],
529
-        ];
530
-    }
531
-
532
-
533
-    protected function _set_page_config()
534
-    {
535
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
536
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
537
-        $this->_page_config = [
538
-            'default'           => [
539
-                'nav'           => [
540
-                    'label' => esc_html__('Overview', 'event_espresso'),
541
-                    'icon'  => 'dashicons-list-view',
542
-                    'order' => 5,
543
-                ],
544
-                'help_tabs'     => [
545
-                    'registrations_overview_help_tab'                       => [
546
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
-                        'filename' => 'registrations_overview',
548
-                    ],
549
-                    'registrations_overview_table_column_headings_help_tab' => [
550
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
-                        'filename' => 'registrations_overview_table_column_headings',
552
-                    ],
553
-                    'registrations_overview_filters_help_tab'               => [
554
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
-                        'filename' => 'registrations_overview_filters',
556
-                    ],
557
-                    'registrations_overview_views_help_tab'                 => [
558
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
559
-                        'filename' => 'registrations_overview_views',
560
-                    ],
561
-                    'registrations_regoverview_other_help_tab'              => [
562
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
-                        'filename' => 'registrations_overview_other',
564
-                    ],
565
-                ],
566
-                'list_table'    => 'EE_Registrations_List_Table',
567
-                'require_nonce' => false,
568
-            ],
569
-            'view_registration' => [
570
-                'nav'           => [
571
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
572
-                    'icon'       => 'dashicons-clipboard',
573
-                    'order'      => 15,
574
-                    'url'        => $REG_ID
575
-                        ? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
576
-                        : $this->_admin_base_url,
577
-                    'persistent' => false,
578
-                ],
579
-                'help_tabs'     => [
580
-                    'registrations_details_help_tab'                    => [
581
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
582
-                        'filename' => 'registrations_details',
583
-                    ],
584
-                    'registrations_details_table_help_tab'              => [
585
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
586
-                        'filename' => 'registrations_details_table',
587
-                    ],
588
-                    'registrations_details_form_answers_help_tab'       => [
589
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
590
-                        'filename' => 'registrations_details_form_answers',
591
-                    ],
592
-                    'registrations_details_registrant_details_help_tab' => [
593
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
594
-                        'filename' => 'registrations_details_registrant_details',
595
-                    ],
596
-                ],
597
-                'metaboxes'     => array_merge(
598
-                    $this->_default_espresso_metaboxes,
599
-                    ['_registration_details_metaboxes']
600
-                ),
601
-                'require_nonce' => false,
602
-            ],
603
-            'new_registration'  => [
604
-                'nav'           => [
605
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
606
-                    'icon'       => 'dashicons-plus-alt',
607
-                    'url'        => '#',
608
-                    'order'      => 15,
609
-                    'persistent' => false,
610
-                ],
611
-                'metaboxes'     => $this->_default_espresso_metaboxes,
612
-                'labels'        => [
613
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
614
-                ],
615
-                'require_nonce' => false,
616
-            ],
617
-            'add_new_attendee'  => [
618
-                'nav'           => [
619
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
620
-                    'icon'       => 'dashicons-plus-alt',
621
-                    'order'      => 15,
622
-                    'persistent' => false,
623
-                ],
624
-                'metaboxes'     => array_merge(
625
-                    $this->_default_espresso_metaboxes,
626
-                    ['_publish_post_box', 'attendee_editor_metaboxes']
627
-                ),
628
-                'require_nonce' => false,
629
-            ],
630
-            'edit_attendee'     => [
631
-                'nav'           => [
632
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
-                    'icon'       => 'dashicons-edit-large',
634
-                    'order'      => 15,
635
-                    'persistent' => false,
636
-                    'url'        => $ATT_ID
637
-                        ? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
638
-                        : $this->_admin_base_url,
639
-                ],
640
-                'metaboxes'     => array_merge(
641
-                    $this->_default_espresso_metaboxes,
642
-                    ['attendee_editor_metaboxes']
643
-                ),
644
-                'require_nonce' => false,
645
-            ],
646
-            'contact_list'      => [
647
-                'nav'           => [
648
-                    'label' => esc_html__('Contact List', 'event_espresso'),
649
-                    'icon'  => 'dashicons-id-alt',
650
-                    'order' => 20,
651
-                ],
652
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
653
-                'help_tabs'     => [
654
-                    'registrations_contact_list_help_tab'                       => [
655
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
656
-                        'filename' => 'registrations_contact_list',
657
-                    ],
658
-                    'registrations_contact-list_table_column_headings_help_tab' => [
659
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
660
-                        'filename' => 'registrations_contact_list_table_column_headings',
661
-                    ],
662
-                    'registrations_contact_list_views_help_tab'                 => [
663
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
664
-                        'filename' => 'registrations_contact_list_views',
665
-                    ],
666
-                    'registrations_contact_list_other_help_tab'                 => [
667
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
668
-                        'filename' => 'registrations_contact_list_other',
669
-                    ],
670
-                ],
671
-                'metaboxes'     => [],
672
-                'require_nonce' => false,
673
-            ],
674
-            // override default cpt routes
675
-            'create_new'        => '',
676
-            'edit'              => '',
677
-        ];
678
-    }
679
-
680
-
681
-    /**
682
-     * The below methods aren't used by this class currently
683
-     */
684
-    protected function _add_screen_options()
685
-    {
686
-    }
687
-
688
-
689
-    protected function _add_feature_pointers()
690
-    {
691
-    }
692
-
693
-
694
-    public function admin_init()
695
-    {
696
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
697
-            'click "Update Registration Questions" to save your changes',
698
-            'event_espresso'
699
-        );
700
-        EE_Registry::$i18n_js_strings['confirm_update_reg_details'] = esc_html__(
701
-            "Are you sure you want to update the submitted registration form data? This cannot be undone.\nPress OK to proceed or Cancel to keep the current data.",
702
-        );
703
-    }
704
-
705
-
706
-    public function admin_notices()
707
-    {
708
-    }
709
-
710
-
711
-    public function admin_footer_scripts()
712
-    {
713
-    }
714
-
715
-
716
-    /**
717
-     * get list of registration statuses
718
-     *
719
-     * @return void
720
-     * @throws EE_Error
721
-     * @throws ReflectionException
722
-     */
723
-    private function _get_registration_status_array()
724
-    {
725
-        self::$_reg_status = EEM_Registration::reg_status_array([], true);
726
-    }
727
-
728
-
729
-    /**
730
-     * @throws InvalidArgumentException
731
-     * @throws InvalidDataTypeException
732
-     * @throws InvalidInterfaceException
733
-     * @since 4.10.2.p
734
-     */
735
-    protected function _add_screen_options_default()
736
-    {
737
-        $this->_per_page_screen_option();
738
-    }
739
-
740
-
741
-    /**
742
-     * @throws InvalidArgumentException
743
-     * @throws InvalidDataTypeException
744
-     * @throws InvalidInterfaceException
745
-     * @since 4.10.2.p
746
-     */
747
-    protected function _add_screen_options_contact_list()
748
-    {
749
-        $page_title              = $this->_admin_page_title;
750
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
751
-        $this->_per_page_screen_option();
752
-        $this->_admin_page_title = $page_title;
753
-    }
754
-
755
-
756
-    public function load_scripts_styles()
757
-    {
758
-        // style
759
-        wp_register_style(
760
-            'espresso_reg',
761
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
762
-            ['ee-admin-css'],
763
-            EVENT_ESPRESSO_VERSION
764
-        );
765
-        wp_enqueue_style('espresso_reg');
766
-        // script
767
-        wp_register_script(
768
-            'espresso_reg',
769
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
770
-            ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
771
-            EVENT_ESPRESSO_VERSION,
772
-            true
773
-        );
774
-        wp_enqueue_script('espresso_reg');
775
-    }
776
-
777
-
778
-    /**
779
-     * @throws EE_Error
780
-     * @throws InvalidArgumentException
781
-     * @throws InvalidDataTypeException
782
-     * @throws InvalidInterfaceException
783
-     * @throws ReflectionException
784
-     * @since 4.10.2.p
785
-     */
786
-    public function load_scripts_styles_edit_attendee()
787
-    {
788
-        // stuff to only show up on our attendee edit details page.
789
-        $attendee_details_translations = [
790
-            'att_publish_text' => sprintf(
791
-            /* translators: The date and time */
792
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
793
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
794
-            ),
795
-        ];
796
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
797
-        wp_enqueue_script(JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE);
798
-    }
799
-
800
-
801
-    /**
802
-     * @throws EE_Error
803
-     * @throws InvalidArgumentException
804
-     * @throws InvalidDataTypeException
805
-     * @throws InvalidInterfaceException
806
-     * @throws ReflectionException
807
-     * @since 4.10.2.p
808
-     */
809
-    public function load_scripts_styles_view_registration()
810
-    {
811
-        $this->_set_registration_object();
812
-        // styles
813
-        wp_enqueue_style('espresso-ui-theme');
814
-        // scripts
815
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
816
-        $this->_reg_custom_questions_form->wp_enqueue_scripts();
817
-    }
818
-
819
-
820
-    public function load_scripts_styles_contact_list()
821
-    {
822
-        wp_dequeue_style('espresso_reg');
823
-        wp_register_style(
824
-            'espresso_att',
825
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
826
-            ['ee-admin-css'],
827
-            EVENT_ESPRESSO_VERSION
828
-        );
829
-        wp_enqueue_style('espresso_att');
830
-    }
831
-
832
-
833
-    /**
834
-     * @throws ReflectionException
835
-     * @throws EE_Error
836
-     */
837
-    public function load_scripts_styles_new_registration()
838
-    {
839
-        wp_register_script(
840
-            'ee-spco-for-admin',
841
-            REG_ASSETS_URL . 'spco_for_admin.js',
842
-            ['underscore', 'jquery'],
843
-            EVENT_ESPRESSO_VERSION,
844
-            true
845
-        );
846
-        wp_enqueue_script('ee-spco-for-admin');
847
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
848
-        EE_Form_Section_Proper::wp_enqueue_scripts();
849
-        EED_Ticket_Selector::load_tckt_slctr_assets();
850
-    }
851
-
852
-
853
-    public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
854
-    {
855
-        add_filter('FHEE_load_EE_messages', '__return_true');
856
-    }
857
-
858
-
859
-    public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
860
-    {
861
-        add_filter('FHEE_load_EE_messages', '__return_true');
862
-    }
863
-
864
-
865
-    /**
866
-     * @throws EE_Error
867
-     * @throws InvalidArgumentException
868
-     * @throws InvalidDataTypeException
869
-     * @throws InvalidInterfaceException
870
-     * @throws ReflectionException
871
-     * @since 4.10.2.p
872
-     */
873
-    protected function _set_list_table_views_default()
874
-    {
875
-        // for notification related bulk actions we need to make sure only active messengers have an option.
876
-        EED_Messages::set_autoloaders();
877
-        /** @type EE_Message_Resource_Manager $message_resource_manager */
878
-        $message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
879
-        $active_mts               = $message_resource_manager->list_of_active_message_types();
880
-        // key= bulk_action_slug, value= message type.
881
-        $match_array = [
882
-            'approve_registrations'    => 'registration',
883
-            'decline_registrations'    => 'declined_registration',
884
-            'pending_registrations'    => 'pending_approval',
885
-            'no_approve_registrations' => 'not_approved_registration',
886
-            'cancel_registrations'     => 'cancelled_registration',
887
-        ];
888
-        $can_send    = $this->capabilities->current_user_can(
889
-            'ee_send_message',
890
-            'batch_send_messages'
891
-        );
892
-        /** setup reg status bulk actions **/
893
-        $def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
894
-        if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
895
-            $def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
896
-                'Approve and Notify Registrations',
897
-                'event_espresso'
898
-            );
899
-        }
900
-        $def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
901
-        if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
902
-            $def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
903
-                'Decline and Notify Registrations',
904
-                'event_espresso'
905
-            );
906
-        }
907
-        $def_reg_status_actions['pending_registrations'] = esc_html__(
908
-            'Set Registrations to Pending Payment',
909
-            'event_espresso'
910
-        );
911
-        if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
912
-            $def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
913
-                'Set Registrations to Pending Payment and Notify',
914
-                'event_espresso'
915
-            );
916
-        }
917
-        $def_reg_status_actions['no_approve_registrations'] = esc_html__(
918
-            'Set Registrations to Awaiting Review',
919
-            'event_espresso'
920
-        );
921
-        if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
922
-            $def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
923
-                'Set Registrations to Awaiting Review and Notify',
924
-                'event_espresso'
925
-            );
926
-        }
927
-        $def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
928
-        if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
929
-            $def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
930
-                'Cancel Registrations and Notify',
931
-                'event_espresso'
932
-            );
933
-        }
934
-        $def_reg_status_actions = apply_filters(
935
-            'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
936
-            $def_reg_status_actions,
937
-            $active_mts,
938
-            $can_send
939
-        );
940
-
941
-        $current_time = current_time('timestamp');
942
-        $this->_views = [
943
-            'all'       => [
944
-                'slug'        => 'all',
945
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
946
-                'count'       => 0,
947
-                'bulk_action' => array_merge(
948
-                    $def_reg_status_actions,
949
-                    [
950
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
951
-                    ]
952
-                ),
953
-            ],
954
-            'today'     => [
955
-                'slug'        => 'today',
956
-                'label'       => sprintf(
957
-                    esc_html__('Today - %s', 'event_espresso'),
958
-                    date('M d, Y', $current_time)
959
-                ),
960
-                'count'       => 0,
961
-                'bulk_action' => array_merge(
962
-                    $def_reg_status_actions,
963
-                    [
964
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
965
-                    ]
966
-                ),
967
-            ],
968
-            'yesterday' => [
969
-                'slug'        => 'yesterday',
970
-                'label'       => sprintf(
971
-                    esc_html__('Yesterday - %s', 'event_espresso'),
972
-                    date('M d, Y', $current_time - DAY_IN_SECONDS)
973
-                ),
974
-                'count'       => 0,
975
-                'bulk_action' => array_merge(
976
-                    $def_reg_status_actions,
977
-                    [
978
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
979
-                    ]
980
-                ),
981
-            ],
982
-            'month'     => [
983
-                'slug'        => 'month',
984
-                'label'       => esc_html__('This Month', 'event_espresso'),
985
-                'count'       => 0,
986
-                'bulk_action' => array_merge(
987
-                    $def_reg_status_actions,
988
-                    [
989
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
990
-                    ]
991
-                ),
992
-            ],
993
-        ];
994
-        if (
995
-            $this->capabilities->current_user_can(
996
-                'ee_delete_registrations',
997
-                'espresso_registrations_delete_registration'
998
-            )
999
-        ) {
1000
-            $this->_views['incomplete'] = [
1001
-                'slug'        => 'incomplete',
1002
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
1003
-                'count'       => 0,
1004
-                'bulk_action' => [
1005
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
1006
-                ],
1007
-            ];
1008
-            $this->_views['trash']      = [
1009
-                'slug'        => 'trash',
1010
-                'label'       => esc_html__('Trash', 'event_espresso'),
1011
-                'count'       => 0,
1012
-                'bulk_action' => [
1013
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
1014
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
1015
-                ],
1016
-            ];
1017
-        }
1018
-    }
1019
-
1020
-
1021
-    protected function _set_list_table_views_contact_list()
1022
-    {
1023
-        $this->_views = [
1024
-            'in_use' => [
1025
-                'slug'        => 'in_use',
1026
-                'label'       => esc_html__('In Use', 'event_espresso'),
1027
-                'count'       => 0,
1028
-                'bulk_action' => [
1029
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1030
-                ],
1031
-            ],
1032
-        ];
1033
-        if (
1034
-            $this->capabilities->current_user_can(
1035
-                'ee_delete_contacts',
1036
-                'espresso_registrations_trash_attendees'
1037
-            )
1038
-        ) {
1039
-            $this->_views['trash'] = [
1040
-                'slug'        => 'trash',
1041
-                'label'       => esc_html__('Trash', 'event_espresso'),
1042
-                'count'       => 0,
1043
-                'bulk_action' => [
1044
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1045
-                    'delete_attendees'  => esc_html__('Permanently Delete', 'event_espresso'),
1046
-                ],
1047
-            ];
1048
-        }
1049
-    }
1050
-
1051
-
1052
-    /**
1053
-     * @return array
1054
-     * @throws EE_Error
1055
-     */
1056
-    protected function _registration_legend_items(): array
1057
-    {
1058
-        $fc_items = [
1059
-            'star-icon'        => [
1060
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1061
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1062
-            ],
1063
-            'view_details'     => [
1064
-                'class' => 'dashicons dashicons-clipboard',
1065
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1066
-            ],
1067
-            'edit_attendee'    => [
1068
-                'class' => 'dashicons dashicons-admin-users',
1069
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1070
-            ],
1071
-            'view_transaction' => [
1072
-                'class' => 'dashicons dashicons-cart',
1073
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1074
-            ],
1075
-            'view_invoice'     => [
1076
-                'class' => 'dashicons dashicons-media-spreadsheet',
1077
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1078
-            ],
1079
-        ];
1080
-        if (
1081
-            $this->capabilities->current_user_can(
1082
-                'ee_send_message',
1083
-                'espresso_registrations_resend_registration'
1084
-            )
1085
-        ) {
1086
-            $fc_items['resend_registration'] = [
1087
-                'class' => 'dashicons dashicons-email-alt',
1088
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1089
-            ];
1090
-        } else {
1091
-            $fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1092
-        }
1093
-        if (
1094
-            $this->capabilities->current_user_can(
1095
-                'ee_read_global_messages',
1096
-                'view_filtered_messages'
1097
-            )
1098
-        ) {
1099
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1100
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1101
-                $fc_items['view_related_messages'] = [
1102
-                    'class' => $related_for_icon['css_class'],
1103
-                    'desc'  => $related_for_icon['label'],
1104
-                ];
1105
-            }
1106
-        }
1107
-        $sc_items = [
1108
-            'approved_status'   => [
1109
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1110
-                'desc'  => EEH_Template::pretty_status(
1111
-                    RegStatus::APPROVED,
1112
-                    false,
1113
-                    'sentence'
1114
-                ),
1115
-            ],
1116
-            'pending_status'    => [
1117
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1118
-                'desc'  => EEH_Template::pretty_status(
1119
-                    RegStatus::PENDING_PAYMENT,
1120
-                    false,
1121
-                    'sentence'
1122
-                ),
1123
-            ],
1124
-            'wait_list'         => [
1125
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1126
-                'desc'  => EEH_Template::pretty_status(
1127
-                    RegStatus::WAIT_LIST,
1128
-                    false,
1129
-                    'sentence'
1130
-                ),
1131
-            ],
1132
-            'incomplete_status' => [
1133
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::INCOMPLETE,
1134
-                'desc'  => EEH_Template::pretty_status(
1135
-                    RegStatus::INCOMPLETE,
1136
-                    false,
1137
-                    'sentence'
1138
-                ),
1139
-            ],
1140
-            'not_approved'      => [
1141
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1142
-                'desc'  => EEH_Template::pretty_status(
1143
-                    RegStatus::AWAITING_REVIEW,
1144
-                    false,
1145
-                    'sentence'
1146
-                ),
1147
-            ],
1148
-            'declined_status'   => [
1149
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1150
-                'desc'  => EEH_Template::pretty_status(
1151
-                    RegStatus::DECLINED,
1152
-                    false,
1153
-                    'sentence'
1154
-                ),
1155
-            ],
1156
-            'cancelled_status'  => [
1157
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1158
-                'desc'  => EEH_Template::pretty_status(
1159
-                    RegStatus::CANCELLED,
1160
-                    false,
1161
-                    'sentence'
1162
-                ),
1163
-            ],
1164
-        ];
1165
-        return array_merge($fc_items, $sc_items);
1166
-    }
1167
-
1168
-
1169
-
1170
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1171
-
1172
-
1173
-    /**
1174
-     * @throws DomainException
1175
-     * @throws EE_Error
1176
-     * @throws InvalidArgumentException
1177
-     * @throws InvalidDataTypeException
1178
-     * @throws InvalidInterfaceException
1179
-     */
1180
-    protected function _registrations_overview_list_table()
1181
-    {
1182
-        $this->appendAddNewRegistrationButtonToPageTitle();
1183
-        $header_text                  = '';
1184
-        $admin_page_header_decorators = [
1185
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1186
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1187
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1188
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1189
-        ];
1190
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1191
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1192
-            $header_text             = $filter_header_decorator->getHeaderText($header_text);
1193
-        }
1194
-        $this->_template_args['before_list_table'] = $header_text;
1195
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1196
-        $this->display_admin_list_table_page_with_no_sidebar();
1197
-    }
1198
-
1199
-
1200
-    /**
1201
-     * @throws EE_Error
1202
-     * @throws InvalidArgumentException
1203
-     * @throws InvalidDataTypeException
1204
-     * @throws InvalidInterfaceException
1205
-     */
1206
-    private function appendAddNewRegistrationButtonToPageTitle()
1207
-    {
1208
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1209
-        if (
1210
-            $EVT_ID
1211
-            && $this->capabilities->current_user_can(
1212
-                'ee_edit_registrations',
1213
-                'espresso_registrations_new_registration',
1214
-                $EVT_ID
1215
-            )
1216
-        ) {
1217
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1218
-                    'new_registration',
1219
-                    'add-registrant',
1220
-                    ['event_id' => $EVT_ID],
1221
-                    'add-new-h2'
1222
-                );
1223
-        }
1224
-    }
1225
-
1226
-
1227
-    /**
1228
-     * This sets the _registration property for the registration details screen
1229
-     *
1230
-     * @return void
1231
-     * @throws EE_Error
1232
-     * @throws InvalidArgumentException
1233
-     * @throws InvalidDataTypeException
1234
-     * @throws InvalidInterfaceException
1235
-     * @throws ReflectionException
1236
-     */
1237
-    private function _set_registration_object()
1238
-    {
1239
-        // get out if we've already set the object
1240
-        if ($this->_registration instanceof EE_Registration) {
1241
-            return;
1242
-        }
1243
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1244
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1245
-            return;
1246
-        }
1247
-        $error_msg = sprintf(
1248
-            esc_html__(
1249
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1250
-                'event_espresso'
1251
-            ),
1252
-            $REG_ID
1253
-        );
1254
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1255
-        $this->_registration = null;
1256
-    }
1257
-
1258
-
1259
-    /**
1260
-     * Used to retrieve registrations for the list table.
1261
-     *
1262
-     * @param int  $per_page
1263
-     * @param bool $count
1264
-     * @param bool $this_month
1265
-     * @param bool $today
1266
-     * @param bool $yesterday
1267
-     * @return EE_Registration[]|int
1268
-     * @throws EE_Error
1269
-     * @throws ReflectionException
1270
-     */
1271
-    public function get_registrations(
1272
-        int $per_page = 10,
1273
-        bool $count = false,
1274
-        bool $this_month = false,
1275
-        bool $today = false,
1276
-        bool $yesterday = false
1277
-    ) {
1278
-        if ($this_month) {
1279
-            $this->request->setRequestParam('status', 'month');
1280
-        }
1281
-        if ($today) {
1282
-            $this->request->setRequestParam('status', 'today');
1283
-        }
1284
-        if ($yesterday) {
1285
-            $this->request->setRequestParam('status', 'yesterday');
1286
-        }
1287
-        $query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1288
-        /**
1289
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1290
-         *
1291
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1292
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1293
-         *                      or if you have the development copy of EE you can view this at the path:
1294
-         *                      /docs/G--Model-System/model-query-params.md
1295
-         */
1296
-        $query_params['group_by'] = '';
1297
-
1298
-        return $count
1299
-            ? $this->getRegistrationModel()->count($query_params)
1300
-            /** @type EE_Registration[] */
1301
-            : $this->getRegistrationModel()->get_all($query_params);
1302
-    }
1303
-
1304
-
1305
-    /**
1306
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1307
-     * Note: this listens to values on the request for some query parameters.
1308
-     *
1309
-     * @param array $request
1310
-     * @param int   $per_page
1311
-     * @param bool  $count
1312
-     * @return array
1313
-     * @throws EE_Error
1314
-     * @throws InvalidArgumentException
1315
-     * @throws InvalidDataTypeException
1316
-     * @throws InvalidInterfaceException
1317
-     */
1318
-    protected function _get_registration_query_parameters(
1319
-        array $request = [],
1320
-        int $per_page = 10,
1321
-        bool $count = false
1322
-    ): array {
1323
-        /** @var QueryBuilder $list_table_query_builder */
1324
-        $list_table_query_builder = $this->loader->getNew(QueryBuilder::class, [null, null, $request]);
1325
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1326
-    }
1327
-
1328
-
1329
-    public function get_registration_status_array(): array
1330
-    {
1331
-        return self::$_reg_status;
1332
-    }
1333
-
1334
-
1335
-
1336
-
1337
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1338
-    /**
1339
-     * generates HTML for the View Registration Details Admin page
1340
-     *
1341
-     * @return void
1342
-     * @throws DomainException
1343
-     * @throws EE_Error
1344
-     * @throws InvalidArgumentException
1345
-     * @throws InvalidDataTypeException
1346
-     * @throws InvalidInterfaceException
1347
-     * @throws EntityNotFoundException
1348
-     * @throws ReflectionException
1349
-     */
1350
-    protected function _registration_details()
1351
-    {
1352
-        $this->_template_args = [];
1353
-        $this->_set_registration_object();
1354
-        if (is_object($this->_registration)) {
1355
-            $transaction                                   = $this->_registration->transaction()
1356
-                ? $this->_registration->transaction()
1357
-                : EE_Transaction::new_instance();
1358
-            $this->session_data                            = $transaction->session_data();
1359
-            $event_id                                      = $this->_registration->event_ID();
1360
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1361
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1362
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1363
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1364
-            $this->_template_args['grand_total']           = $transaction->total();
1365
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1366
-            // link back to overview
1367
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1368
-            $this->_template_args['registration']                = $this->_registration;
1369
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1370
-                [
1371
-                    'action'   => 'default',
1372
-                    'event_id' => $event_id,
1373
-                ],
1374
-                REG_ADMIN_URL
1375
-            );
1376
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1377
-                [
1378
-                    'action' => 'default',
1379
-                    'EVT_ID' => $event_id,
1380
-                    'page'   => 'espresso_transactions',
1381
-                ],
1382
-                admin_url('admin.php')
1383
-            );
1384
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1385
-                [
1386
-                    'page'   => 'espresso_events',
1387
-                    'action' => 'edit',
1388
-                    'post'   => $event_id,
1389
-                ],
1390
-                admin_url('admin.php')
1391
-            );
1392
-            // next and previous links
1393
-            $next_reg                                      = $this->_registration->next(
1394
-                null,
1395
-                [],
1396
-                'REG_ID'
1397
-            );
1398
-            $this->_template_args['next_registration']     = $next_reg
1399
-                ? $this->_next_link(
1400
-                    EE_Admin_Page::add_query_args_and_nonce(
1401
-                        [
1402
-                            'action'  => 'view_registration',
1403
-                            '_REG_ID' => $next_reg['REG_ID'],
1404
-                        ],
1405
-                        REG_ADMIN_URL
1406
-                    ),
1407
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1408
-                )
1409
-                : '';
1410
-            $previous_reg                                  = $this->_registration->previous(
1411
-                null,
1412
-                [],
1413
-                'REG_ID'
1414
-            );
1415
-            $this->_template_args['previous_registration'] = $previous_reg
1416
-                ? $this->_previous_link(
1417
-                    EE_Admin_Page::add_query_args_and_nonce(
1418
-                        [
1419
-                            'action'  => 'view_registration',
1420
-                            '_REG_ID' => $previous_reg['REG_ID'],
1421
-                        ],
1422
-                        REG_ADMIN_URL
1423
-                    ),
1424
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1425
-                )
1426
-                : '';
1427
-            // grab header
1428
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1429
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1430
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1431
-                $template_path,
1432
-                $this->_template_args,
1433
-                true
1434
-            );
1435
-        } else {
1436
-            $this->_template_args['admin_page_header'] = '';
1437
-            $this->_display_espresso_notices();
1438
-        }
1439
-        // the details template wrapper
1440
-        $this->display_admin_page_with_sidebar();
1441
-    }
1442
-
1443
-
1444
-    /**
1445
-     * @throws EE_Error
1446
-     * @throws InvalidArgumentException
1447
-     * @throws InvalidDataTypeException
1448
-     * @throws InvalidInterfaceException
1449
-     * @throws ReflectionException
1450
-     * @since 4.10.2.p
1451
-     */
1452
-    protected function _registration_details_metaboxes()
1453
-    {
1454
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1455
-        $this->_set_registration_object();
1456
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1457
-        $this->addMetaBox(
1458
-            'edit-reg-status-mbox',
1459
-            esc_html__('Registration Status', 'event_espresso'),
1460
-            [$this, 'set_reg_status_buttons_metabox'],
1461
-            $this->_wp_page_slug
1462
-        );
1463
-        $this->addMetaBox(
1464
-            'edit-reg-details-mbox',
1465
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1466
-            . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1467
-            [$this, '_reg_details_meta_box'],
1468
-            $this->_wp_page_slug
1469
-        );
1470
-        if (
1471
-            $attendee instanceof EE_Attendee
1472
-            && $this->capabilities->current_user_can(
1473
-                'ee_read_registration',
1474
-                'edit-reg-questions-mbox',
1475
-                $this->_registration->ID()
1476
-            )
1477
-        ) {
1478
-            $this->addMetaBox(
1479
-                'edit-reg-questions-mbox',
1480
-                esc_html__('Registration Form Answers', 'event_espresso'),
1481
-                [$this, '_reg_questions_meta_box'],
1482
-                $this->_wp_page_slug
1483
-            );
1484
-        }
1485
-        $this->addMetaBox(
1486
-            'edit-reg-registrant-mbox',
1487
-            esc_html__('Contact Details', 'event_espresso'),
1488
-            [$this, '_reg_registrant_side_meta_box'],
1489
-            $this->_wp_page_slug,
1490
-            'side'
1491
-        );
1492
-        if ($this->_registration->group_size() > 1) {
1493
-            $this->addMetaBox(
1494
-                'edit-reg-attendees-mbox',
1495
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1496
-                [$this, '_reg_attendees_meta_box'],
1497
-                $this->_wp_page_slug
1498
-            );
1499
-        }
1500
-    }
1501
-
1502
-
1503
-    /**
1504
-     * set_reg_status_buttons_metabox
1505
-     *
1506
-     * @return void
1507
-     * @throws EE_Error
1508
-     * @throws EntityNotFoundException
1509
-     * @throws InvalidArgumentException
1510
-     * @throws InvalidDataTypeException
1511
-     * @throws InvalidInterfaceException
1512
-     * @throws ReflectionException
1513
-     * @throws DateMalformedStringException
1514
-     */
1515
-    public function set_reg_status_buttons_metabox()
1516
-    {
1517
-        $this->_set_registration_object();
1518
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1519
-        $output                 = $change_reg_status_form->form_open(
1520
-            self::add_query_args_and_nonce(
1521
-                [
1522
-                    'action' => 'change_reg_status',
1523
-                ],
1524
-                REG_ADMIN_URL
1525
-            )
1526
-        );
1527
-        $output                 .= $change_reg_status_form->get_html();
1528
-        $output                 .= $change_reg_status_form->form_close();
1529
-        echo wp_kses($output, AllowedTags::getWithFormTags());
1530
-    }
1531
-
1532
-
1533
-    /**
1534
-     * @return EE_Form_Section_Proper
1535
-     * @throws EE_Error
1536
-     * @throws EntityNotFoundException
1537
-     * @throws ReflectionException
1538
-     * @throws DateMalformedStringException
1539
-     */
1540
-    protected function _generate_reg_status_change_form(): EE_Form_Section_Proper
1541
-    {
1542
-        $subsections = [
1543
-            'return' => new EE_Hidden_Input(
1544
-                [
1545
-                    'name'    => 'return',
1546
-                    'default' => 'view_registration',
1547
-                ]
1548
-            ),
1549
-            'REG_ID' => new EE_Hidden_Input(
1550
-                [
1551
-                    'name'    => 'REG_ID',
1552
-                    'default' => $this->_registration->ID(),
1553
-                ]
1554
-            ),
1555
-        ];
1556
-
1557
-        $status_changes = $this->_registration->get_extra_meta(EE_Registration::META_KEY_REG_STATUS_CHANGE);
1558
-
1559
-        if (! empty($status_changes)) {
1560
-            $date_format = get_option('date_format', 'Y-m-d') . ' ' . get_option('time_format', 'H:i:s');
1561
-            $html = EEH_HTML::tr();
1562
-            $html .= EEH_HTML::th(
1563
-                EEH_HTML::label(esc_html__('Registration Status Changes', 'event_espresso'))
1564
-            );
1565
-            $html .= EEH_HTML::td();
1566
-            $html .= EEH_HTML::ul();
1567
-            foreach ($status_changes as $status_change) {
1568
-                $date = new DateTime('@' . $status_change['date']);
1569
-                $reason = $status_change['reason'] ?: esc_html__('not specified', 'event_espresso');
1570
-                $html .= EEH_HTML::li(
1571
-                    EEH_HTML::strong($date->format($date_format))
1572
-                    . EEH_HTML::br()
1573
-                    . EEH_HTML::span(
1574
-                        $status_change['change'],
1575
-                        '',
1576
-                        '',
1577
-                        'margin-inline-start: 1em;'
1578
-                    )
1579
-                    . EEH_HTML::br()
1580
-                    . EEH_HTML::span(
1581
-                        sprintf(
1582
-                            esc_html__('Reason: %1$s', 'event_espresso'),
1583
-                            $reason,
1584
-                        ),
1585
-                        '',
1586
-                        '',
1587
-                        'margin-inline-start: 1em;'
1588
-                    )
1589
-                );
1590
-            }
1591
-            $html .= EEH_HTML::ulx();
1592
-            $html .= EEH_HTML::tdx();
1593
-            $html .= EEH_HTML::trx();
1594
-            $subsections['reg_cancellations'] = new EE_Form_Section_HTML($html, ['add_wrapper' => false]);
1595
-        }
1596
-
1597
-
1598
-        if (
1599
-            $this->capabilities->current_user_can(
1600
-                'ee_edit_registration',
1601
-                'toggle_registration_status',
1602
-                $this->_registration->ID()
1603
-            )
1604
-        ) {
1605
-            $subsections['reg_status']         = new EE_Select_Input(
1606
-                $this->_get_reg_statuses(),
1607
-                [
1608
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1609
-                    'default'         => $this->_registration->status_ID(),
1610
-                    'html_class'      => 'ee-input-width--small',
1611
-                ]
1612
-            );
1613
-            $subsections['reason']         = new EE_Text_Input(
1614
-                [
1615
-                    'html_label_text' => esc_html__('Reason for Registration Status Change', 'event_espresso')
1616
-                ]
1617
-            );
1618
-            $subsections['send_notifications'] = new EE_Yes_No_Input(
1619
-                [
1620
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1621
-                    'default'         => false,
1622
-                    'html_help_text'  => esc_html__(
1623
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1624
-                        'event_espresso'
1625
-                    ),
1626
-                ]
1627
-            );
1628
-            $subsections['submit']             = new EE_Submit_Input(
1629
-                [
1630
-                    'html_class'      => 'button--primary',
1631
-                    'html_label_text' => '&nbsp;',
1632
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1633
-                ]
1634
-            );
1635
-        }
1636
-        return new EE_Form_Section_Proper(
1637
-            [
1638
-              'name'            => 'reg_status_change_form',
1639
-              'html_id'         => 'reg-status-change-form',
1640
-              'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1641
-              'subsections'     => $subsections
1642
-            ]
1643
-        );
1644
-    }
1645
-
1646
-
1647
-    /**
1648
-     * Returns an array of all the buttons for the various statuses and switch status actions
1649
-     *
1650
-     * @return array
1651
-     * @throws EE_Error
1652
-     * @throws InvalidArgumentException
1653
-     * @throws InvalidDataTypeException
1654
-     * @throws InvalidInterfaceException
1655
-     * @throws EntityNotFoundException
1656
-     * @throws ReflectionException
1657
-     */
1658
-    protected function _get_reg_statuses(): array
1659
-    {
1660
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1661
-        unset($reg_status_array[ RegStatus::INCOMPLETE ]);
1662
-        // get current reg status
1663
-        $current_status = $this->_registration->status_ID();
1664
-        // is registration for free event? This will determine whether to display the pending payment option
1665
-        if (
1666
-            $current_status !== RegStatus::PENDING_PAYMENT
1667
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1668
-        ) {
1669
-            unset($reg_status_array[ RegStatus::PENDING_PAYMENT ]);
1670
-        }
1671
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1672
-    }
1673
-
1674
-
1675
-    /**
1676
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1677
-     *
1678
-     * @param string $status REG status given for changing registrations to.
1679
-     * @param bool $notify Whether to send messages notifications or not.
1680
-     * @return array (array with reg_id(s) updated and whether update was successful.
1681
-     * @throws DomainException
1682
-     * @throws EE_Error
1683
-     * @throws EntityNotFoundException
1684
-     * @throws InvalidArgumentException
1685
-     * @throws InvalidDataTypeException
1686
-     * @throws InvalidInterfaceException
1687
-     * @throws ReflectionException
1688
-     * @throws RuntimeException
1689
-     */
1690
-    protected function _set_registration_status_from_request(string $status = '', bool $notify = false): array
1691
-    {
1692
-        $REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1693
-            ? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1694
-            : $this->request->getRequestParam('_REG_ID', [], 'int', true);
1695
-
1696
-        // sanitize $REG_IDs
1697
-        $REG_IDs = array_map('absint', $REG_IDs);
1698
-        // and remove empty entries
1699
-        $REG_IDs = array_filter($REG_IDs);
1700
-
1701
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1702
-
1703
-        /**
1704
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1705
-         * Currently this value is used downstream by the _process_resend_registration method.
1706
-         *
1707
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1708
-         * @param bool                     $status           The status registrations were changed to.
1709
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1710
-         * @param Registrations_Admin_Page $admin_page
1711
-         */
1712
-        $REG_ID = apply_filters(
1713
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1714
-            $result['REG_ID'],
1715
-            $status,
1716
-            $result['success'],
1717
-            $this
1718
-        );
1719
-        $this->request->setRequestParam('_REG_ID', $REG_ID);
1720
-
1721
-        // notify?
1722
-        if (
1723
-            $notify
1724
-            && $result['success']
1725
-            && ! empty($REG_ID)
1726
-            && $this->capabilities->current_user_can(
1727
-                'ee_send_message',
1728
-                'espresso_registrations_resend_registration'
1729
-            )
1730
-        ) {
1731
-            $this->_process_resend_registration();
1732
-        }
1733
-        return $result;
1734
-    }
1735
-
1736
-
1737
-    /**
1738
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1739
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1740
-     *
1741
-     * @param array  $REG_IDs
1742
-     * @param string $status
1743
-     * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1744
-     *                       slug sent with setting the registration status.
1745
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1746
-     * @throws EE_Error
1747
-     * @throws InvalidArgumentException
1748
-     * @throws InvalidDataTypeException
1749
-     * @throws InvalidInterfaceException
1750
-     * @throws ReflectionException
1751
-     * @throws RuntimeException
1752
-     * @throws EntityNotFoundException
1753
-     * @throws DomainException
1754
-     */
1755
-    protected function _set_registration_status(array $REG_IDs = [], string $status = '', bool $notify = false): array
1756
-    {
1757
-        global $current_user;
1758
-        $admin_name = $current_user->display_name;
1759
-        $reason = $this->request->getRequestParam('reg_status_change_form[reason]');
1760
-        if (empty($REG_IDs)) {
1761
-            return ['REG_ID' => $REG_IDs, 'success' => false];
1762
-        }
1763
-        $success = true;
1764
-        // set default status if none is passed
1765
-        $status         = $status ?: RegStatus::PENDING_PAYMENT;
1766
-        $status_context = $notify
1767
-            ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1768
-            : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1769
-        // loop through REG_ID's and change status
1770
-        foreach ($REG_IDs as $REG_ID) {
1771
-            $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1772
-            if ($registration instanceof EE_Registration) {
1773
-                $updated = $registration->set_status(
1774
-                    $status,
1775
-                    false,
1776
-                    new Context(
1777
-                        $status_context,
1778
-                        esc_html__(
1779
-                            'Manually triggered status change on a Registration Admin Page route.',
1780
-                            'event_espresso'
1781
-                        )
1782
-                    )
1783
-                );
1784
-                $registration->add_extra_meta(
1785
-                    EE_Registration::META_KEY_REG_STATUS_CHANGE,
1786
-                    [
1787
-                        'date'   => time(),
1788
-                        'change' => sprintf(
1789
-                            esc_html__('changed to "%1$s" by %2$s', 'event_espresso'),
1790
-                            EEH_Template::pretty_status($status, false, 'sentence'),
1791
-                            $admin_name
1792
-                        ),
1793
-                        'reason' => $reason,
1794
-                    ]
1795
-                );
1796
-                $registration->save();
1797
-                // verifying explicit fails because update *may* just return 0 for 0 rows affected
1798
-                $success = $updated && $success;
1799
-            }
1800
-        }
1801
-
1802
-        // return $success and processed registrations
1803
-        return ['REG_ID' => $REG_IDs, 'success' => $success];
1804
-    }
1805
-
1806
-
1807
-    /**
1808
-     * Common logic for setting up success message and redirecting to appropriate route
1809
-     *
1810
-     * @param string $STS_ID status id for the registration changed to
1811
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1812
-     * @return void
1813
-     * @throws DomainException
1814
-     * @throws EE_Error
1815
-     * @throws EntityNotFoundException
1816
-     * @throws InvalidArgumentException
1817
-     * @throws InvalidDataTypeException
1818
-     * @throws InvalidInterfaceException
1819
-     * @throws ReflectionException
1820
-     * @throws RuntimeException
1821
-     */
1822
-    protected function _reg_status_change_return(string $STS_ID, bool $notify = false)
1823
-    {
1824
-        $result  = ! empty($STS_ID)
1825
-            ? $this->_set_registration_status_from_request($STS_ID, $notify)
1826
-            : ['success' => false];
1827
-        $success = isset($result['success']) && $result['success'];
1828
-        // setup success message
1829
-        if ($success) {
1830
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1831
-                $msg = sprintf(
1832
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1833
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1834
-                );
1835
-            } else {
1836
-                $msg = sprintf(
1837
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1838
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1839
-                );
1840
-            }
1841
-            EE_Error::add_success($msg);
1842
-        } else {
1843
-            EE_Error::add_error(
1844
-                esc_html__(
1845
-                    'Something went wrong, and the status was not changed',
1846
-                    'event_espresso'
1847
-                ),
1848
-                __FILE__,
1849
-                __LINE__,
1850
-                __FUNCTION__
1851
-            );
1852
-        }
1853
-        $return = $this->request->getRequestParam('return');
1854
-        $route  = $return === 'view_registration'
1855
-            ? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1856
-            : ['action' => 'default'];
1857
-        $route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1858
-        $this->_redirect_after_action($success, '', '', $route, true);
1859
-    }
1860
-
1861
-
1862
-    /**
1863
-     * incoming reg status change from reg details page.
1864
-     *
1865
-     * @return void
1866
-     * @throws EE_Error
1867
-     * @throws EntityNotFoundException
1868
-     * @throws InvalidArgumentException
1869
-     * @throws InvalidDataTypeException
1870
-     * @throws InvalidInterfaceException
1871
-     * @throws ReflectionException
1872
-     * @throws RuntimeException
1873
-     * @throws DomainException
1874
-     */
1875
-    protected function _change_reg_status()
1876
-    {
1877
-        $this->request->setRequestParam('return', 'view_registration');
1878
-        // set notify based on whether the send notifications toggle is set or not
1879
-        $notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1880
-        $reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1881
-
1882
-        switch ($reg_status) {
1883
-            case RegStatus::APPROVED:
1884
-            case EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'):
1885
-                $this->approve_registration($notify);
1886
-                break;
1887
-            case RegStatus::PENDING_PAYMENT:
1888
-            case EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'):
1889
-                $this->pending_registration($notify);
1890
-                break;
1891
-            case RegStatus::AWAITING_REVIEW:
1892
-            case EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'):
1893
-                $this->not_approve_registration($notify);
1894
-                break;
1895
-            case RegStatus::DECLINED:
1896
-            case EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'):
1897
-                $this->decline_registration($notify);
1898
-                break;
1899
-            case RegStatus::CANCELLED:
1900
-            case EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'):
1901
-                $this->cancel_registration($notify);
1902
-                break;
1903
-            case RegStatus::WAIT_LIST:
1904
-            case EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'):
1905
-                $this->wait_list_registration($notify);
1906
-                break;
1907
-            case RegStatus::INCOMPLETE:
1908
-            default:
1909
-                $this->request->unSetRequestParam('return');
1910
-                $this->_reg_status_change_return('');
1911
-                break;
1912
-        }
1913
-    }
1914
-
1915
-
1916
-    /**
1917
-     * Callback for bulk action routes.
1918
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1919
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1920
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1921
-     * when an action is happening on just a single registration).
1922
-     *
1923
-     * @param string $action
1924
-     * @param bool   $notify
1925
-     */
1926
-    protected function bulk_action_on_registrations(string $action, bool $notify = false)
1927
-    {
1928
-        do_action(
1929
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1930
-            $this,
1931
-            $action,
1932
-            $notify
1933
-        );
1934
-        $method = $action . '_registration';
1935
-        if (method_exists($this, $method)) {
1936
-            $this->$method($notify);
1937
-        }
1938
-    }
1939
-
1940
-
1941
-    /**
1942
-     * approve_registration
1943
-     *
1944
-     * @param bool $notify whether to notify the registrant about their approval.
1945
-     * @return void
1946
-     * @throws EE_Error
1947
-     * @throws EntityNotFoundException
1948
-     * @throws InvalidArgumentException
1949
-     * @throws InvalidDataTypeException
1950
-     * @throws InvalidInterfaceException
1951
-     * @throws ReflectionException
1952
-     * @throws RuntimeException
1953
-     * @throws DomainException
1954
-     */
1955
-    protected function approve_registration(bool $notify = false)
1956
-    {
1957
-        $this->_reg_status_change_return(RegStatus::APPROVED, $notify);
1958
-    }
1959
-
1960
-
1961
-    /**
1962
-     * decline_registration
1963
-     *
1964
-     * @param bool $notify whether to notify the registrant about their status change.
1965
-     * @return void
1966
-     * @throws EE_Error
1967
-     * @throws EntityNotFoundException
1968
-     * @throws InvalidArgumentException
1969
-     * @throws InvalidDataTypeException
1970
-     * @throws InvalidInterfaceException
1971
-     * @throws ReflectionException
1972
-     * @throws RuntimeException
1973
-     * @throws DomainException
1974
-     */
1975
-    protected function decline_registration(bool $notify = false)
1976
-    {
1977
-        $this->_reg_status_change_return(RegStatus::DECLINED, $notify);
1978
-    }
1979
-
1980
-
1981
-    /**
1982
-     * cancel_registration
1983
-     *
1984
-     * @param bool $notify whether to notify the registrant about their status change.
1985
-     * @return void
1986
-     * @throws EE_Error
1987
-     * @throws EntityNotFoundException
1988
-     * @throws InvalidArgumentException
1989
-     * @throws InvalidDataTypeException
1990
-     * @throws InvalidInterfaceException
1991
-     * @throws ReflectionException
1992
-     * @throws RuntimeException
1993
-     * @throws DomainException
1994
-     */
1995
-    protected function cancel_registration(bool $notify = false)
1996
-    {
1997
-        $this->_reg_status_change_return(RegStatus::CANCELLED, $notify);
1998
-    }
1999
-
2000
-
2001
-    /**
2002
-     * not_approve_registration
2003
-     *
2004
-     * @param bool $notify whether to notify the registrant about their status change.
2005
-     * @return void
2006
-     * @throws EE_Error
2007
-     * @throws EntityNotFoundException
2008
-     * @throws InvalidArgumentException
2009
-     * @throws InvalidDataTypeException
2010
-     * @throws InvalidInterfaceException
2011
-     * @throws ReflectionException
2012
-     * @throws RuntimeException
2013
-     * @throws DomainException
2014
-     */
2015
-    protected function not_approve_registration(bool $notify = false)
2016
-    {
2017
-        $this->_reg_status_change_return(RegStatus::AWAITING_REVIEW, $notify);
2018
-    }
2019
-
2020
-
2021
-    /**
2022
-     * decline_registration
2023
-     *
2024
-     * @param bool $notify whether to notify the registrant about their status change.
2025
-     * @return void
2026
-     * @throws EE_Error
2027
-     * @throws EntityNotFoundException
2028
-     * @throws InvalidArgumentException
2029
-     * @throws InvalidDataTypeException
2030
-     * @throws InvalidInterfaceException
2031
-     * @throws ReflectionException
2032
-     * @throws RuntimeException
2033
-     * @throws DomainException
2034
-     */
2035
-    protected function pending_registration(bool $notify = false)
2036
-    {
2037
-        $this->_reg_status_change_return(RegStatus::PENDING_PAYMENT, $notify);
2038
-    }
2039
-
2040
-
2041
-    /**
2042
-     * waitlist_registration
2043
-     *
2044
-     * @param bool $notify whether to notify the registrant about their status change.
2045
-     * @return void
2046
-     * @throws EE_Error
2047
-     * @throws EntityNotFoundException
2048
-     * @throws InvalidArgumentException
2049
-     * @throws InvalidDataTypeException
2050
-     * @throws InvalidInterfaceException
2051
-     * @throws ReflectionException
2052
-     * @throws RuntimeException
2053
-     * @throws DomainException
2054
-     */
2055
-    protected function wait_list_registration(bool $notify = false)
2056
-    {
2057
-        $this->_reg_status_change_return(RegStatus::WAIT_LIST, $notify);
2058
-    }
2059
-
2060
-
2061
-    /**
2062
-     * generates HTML for the Registration main meta box
2063
-     *
2064
-     * @return void
2065
-     * @throws DomainException
2066
-     * @throws EE_Error
2067
-     * @throws InvalidArgumentException
2068
-     * @throws InvalidDataTypeException
2069
-     * @throws InvalidInterfaceException
2070
-     * @throws ReflectionException
2071
-     * @throws EntityNotFoundException
2072
-     */
2073
-    public function _reg_details_meta_box()
2074
-    {
2075
-        EEH_Autoloader::register_line_item_display_autoloaders();
2076
-        EEH_Autoloader::register_line_item_filter_autoloaders();
2077
-
2078
-        $transaction        = $this->_registration->transaction()
2079
-            ? $this->_registration->transaction()
2080
-            : EE_Transaction::new_instance();
2081
-        $this->session_data = $transaction->session_data();
2082
-        $filters            = new EE_Line_Item_Filter_Collection();
2083
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2084
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2085
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2086
-            $filters,
2087
-            $transaction->total_line_item()
2088
-        );
2089
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2090
-        $line_item_display                       = new EE_Line_Item_Display(
2091
-            'reg_admin_table',
2092
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2093
-        );
2094
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2095
-            $filtered_line_item_tree,
2096
-            ['EE_Registration' => $this->_registration]
2097
-        );
2098
-        $attendee                                = $this->_registration->attendee();
2099
-        if (
2100
-            $this->capabilities->current_user_can(
2101
-                'ee_read_transaction',
2102
-                'espresso_transactions_view_transaction'
2103
-            )
2104
-        ) {
2105
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2106
-                EE_Admin_Page::add_query_args_and_nonce(
2107
-                    [
2108
-                        'action' => 'view_transaction',
2109
-                        'TXN_ID' => $transaction->ID(),
2110
-                    ],
2111
-                    TXN_ADMIN_URL
2112
-                ),
2113
-                esc_html__(' View Transaction', 'event_espresso'),
2114
-                'button button--secondary right',
2115
-                'dashicons dashicons-cart'
2116
-            );
2117
-        } else {
2118
-            $this->_template_args['view_transaction_button'] = '';
2119
-        }
2120
-        if (
2121
-            $attendee instanceof EE_Attendee
2122
-            && $this->capabilities->current_user_can(
2123
-                'ee_send_message',
2124
-                'espresso_registrations_resend_registration'
2125
-            )
2126
-        ) {
2127
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2128
-                EE_Admin_Page::add_query_args_and_nonce(
2129
-                    [
2130
-                        'action'      => 'resend_registration',
2131
-                        '_REG_ID'     => $this->_registration->ID(),
2132
-                        'redirect_to' => 'view_registration',
2133
-                    ],
2134
-                    REG_ADMIN_URL
2135
-                ),
2136
-                esc_html__(' Resend Registration', 'event_espresso'),
2137
-                'button button--secondary right',
2138
-                'dashicons dashicons-email-alt'
2139
-            );
2140
-        } else {
2141
-            $this->_template_args['resend_registration_button'] = '';
2142
-        }
2143
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2144
-        $payment                               = $transaction->get_first_related('Payment');
2145
-        $payment                               = ! $payment instanceof EE_Payment
2146
-            ? EE_Payment::new_instance()
2147
-            : $payment;
2148
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2149
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2150
-            ? EE_Payment_Method::new_instance()
2151
-            : $payment_method;
2152
-        $reg_details                           = [
2153
-            'payment_method'       => $payment_method->name(),
2154
-            'response_msg'         => $payment->gateway_response(),
2155
-            'registration_id'      => $this->_registration->get('REG_code'),
2156
-            'registration_session' => $this->_registration->session_ID(),
2157
-            'ip_address'           => $this->session_data['ip_address'] ?? '',
2158
-            'user_agent'           => $this->session_data['user_agent'] ?? '',
2159
-        ];
2160
-        if (isset($reg_details['registration_id'])) {
2161
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2162
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2163
-                'Registration ID',
2164
-                'event_espresso'
2165
-            );
2166
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2167
-        }
2168
-        if (isset($reg_details['payment_method'])) {
2169
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2170
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2171
-                'Most Recent Payment Method',
2172
-                'event_espresso'
2173
-            );
2174
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2175
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2176
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2177
-                'Payment method response',
2178
-                'event_espresso'
2179
-            );
2180
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2181
-        }
2182
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2183
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2184
-            'Registration Session',
2185
-            'event_espresso'
2186
-        );
2187
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2188
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2189
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2190
-            'Registration placed from IP',
2191
-            'event_espresso'
2192
-        );
2193
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2194
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2195
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2196
-            'Registrant User Agent',
2197
-            'event_espresso'
2198
-        );
2199
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2200
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2201
-            [
2202
-                'action'   => 'default',
2203
-                'event_id' => $this->_registration->event_ID(),
2204
-            ],
2205
-            REG_ADMIN_URL
2206
-        );
2207
-
2208
-        $this->_template_args['REG_ID']   = $this->_registration->ID();
2209
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2210
-
2211
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2212
-        EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2213
-    }
2214
-
2215
-
2216
-    /**
2217
-     * generates HTML for the Registration Questions meta box.
2218
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2219
-     * otherwise uses new forms system
2220
-     *
2221
-     * @return void
2222
-     * @throws DomainException
2223
-     * @throws EE_Error
2224
-     * @throws InvalidArgumentException
2225
-     * @throws InvalidDataTypeException
2226
-     * @throws InvalidInterfaceException
2227
-     * @throws ReflectionException
2228
-     */
2229
-    public function _reg_questions_meta_box()
2230
-    {
2231
-        // allow someone to override this method entirely
2232
-        if (
2233
-            apply_filters(
2234
-                'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2235
-                true,
2236
-                $this,
2237
-                $this->_registration
2238
-            )
2239
-        ) {
2240
-            $form = $this->_get_reg_custom_questions_form(
2241
-                $this->_registration->ID()
2242
-            );
2243
-
2244
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2245
-                ? $form->get_html_and_js()
2246
-                : '';
2247
-
2248
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2249
-            $this->_template_args['REG_ID']                    = $this->_registration->ID();
2250
-            $template_path                                     =
2251
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2252
-            EEH_Template::display_template($template_path, $this->_template_args);
2253
-        }
2254
-    }
2255
-
2256
-
2257
-    /**
2258
-     * form_before_question_group
2259
-     *
2260
-     * @param string $output
2261
-     * @return        string
2262
-     * @deprecated    as of 4.8.32.rc.000
2263
-     */
2264
-    public function form_before_question_group(string $output): string
2265
-    {
2266
-        EE_Error::doing_it_wrong(
2267
-            __CLASS__ . '::' . __FUNCTION__,
2268
-            esc_html__(
2269
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2270
-                'event_espresso'
2271
-            ),
2272
-            '4.8.32.rc.000'
2273
-        );
2274
-        return '
28
+	private ?EE_Registration $_registration = null;
29
+
30
+	private ?EE_Event $_reg_event = null;
31
+
32
+	private array $session_data = [];
33
+
34
+	private static array $_reg_status = [];
35
+
36
+	/**
37
+	 * Form for displaying the custom questions for this registration.
38
+	 * This gets used a few times throughout the request so it's best to cache it
39
+	 */
40
+	protected ?EE_Registration_Custom_Questions_Form $_reg_custom_questions_form = null;
41
+
42
+	private ?EEM_Registration $registration_model = null;
43
+
44
+	private ?EEM_Attendee $attendee_model = null;
45
+
46
+	private ?EEM_Event $event_model = null;
47
+
48
+	private ?EEM_Status $status_model = null;
49
+
50
+	/**
51
+	 * @var EE_Attendee|null
52
+	 */
53
+	protected $_cpt_model_obj;
54
+
55
+
56
+	/**
57
+	 * @param bool $routing
58
+	 * @throws InvalidArgumentException
59
+	 * @throws InvalidDataTypeException
60
+	 * @throws InvalidInterfaceException
61
+	 * @throws ReflectionException
62
+	 */
63
+	public function __construct($routing = true)
64
+	{
65
+		parent::__construct($routing);
66
+		$this->cpt_editpost_route = 'edit_attendee';
67
+		add_action('wp_loaded', [$this, 'wp_loaded']);
68
+	}
69
+
70
+
71
+	/**
72
+	 * @return EEM_Registration
73
+	 * @throws InvalidArgumentException
74
+	 * @throws InvalidDataTypeException
75
+	 * @throws InvalidInterfaceException
76
+	 * @since 4.10.2.p
77
+	 */
78
+	protected function getRegistrationModel(): EEM_Registration
79
+	{
80
+		if (! $this->registration_model instanceof EEM_Registration) {
81
+			$this->registration_model = $this->loader->getShared('EEM_Registration');
82
+		}
83
+		return $this->registration_model;
84
+	}
85
+
86
+
87
+	/**
88
+	 * @return EEM_Attendee
89
+	 * @throws InvalidArgumentException
90
+	 * @throws InvalidDataTypeException
91
+	 * @throws InvalidInterfaceException
92
+	 * @since 4.10.2.p
93
+	 */
94
+	protected function getAttendeeModel(): EEM_Attendee
95
+	{
96
+		if (! $this->attendee_model instanceof EEM_Attendee) {
97
+			$this->attendee_model = $this->loader->getShared('EEM_Attendee');
98
+		}
99
+		return $this->attendee_model;
100
+	}
101
+
102
+
103
+	/**
104
+	 * @return EEM_Event
105
+	 * @throws InvalidArgumentException
106
+	 * @throws InvalidDataTypeException
107
+	 * @throws InvalidInterfaceException
108
+	 * @since 4.10.2.p
109
+	 */
110
+	protected function getEventModel(): EEM_Event
111
+	{
112
+		if (! $this->event_model instanceof EEM_Event) {
113
+			$this->event_model = $this->loader->getShared('EEM_Event');
114
+		}
115
+		return $this->event_model;
116
+	}
117
+
118
+
119
+	/**
120
+	 * @return EEM_Status
121
+	 * @throws InvalidArgumentException
122
+	 * @throws InvalidDataTypeException
123
+	 * @throws InvalidInterfaceException
124
+	 * @since 4.10.2.p
125
+	 */
126
+	protected function getStatusModel(): EEM_Status
127
+	{
128
+		if (! $this->status_model instanceof EEM_Status) {
129
+			$this->status_model = $this->loader->getShared('EEM_Status');
130
+		}
131
+		return $this->status_model;
132
+	}
133
+
134
+
135
+	public function wp_loaded()
136
+	{
137
+		// when adding a new registration...
138
+		$action = $this->request->getRequestParam('action');
139
+		if ($action === 'new_registration') {
140
+			EE_System::do_not_cache();
141
+			if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
142
+				// and it's NOT the attendee information reg step
143
+				// force cookie expiration by setting time to last week
144
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
145
+				// and update the global
146
+				$_COOKIE['ee_registration_added'] = 0;
147
+			}
148
+		}
149
+	}
150
+
151
+
152
+	protected function _init_page_props()
153
+	{
154
+		$this->page_slug        = REG_PG_SLUG;
155
+		$this->_admin_base_url  = REG_ADMIN_URL;
156
+		$this->_admin_base_path = REG_ADMIN;
157
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
158
+		$this->_cpt_routes      = [
159
+			'add_new_attendee' => 'espresso_attendees',
160
+			'edit_attendee'    => 'espresso_attendees',
161
+			'insert_attendee'  => 'espresso_attendees',
162
+			'update_attendee'  => 'espresso_attendees',
163
+		];
164
+		$this->_cpt_model_names = [
165
+			'add_new_attendee' => 'EEM_Attendee',
166
+			'edit_attendee'    => 'EEM_Attendee',
167
+		];
168
+		$this->_cpt_edit_routes = [
169
+			'espresso_attendees' => 'edit_attendee',
170
+		];
171
+		$this->_pagenow_map     = [
172
+			'add_new_attendee' => 'post-new.php',
173
+			'edit_attendee'    => 'post.php',
174
+			'trash'            => 'post.php',
175
+		];
176
+		add_action('edit_form_after_title', [$this, 'after_title_form_fields']);
177
+		// add filters so that the comment urls don't take users to a confusing 404 page
178
+		add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
179
+	}
180
+
181
+
182
+	/**
183
+	 * @param string     $link    The comment permalink with '#comment-$id' appended.
184
+	 * @param WP_Comment $comment The current comment object.
185
+	 * @return string
186
+	 */
187
+	public function clear_comment_link(string $link, WP_Comment $comment): string
188
+	{
189
+		// gotta make sure this only happens on this route
190
+		$post_type = get_post_type($comment->comment_post_ID);
191
+		if ($post_type === EspressoPostType::ATTENDEES) {
192
+			return '#commentsdiv';
193
+		}
194
+		return $link;
195
+	}
196
+
197
+
198
+	protected function _ajax_hooks()
199
+	{
200
+	}
201
+
202
+
203
+	protected function _define_page_props()
204
+	{
205
+		$this->_admin_page_title = $this->page_label;
206
+		$this->_labels           = [
207
+			'buttons'                      => [
208
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
209
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
210
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
211
+				'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
212
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
213
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
214
+			],
215
+			'publishbox'                   => [
216
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
217
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
218
+			],
219
+			'hide_add_button_on_cpt_route' => [
220
+				'edit_attendee' => true,
221
+			],
222
+		];
223
+	}
224
+
225
+
226
+	/**
227
+	 * grab url requests and route them
228
+	 *
229
+	 * @return void
230
+	 * @throws EE_Error
231
+	 * @throws ReflectionException
232
+	 */
233
+	public function _set_page_routes()
234
+	{
235
+		$this->_get_registration_status_array();
236
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
237
+		$REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
238
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
239
+		$ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
240
+		$this->_page_routes = [
241
+			'default'                             => [
242
+				'func'       => [$this, '_registrations_overview_list_table'],
243
+				'capability' => 'ee_read_registrations',
244
+			],
245
+			'view_registration'                   => [
246
+				'func'       => [$this, '_registration_details'],
247
+				'capability' => 'ee_read_registration',
248
+				'obj_id'     => $REG_ID,
249
+			],
250
+			'edit_registration'                   => [
251
+				'func'       => [$this, '_update_attendee_registration_form'],
252
+				'noheader'           => true,
253
+				'headers_sent_route' => 'view_registration',
254
+				'capability'         => 'ee_edit_registration',
255
+				'obj_id'             => $REG_ID,
256
+				'_REG_ID'            => $REG_ID,
257
+			],
258
+			'trash_registrations'                 => [
259
+				'func'       => [$this, '_trash_or_restore_registrations'],
260
+				'args'       => ['trash' => true],
261
+				'noheader'   => true,
262
+				'capability' => 'ee_delete_registrations',
263
+			],
264
+			'restore_registrations'               => [
265
+				'func'       => [$this, '_trash_or_restore_registrations'],
266
+				'args'       => ['trash' => false],
267
+				'noheader'   => true,
268
+				'capability' => 'ee_delete_registrations',
269
+			],
270
+			'delete_registrations'                => [
271
+				'func'       => [$this, '_delete_registrations'],
272
+				'noheader'   => true,
273
+				'capability' => 'ee_delete_registrations',
274
+			],
275
+			'new_registration'                    => [
276
+				'func'       => [$this, 'new_registration'],
277
+				'capability' => 'ee_edit_registrations',
278
+			],
279
+			'process_reg_step'                    => [
280
+				'func'       => [$this, 'process_reg_step'],
281
+				'noheader'   => true,
282
+				'capability' => 'ee_edit_registrations',
283
+			],
284
+			'redirect_to_txn'                     => [
285
+				'func'       => [$this, 'redirect_to_txn'],
286
+				'noheader'   => true,
287
+				'capability' => 'ee_edit_registrations',
288
+			],
289
+			'change_reg_status'                   => [
290
+				'func'       => [$this, '_change_reg_status'],
291
+				'noheader'   => true,
292
+				'capability' => 'ee_edit_registration',
293
+				'obj_id'     => $REG_ID,
294
+			],
295
+			'approve_registration'                => [
296
+				'func'       => [$this, 'approve_registration'],
297
+				'noheader'   => true,
298
+				'capability' => 'ee_edit_registration',
299
+				'obj_id'     => $REG_ID,
300
+			],
301
+			'approve_and_notify_registration'     => [
302
+				'func'       => [$this, 'approve_registration'],
303
+				'noheader'   => true,
304
+				'args'       => [true],
305
+				'capability' => 'ee_edit_registration',
306
+				'obj_id'     => $REG_ID,
307
+			],
308
+			'approve_registrations'               => [
309
+				'func'       => [$this, 'bulk_action_on_registrations'],
310
+				'noheader'   => true,
311
+				'capability' => 'ee_edit_registrations',
312
+				'args'       => ['approve'],
313
+			],
314
+			'approve_and_notify_registrations'    => [
315
+				'func'       => [$this, 'bulk_action_on_registrations'],
316
+				'noheader'   => true,
317
+				'capability' => 'ee_edit_registrations',
318
+				'args'       => ['approve', true],
319
+			],
320
+			'decline_registration'                => [
321
+				'func'       => [$this, 'decline_registration'],
322
+				'noheader'   => true,
323
+				'capability' => 'ee_edit_registration',
324
+				'obj_id'     => $REG_ID,
325
+			],
326
+			'decline_and_notify_registration'     => [
327
+				'func'       => [$this, 'decline_registration'],
328
+				'noheader'   => true,
329
+				'args'       => [true],
330
+				'capability' => 'ee_edit_registration',
331
+				'obj_id'     => $REG_ID,
332
+			],
333
+			'decline_registrations'               => [
334
+				'func'       => [$this, 'bulk_action_on_registrations'],
335
+				'noheader'   => true,
336
+				'capability' => 'ee_edit_registrations',
337
+				'args'       => ['decline'],
338
+			],
339
+			'decline_and_notify_registrations'    => [
340
+				'func'       => [$this, 'bulk_action_on_registrations'],
341
+				'noheader'   => true,
342
+				'capability' => 'ee_edit_registrations',
343
+				'args'       => ['decline', true],
344
+			],
345
+			'pending_registration'                => [
346
+				'func'       => [$this, 'pending_registration'],
347
+				'noheader'   => true,
348
+				'capability' => 'ee_edit_registration',
349
+				'obj_id'     => $REG_ID,
350
+			],
351
+			'pending_and_notify_registration'     => [
352
+				'func'       => [$this, 'pending_registration'],
353
+				'noheader'   => true,
354
+				'args'       => [true],
355
+				'capability' => 'ee_edit_registration',
356
+				'obj_id'     => $REG_ID,
357
+			],
358
+			'pending_registrations'               => [
359
+				'func'       => [$this, 'bulk_action_on_registrations'],
360
+				'noheader'   => true,
361
+				'capability' => 'ee_edit_registrations',
362
+				'args'       => ['pending'],
363
+			],
364
+			'pending_and_notify_registrations'    => [
365
+				'func'       => [$this, 'bulk_action_on_registrations'],
366
+				'noheader'   => true,
367
+				'capability' => 'ee_edit_registrations',
368
+				'args'       => ['pending', true],
369
+			],
370
+			'no_approve_registration'             => [
371
+				'func'       => [$this, 'not_approve_registration'],
372
+				'noheader'   => true,
373
+				'capability' => 'ee_edit_registration',
374
+				'obj_id'     => $REG_ID,
375
+			],
376
+			'no_approve_and_notify_registration'  => [
377
+				'func'       => [$this, 'not_approve_registration'],
378
+				'noheader'   => true,
379
+				'args'       => [true],
380
+				'capability' => 'ee_edit_registration',
381
+				'obj_id'     => $REG_ID,
382
+			],
383
+			'no_approve_registrations'            => [
384
+				'func'       => [$this, 'bulk_action_on_registrations'],
385
+				'noheader'   => true,
386
+				'capability' => 'ee_edit_registrations',
387
+				'args'       => ['not_approve'],
388
+			],
389
+			'no_approve_and_notify_registrations' => [
390
+				'func'       => [$this, 'bulk_action_on_registrations'],
391
+				'noheader'   => true,
392
+				'capability' => 'ee_edit_registrations',
393
+				'args'       => ['not_approve', true],
394
+			],
395
+			'cancel_registration'                 => [
396
+				'func'       => [$this, 'cancel_registration'],
397
+				'noheader'   => true,
398
+				'capability' => 'ee_edit_registration',
399
+				'obj_id'     => $REG_ID,
400
+			],
401
+			'cancel_and_notify_registration'      => [
402
+				'func'       => [$this, 'cancel_registration'],
403
+				'noheader'   => true,
404
+				'args'       => [true],
405
+				'capability' => 'ee_edit_registration',
406
+				'obj_id'     => $REG_ID,
407
+			],
408
+			'cancel_registrations'                => [
409
+				'func'       => [$this, 'bulk_action_on_registrations'],
410
+				'noheader'   => true,
411
+				'capability' => 'ee_edit_registrations',
412
+				'args'       => ['cancel'],
413
+			],
414
+			'cancel_and_notify_registrations'     => [
415
+				'func'       => [$this, 'bulk_action_on_registrations'],
416
+				'noheader'   => true,
417
+				'capability' => 'ee_edit_registrations',
418
+				'args'       => ['cancel', true],
419
+			],
420
+			'wait_list_registration'              => [
421
+				'func'       => [$this, 'wait_list_registration'],
422
+				'noheader'   => true,
423
+				'capability' => 'ee_edit_registration',
424
+				'obj_id'     => $REG_ID,
425
+			],
426
+			'wait_list_and_notify_registration'   => [
427
+				'func'       => [$this, 'wait_list_registration'],
428
+				'noheader'   => true,
429
+				'args'       => [true],
430
+				'capability' => 'ee_edit_registration',
431
+				'obj_id'     => $REG_ID,
432
+			],
433
+			'contact_list'                        => [
434
+				'func'       => [$this, '_attendee_contact_list_table'],
435
+				'capability' => 'ee_read_contacts',
436
+			],
437
+			'add_new_attendee'                    => [
438
+				'func'       => [$this, '_create_new_cpt_item'],
439
+				'args' => [
440
+					'new_attendee' => true,
441
+					'capability'   => 'ee_edit_contacts',
442
+				],
443
+			],
444
+			'edit_attendee'                       => [
445
+				'func'       => [$this, '_edit_cpt_item'],
446
+				'capability' => 'ee_edit_contacts',
447
+				'obj_id'     => $ATT_ID,
448
+			],
449
+			'duplicate_attendee'                  => [
450
+				'func'       => [$this, '_duplicate_attendee'],
451
+				'noheader'   => true,
452
+				'capability' => 'ee_edit_contacts',
453
+				'obj_id'     => $ATT_ID,
454
+			],
455
+			'insert_attendee'                     => [
456
+				'func'       => [$this, '_insert_or_update_attendee'],
457
+				'args'       => [
458
+					'new_attendee' => true,
459
+				],
460
+				'noheader'   => true,
461
+				'capability' => 'ee_edit_contacts',
462
+			],
463
+			'update_attendee'                     => [
464
+				'func'       => [$this, '_insert_or_update_attendee'],
465
+				'args'       => [
466
+					'new_attendee' => false,
467
+				],
468
+				'noheader'   => true,
469
+				'capability' => 'ee_edit_contacts',
470
+				'obj_id'     => $ATT_ID,
471
+			],
472
+			'trash_attendees'                     => [
473
+				'func'       => [$this, '_trash_or_restore_attendees'],
474
+				'args'       => [
475
+					'trash' => 'true',
476
+				],
477
+				'noheader'   => true,
478
+				'capability' => 'ee_delete_contacts',
479
+			],
480
+			'trash_attendee'                      => [
481
+				'func'       => [$this, '_trash_or_restore_attendees'],
482
+				'args'       => [
483
+					'trash' => true,
484
+				],
485
+				'noheader'   => true,
486
+				'capability' => 'ee_delete_contacts',
487
+				'obj_id'     => $ATT_ID,
488
+			],
489
+			'restore_attendees'                   => [
490
+				'func'       => [$this, '_trash_or_restore_attendees'],
491
+				'args'       => [
492
+					'trash' => false,
493
+				],
494
+				'noheader'   => true,
495
+				'capability' => 'ee_delete_contacts',
496
+				'obj_id'     => $ATT_ID,
497
+			],
498
+			'delete_attendee'                     => [
499
+				'func'       => [$this, 'deleteAttendees'],
500
+				'capability' => 'ee_delete_contacts',
501
+				'obj_id'     => $ATT_ID,
502
+				'noheader'   => true,
503
+			],
504
+			'delete_attendees'                    => [
505
+				'func'       => [$this, 'deleteAttendees'],
506
+				'capability' => 'ee_delete_contacts',
507
+				'noheader'   => true,
508
+			],
509
+			'resend_registration'                 => [
510
+				'func'       => [$this, '_resend_registration'],
511
+				'noheader'   => true,
512
+				'capability' => 'ee_send_message',
513
+			],
514
+			'registrations_report'                => [
515
+				'func'       => [$this, '_registrations_report'],
516
+				'noheader'   => true,
517
+				'capability' => 'ee_read_registrations',
518
+			],
519
+			'contact_list_export'                 => [
520
+				'func'       => [$this, '_contact_list_export'],
521
+				'noheader'   => true,
522
+				'capability' => 'export',
523
+			],
524
+			'contact_list_report'                 => [
525
+				'func'       => [$this, '_contact_list_report'],
526
+				'noheader'   => true,
527
+				'capability' => 'ee_read_contacts',
528
+			],
529
+		];
530
+	}
531
+
532
+
533
+	protected function _set_page_config()
534
+	{
535
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
536
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
537
+		$this->_page_config = [
538
+			'default'           => [
539
+				'nav'           => [
540
+					'label' => esc_html__('Overview', 'event_espresso'),
541
+					'icon'  => 'dashicons-list-view',
542
+					'order' => 5,
543
+				],
544
+				'help_tabs'     => [
545
+					'registrations_overview_help_tab'                       => [
546
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
547
+						'filename' => 'registrations_overview',
548
+					],
549
+					'registrations_overview_table_column_headings_help_tab' => [
550
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
551
+						'filename' => 'registrations_overview_table_column_headings',
552
+					],
553
+					'registrations_overview_filters_help_tab'               => [
554
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
555
+						'filename' => 'registrations_overview_filters',
556
+					],
557
+					'registrations_overview_views_help_tab'                 => [
558
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
559
+						'filename' => 'registrations_overview_views',
560
+					],
561
+					'registrations_regoverview_other_help_tab'              => [
562
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
563
+						'filename' => 'registrations_overview_other',
564
+					],
565
+				],
566
+				'list_table'    => 'EE_Registrations_List_Table',
567
+				'require_nonce' => false,
568
+			],
569
+			'view_registration' => [
570
+				'nav'           => [
571
+					'label'      => esc_html__('REG Details', 'event_espresso'),
572
+					'icon'       => 'dashicons-clipboard',
573
+					'order'      => 15,
574
+					'url'        => $REG_ID
575
+						? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
576
+						: $this->_admin_base_url,
577
+					'persistent' => false,
578
+				],
579
+				'help_tabs'     => [
580
+					'registrations_details_help_tab'                    => [
581
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
582
+						'filename' => 'registrations_details',
583
+					],
584
+					'registrations_details_table_help_tab'              => [
585
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
586
+						'filename' => 'registrations_details_table',
587
+					],
588
+					'registrations_details_form_answers_help_tab'       => [
589
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
590
+						'filename' => 'registrations_details_form_answers',
591
+					],
592
+					'registrations_details_registrant_details_help_tab' => [
593
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
594
+						'filename' => 'registrations_details_registrant_details',
595
+					],
596
+				],
597
+				'metaboxes'     => array_merge(
598
+					$this->_default_espresso_metaboxes,
599
+					['_registration_details_metaboxes']
600
+				),
601
+				'require_nonce' => false,
602
+			],
603
+			'new_registration'  => [
604
+				'nav'           => [
605
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
606
+					'icon'       => 'dashicons-plus-alt',
607
+					'url'        => '#',
608
+					'order'      => 15,
609
+					'persistent' => false,
610
+				],
611
+				'metaboxes'     => $this->_default_espresso_metaboxes,
612
+				'labels'        => [
613
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
614
+				],
615
+				'require_nonce' => false,
616
+			],
617
+			'add_new_attendee'  => [
618
+				'nav'           => [
619
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
620
+					'icon'       => 'dashicons-plus-alt',
621
+					'order'      => 15,
622
+					'persistent' => false,
623
+				],
624
+				'metaboxes'     => array_merge(
625
+					$this->_default_espresso_metaboxes,
626
+					['_publish_post_box', 'attendee_editor_metaboxes']
627
+				),
628
+				'require_nonce' => false,
629
+			],
630
+			'edit_attendee'     => [
631
+				'nav'           => [
632
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
633
+					'icon'       => 'dashicons-edit-large',
634
+					'order'      => 15,
635
+					'persistent' => false,
636
+					'url'        => $ATT_ID
637
+						? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
638
+						: $this->_admin_base_url,
639
+				],
640
+				'metaboxes'     => array_merge(
641
+					$this->_default_espresso_metaboxes,
642
+					['attendee_editor_metaboxes']
643
+				),
644
+				'require_nonce' => false,
645
+			],
646
+			'contact_list'      => [
647
+				'nav'           => [
648
+					'label' => esc_html__('Contact List', 'event_espresso'),
649
+					'icon'  => 'dashicons-id-alt',
650
+					'order' => 20,
651
+				],
652
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
653
+				'help_tabs'     => [
654
+					'registrations_contact_list_help_tab'                       => [
655
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
656
+						'filename' => 'registrations_contact_list',
657
+					],
658
+					'registrations_contact-list_table_column_headings_help_tab' => [
659
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
660
+						'filename' => 'registrations_contact_list_table_column_headings',
661
+					],
662
+					'registrations_contact_list_views_help_tab'                 => [
663
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
664
+						'filename' => 'registrations_contact_list_views',
665
+					],
666
+					'registrations_contact_list_other_help_tab'                 => [
667
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
668
+						'filename' => 'registrations_contact_list_other',
669
+					],
670
+				],
671
+				'metaboxes'     => [],
672
+				'require_nonce' => false,
673
+			],
674
+			// override default cpt routes
675
+			'create_new'        => '',
676
+			'edit'              => '',
677
+		];
678
+	}
679
+
680
+
681
+	/**
682
+	 * The below methods aren't used by this class currently
683
+	 */
684
+	protected function _add_screen_options()
685
+	{
686
+	}
687
+
688
+
689
+	protected function _add_feature_pointers()
690
+	{
691
+	}
692
+
693
+
694
+	public function admin_init()
695
+	{
696
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
697
+			'click "Update Registration Questions" to save your changes',
698
+			'event_espresso'
699
+		);
700
+		EE_Registry::$i18n_js_strings['confirm_update_reg_details'] = esc_html__(
701
+			"Are you sure you want to update the submitted registration form data? This cannot be undone.\nPress OK to proceed or Cancel to keep the current data.",
702
+		);
703
+	}
704
+
705
+
706
+	public function admin_notices()
707
+	{
708
+	}
709
+
710
+
711
+	public function admin_footer_scripts()
712
+	{
713
+	}
714
+
715
+
716
+	/**
717
+	 * get list of registration statuses
718
+	 *
719
+	 * @return void
720
+	 * @throws EE_Error
721
+	 * @throws ReflectionException
722
+	 */
723
+	private function _get_registration_status_array()
724
+	{
725
+		self::$_reg_status = EEM_Registration::reg_status_array([], true);
726
+	}
727
+
728
+
729
+	/**
730
+	 * @throws InvalidArgumentException
731
+	 * @throws InvalidDataTypeException
732
+	 * @throws InvalidInterfaceException
733
+	 * @since 4.10.2.p
734
+	 */
735
+	protected function _add_screen_options_default()
736
+	{
737
+		$this->_per_page_screen_option();
738
+	}
739
+
740
+
741
+	/**
742
+	 * @throws InvalidArgumentException
743
+	 * @throws InvalidDataTypeException
744
+	 * @throws InvalidInterfaceException
745
+	 * @since 4.10.2.p
746
+	 */
747
+	protected function _add_screen_options_contact_list()
748
+	{
749
+		$page_title              = $this->_admin_page_title;
750
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
751
+		$this->_per_page_screen_option();
752
+		$this->_admin_page_title = $page_title;
753
+	}
754
+
755
+
756
+	public function load_scripts_styles()
757
+	{
758
+		// style
759
+		wp_register_style(
760
+			'espresso_reg',
761
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
762
+			['ee-admin-css'],
763
+			EVENT_ESPRESSO_VERSION
764
+		);
765
+		wp_enqueue_style('espresso_reg');
766
+		// script
767
+		wp_register_script(
768
+			'espresso_reg',
769
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
770
+			['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
771
+			EVENT_ESPRESSO_VERSION,
772
+			true
773
+		);
774
+		wp_enqueue_script('espresso_reg');
775
+	}
776
+
777
+
778
+	/**
779
+	 * @throws EE_Error
780
+	 * @throws InvalidArgumentException
781
+	 * @throws InvalidDataTypeException
782
+	 * @throws InvalidInterfaceException
783
+	 * @throws ReflectionException
784
+	 * @since 4.10.2.p
785
+	 */
786
+	public function load_scripts_styles_edit_attendee()
787
+	{
788
+		// stuff to only show up on our attendee edit details page.
789
+		$attendee_details_translations = [
790
+			'att_publish_text' => sprintf(
791
+			/* translators: The date and time */
792
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
793
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
794
+			),
795
+		];
796
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
797
+		wp_enqueue_script(JqueryAssetManager::JS_HANDLE_JQUERY_VALIDATE);
798
+	}
799
+
800
+
801
+	/**
802
+	 * @throws EE_Error
803
+	 * @throws InvalidArgumentException
804
+	 * @throws InvalidDataTypeException
805
+	 * @throws InvalidInterfaceException
806
+	 * @throws ReflectionException
807
+	 * @since 4.10.2.p
808
+	 */
809
+	public function load_scripts_styles_view_registration()
810
+	{
811
+		$this->_set_registration_object();
812
+		// styles
813
+		wp_enqueue_style('espresso-ui-theme');
814
+		// scripts
815
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
816
+		$this->_reg_custom_questions_form->wp_enqueue_scripts();
817
+	}
818
+
819
+
820
+	public function load_scripts_styles_contact_list()
821
+	{
822
+		wp_dequeue_style('espresso_reg');
823
+		wp_register_style(
824
+			'espresso_att',
825
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
826
+			['ee-admin-css'],
827
+			EVENT_ESPRESSO_VERSION
828
+		);
829
+		wp_enqueue_style('espresso_att');
830
+	}
831
+
832
+
833
+	/**
834
+	 * @throws ReflectionException
835
+	 * @throws EE_Error
836
+	 */
837
+	public function load_scripts_styles_new_registration()
838
+	{
839
+		wp_register_script(
840
+			'ee-spco-for-admin',
841
+			REG_ASSETS_URL . 'spco_for_admin.js',
842
+			['underscore', 'jquery'],
843
+			EVENT_ESPRESSO_VERSION,
844
+			true
845
+		);
846
+		wp_enqueue_script('ee-spco-for-admin');
847
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
848
+		EE_Form_Section_Proper::wp_enqueue_scripts();
849
+		EED_Ticket_Selector::load_tckt_slctr_assets();
850
+	}
851
+
852
+
853
+	public function AHEE__EE_Admin_Page__route_admin_request_resend_registration()
854
+	{
855
+		add_filter('FHEE_load_EE_messages', '__return_true');
856
+	}
857
+
858
+
859
+	public function AHEE__EE_Admin_Page__route_admin_request_approve_registration()
860
+	{
861
+		add_filter('FHEE_load_EE_messages', '__return_true');
862
+	}
863
+
864
+
865
+	/**
866
+	 * @throws EE_Error
867
+	 * @throws InvalidArgumentException
868
+	 * @throws InvalidDataTypeException
869
+	 * @throws InvalidInterfaceException
870
+	 * @throws ReflectionException
871
+	 * @since 4.10.2.p
872
+	 */
873
+	protected function _set_list_table_views_default()
874
+	{
875
+		// for notification related bulk actions we need to make sure only active messengers have an option.
876
+		EED_Messages::set_autoloaders();
877
+		/** @type EE_Message_Resource_Manager $message_resource_manager */
878
+		$message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
879
+		$active_mts               = $message_resource_manager->list_of_active_message_types();
880
+		// key= bulk_action_slug, value= message type.
881
+		$match_array = [
882
+			'approve_registrations'    => 'registration',
883
+			'decline_registrations'    => 'declined_registration',
884
+			'pending_registrations'    => 'pending_approval',
885
+			'no_approve_registrations' => 'not_approved_registration',
886
+			'cancel_registrations'     => 'cancelled_registration',
887
+		];
888
+		$can_send    = $this->capabilities->current_user_can(
889
+			'ee_send_message',
890
+			'batch_send_messages'
891
+		);
892
+		/** setup reg status bulk actions **/
893
+		$def_reg_status_actions['approve_registrations'] = esc_html__('Approve Registrations', 'event_espresso');
894
+		if ($can_send && in_array($match_array['approve_registrations'], $active_mts, true)) {
895
+			$def_reg_status_actions['approve_and_notify_registrations'] = esc_html__(
896
+				'Approve and Notify Registrations',
897
+				'event_espresso'
898
+			);
899
+		}
900
+		$def_reg_status_actions['decline_registrations'] = esc_html__('Decline Registrations', 'event_espresso');
901
+		if ($can_send && in_array($match_array['decline_registrations'], $active_mts, true)) {
902
+			$def_reg_status_actions['decline_and_notify_registrations'] = esc_html__(
903
+				'Decline and Notify Registrations',
904
+				'event_espresso'
905
+			);
906
+		}
907
+		$def_reg_status_actions['pending_registrations'] = esc_html__(
908
+			'Set Registrations to Pending Payment',
909
+			'event_espresso'
910
+		);
911
+		if ($can_send && in_array($match_array['pending_registrations'], $active_mts, true)) {
912
+			$def_reg_status_actions['pending_and_notify_registrations'] = esc_html__(
913
+				'Set Registrations to Pending Payment and Notify',
914
+				'event_espresso'
915
+			);
916
+		}
917
+		$def_reg_status_actions['no_approve_registrations'] = esc_html__(
918
+			'Set Registrations to Awaiting Review',
919
+			'event_espresso'
920
+		);
921
+		if ($can_send && in_array($match_array['no_approve_registrations'], $active_mts, true)) {
922
+			$def_reg_status_actions['no_approve_and_notify_registrations'] = esc_html__(
923
+				'Set Registrations to Awaiting Review and Notify',
924
+				'event_espresso'
925
+			);
926
+		}
927
+		$def_reg_status_actions['cancel_registrations'] = esc_html__('Cancel Registrations', 'event_espresso');
928
+		if ($can_send && in_array($match_array['cancel_registrations'], $active_mts, true)) {
929
+			$def_reg_status_actions['cancel_and_notify_registrations'] = esc_html__(
930
+				'Cancel Registrations and Notify',
931
+				'event_espresso'
932
+			);
933
+		}
934
+		$def_reg_status_actions = apply_filters(
935
+			'FHEE__Registrations_Admin_Page___set_list_table_views_default__def_reg_status_actions_array',
936
+			$def_reg_status_actions,
937
+			$active_mts,
938
+			$can_send
939
+		);
940
+
941
+		$current_time = current_time('timestamp');
942
+		$this->_views = [
943
+			'all'       => [
944
+				'slug'        => 'all',
945
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
946
+				'count'       => 0,
947
+				'bulk_action' => array_merge(
948
+					$def_reg_status_actions,
949
+					[
950
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
951
+					]
952
+				),
953
+			],
954
+			'today'     => [
955
+				'slug'        => 'today',
956
+				'label'       => sprintf(
957
+					esc_html__('Today - %s', 'event_espresso'),
958
+					date('M d, Y', $current_time)
959
+				),
960
+				'count'       => 0,
961
+				'bulk_action' => array_merge(
962
+					$def_reg_status_actions,
963
+					[
964
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
965
+					]
966
+				),
967
+			],
968
+			'yesterday' => [
969
+				'slug'        => 'yesterday',
970
+				'label'       => sprintf(
971
+					esc_html__('Yesterday - %s', 'event_espresso'),
972
+					date('M d, Y', $current_time - DAY_IN_SECONDS)
973
+				),
974
+				'count'       => 0,
975
+				'bulk_action' => array_merge(
976
+					$def_reg_status_actions,
977
+					[
978
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
979
+					]
980
+				),
981
+			],
982
+			'month'     => [
983
+				'slug'        => 'month',
984
+				'label'       => esc_html__('This Month', 'event_espresso'),
985
+				'count'       => 0,
986
+				'bulk_action' => array_merge(
987
+					$def_reg_status_actions,
988
+					[
989
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
990
+					]
991
+				),
992
+			],
993
+		];
994
+		if (
995
+			$this->capabilities->current_user_can(
996
+				'ee_delete_registrations',
997
+				'espresso_registrations_delete_registration'
998
+			)
999
+		) {
1000
+			$this->_views['incomplete'] = [
1001
+				'slug'        => 'incomplete',
1002
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
1003
+				'count'       => 0,
1004
+				'bulk_action' => [
1005
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
1006
+				],
1007
+			];
1008
+			$this->_views['trash']      = [
1009
+				'slug'        => 'trash',
1010
+				'label'       => esc_html__('Trash', 'event_espresso'),
1011
+				'count'       => 0,
1012
+				'bulk_action' => [
1013
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
1014
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
1015
+				],
1016
+			];
1017
+		}
1018
+	}
1019
+
1020
+
1021
+	protected function _set_list_table_views_contact_list()
1022
+	{
1023
+		$this->_views = [
1024
+			'in_use' => [
1025
+				'slug'        => 'in_use',
1026
+				'label'       => esc_html__('In Use', 'event_espresso'),
1027
+				'count'       => 0,
1028
+				'bulk_action' => [
1029
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1030
+				],
1031
+			],
1032
+		];
1033
+		if (
1034
+			$this->capabilities->current_user_can(
1035
+				'ee_delete_contacts',
1036
+				'espresso_registrations_trash_attendees'
1037
+			)
1038
+		) {
1039
+			$this->_views['trash'] = [
1040
+				'slug'        => 'trash',
1041
+				'label'       => esc_html__('Trash', 'event_espresso'),
1042
+				'count'       => 0,
1043
+				'bulk_action' => [
1044
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1045
+					'delete_attendees'  => esc_html__('Permanently Delete', 'event_espresso'),
1046
+				],
1047
+			];
1048
+		}
1049
+	}
1050
+
1051
+
1052
+	/**
1053
+	 * @return array
1054
+	 * @throws EE_Error
1055
+	 */
1056
+	protected function _registration_legend_items(): array
1057
+	{
1058
+		$fc_items = [
1059
+			'star-icon'        => [
1060
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1061
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1062
+			],
1063
+			'view_details'     => [
1064
+				'class' => 'dashicons dashicons-clipboard',
1065
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1066
+			],
1067
+			'edit_attendee'    => [
1068
+				'class' => 'dashicons dashicons-admin-users',
1069
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1070
+			],
1071
+			'view_transaction' => [
1072
+				'class' => 'dashicons dashicons-cart',
1073
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1074
+			],
1075
+			'view_invoice'     => [
1076
+				'class' => 'dashicons dashicons-media-spreadsheet',
1077
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1078
+			],
1079
+		];
1080
+		if (
1081
+			$this->capabilities->current_user_can(
1082
+				'ee_send_message',
1083
+				'espresso_registrations_resend_registration'
1084
+			)
1085
+		) {
1086
+			$fc_items['resend_registration'] = [
1087
+				'class' => 'dashicons dashicons-email-alt',
1088
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1089
+			];
1090
+		} else {
1091
+			$fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1092
+		}
1093
+		if (
1094
+			$this->capabilities->current_user_can(
1095
+				'ee_read_global_messages',
1096
+				'view_filtered_messages'
1097
+			)
1098
+		) {
1099
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1100
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1101
+				$fc_items['view_related_messages'] = [
1102
+					'class' => $related_for_icon['css_class'],
1103
+					'desc'  => $related_for_icon['label'],
1104
+				];
1105
+			}
1106
+		}
1107
+		$sc_items = [
1108
+			'approved_status'   => [
1109
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1110
+				'desc'  => EEH_Template::pretty_status(
1111
+					RegStatus::APPROVED,
1112
+					false,
1113
+					'sentence'
1114
+				),
1115
+			],
1116
+			'pending_status'    => [
1117
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1118
+				'desc'  => EEH_Template::pretty_status(
1119
+					RegStatus::PENDING_PAYMENT,
1120
+					false,
1121
+					'sentence'
1122
+				),
1123
+			],
1124
+			'wait_list'         => [
1125
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1126
+				'desc'  => EEH_Template::pretty_status(
1127
+					RegStatus::WAIT_LIST,
1128
+					false,
1129
+					'sentence'
1130
+				),
1131
+			],
1132
+			'incomplete_status' => [
1133
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::INCOMPLETE,
1134
+				'desc'  => EEH_Template::pretty_status(
1135
+					RegStatus::INCOMPLETE,
1136
+					false,
1137
+					'sentence'
1138
+				),
1139
+			],
1140
+			'not_approved'      => [
1141
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1142
+				'desc'  => EEH_Template::pretty_status(
1143
+					RegStatus::AWAITING_REVIEW,
1144
+					false,
1145
+					'sentence'
1146
+				),
1147
+			],
1148
+			'declined_status'   => [
1149
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1150
+				'desc'  => EEH_Template::pretty_status(
1151
+					RegStatus::DECLINED,
1152
+					false,
1153
+					'sentence'
1154
+				),
1155
+			],
1156
+			'cancelled_status'  => [
1157
+				'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1158
+				'desc'  => EEH_Template::pretty_status(
1159
+					RegStatus::CANCELLED,
1160
+					false,
1161
+					'sentence'
1162
+				),
1163
+			],
1164
+		];
1165
+		return array_merge($fc_items, $sc_items);
1166
+	}
1167
+
1168
+
1169
+
1170
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1171
+
1172
+
1173
+	/**
1174
+	 * @throws DomainException
1175
+	 * @throws EE_Error
1176
+	 * @throws InvalidArgumentException
1177
+	 * @throws InvalidDataTypeException
1178
+	 * @throws InvalidInterfaceException
1179
+	 */
1180
+	protected function _registrations_overview_list_table()
1181
+	{
1182
+		$this->appendAddNewRegistrationButtonToPageTitle();
1183
+		$header_text                  = '';
1184
+		$admin_page_header_decorators = [
1185
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1186
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1187
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1188
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1189
+		];
1190
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1191
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1192
+			$header_text             = $filter_header_decorator->getHeaderText($header_text);
1193
+		}
1194
+		$this->_template_args['before_list_table'] = $header_text;
1195
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1196
+		$this->display_admin_list_table_page_with_no_sidebar();
1197
+	}
1198
+
1199
+
1200
+	/**
1201
+	 * @throws EE_Error
1202
+	 * @throws InvalidArgumentException
1203
+	 * @throws InvalidDataTypeException
1204
+	 * @throws InvalidInterfaceException
1205
+	 */
1206
+	private function appendAddNewRegistrationButtonToPageTitle()
1207
+	{
1208
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1209
+		if (
1210
+			$EVT_ID
1211
+			&& $this->capabilities->current_user_can(
1212
+				'ee_edit_registrations',
1213
+				'espresso_registrations_new_registration',
1214
+				$EVT_ID
1215
+			)
1216
+		) {
1217
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1218
+					'new_registration',
1219
+					'add-registrant',
1220
+					['event_id' => $EVT_ID],
1221
+					'add-new-h2'
1222
+				);
1223
+		}
1224
+	}
1225
+
1226
+
1227
+	/**
1228
+	 * This sets the _registration property for the registration details screen
1229
+	 *
1230
+	 * @return void
1231
+	 * @throws EE_Error
1232
+	 * @throws InvalidArgumentException
1233
+	 * @throws InvalidDataTypeException
1234
+	 * @throws InvalidInterfaceException
1235
+	 * @throws ReflectionException
1236
+	 */
1237
+	private function _set_registration_object()
1238
+	{
1239
+		// get out if we've already set the object
1240
+		if ($this->_registration instanceof EE_Registration) {
1241
+			return;
1242
+		}
1243
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1244
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1245
+			return;
1246
+		}
1247
+		$error_msg = sprintf(
1248
+			esc_html__(
1249
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1250
+				'event_espresso'
1251
+			),
1252
+			$REG_ID
1253
+		);
1254
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1255
+		$this->_registration = null;
1256
+	}
1257
+
1258
+
1259
+	/**
1260
+	 * Used to retrieve registrations for the list table.
1261
+	 *
1262
+	 * @param int  $per_page
1263
+	 * @param bool $count
1264
+	 * @param bool $this_month
1265
+	 * @param bool $today
1266
+	 * @param bool $yesterday
1267
+	 * @return EE_Registration[]|int
1268
+	 * @throws EE_Error
1269
+	 * @throws ReflectionException
1270
+	 */
1271
+	public function get_registrations(
1272
+		int $per_page = 10,
1273
+		bool $count = false,
1274
+		bool $this_month = false,
1275
+		bool $today = false,
1276
+		bool $yesterday = false
1277
+	) {
1278
+		if ($this_month) {
1279
+			$this->request->setRequestParam('status', 'month');
1280
+		}
1281
+		if ($today) {
1282
+			$this->request->setRequestParam('status', 'today');
1283
+		}
1284
+		if ($yesterday) {
1285
+			$this->request->setRequestParam('status', 'yesterday');
1286
+		}
1287
+		$query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1288
+		/**
1289
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1290
+		 *
1291
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1292
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1293
+		 *                      or if you have the development copy of EE you can view this at the path:
1294
+		 *                      /docs/G--Model-System/model-query-params.md
1295
+		 */
1296
+		$query_params['group_by'] = '';
1297
+
1298
+		return $count
1299
+			? $this->getRegistrationModel()->count($query_params)
1300
+			/** @type EE_Registration[] */
1301
+			: $this->getRegistrationModel()->get_all($query_params);
1302
+	}
1303
+
1304
+
1305
+	/**
1306
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1307
+	 * Note: this listens to values on the request for some query parameters.
1308
+	 *
1309
+	 * @param array $request
1310
+	 * @param int   $per_page
1311
+	 * @param bool  $count
1312
+	 * @return array
1313
+	 * @throws EE_Error
1314
+	 * @throws InvalidArgumentException
1315
+	 * @throws InvalidDataTypeException
1316
+	 * @throws InvalidInterfaceException
1317
+	 */
1318
+	protected function _get_registration_query_parameters(
1319
+		array $request = [],
1320
+		int $per_page = 10,
1321
+		bool $count = false
1322
+	): array {
1323
+		/** @var QueryBuilder $list_table_query_builder */
1324
+		$list_table_query_builder = $this->loader->getNew(QueryBuilder::class, [null, null, $request]);
1325
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1326
+	}
1327
+
1328
+
1329
+	public function get_registration_status_array(): array
1330
+	{
1331
+		return self::$_reg_status;
1332
+	}
1333
+
1334
+
1335
+
1336
+
1337
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1338
+	/**
1339
+	 * generates HTML for the View Registration Details Admin page
1340
+	 *
1341
+	 * @return void
1342
+	 * @throws DomainException
1343
+	 * @throws EE_Error
1344
+	 * @throws InvalidArgumentException
1345
+	 * @throws InvalidDataTypeException
1346
+	 * @throws InvalidInterfaceException
1347
+	 * @throws EntityNotFoundException
1348
+	 * @throws ReflectionException
1349
+	 */
1350
+	protected function _registration_details()
1351
+	{
1352
+		$this->_template_args = [];
1353
+		$this->_set_registration_object();
1354
+		if (is_object($this->_registration)) {
1355
+			$transaction                                   = $this->_registration->transaction()
1356
+				? $this->_registration->transaction()
1357
+				: EE_Transaction::new_instance();
1358
+			$this->session_data                            = $transaction->session_data();
1359
+			$event_id                                      = $this->_registration->event_ID();
1360
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1361
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1362
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1363
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1364
+			$this->_template_args['grand_total']           = $transaction->total();
1365
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1366
+			// link back to overview
1367
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1368
+			$this->_template_args['registration']                = $this->_registration;
1369
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1370
+				[
1371
+					'action'   => 'default',
1372
+					'event_id' => $event_id,
1373
+				],
1374
+				REG_ADMIN_URL
1375
+			);
1376
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1377
+				[
1378
+					'action' => 'default',
1379
+					'EVT_ID' => $event_id,
1380
+					'page'   => 'espresso_transactions',
1381
+				],
1382
+				admin_url('admin.php')
1383
+			);
1384
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1385
+				[
1386
+					'page'   => 'espresso_events',
1387
+					'action' => 'edit',
1388
+					'post'   => $event_id,
1389
+				],
1390
+				admin_url('admin.php')
1391
+			);
1392
+			// next and previous links
1393
+			$next_reg                                      = $this->_registration->next(
1394
+				null,
1395
+				[],
1396
+				'REG_ID'
1397
+			);
1398
+			$this->_template_args['next_registration']     = $next_reg
1399
+				? $this->_next_link(
1400
+					EE_Admin_Page::add_query_args_and_nonce(
1401
+						[
1402
+							'action'  => 'view_registration',
1403
+							'_REG_ID' => $next_reg['REG_ID'],
1404
+						],
1405
+						REG_ADMIN_URL
1406
+					),
1407
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1408
+				)
1409
+				: '';
1410
+			$previous_reg                                  = $this->_registration->previous(
1411
+				null,
1412
+				[],
1413
+				'REG_ID'
1414
+			);
1415
+			$this->_template_args['previous_registration'] = $previous_reg
1416
+				? $this->_previous_link(
1417
+					EE_Admin_Page::add_query_args_and_nonce(
1418
+						[
1419
+							'action'  => 'view_registration',
1420
+							'_REG_ID' => $previous_reg['REG_ID'],
1421
+						],
1422
+						REG_ADMIN_URL
1423
+					),
1424
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1425
+				)
1426
+				: '';
1427
+			// grab header
1428
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1429
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1430
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1431
+				$template_path,
1432
+				$this->_template_args,
1433
+				true
1434
+			);
1435
+		} else {
1436
+			$this->_template_args['admin_page_header'] = '';
1437
+			$this->_display_espresso_notices();
1438
+		}
1439
+		// the details template wrapper
1440
+		$this->display_admin_page_with_sidebar();
1441
+	}
1442
+
1443
+
1444
+	/**
1445
+	 * @throws EE_Error
1446
+	 * @throws InvalidArgumentException
1447
+	 * @throws InvalidDataTypeException
1448
+	 * @throws InvalidInterfaceException
1449
+	 * @throws ReflectionException
1450
+	 * @since 4.10.2.p
1451
+	 */
1452
+	protected function _registration_details_metaboxes()
1453
+	{
1454
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1455
+		$this->_set_registration_object();
1456
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1457
+		$this->addMetaBox(
1458
+			'edit-reg-status-mbox',
1459
+			esc_html__('Registration Status', 'event_espresso'),
1460
+			[$this, 'set_reg_status_buttons_metabox'],
1461
+			$this->_wp_page_slug
1462
+		);
1463
+		$this->addMetaBox(
1464
+			'edit-reg-details-mbox',
1465
+			'<span>' . esc_html__('Registration Details', 'event_espresso')
1466
+			. '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1467
+			[$this, '_reg_details_meta_box'],
1468
+			$this->_wp_page_slug
1469
+		);
1470
+		if (
1471
+			$attendee instanceof EE_Attendee
1472
+			&& $this->capabilities->current_user_can(
1473
+				'ee_read_registration',
1474
+				'edit-reg-questions-mbox',
1475
+				$this->_registration->ID()
1476
+			)
1477
+		) {
1478
+			$this->addMetaBox(
1479
+				'edit-reg-questions-mbox',
1480
+				esc_html__('Registration Form Answers', 'event_espresso'),
1481
+				[$this, '_reg_questions_meta_box'],
1482
+				$this->_wp_page_slug
1483
+			);
1484
+		}
1485
+		$this->addMetaBox(
1486
+			'edit-reg-registrant-mbox',
1487
+			esc_html__('Contact Details', 'event_espresso'),
1488
+			[$this, '_reg_registrant_side_meta_box'],
1489
+			$this->_wp_page_slug,
1490
+			'side'
1491
+		);
1492
+		if ($this->_registration->group_size() > 1) {
1493
+			$this->addMetaBox(
1494
+				'edit-reg-attendees-mbox',
1495
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1496
+				[$this, '_reg_attendees_meta_box'],
1497
+				$this->_wp_page_slug
1498
+			);
1499
+		}
1500
+	}
1501
+
1502
+
1503
+	/**
1504
+	 * set_reg_status_buttons_metabox
1505
+	 *
1506
+	 * @return void
1507
+	 * @throws EE_Error
1508
+	 * @throws EntityNotFoundException
1509
+	 * @throws InvalidArgumentException
1510
+	 * @throws InvalidDataTypeException
1511
+	 * @throws InvalidInterfaceException
1512
+	 * @throws ReflectionException
1513
+	 * @throws DateMalformedStringException
1514
+	 */
1515
+	public function set_reg_status_buttons_metabox()
1516
+	{
1517
+		$this->_set_registration_object();
1518
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1519
+		$output                 = $change_reg_status_form->form_open(
1520
+			self::add_query_args_and_nonce(
1521
+				[
1522
+					'action' => 'change_reg_status',
1523
+				],
1524
+				REG_ADMIN_URL
1525
+			)
1526
+		);
1527
+		$output                 .= $change_reg_status_form->get_html();
1528
+		$output                 .= $change_reg_status_form->form_close();
1529
+		echo wp_kses($output, AllowedTags::getWithFormTags());
1530
+	}
1531
+
1532
+
1533
+	/**
1534
+	 * @return EE_Form_Section_Proper
1535
+	 * @throws EE_Error
1536
+	 * @throws EntityNotFoundException
1537
+	 * @throws ReflectionException
1538
+	 * @throws DateMalformedStringException
1539
+	 */
1540
+	protected function _generate_reg_status_change_form(): EE_Form_Section_Proper
1541
+	{
1542
+		$subsections = [
1543
+			'return' => new EE_Hidden_Input(
1544
+				[
1545
+					'name'    => 'return',
1546
+					'default' => 'view_registration',
1547
+				]
1548
+			),
1549
+			'REG_ID' => new EE_Hidden_Input(
1550
+				[
1551
+					'name'    => 'REG_ID',
1552
+					'default' => $this->_registration->ID(),
1553
+				]
1554
+			),
1555
+		];
1556
+
1557
+		$status_changes = $this->_registration->get_extra_meta(EE_Registration::META_KEY_REG_STATUS_CHANGE);
1558
+
1559
+		if (! empty($status_changes)) {
1560
+			$date_format = get_option('date_format', 'Y-m-d') . ' ' . get_option('time_format', 'H:i:s');
1561
+			$html = EEH_HTML::tr();
1562
+			$html .= EEH_HTML::th(
1563
+				EEH_HTML::label(esc_html__('Registration Status Changes', 'event_espresso'))
1564
+			);
1565
+			$html .= EEH_HTML::td();
1566
+			$html .= EEH_HTML::ul();
1567
+			foreach ($status_changes as $status_change) {
1568
+				$date = new DateTime('@' . $status_change['date']);
1569
+				$reason = $status_change['reason'] ?: esc_html__('not specified', 'event_espresso');
1570
+				$html .= EEH_HTML::li(
1571
+					EEH_HTML::strong($date->format($date_format))
1572
+					. EEH_HTML::br()
1573
+					. EEH_HTML::span(
1574
+						$status_change['change'],
1575
+						'',
1576
+						'',
1577
+						'margin-inline-start: 1em;'
1578
+					)
1579
+					. EEH_HTML::br()
1580
+					. EEH_HTML::span(
1581
+						sprintf(
1582
+							esc_html__('Reason: %1$s', 'event_espresso'),
1583
+							$reason,
1584
+						),
1585
+						'',
1586
+						'',
1587
+						'margin-inline-start: 1em;'
1588
+					)
1589
+				);
1590
+			}
1591
+			$html .= EEH_HTML::ulx();
1592
+			$html .= EEH_HTML::tdx();
1593
+			$html .= EEH_HTML::trx();
1594
+			$subsections['reg_cancellations'] = new EE_Form_Section_HTML($html, ['add_wrapper' => false]);
1595
+		}
1596
+
1597
+
1598
+		if (
1599
+			$this->capabilities->current_user_can(
1600
+				'ee_edit_registration',
1601
+				'toggle_registration_status',
1602
+				$this->_registration->ID()
1603
+			)
1604
+		) {
1605
+			$subsections['reg_status']         = new EE_Select_Input(
1606
+				$this->_get_reg_statuses(),
1607
+				[
1608
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1609
+					'default'         => $this->_registration->status_ID(),
1610
+					'html_class'      => 'ee-input-width--small',
1611
+				]
1612
+			);
1613
+			$subsections['reason']         = new EE_Text_Input(
1614
+				[
1615
+					'html_label_text' => esc_html__('Reason for Registration Status Change', 'event_espresso')
1616
+				]
1617
+			);
1618
+			$subsections['send_notifications'] = new EE_Yes_No_Input(
1619
+				[
1620
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1621
+					'default'         => false,
1622
+					'html_help_text'  => esc_html__(
1623
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1624
+						'event_espresso'
1625
+					),
1626
+				]
1627
+			);
1628
+			$subsections['submit']             = new EE_Submit_Input(
1629
+				[
1630
+					'html_class'      => 'button--primary',
1631
+					'html_label_text' => '&nbsp;',
1632
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1633
+				]
1634
+			);
1635
+		}
1636
+		return new EE_Form_Section_Proper(
1637
+			[
1638
+			  'name'            => 'reg_status_change_form',
1639
+			  'html_id'         => 'reg-status-change-form',
1640
+			  'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1641
+			  'subsections'     => $subsections
1642
+			]
1643
+		);
1644
+	}
1645
+
1646
+
1647
+	/**
1648
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1649
+	 *
1650
+	 * @return array
1651
+	 * @throws EE_Error
1652
+	 * @throws InvalidArgumentException
1653
+	 * @throws InvalidDataTypeException
1654
+	 * @throws InvalidInterfaceException
1655
+	 * @throws EntityNotFoundException
1656
+	 * @throws ReflectionException
1657
+	 */
1658
+	protected function _get_reg_statuses(): array
1659
+	{
1660
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1661
+		unset($reg_status_array[ RegStatus::INCOMPLETE ]);
1662
+		// get current reg status
1663
+		$current_status = $this->_registration->status_ID();
1664
+		// is registration for free event? This will determine whether to display the pending payment option
1665
+		if (
1666
+			$current_status !== RegStatus::PENDING_PAYMENT
1667
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1668
+		) {
1669
+			unset($reg_status_array[ RegStatus::PENDING_PAYMENT ]);
1670
+		}
1671
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1672
+	}
1673
+
1674
+
1675
+	/**
1676
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1677
+	 *
1678
+	 * @param string $status REG status given for changing registrations to.
1679
+	 * @param bool $notify Whether to send messages notifications or not.
1680
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1681
+	 * @throws DomainException
1682
+	 * @throws EE_Error
1683
+	 * @throws EntityNotFoundException
1684
+	 * @throws InvalidArgumentException
1685
+	 * @throws InvalidDataTypeException
1686
+	 * @throws InvalidInterfaceException
1687
+	 * @throws ReflectionException
1688
+	 * @throws RuntimeException
1689
+	 */
1690
+	protected function _set_registration_status_from_request(string $status = '', bool $notify = false): array
1691
+	{
1692
+		$REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1693
+			? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1694
+			: $this->request->getRequestParam('_REG_ID', [], 'int', true);
1695
+
1696
+		// sanitize $REG_IDs
1697
+		$REG_IDs = array_map('absint', $REG_IDs);
1698
+		// and remove empty entries
1699
+		$REG_IDs = array_filter($REG_IDs);
1700
+
1701
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1702
+
1703
+		/**
1704
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1705
+		 * Currently this value is used downstream by the _process_resend_registration method.
1706
+		 *
1707
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1708
+		 * @param bool                     $status           The status registrations were changed to.
1709
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1710
+		 * @param Registrations_Admin_Page $admin_page
1711
+		 */
1712
+		$REG_ID = apply_filters(
1713
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1714
+			$result['REG_ID'],
1715
+			$status,
1716
+			$result['success'],
1717
+			$this
1718
+		);
1719
+		$this->request->setRequestParam('_REG_ID', $REG_ID);
1720
+
1721
+		// notify?
1722
+		if (
1723
+			$notify
1724
+			&& $result['success']
1725
+			&& ! empty($REG_ID)
1726
+			&& $this->capabilities->current_user_can(
1727
+				'ee_send_message',
1728
+				'espresso_registrations_resend_registration'
1729
+			)
1730
+		) {
1731
+			$this->_process_resend_registration();
1732
+		}
1733
+		return $result;
1734
+	}
1735
+
1736
+
1737
+	/**
1738
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1739
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1740
+	 *
1741
+	 * @param array  $REG_IDs
1742
+	 * @param string $status
1743
+	 * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1744
+	 *                       slug sent with setting the registration status.
1745
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1746
+	 * @throws EE_Error
1747
+	 * @throws InvalidArgumentException
1748
+	 * @throws InvalidDataTypeException
1749
+	 * @throws InvalidInterfaceException
1750
+	 * @throws ReflectionException
1751
+	 * @throws RuntimeException
1752
+	 * @throws EntityNotFoundException
1753
+	 * @throws DomainException
1754
+	 */
1755
+	protected function _set_registration_status(array $REG_IDs = [], string $status = '', bool $notify = false): array
1756
+	{
1757
+		global $current_user;
1758
+		$admin_name = $current_user->display_name;
1759
+		$reason = $this->request->getRequestParam('reg_status_change_form[reason]');
1760
+		if (empty($REG_IDs)) {
1761
+			return ['REG_ID' => $REG_IDs, 'success' => false];
1762
+		}
1763
+		$success = true;
1764
+		// set default status if none is passed
1765
+		$status         = $status ?: RegStatus::PENDING_PAYMENT;
1766
+		$status_context = $notify
1767
+			? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1768
+			: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1769
+		// loop through REG_ID's and change status
1770
+		foreach ($REG_IDs as $REG_ID) {
1771
+			$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1772
+			if ($registration instanceof EE_Registration) {
1773
+				$updated = $registration->set_status(
1774
+					$status,
1775
+					false,
1776
+					new Context(
1777
+						$status_context,
1778
+						esc_html__(
1779
+							'Manually triggered status change on a Registration Admin Page route.',
1780
+							'event_espresso'
1781
+						)
1782
+					)
1783
+				);
1784
+				$registration->add_extra_meta(
1785
+					EE_Registration::META_KEY_REG_STATUS_CHANGE,
1786
+					[
1787
+						'date'   => time(),
1788
+						'change' => sprintf(
1789
+							esc_html__('changed to "%1$s" by %2$s', 'event_espresso'),
1790
+							EEH_Template::pretty_status($status, false, 'sentence'),
1791
+							$admin_name
1792
+						),
1793
+						'reason' => $reason,
1794
+					]
1795
+				);
1796
+				$registration->save();
1797
+				// verifying explicit fails because update *may* just return 0 for 0 rows affected
1798
+				$success = $updated && $success;
1799
+			}
1800
+		}
1801
+
1802
+		// return $success and processed registrations
1803
+		return ['REG_ID' => $REG_IDs, 'success' => $success];
1804
+	}
1805
+
1806
+
1807
+	/**
1808
+	 * Common logic for setting up success message and redirecting to appropriate route
1809
+	 *
1810
+	 * @param string $STS_ID status id for the registration changed to
1811
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1812
+	 * @return void
1813
+	 * @throws DomainException
1814
+	 * @throws EE_Error
1815
+	 * @throws EntityNotFoundException
1816
+	 * @throws InvalidArgumentException
1817
+	 * @throws InvalidDataTypeException
1818
+	 * @throws InvalidInterfaceException
1819
+	 * @throws ReflectionException
1820
+	 * @throws RuntimeException
1821
+	 */
1822
+	protected function _reg_status_change_return(string $STS_ID, bool $notify = false)
1823
+	{
1824
+		$result  = ! empty($STS_ID)
1825
+			? $this->_set_registration_status_from_request($STS_ID, $notify)
1826
+			: ['success' => false];
1827
+		$success = isset($result['success']) && $result['success'];
1828
+		// setup success message
1829
+		if ($success) {
1830
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1831
+				$msg = sprintf(
1832
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1833
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1834
+				);
1835
+			} else {
1836
+				$msg = sprintf(
1837
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1838
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1839
+				);
1840
+			}
1841
+			EE_Error::add_success($msg);
1842
+		} else {
1843
+			EE_Error::add_error(
1844
+				esc_html__(
1845
+					'Something went wrong, and the status was not changed',
1846
+					'event_espresso'
1847
+				),
1848
+				__FILE__,
1849
+				__LINE__,
1850
+				__FUNCTION__
1851
+			);
1852
+		}
1853
+		$return = $this->request->getRequestParam('return');
1854
+		$route  = $return === 'view_registration'
1855
+			? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1856
+			: ['action' => 'default'];
1857
+		$route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1858
+		$this->_redirect_after_action($success, '', '', $route, true);
1859
+	}
1860
+
1861
+
1862
+	/**
1863
+	 * incoming reg status change from reg details page.
1864
+	 *
1865
+	 * @return void
1866
+	 * @throws EE_Error
1867
+	 * @throws EntityNotFoundException
1868
+	 * @throws InvalidArgumentException
1869
+	 * @throws InvalidDataTypeException
1870
+	 * @throws InvalidInterfaceException
1871
+	 * @throws ReflectionException
1872
+	 * @throws RuntimeException
1873
+	 * @throws DomainException
1874
+	 */
1875
+	protected function _change_reg_status()
1876
+	{
1877
+		$this->request->setRequestParam('return', 'view_registration');
1878
+		// set notify based on whether the send notifications toggle is set or not
1879
+		$notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1880
+		$reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1881
+
1882
+		switch ($reg_status) {
1883
+			case RegStatus::APPROVED:
1884
+			case EEH_Template::pretty_status(RegStatus::APPROVED, false, 'sentence'):
1885
+				$this->approve_registration($notify);
1886
+				break;
1887
+			case RegStatus::PENDING_PAYMENT:
1888
+			case EEH_Template::pretty_status(RegStatus::PENDING_PAYMENT, false, 'sentence'):
1889
+				$this->pending_registration($notify);
1890
+				break;
1891
+			case RegStatus::AWAITING_REVIEW:
1892
+			case EEH_Template::pretty_status(RegStatus::AWAITING_REVIEW, false, 'sentence'):
1893
+				$this->not_approve_registration($notify);
1894
+				break;
1895
+			case RegStatus::DECLINED:
1896
+			case EEH_Template::pretty_status(RegStatus::DECLINED, false, 'sentence'):
1897
+				$this->decline_registration($notify);
1898
+				break;
1899
+			case RegStatus::CANCELLED:
1900
+			case EEH_Template::pretty_status(RegStatus::CANCELLED, false, 'sentence'):
1901
+				$this->cancel_registration($notify);
1902
+				break;
1903
+			case RegStatus::WAIT_LIST:
1904
+			case EEH_Template::pretty_status(RegStatus::WAIT_LIST, false, 'sentence'):
1905
+				$this->wait_list_registration($notify);
1906
+				break;
1907
+			case RegStatus::INCOMPLETE:
1908
+			default:
1909
+				$this->request->unSetRequestParam('return');
1910
+				$this->_reg_status_change_return('');
1911
+				break;
1912
+		}
1913
+	}
1914
+
1915
+
1916
+	/**
1917
+	 * Callback for bulk action routes.
1918
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1919
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1920
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1921
+	 * when an action is happening on just a single registration).
1922
+	 *
1923
+	 * @param string $action
1924
+	 * @param bool   $notify
1925
+	 */
1926
+	protected function bulk_action_on_registrations(string $action, bool $notify = false)
1927
+	{
1928
+		do_action(
1929
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1930
+			$this,
1931
+			$action,
1932
+			$notify
1933
+		);
1934
+		$method = $action . '_registration';
1935
+		if (method_exists($this, $method)) {
1936
+			$this->$method($notify);
1937
+		}
1938
+	}
1939
+
1940
+
1941
+	/**
1942
+	 * approve_registration
1943
+	 *
1944
+	 * @param bool $notify whether to notify the registrant about their approval.
1945
+	 * @return void
1946
+	 * @throws EE_Error
1947
+	 * @throws EntityNotFoundException
1948
+	 * @throws InvalidArgumentException
1949
+	 * @throws InvalidDataTypeException
1950
+	 * @throws InvalidInterfaceException
1951
+	 * @throws ReflectionException
1952
+	 * @throws RuntimeException
1953
+	 * @throws DomainException
1954
+	 */
1955
+	protected function approve_registration(bool $notify = false)
1956
+	{
1957
+		$this->_reg_status_change_return(RegStatus::APPROVED, $notify);
1958
+	}
1959
+
1960
+
1961
+	/**
1962
+	 * decline_registration
1963
+	 *
1964
+	 * @param bool $notify whether to notify the registrant about their status change.
1965
+	 * @return void
1966
+	 * @throws EE_Error
1967
+	 * @throws EntityNotFoundException
1968
+	 * @throws InvalidArgumentException
1969
+	 * @throws InvalidDataTypeException
1970
+	 * @throws InvalidInterfaceException
1971
+	 * @throws ReflectionException
1972
+	 * @throws RuntimeException
1973
+	 * @throws DomainException
1974
+	 */
1975
+	protected function decline_registration(bool $notify = false)
1976
+	{
1977
+		$this->_reg_status_change_return(RegStatus::DECLINED, $notify);
1978
+	}
1979
+
1980
+
1981
+	/**
1982
+	 * cancel_registration
1983
+	 *
1984
+	 * @param bool $notify whether to notify the registrant about their status change.
1985
+	 * @return void
1986
+	 * @throws EE_Error
1987
+	 * @throws EntityNotFoundException
1988
+	 * @throws InvalidArgumentException
1989
+	 * @throws InvalidDataTypeException
1990
+	 * @throws InvalidInterfaceException
1991
+	 * @throws ReflectionException
1992
+	 * @throws RuntimeException
1993
+	 * @throws DomainException
1994
+	 */
1995
+	protected function cancel_registration(bool $notify = false)
1996
+	{
1997
+		$this->_reg_status_change_return(RegStatus::CANCELLED, $notify);
1998
+	}
1999
+
2000
+
2001
+	/**
2002
+	 * not_approve_registration
2003
+	 *
2004
+	 * @param bool $notify whether to notify the registrant about their status change.
2005
+	 * @return void
2006
+	 * @throws EE_Error
2007
+	 * @throws EntityNotFoundException
2008
+	 * @throws InvalidArgumentException
2009
+	 * @throws InvalidDataTypeException
2010
+	 * @throws InvalidInterfaceException
2011
+	 * @throws ReflectionException
2012
+	 * @throws RuntimeException
2013
+	 * @throws DomainException
2014
+	 */
2015
+	protected function not_approve_registration(bool $notify = false)
2016
+	{
2017
+		$this->_reg_status_change_return(RegStatus::AWAITING_REVIEW, $notify);
2018
+	}
2019
+
2020
+
2021
+	/**
2022
+	 * decline_registration
2023
+	 *
2024
+	 * @param bool $notify whether to notify the registrant about their status change.
2025
+	 * @return void
2026
+	 * @throws EE_Error
2027
+	 * @throws EntityNotFoundException
2028
+	 * @throws InvalidArgumentException
2029
+	 * @throws InvalidDataTypeException
2030
+	 * @throws InvalidInterfaceException
2031
+	 * @throws ReflectionException
2032
+	 * @throws RuntimeException
2033
+	 * @throws DomainException
2034
+	 */
2035
+	protected function pending_registration(bool $notify = false)
2036
+	{
2037
+		$this->_reg_status_change_return(RegStatus::PENDING_PAYMENT, $notify);
2038
+	}
2039
+
2040
+
2041
+	/**
2042
+	 * waitlist_registration
2043
+	 *
2044
+	 * @param bool $notify whether to notify the registrant about their status change.
2045
+	 * @return void
2046
+	 * @throws EE_Error
2047
+	 * @throws EntityNotFoundException
2048
+	 * @throws InvalidArgumentException
2049
+	 * @throws InvalidDataTypeException
2050
+	 * @throws InvalidInterfaceException
2051
+	 * @throws ReflectionException
2052
+	 * @throws RuntimeException
2053
+	 * @throws DomainException
2054
+	 */
2055
+	protected function wait_list_registration(bool $notify = false)
2056
+	{
2057
+		$this->_reg_status_change_return(RegStatus::WAIT_LIST, $notify);
2058
+	}
2059
+
2060
+
2061
+	/**
2062
+	 * generates HTML for the Registration main meta box
2063
+	 *
2064
+	 * @return void
2065
+	 * @throws DomainException
2066
+	 * @throws EE_Error
2067
+	 * @throws InvalidArgumentException
2068
+	 * @throws InvalidDataTypeException
2069
+	 * @throws InvalidInterfaceException
2070
+	 * @throws ReflectionException
2071
+	 * @throws EntityNotFoundException
2072
+	 */
2073
+	public function _reg_details_meta_box()
2074
+	{
2075
+		EEH_Autoloader::register_line_item_display_autoloaders();
2076
+		EEH_Autoloader::register_line_item_filter_autoloaders();
2077
+
2078
+		$transaction        = $this->_registration->transaction()
2079
+			? $this->_registration->transaction()
2080
+			: EE_Transaction::new_instance();
2081
+		$this->session_data = $transaction->session_data();
2082
+		$filters            = new EE_Line_Item_Filter_Collection();
2083
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2084
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2085
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2086
+			$filters,
2087
+			$transaction->total_line_item()
2088
+		);
2089
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2090
+		$line_item_display                       = new EE_Line_Item_Display(
2091
+			'reg_admin_table',
2092
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2093
+		);
2094
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2095
+			$filtered_line_item_tree,
2096
+			['EE_Registration' => $this->_registration]
2097
+		);
2098
+		$attendee                                = $this->_registration->attendee();
2099
+		if (
2100
+			$this->capabilities->current_user_can(
2101
+				'ee_read_transaction',
2102
+				'espresso_transactions_view_transaction'
2103
+			)
2104
+		) {
2105
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2106
+				EE_Admin_Page::add_query_args_and_nonce(
2107
+					[
2108
+						'action' => 'view_transaction',
2109
+						'TXN_ID' => $transaction->ID(),
2110
+					],
2111
+					TXN_ADMIN_URL
2112
+				),
2113
+				esc_html__(' View Transaction', 'event_espresso'),
2114
+				'button button--secondary right',
2115
+				'dashicons dashicons-cart'
2116
+			);
2117
+		} else {
2118
+			$this->_template_args['view_transaction_button'] = '';
2119
+		}
2120
+		if (
2121
+			$attendee instanceof EE_Attendee
2122
+			&& $this->capabilities->current_user_can(
2123
+				'ee_send_message',
2124
+				'espresso_registrations_resend_registration'
2125
+			)
2126
+		) {
2127
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2128
+				EE_Admin_Page::add_query_args_and_nonce(
2129
+					[
2130
+						'action'      => 'resend_registration',
2131
+						'_REG_ID'     => $this->_registration->ID(),
2132
+						'redirect_to' => 'view_registration',
2133
+					],
2134
+					REG_ADMIN_URL
2135
+				),
2136
+				esc_html__(' Resend Registration', 'event_espresso'),
2137
+				'button button--secondary right',
2138
+				'dashicons dashicons-email-alt'
2139
+			);
2140
+		} else {
2141
+			$this->_template_args['resend_registration_button'] = '';
2142
+		}
2143
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2144
+		$payment                               = $transaction->get_first_related('Payment');
2145
+		$payment                               = ! $payment instanceof EE_Payment
2146
+			? EE_Payment::new_instance()
2147
+			: $payment;
2148
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2149
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2150
+			? EE_Payment_Method::new_instance()
2151
+			: $payment_method;
2152
+		$reg_details                           = [
2153
+			'payment_method'       => $payment_method->name(),
2154
+			'response_msg'         => $payment->gateway_response(),
2155
+			'registration_id'      => $this->_registration->get('REG_code'),
2156
+			'registration_session' => $this->_registration->session_ID(),
2157
+			'ip_address'           => $this->session_data['ip_address'] ?? '',
2158
+			'user_agent'           => $this->session_data['user_agent'] ?? '',
2159
+		];
2160
+		if (isset($reg_details['registration_id'])) {
2161
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2162
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2163
+				'Registration ID',
2164
+				'event_espresso'
2165
+			);
2166
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2167
+		}
2168
+		if (isset($reg_details['payment_method'])) {
2169
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2170
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2171
+				'Most Recent Payment Method',
2172
+				'event_espresso'
2173
+			);
2174
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2175
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2176
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2177
+				'Payment method response',
2178
+				'event_espresso'
2179
+			);
2180
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2181
+		}
2182
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2183
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2184
+			'Registration Session',
2185
+			'event_espresso'
2186
+		);
2187
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2188
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2189
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2190
+			'Registration placed from IP',
2191
+			'event_espresso'
2192
+		);
2193
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2194
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2195
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2196
+			'Registrant User Agent',
2197
+			'event_espresso'
2198
+		);
2199
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2200
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2201
+			[
2202
+				'action'   => 'default',
2203
+				'event_id' => $this->_registration->event_ID(),
2204
+			],
2205
+			REG_ADMIN_URL
2206
+		);
2207
+
2208
+		$this->_template_args['REG_ID']   = $this->_registration->ID();
2209
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2210
+
2211
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2212
+		EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2213
+	}
2214
+
2215
+
2216
+	/**
2217
+	 * generates HTML for the Registration Questions meta box.
2218
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2219
+	 * otherwise uses new forms system
2220
+	 *
2221
+	 * @return void
2222
+	 * @throws DomainException
2223
+	 * @throws EE_Error
2224
+	 * @throws InvalidArgumentException
2225
+	 * @throws InvalidDataTypeException
2226
+	 * @throws InvalidInterfaceException
2227
+	 * @throws ReflectionException
2228
+	 */
2229
+	public function _reg_questions_meta_box()
2230
+	{
2231
+		// allow someone to override this method entirely
2232
+		if (
2233
+			apply_filters(
2234
+				'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2235
+				true,
2236
+				$this,
2237
+				$this->_registration
2238
+			)
2239
+		) {
2240
+			$form = $this->_get_reg_custom_questions_form(
2241
+				$this->_registration->ID()
2242
+			);
2243
+
2244
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2245
+				? $form->get_html_and_js()
2246
+				: '';
2247
+
2248
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2249
+			$this->_template_args['REG_ID']                    = $this->_registration->ID();
2250
+			$template_path                                     =
2251
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2252
+			EEH_Template::display_template($template_path, $this->_template_args);
2253
+		}
2254
+	}
2255
+
2256
+
2257
+	/**
2258
+	 * form_before_question_group
2259
+	 *
2260
+	 * @param string $output
2261
+	 * @return        string
2262
+	 * @deprecated    as of 4.8.32.rc.000
2263
+	 */
2264
+	public function form_before_question_group(string $output): string
2265
+	{
2266
+		EE_Error::doing_it_wrong(
2267
+			__CLASS__ . '::' . __FUNCTION__,
2268
+			esc_html__(
2269
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2270
+				'event_espresso'
2271
+			),
2272
+			'4.8.32.rc.000'
2273
+		);
2274
+		return '
2275 2275
 	<table class="form-table ee-width-100">
2276 2276
 		<tbody>
2277 2277
 			';
2278
-    }
2279
-
2280
-
2281
-    /**
2282
-     * form_after_question_group
2283
-     *
2284
-     * @param string $output
2285
-     * @return        string
2286
-     * @deprecated    as of 4.8.32.rc.000
2287
-     */
2288
-    public function form_after_question_group(string $output): string
2289
-    {
2290
-        EE_Error::doing_it_wrong(
2291
-            __CLASS__ . '::' . __FUNCTION__,
2292
-            esc_html__(
2293
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2294
-                'event_espresso'
2295
-            ),
2296
-            '4.8.32.rc.000'
2297
-        );
2298
-        return '
2278
+	}
2279
+
2280
+
2281
+	/**
2282
+	 * form_after_question_group
2283
+	 *
2284
+	 * @param string $output
2285
+	 * @return        string
2286
+	 * @deprecated    as of 4.8.32.rc.000
2287
+	 */
2288
+	public function form_after_question_group(string $output): string
2289
+	{
2290
+		EE_Error::doing_it_wrong(
2291
+			__CLASS__ . '::' . __FUNCTION__,
2292
+			esc_html__(
2293
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2294
+				'event_espresso'
2295
+			),
2296
+			'4.8.32.rc.000'
2297
+		);
2298
+		return '
2299 2299
 			<tr class="hide-if-no-js">
2300 2300
 				<th> </th>
2301 2301
 				<td class="reg-admin-edit-attendee-question-td">
2302 2302
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="'
2303
-            . esc_attr__('click to edit question', 'event_espresso')
2304
-            . '">
2303
+			. esc_attr__('click to edit question', 'event_espresso')
2304
+			. '">
2305 2305
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2306
-            . esc_html__('edit the above question group', 'event_espresso')
2307
-            . '</span>
2306
+			. esc_html__('edit the above question group', 'event_espresso')
2307
+			. '</span>
2308 2308
 						<div class="dashicons dashicons-edit"></div>
2309 2309
 					</a>
2310 2310
 				</td>
@@ -2312,631 +2312,631 @@  discard block
 block discarded – undo
2312 2312
 		</tbody>
2313 2313
 	</table>
2314 2314
 ';
2315
-    }
2316
-
2317
-
2318
-    /**
2319
-     * form_form_field_label_wrap
2320
-     *
2321
-     * @param string $label
2322
-     * @return        string
2323
-     * @deprecated    as of 4.8.32.rc.000
2324
-     */
2325
-    public function form_form_field_label_wrap(string $label): string
2326
-    {
2327
-        EE_Error::doing_it_wrong(
2328
-            __CLASS__ . '::' . __FUNCTION__,
2329
-            esc_html__(
2330
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2331
-                'event_espresso'
2332
-            ),
2333
-            '4.8.32.rc.000'
2334
-        );
2335
-        return '
2315
+	}
2316
+
2317
+
2318
+	/**
2319
+	 * form_form_field_label_wrap
2320
+	 *
2321
+	 * @param string $label
2322
+	 * @return        string
2323
+	 * @deprecated    as of 4.8.32.rc.000
2324
+	 */
2325
+	public function form_form_field_label_wrap(string $label): string
2326
+	{
2327
+		EE_Error::doing_it_wrong(
2328
+			__CLASS__ . '::' . __FUNCTION__,
2329
+			esc_html__(
2330
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2331
+				'event_espresso'
2332
+			),
2333
+			'4.8.32.rc.000'
2334
+		);
2335
+		return '
2336 2336
 			<tr>
2337 2337
 				<th>
2338 2338
 					' . $label . '
2339 2339
 				</th>';
2340
-    }
2341
-
2342
-
2343
-    /**
2344
-     * form_form_field_input__wrap
2345
-     *
2346
-     * @param string $input
2347
-     * @return        string
2348
-     * @deprecated    as of 4.8.32.rc.000
2349
-     */
2350
-    public function form_form_field_input__wrap(string $input): string
2351
-    {
2352
-        EE_Error::doing_it_wrong(
2353
-            __CLASS__ . '::' . __FUNCTION__,
2354
-            esc_html__(
2355
-                'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2356
-                'event_espresso'
2357
-            ),
2358
-            '4.8.32.rc.000'
2359
-        );
2360
-        return '
2340
+	}
2341
+
2342
+
2343
+	/**
2344
+	 * form_form_field_input__wrap
2345
+	 *
2346
+	 * @param string $input
2347
+	 * @return        string
2348
+	 * @deprecated    as of 4.8.32.rc.000
2349
+	 */
2350
+	public function form_form_field_input__wrap(string $input): string
2351
+	{
2352
+		EE_Error::doing_it_wrong(
2353
+			__CLASS__ . '::' . __FUNCTION__,
2354
+			esc_html__(
2355
+				'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2356
+				'event_espresso'
2357
+			),
2358
+			'4.8.32.rc.000'
2359
+		);
2360
+		return '
2361 2361
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2362 2362
 					' . $input . '
2363 2363
 				</td>
2364 2364
 			</tr>';
2365
-    }
2366
-
2367
-
2368
-    /**
2369
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2370
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2371
-     * to display the page
2372
-     *
2373
-     * @return void
2374
-     * @throws EE_Error
2375
-     * @throws InvalidArgumentException
2376
-     * @throws InvalidDataTypeException
2377
-     * @throws InvalidInterfaceException
2378
-     * @throws ReflectionException
2379
-     */
2380
-    protected function _update_attendee_registration_form()
2381
-    {
2382
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2383
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2384
-            $REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2385
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2386
-            if ($success) {
2387
-                $what  = esc_html__('Registration Form', 'event_espresso');
2388
-                $route = $REG_ID
2389
-                    ? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2390
-                    : ['action' => 'default'];
2391
-                $this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2392
-            }
2393
-        }
2394
-    }
2395
-
2396
-
2397
-    /**
2398
-     * Gets the form for saving registrations custom questions (if done
2399
-     * previously retrieves the cached form object, which may have validation errors in it)
2400
-     *
2401
-     * @param int $REG_ID
2402
-     * @return EE_Registration_Custom_Questions_Form
2403
-     * @throws EE_Error
2404
-     * @throws InvalidArgumentException
2405
-     * @throws InvalidDataTypeException
2406
-     * @throws InvalidInterfaceException
2407
-     * @throws ReflectionException
2408
-     */
2409
-    protected function _get_reg_custom_questions_form(int $REG_ID): EE_Registration_Custom_Questions_Form
2410
-    {
2411
-        if (! $this->_reg_custom_questions_form) {
2412
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2413
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2414
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2415
-            );
2416
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2417
-        }
2418
-        return $this->_reg_custom_questions_form;
2419
-    }
2420
-
2421
-
2422
-    /**
2423
-     * Saves
2424
-     *
2425
-     * @param bool $REG_ID
2426
-     * @return bool
2427
-     * @throws EE_Error
2428
-     * @throws InvalidArgumentException
2429
-     * @throws InvalidDataTypeException
2430
-     * @throws InvalidInterfaceException
2431
-     * @throws ReflectionException
2432
-     */
2433
-    private function _save_reg_custom_questions_form($REG_ID = 0): bool
2434
-    {
2435
-        if (! $REG_ID) {
2436
-            EE_Error::add_error(
2437
-                esc_html__(
2438
-                    'An error occurred. No registration ID was received.',
2439
-                    'event_espresso'
2440
-                ),
2441
-                __FILE__,
2442
-                __FUNCTION__,
2443
-                __LINE__
2444
-            );
2445
-        }
2446
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2447
-        $form->receive_form_submission($this->request->requestParams());
2448
-        $success = false;
2449
-        if ($form->is_valid()) {
2450
-            foreach ($form->subforms() as $question_group_form) {
2451
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2452
-                    $where_conditions    = [
2453
-                        'QST_ID' => $question_id,
2454
-                        'REG_ID' => $REG_ID,
2455
-                    ];
2456
-                    $possibly_new_values = [
2457
-                        'ANS_value' => $input->normalized_value(),
2458
-                    ];
2459
-                    $answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2460
-                    if ($answer instanceof EE_Answer) {
2461
-                        $success = $answer->save($possibly_new_values);
2462
-                    } else {
2463
-                        // insert it then
2464
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2465
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2466
-                        $success     = $answer->save();
2467
-                    }
2468
-                }
2469
-            }
2470
-        } else {
2471
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2472
-        }
2473
-        return $success;
2474
-    }
2475
-
2476
-
2477
-    /**
2478
-     * generates HTML for the Registration main meta box
2479
-     *
2480
-     * @return void
2481
-     * @throws DomainException
2482
-     * @throws EE_Error
2483
-     * @throws InvalidArgumentException
2484
-     * @throws InvalidDataTypeException
2485
-     * @throws InvalidInterfaceException
2486
-     * @throws ReflectionException
2487
-     */
2488
-    public function _reg_attendees_meta_box()
2489
-    {
2490
-        $REG = $this->getRegistrationModel();
2491
-        // get all other registrations on this transaction, and cache
2492
-        // the attendees for them so we don't have to run another query using force_join
2493
-        $registrations                           = $REG->get_all(
2494
-            [
2495
-                [
2496
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2497
-                    'REG_ID' => ['!=', $this->_registration->ID()],
2498
-                ],
2499
-                'force_join'               => ['Attendee'],
2500
-                'default_where_conditions' => 'other_models_only',
2501
-            ]
2502
-        );
2503
-        $this->_template_args['attendees']       = [];
2504
-        $this->_template_args['attendee_notice'] = '';
2505
-        if (
2506
-            empty($registrations)
2507
-            || (is_array($registrations)
2508
-                && ! EEH_Array::get_one_item_from_array($registrations))
2509
-        ) {
2510
-            EE_Error::add_error(
2511
-                esc_html__(
2512
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2513
-                    'event_espresso'
2514
-                ),
2515
-                __FILE__,
2516
-                __FUNCTION__,
2517
-                __LINE__
2518
-            );
2519
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2520
-        } else {
2521
-            $att_nmbr = 1;
2522
-            foreach ($registrations as $registration) {
2523
-                /* @var $registration EE_Registration */
2524
-                $attendee                                                      = $registration->attendee()
2525
-                    ? $registration->attendee()
2526
-                    : $this->getAttendeeModel()->create_default_object();
2527
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2528
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2529
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2530
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2531
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2532
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2533
-                    ', ',
2534
-                    $attendee->full_address_as_array()
2535
-                );
2536
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2537
-                    [
2538
-                        'action' => 'edit_attendee',
2539
-                        'post'   => $attendee->ID(),
2540
-                    ],
2541
-                    REG_ADMIN_URL
2542
-                );
2543
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2544
-                    $registration->event_obj() instanceof EE_Event
2545
-                        ? $registration->event_obj()->name()
2546
-                        : '';
2547
-                $att_nmbr++;
2548
-            }
2549
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2550
-        }
2551
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2552
-        EEH_Template::display_template($template_path, $this->_template_args);
2553
-    }
2554
-
2555
-
2556
-    /**
2557
-     * generates HTML for the Edit Registration side meta box
2558
-     *
2559
-     * @return void
2560
-     * @throws DomainException
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws InvalidDataTypeException
2564
-     * @throws InvalidInterfaceException
2565
-     * @throws ReflectionException
2566
-     */
2567
-    public function _reg_registrant_side_meta_box()
2568
-    {
2569
-        /*@var $attendee EE_Attendee */
2570
-        $att_check = $this->_registration->attendee();
2571
-        $attendee  = $att_check instanceof EE_Attendee
2572
-            ? $att_check
2573
-            : $this->getAttendeeModel()->create_default_object();
2574
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2575
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2576
-        // primary registration object (that way we know if we need to show create button or not)
2577
-        if (! $this->_registration->is_primary_registrant()) {
2578
-            $primary_registration = $this->_registration->get_primary_registration();
2579
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2580
-                : null;
2581
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2582
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2583
-                // custom attendee object so let's not worry about the primary reg.
2584
-                $primary_registration = null;
2585
-            }
2586
-        } else {
2587
-            $primary_registration = null;
2588
-        }
2589
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2590
-        $this->_template_args['fname']             = $attendee->fname();
2591
-        $this->_template_args['lname']             = $attendee->lname();
2592
-        $this->_template_args['email']             = $attendee->email();
2593
-        $this->_template_args['phone']             = $attendee->phone();
2594
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2595
-        // edit link
2596
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2597
-            [
2598
-                'action' => 'edit_attendee',
2599
-                'post'   => $attendee->ID(),
2600
-            ],
2601
-            REG_ADMIN_URL
2602
-        );
2603
-        $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2604
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2605
-        // create link
2606
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2607
-            ? EE_Admin_Page::add_query_args_and_nonce(
2608
-                [
2609
-                    'action'  => 'duplicate_attendee',
2610
-                    '_REG_ID' => $this->_registration->ID(),
2611
-                ],
2612
-                REG_ADMIN_URL
2613
-            ) : '';
2614
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2615
-        $this->_template_args['att_check']    = $att_check;
2616
-        $template_path                        =
2617
-            REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2618
-        EEH_Template::display_template($template_path, $this->_template_args);
2619
-    }
2620
-
2621
-
2622
-    /**
2623
-     * trash or restore registrations
2624
-     *
2625
-     * @param boolean $trash whether to archive or restore
2626
-     * @return void
2627
-     * @throws DomainException
2628
-     * @throws EE_Error
2629
-     * @throws EntityNotFoundException
2630
-     * @throws InvalidArgumentException
2631
-     * @throws InvalidDataTypeException
2632
-     * @throws InvalidInterfaceException
2633
-     * @throws ReflectionException
2634
-     * @throws RuntimeException
2635
-     * @throws UnexpectedEntityException
2636
-     */
2637
-    protected function _trash_or_restore_registrations(bool $trash = true)
2638
-    {
2639
-        // if empty _REG_ID then get out because there's nothing to do
2640
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2641
-        if (empty($REG_IDs)) {
2642
-            EE_Error::add_error(
2643
-                sprintf(
2644
-                    esc_html__(
2645
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2646
-                        'event_espresso'
2647
-                    ),
2648
-                    $trash ? 'trash' : 'restore'
2649
-                ),
2650
-                __FILE__,
2651
-                __LINE__,
2652
-                __FUNCTION__
2653
-            );
2654
-            $this->_redirect_after_action(false, '', '', [], true);
2655
-        }
2656
-        $success        = 0;
2657
-        $overwrite_msgs = false;
2658
-        // Checkboxes
2659
-        $reg_count = count($REG_IDs);
2660
-        // cycle thru checkboxes
2661
-        foreach ($REG_IDs as $REG_ID) {
2662
-            /** @var EE_Registration $REG */
2663
-            $REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2664
-            if ($trash) {
2665
-                $payments = $REG->registration_payments();
2666
-                if (! empty($payments)) {
2667
-                    $name           = $REG->attendee() instanceof EE_Attendee
2668
-                        ? $REG->attendee()->full_name()
2669
-                        : esc_html__('Unknown Attendee', 'event_espresso');
2670
-                    $overwrite_msgs = true;
2671
-                    EE_Error::add_error(
2672
-                        sprintf(
2673
-                            esc_html__(
2674
-                                'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2675
-                                'event_espresso'
2676
-                            ),
2677
-                            $name
2678
-                        ),
2679
-                        __FILE__,
2680
-                        __FUNCTION__,
2681
-                        __LINE__
2682
-                    );
2683
-                    // can't trash this registration because it has payments.
2684
-                    continue;
2685
-                }
2686
-            }
2687
-            $updated = $trash ? $REG->delete() : $REG->restore();
2688
-            if ($updated) {
2689
-                $success++;
2690
-            }
2691
-        }
2692
-        $this->_redirect_after_action(
2693
-            $success === $reg_count, // were ALL registrations affected?
2694
-            $success > 1
2695
-                ? esc_html__('Registrations', 'event_espresso')
2696
-                : esc_html__('Registration', 'event_espresso'),
2697
-            $trash
2698
-                ? esc_html__('moved to the trash', 'event_espresso')
2699
-                : esc_html__('restored', 'event_espresso'),
2700
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2701
-            $overwrite_msgs
2702
-        );
2703
-    }
2704
-
2705
-
2706
-    /**
2707
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2708
-     * registration but also.
2709
-     * 1. Removing relations to EE_Attendee
2710
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2711
-     * ALSO trashed.
2712
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2713
-     * 4. Removing relationships between all tickets and the related registrations
2714
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2715
-     * 6. Deleting permanently any related Check-ins.
2716
-     *
2717
-     * @return void
2718
-     * @throws EE_Error
2719
-     * @throws InvalidArgumentException
2720
-     * @throws InvalidDataTypeException
2721
-     * @throws InvalidInterfaceException
2722
-     * @throws ReflectionException
2723
-     */
2724
-    protected function _delete_registrations()
2725
-    {
2726
-        $REG_MDL = $this->getRegistrationModel();
2727
-        $success = 0;
2728
-        // Checkboxes
2729
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2730
-
2731
-        if (! empty($REG_IDs)) {
2732
-            // if array has more than one element than success message should be plural
2733
-            $success = count($REG_IDs) > 1 ? 2 : 1;
2734
-            // cycle thru checkboxes
2735
-            foreach ($REG_IDs as $REG_ID) {
2736
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2737
-                if (! $REG instanceof EE_Registration) {
2738
-                    continue;
2739
-                }
2740
-                $deleted = $this->_delete_registration($REG);
2741
-                if (! $deleted) {
2742
-                    $success = 0;
2743
-                }
2744
-            }
2745
-        }
2746
-
2747
-        $what        = $success > 1
2748
-            ? esc_html__('Registrations', 'event_espresso')
2749
-            : esc_html__('Registration', 'event_espresso');
2750
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2751
-        $this->_redirect_after_action(
2752
-            $success,
2753
-            $what,
2754
-            $action_desc,
2755
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2756
-            true
2757
-        );
2758
-    }
2759
-
2760
-
2761
-    /**
2762
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2763
-     * models get affected.
2764
-     *
2765
-     * @param EE_Registration $REG registration to be deleted permanently
2766
-     * @return bool true = successful deletion, false = fail.
2767
-     * @throws EE_Error
2768
-     * @throws InvalidArgumentException
2769
-     * @throws InvalidDataTypeException
2770
-     * @throws InvalidInterfaceException
2771
-     * @throws ReflectionException
2772
-     */
2773
-    protected function _delete_registration(EE_Registration $REG): bool
2774
-    {
2775
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2776
-        // registrations on the transaction that are NOT trashed.
2777
-        $TXN         = $REG->transaction();
2778
-        $REGS        = $TXN->get_many_related('Registration');
2779
-        $all_trashed = true;
2780
-        foreach ($REGS as $registration) {
2781
-            if (! $registration->get('REG_deleted')) {
2782
-                $all_trashed = false;
2783
-            }
2784
-        }
2785
-        if (! $all_trashed) {
2786
-            EE_Error::add_error(
2787
-                esc_html__(
2788
-                    'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2789
-                    'event_espresso'
2790
-                ),
2791
-                __FILE__,
2792
-                __FUNCTION__,
2793
-                __LINE__
2794
-            );
2795
-            return false;
2796
-        }
2797
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2798
-        // separately from THIS one).
2799
-        foreach ($REGS as $registration) {
2800
-            // delete related answers
2801
-            $registration->delete_related_permanently('Answer');
2802
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2803
-            $attendee = $registration->get_first_related('Attendee');
2804
-            if ($attendee instanceof EE_Attendee) {
2805
-                $registration->_remove_relation_to($attendee, 'Attendee');
2806
-            }
2807
-            // now remove relationships to tickets on this registration.
2808
-            $registration->_remove_relations('Ticket');
2809
-            // now delete permanently the checkins related to this registration.
2810
-            $registration->delete_related_permanently('Checkin');
2811
-            if ($registration->ID() === $REG->ID()) {
2812
-                continue;
2813
-            } //we don't want to delete permanently the existing registration just yet.
2814
-            // remove relation to transaction for these registrations if NOT the existing registrations
2815
-            $registration->_remove_relations('Transaction');
2816
-            // delete permanently any related messages.
2817
-            $registration->delete_related_permanently('Message');
2818
-            // now delete this registration permanently
2819
-            $registration->delete_permanently();
2820
-        }
2821
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2822
-        // (the transaction and line items should be all that's left).
2823
-        // delete the line items related to the transaction for this registration.
2824
-        $TXN->delete_related_permanently('Line_Item');
2825
-        // we need to remove all the relationships on the transaction
2826
-        $TXN->delete_related_permanently('Payment');
2827
-        $TXN->delete_related_permanently('Extra_Meta');
2828
-        $TXN->delete_related_permanently('Message');
2829
-        // now we can delete this REG permanently (and the transaction of course)
2830
-        $REG->delete_related_permanently('Transaction');
2831
-        return $REG->delete_permanently();
2832
-    }
2833
-
2834
-
2835
-    /**
2836
-     *    generates HTML for the Register New Attendee Admin page
2837
-     *
2838
-     * @throws DomainException
2839
-     * @throws EE_Error
2840
-     * @throws InvalidArgumentException
2841
-     * @throws InvalidDataTypeException
2842
-     * @throws InvalidInterfaceException
2843
-     * @throws ReflectionException
2844
-     * @throws Throwable
2845
-     */
2846
-    public function new_registration()
2847
-    {
2848
-        if (! $this->_set_reg_event()) {
2849
-            throw new EE_Error(
2850
-                esc_html__(
2851
-                    'Unable to continue with registering because there is no Event ID in the request',
2852
-                    'event_espresso'
2853
-                )
2854
-            );
2855
-        }
2856
-        /** @var CurrentPage $current_page */
2857
-        $current_page = $this->loader->getShared(CurrentPage::class);
2858
-        $current_page->setEspressoPage(true);
2859
-        // gotta start with a clean slate if we're not coming here via ajax
2860
-        if (
2861
-            ! $this->request->isAjax()
2862
-            && (
2863
-                ! $this->request->requestParamIsSet('processing_registration')
2864
-                || $this->request->requestParamIsSet('step_error')
2865
-            )
2866
-        ) {
2867
-            $this->clearSession(__CLASS__, __FUNCTION__);
2868
-        }
2869
-        $this->_template_args['event_name'] = '';
2870
-        // event name
2871
-        if ($this->_reg_event) {
2872
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2873
-            $edit_event_url                     = self::add_query_args_and_nonce(
2874
-                [
2875
-                    'action' => 'edit',
2876
-                    'post'   => $this->_reg_event->ID(),
2877
-                ],
2878
-                EVENTS_ADMIN_URL
2879
-            );
2880
-            $edit_event_lnk                     = '<a href="'
2881
-                . $edit_event_url
2882
-                . '" aria-label="'
2883
-                . esc_attr__('Edit ', 'event_espresso')
2884
-                . $this->_reg_event->name()
2885
-                . '">'
2886
-                . esc_html__('Edit Event', 'event_espresso')
2887
-                . '</a>';
2888
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2889
-                . $edit_event_lnk
2890
-                . '</span>';
2891
-        }
2892
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2893
-        if ($this->request->isAjax()) {
2894
-            $this->_return_json();
2895
-        }
2896
-        // grab header
2897
-        $template_path                              =
2898
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2899
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2900
-            $template_path,
2901
-            $this->_template_args,
2902
-            true
2903
-        );
2904
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2905
-        // the details template wrapper
2906
-        $this->display_admin_page_with_sidebar();
2907
-    }
2908
-
2909
-
2910
-    /**
2911
-     * This returns the content for a registration step
2912
-     *
2913
-     * @return string html
2914
-     * @throws DomainException
2915
-     * @throws EE_Error
2916
-     * @throws InvalidArgumentException
2917
-     * @throws InvalidDataTypeException
2918
-     * @throws InvalidInterfaceException
2919
-     * @throws ReflectionException
2920
-     * @throws Throwable
2921
-     */
2922
-    protected function _get_registration_step_content(): string
2923
-    {
2924
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2925
-            $warning_msg = sprintf(
2926
-                esc_html__(
2927
-                    '%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2928
-                    'event_espresso'
2929
-                ),
2930
-                '<br />',
2931
-                '<h3 class="important-notice">',
2932
-                '</h3>',
2933
-                '<div class="float-right">',
2934
-                '<span id="redirect_timer" class="important-notice">30</span>',
2935
-                '</div>',
2936
-                '<b>',
2937
-                '</b>'
2938
-            );
2939
-            return '
2365
+	}
2366
+
2367
+
2368
+	/**
2369
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2370
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2371
+	 * to display the page
2372
+	 *
2373
+	 * @return void
2374
+	 * @throws EE_Error
2375
+	 * @throws InvalidArgumentException
2376
+	 * @throws InvalidDataTypeException
2377
+	 * @throws InvalidInterfaceException
2378
+	 * @throws ReflectionException
2379
+	 */
2380
+	protected function _update_attendee_registration_form()
2381
+	{
2382
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2383
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2384
+			$REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2385
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2386
+			if ($success) {
2387
+				$what  = esc_html__('Registration Form', 'event_espresso');
2388
+				$route = $REG_ID
2389
+					? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2390
+					: ['action' => 'default'];
2391
+				$this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2392
+			}
2393
+		}
2394
+	}
2395
+
2396
+
2397
+	/**
2398
+	 * Gets the form for saving registrations custom questions (if done
2399
+	 * previously retrieves the cached form object, which may have validation errors in it)
2400
+	 *
2401
+	 * @param int $REG_ID
2402
+	 * @return EE_Registration_Custom_Questions_Form
2403
+	 * @throws EE_Error
2404
+	 * @throws InvalidArgumentException
2405
+	 * @throws InvalidDataTypeException
2406
+	 * @throws InvalidInterfaceException
2407
+	 * @throws ReflectionException
2408
+	 */
2409
+	protected function _get_reg_custom_questions_form(int $REG_ID): EE_Registration_Custom_Questions_Form
2410
+	{
2411
+		if (! $this->_reg_custom_questions_form) {
2412
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2413
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2414
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2415
+			);
2416
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2417
+		}
2418
+		return $this->_reg_custom_questions_form;
2419
+	}
2420
+
2421
+
2422
+	/**
2423
+	 * Saves
2424
+	 *
2425
+	 * @param bool $REG_ID
2426
+	 * @return bool
2427
+	 * @throws EE_Error
2428
+	 * @throws InvalidArgumentException
2429
+	 * @throws InvalidDataTypeException
2430
+	 * @throws InvalidInterfaceException
2431
+	 * @throws ReflectionException
2432
+	 */
2433
+	private function _save_reg_custom_questions_form($REG_ID = 0): bool
2434
+	{
2435
+		if (! $REG_ID) {
2436
+			EE_Error::add_error(
2437
+				esc_html__(
2438
+					'An error occurred. No registration ID was received.',
2439
+					'event_espresso'
2440
+				),
2441
+				__FILE__,
2442
+				__FUNCTION__,
2443
+				__LINE__
2444
+			);
2445
+		}
2446
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2447
+		$form->receive_form_submission($this->request->requestParams());
2448
+		$success = false;
2449
+		if ($form->is_valid()) {
2450
+			foreach ($form->subforms() as $question_group_form) {
2451
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2452
+					$where_conditions    = [
2453
+						'QST_ID' => $question_id,
2454
+						'REG_ID' => $REG_ID,
2455
+					];
2456
+					$possibly_new_values = [
2457
+						'ANS_value' => $input->normalized_value(),
2458
+					];
2459
+					$answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2460
+					if ($answer instanceof EE_Answer) {
2461
+						$success = $answer->save($possibly_new_values);
2462
+					} else {
2463
+						// insert it then
2464
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2465
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2466
+						$success     = $answer->save();
2467
+					}
2468
+				}
2469
+			}
2470
+		} else {
2471
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2472
+		}
2473
+		return $success;
2474
+	}
2475
+
2476
+
2477
+	/**
2478
+	 * generates HTML for the Registration main meta box
2479
+	 *
2480
+	 * @return void
2481
+	 * @throws DomainException
2482
+	 * @throws EE_Error
2483
+	 * @throws InvalidArgumentException
2484
+	 * @throws InvalidDataTypeException
2485
+	 * @throws InvalidInterfaceException
2486
+	 * @throws ReflectionException
2487
+	 */
2488
+	public function _reg_attendees_meta_box()
2489
+	{
2490
+		$REG = $this->getRegistrationModel();
2491
+		// get all other registrations on this transaction, and cache
2492
+		// the attendees for them so we don't have to run another query using force_join
2493
+		$registrations                           = $REG->get_all(
2494
+			[
2495
+				[
2496
+					'TXN_ID' => $this->_registration->transaction_ID(),
2497
+					'REG_ID' => ['!=', $this->_registration->ID()],
2498
+				],
2499
+				'force_join'               => ['Attendee'],
2500
+				'default_where_conditions' => 'other_models_only',
2501
+			]
2502
+		);
2503
+		$this->_template_args['attendees']       = [];
2504
+		$this->_template_args['attendee_notice'] = '';
2505
+		if (
2506
+			empty($registrations)
2507
+			|| (is_array($registrations)
2508
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2509
+		) {
2510
+			EE_Error::add_error(
2511
+				esc_html__(
2512
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2513
+					'event_espresso'
2514
+				),
2515
+				__FILE__,
2516
+				__FUNCTION__,
2517
+				__LINE__
2518
+			);
2519
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2520
+		} else {
2521
+			$att_nmbr = 1;
2522
+			foreach ($registrations as $registration) {
2523
+				/* @var $registration EE_Registration */
2524
+				$attendee                                                      = $registration->attendee()
2525
+					? $registration->attendee()
2526
+					: $this->getAttendeeModel()->create_default_object();
2527
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2528
+				$this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2529
+				$this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2530
+				$this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2531
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2532
+				$this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2533
+					', ',
2534
+					$attendee->full_address_as_array()
2535
+				);
2536
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2537
+					[
2538
+						'action' => 'edit_attendee',
2539
+						'post'   => $attendee->ID(),
2540
+					],
2541
+					REG_ADMIN_URL
2542
+				);
2543
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2544
+					$registration->event_obj() instanceof EE_Event
2545
+						? $registration->event_obj()->name()
2546
+						: '';
2547
+				$att_nmbr++;
2548
+			}
2549
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2550
+		}
2551
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2552
+		EEH_Template::display_template($template_path, $this->_template_args);
2553
+	}
2554
+
2555
+
2556
+	/**
2557
+	 * generates HTML for the Edit Registration side meta box
2558
+	 *
2559
+	 * @return void
2560
+	 * @throws DomainException
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws InvalidDataTypeException
2564
+	 * @throws InvalidInterfaceException
2565
+	 * @throws ReflectionException
2566
+	 */
2567
+	public function _reg_registrant_side_meta_box()
2568
+	{
2569
+		/*@var $attendee EE_Attendee */
2570
+		$att_check = $this->_registration->attendee();
2571
+		$attendee  = $att_check instanceof EE_Attendee
2572
+			? $att_check
2573
+			: $this->getAttendeeModel()->create_default_object();
2574
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2575
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2576
+		// primary registration object (that way we know if we need to show create button or not)
2577
+		if (! $this->_registration->is_primary_registrant()) {
2578
+			$primary_registration = $this->_registration->get_primary_registration();
2579
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2580
+				: null;
2581
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2582
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2583
+				// custom attendee object so let's not worry about the primary reg.
2584
+				$primary_registration = null;
2585
+			}
2586
+		} else {
2587
+			$primary_registration = null;
2588
+		}
2589
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2590
+		$this->_template_args['fname']             = $attendee->fname();
2591
+		$this->_template_args['lname']             = $attendee->lname();
2592
+		$this->_template_args['email']             = $attendee->email();
2593
+		$this->_template_args['phone']             = $attendee->phone();
2594
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2595
+		// edit link
2596
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2597
+			[
2598
+				'action' => 'edit_attendee',
2599
+				'post'   => $attendee->ID(),
2600
+			],
2601
+			REG_ADMIN_URL
2602
+		);
2603
+		$this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2604
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2605
+		// create link
2606
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2607
+			? EE_Admin_Page::add_query_args_and_nonce(
2608
+				[
2609
+					'action'  => 'duplicate_attendee',
2610
+					'_REG_ID' => $this->_registration->ID(),
2611
+				],
2612
+				REG_ADMIN_URL
2613
+			) : '';
2614
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2615
+		$this->_template_args['att_check']    = $att_check;
2616
+		$template_path                        =
2617
+			REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2618
+		EEH_Template::display_template($template_path, $this->_template_args);
2619
+	}
2620
+
2621
+
2622
+	/**
2623
+	 * trash or restore registrations
2624
+	 *
2625
+	 * @param boolean $trash whether to archive or restore
2626
+	 * @return void
2627
+	 * @throws DomainException
2628
+	 * @throws EE_Error
2629
+	 * @throws EntityNotFoundException
2630
+	 * @throws InvalidArgumentException
2631
+	 * @throws InvalidDataTypeException
2632
+	 * @throws InvalidInterfaceException
2633
+	 * @throws ReflectionException
2634
+	 * @throws RuntimeException
2635
+	 * @throws UnexpectedEntityException
2636
+	 */
2637
+	protected function _trash_or_restore_registrations(bool $trash = true)
2638
+	{
2639
+		// if empty _REG_ID then get out because there's nothing to do
2640
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2641
+		if (empty($REG_IDs)) {
2642
+			EE_Error::add_error(
2643
+				sprintf(
2644
+					esc_html__(
2645
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2646
+						'event_espresso'
2647
+					),
2648
+					$trash ? 'trash' : 'restore'
2649
+				),
2650
+				__FILE__,
2651
+				__LINE__,
2652
+				__FUNCTION__
2653
+			);
2654
+			$this->_redirect_after_action(false, '', '', [], true);
2655
+		}
2656
+		$success        = 0;
2657
+		$overwrite_msgs = false;
2658
+		// Checkboxes
2659
+		$reg_count = count($REG_IDs);
2660
+		// cycle thru checkboxes
2661
+		foreach ($REG_IDs as $REG_ID) {
2662
+			/** @var EE_Registration $REG */
2663
+			$REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2664
+			if ($trash) {
2665
+				$payments = $REG->registration_payments();
2666
+				if (! empty($payments)) {
2667
+					$name           = $REG->attendee() instanceof EE_Attendee
2668
+						? $REG->attendee()->full_name()
2669
+						: esc_html__('Unknown Attendee', 'event_espresso');
2670
+					$overwrite_msgs = true;
2671
+					EE_Error::add_error(
2672
+						sprintf(
2673
+							esc_html__(
2674
+								'The registration for %s could not be trashed because it has payments attached to the related transaction.  If you wish to trash this registration you must first delete the payments on the related transaction.',
2675
+								'event_espresso'
2676
+							),
2677
+							$name
2678
+						),
2679
+						__FILE__,
2680
+						__FUNCTION__,
2681
+						__LINE__
2682
+					);
2683
+					// can't trash this registration because it has payments.
2684
+					continue;
2685
+				}
2686
+			}
2687
+			$updated = $trash ? $REG->delete() : $REG->restore();
2688
+			if ($updated) {
2689
+				$success++;
2690
+			}
2691
+		}
2692
+		$this->_redirect_after_action(
2693
+			$success === $reg_count, // were ALL registrations affected?
2694
+			$success > 1
2695
+				? esc_html__('Registrations', 'event_espresso')
2696
+				: esc_html__('Registration', 'event_espresso'),
2697
+			$trash
2698
+				? esc_html__('moved to the trash', 'event_espresso')
2699
+				: esc_html__('restored', 'event_espresso'),
2700
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2701
+			$overwrite_msgs
2702
+		);
2703
+	}
2704
+
2705
+
2706
+	/**
2707
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2708
+	 * registration but also.
2709
+	 * 1. Removing relations to EE_Attendee
2710
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2711
+	 * ALSO trashed.
2712
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2713
+	 * 4. Removing relationships between all tickets and the related registrations
2714
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2715
+	 * 6. Deleting permanently any related Check-ins.
2716
+	 *
2717
+	 * @return void
2718
+	 * @throws EE_Error
2719
+	 * @throws InvalidArgumentException
2720
+	 * @throws InvalidDataTypeException
2721
+	 * @throws InvalidInterfaceException
2722
+	 * @throws ReflectionException
2723
+	 */
2724
+	protected function _delete_registrations()
2725
+	{
2726
+		$REG_MDL = $this->getRegistrationModel();
2727
+		$success = 0;
2728
+		// Checkboxes
2729
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2730
+
2731
+		if (! empty($REG_IDs)) {
2732
+			// if array has more than one element than success message should be plural
2733
+			$success = count($REG_IDs) > 1 ? 2 : 1;
2734
+			// cycle thru checkboxes
2735
+			foreach ($REG_IDs as $REG_ID) {
2736
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2737
+				if (! $REG instanceof EE_Registration) {
2738
+					continue;
2739
+				}
2740
+				$deleted = $this->_delete_registration($REG);
2741
+				if (! $deleted) {
2742
+					$success = 0;
2743
+				}
2744
+			}
2745
+		}
2746
+
2747
+		$what        = $success > 1
2748
+			? esc_html__('Registrations', 'event_espresso')
2749
+			: esc_html__('Registration', 'event_espresso');
2750
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2751
+		$this->_redirect_after_action(
2752
+			$success,
2753
+			$what,
2754
+			$action_desc,
2755
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2756
+			true
2757
+		);
2758
+	}
2759
+
2760
+
2761
+	/**
2762
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2763
+	 * models get affected.
2764
+	 *
2765
+	 * @param EE_Registration $REG registration to be deleted permanently
2766
+	 * @return bool true = successful deletion, false = fail.
2767
+	 * @throws EE_Error
2768
+	 * @throws InvalidArgumentException
2769
+	 * @throws InvalidDataTypeException
2770
+	 * @throws InvalidInterfaceException
2771
+	 * @throws ReflectionException
2772
+	 */
2773
+	protected function _delete_registration(EE_Registration $REG): bool
2774
+	{
2775
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2776
+		// registrations on the transaction that are NOT trashed.
2777
+		$TXN         = $REG->transaction();
2778
+		$REGS        = $TXN->get_many_related('Registration');
2779
+		$all_trashed = true;
2780
+		foreach ($REGS as $registration) {
2781
+			if (! $registration->get('REG_deleted')) {
2782
+				$all_trashed = false;
2783
+			}
2784
+		}
2785
+		if (! $all_trashed) {
2786
+			EE_Error::add_error(
2787
+				esc_html__(
2788
+					'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
2789
+					'event_espresso'
2790
+				),
2791
+				__FILE__,
2792
+				__FUNCTION__,
2793
+				__LINE__
2794
+			);
2795
+			return false;
2796
+		}
2797
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2798
+		// separately from THIS one).
2799
+		foreach ($REGS as $registration) {
2800
+			// delete related answers
2801
+			$registration->delete_related_permanently('Answer');
2802
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2803
+			$attendee = $registration->get_first_related('Attendee');
2804
+			if ($attendee instanceof EE_Attendee) {
2805
+				$registration->_remove_relation_to($attendee, 'Attendee');
2806
+			}
2807
+			// now remove relationships to tickets on this registration.
2808
+			$registration->_remove_relations('Ticket');
2809
+			// now delete permanently the checkins related to this registration.
2810
+			$registration->delete_related_permanently('Checkin');
2811
+			if ($registration->ID() === $REG->ID()) {
2812
+				continue;
2813
+			} //we don't want to delete permanently the existing registration just yet.
2814
+			// remove relation to transaction for these registrations if NOT the existing registrations
2815
+			$registration->_remove_relations('Transaction');
2816
+			// delete permanently any related messages.
2817
+			$registration->delete_related_permanently('Message');
2818
+			// now delete this registration permanently
2819
+			$registration->delete_permanently();
2820
+		}
2821
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2822
+		// (the transaction and line items should be all that's left).
2823
+		// delete the line items related to the transaction for this registration.
2824
+		$TXN->delete_related_permanently('Line_Item');
2825
+		// we need to remove all the relationships on the transaction
2826
+		$TXN->delete_related_permanently('Payment');
2827
+		$TXN->delete_related_permanently('Extra_Meta');
2828
+		$TXN->delete_related_permanently('Message');
2829
+		// now we can delete this REG permanently (and the transaction of course)
2830
+		$REG->delete_related_permanently('Transaction');
2831
+		return $REG->delete_permanently();
2832
+	}
2833
+
2834
+
2835
+	/**
2836
+	 *    generates HTML for the Register New Attendee Admin page
2837
+	 *
2838
+	 * @throws DomainException
2839
+	 * @throws EE_Error
2840
+	 * @throws InvalidArgumentException
2841
+	 * @throws InvalidDataTypeException
2842
+	 * @throws InvalidInterfaceException
2843
+	 * @throws ReflectionException
2844
+	 * @throws Throwable
2845
+	 */
2846
+	public function new_registration()
2847
+	{
2848
+		if (! $this->_set_reg_event()) {
2849
+			throw new EE_Error(
2850
+				esc_html__(
2851
+					'Unable to continue with registering because there is no Event ID in the request',
2852
+					'event_espresso'
2853
+				)
2854
+			);
2855
+		}
2856
+		/** @var CurrentPage $current_page */
2857
+		$current_page = $this->loader->getShared(CurrentPage::class);
2858
+		$current_page->setEspressoPage(true);
2859
+		// gotta start with a clean slate if we're not coming here via ajax
2860
+		if (
2861
+			! $this->request->isAjax()
2862
+			&& (
2863
+				! $this->request->requestParamIsSet('processing_registration')
2864
+				|| $this->request->requestParamIsSet('step_error')
2865
+			)
2866
+		) {
2867
+			$this->clearSession(__CLASS__, __FUNCTION__);
2868
+		}
2869
+		$this->_template_args['event_name'] = '';
2870
+		// event name
2871
+		if ($this->_reg_event) {
2872
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2873
+			$edit_event_url                     = self::add_query_args_and_nonce(
2874
+				[
2875
+					'action' => 'edit',
2876
+					'post'   => $this->_reg_event->ID(),
2877
+				],
2878
+				EVENTS_ADMIN_URL
2879
+			);
2880
+			$edit_event_lnk                     = '<a href="'
2881
+				. $edit_event_url
2882
+				. '" aria-label="'
2883
+				. esc_attr__('Edit ', 'event_espresso')
2884
+				. $this->_reg_event->name()
2885
+				. '">'
2886
+				. esc_html__('Edit Event', 'event_espresso')
2887
+				. '</a>';
2888
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2889
+				. $edit_event_lnk
2890
+				. '</span>';
2891
+		}
2892
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2893
+		if ($this->request->isAjax()) {
2894
+			$this->_return_json();
2895
+		}
2896
+		// grab header
2897
+		$template_path                              =
2898
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2899
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2900
+			$template_path,
2901
+			$this->_template_args,
2902
+			true
2903
+		);
2904
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2905
+		// the details template wrapper
2906
+		$this->display_admin_page_with_sidebar();
2907
+	}
2908
+
2909
+
2910
+	/**
2911
+	 * This returns the content for a registration step
2912
+	 *
2913
+	 * @return string html
2914
+	 * @throws DomainException
2915
+	 * @throws EE_Error
2916
+	 * @throws InvalidArgumentException
2917
+	 * @throws InvalidDataTypeException
2918
+	 * @throws InvalidInterfaceException
2919
+	 * @throws ReflectionException
2920
+	 * @throws Throwable
2921
+	 */
2922
+	protected function _get_registration_step_content(): string
2923
+	{
2924
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2925
+			$warning_msg = sprintf(
2926
+				esc_html__(
2927
+					'%2$sWARNING!!!%3$s%1$sPlease do not use the back button to return to this page for the purpose of adding another registration.%1$sThis can result in lost and/or corrupted data.%1$sIf you wish to add another registration, then please click the%1$s%7$s"Add Another New Registration to Event"%8$s button%1$son the Transaction details page, after you are redirected.%1$s%1$s%4$s redirecting in %5$s seconds %6$s',
2928
+					'event_espresso'
2929
+				),
2930
+				'<br />',
2931
+				'<h3 class="important-notice">',
2932
+				'</h3>',
2933
+				'<div class="float-right">',
2934
+				'<span id="redirect_timer" class="important-notice">30</span>',
2935
+				'</div>',
2936
+				'<b>',
2937
+				'</b>'
2938
+			);
2939
+			return '
2940 2940
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2941 2941
 	<script >
2942 2942
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2949,959 +2949,959 @@  discard block
 block discarded – undo
2949 2949
 	        }
2950 2950
 	    }, 800 );
2951 2951
 	</script >';
2952
-        }
2953
-        $template_args = [
2954
-            'title'                    => '',
2955
-            'content'                  => '',
2956
-            'step_button_text'         => '',
2957
-            'show_notification_toggle' => false,
2958
-        ];
2959
-        // to indicate we're processing a new registration
2960
-        $hidden_fields = [
2961
-            'processing_registration' => [
2962
-                'type'  => 'hidden',
2963
-                'value' => 0,
2964
-            ],
2965
-            'event_id'                => [
2966
-                'type'  => 'hidden',
2967
-                'value' => $this->_reg_event->ID(),
2968
-            ],
2969
-        ];
2970
-        // if the cart is empty then we know we're at step one, so we'll display the ticket selector
2971
-        $cart = $this->getCart();
2972
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2973
-        switch ($step) {
2974
-            case 'ticket':
2975
-                $hidden_fields['processing_registration']['value'] = 1;
2976
-                $template_args['title']                            = esc_html__(
2977
-                    'Step One: Select the Ticket for this registration',
2978
-                    'event_espresso'
2979
-                );
2980
-                $template_args['content']                          =
2981
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2982
-                $template_args['content']                          .= '</div>';
2983
-                $template_args['step_button_text']                 = esc_html__(
2984
-                    'Add Tickets and Continue to Registrant Details',
2985
-                    'event_espresso'
2986
-                );
2987
-                $template_args['show_notification_toggle']         = false;
2988
-                break;
2989
-            case 'questions':
2990
-                $hidden_fields['processing_registration']['value'] = 2;
2991
-                $template_args['title']                            = esc_html__(
2992
-                    'Step Two: Add Registrant Details for this Registration',
2993
-                    'event_espresso'
2994
-                );
2995
-                // in theory, we should be able to run EED_SPCO at this point
2996
-                // because the cart should have been set up properly by the first process_reg_step run.
2997
-                $template_args['content']                  =
2998
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2999
-                $template_args['step_button_text']         = esc_html__(
3000
-                    'Save Registration and Continue to Details',
3001
-                    'event_espresso'
3002
-                );
3003
-                $template_args['show_notification_toggle'] = true;
3004
-                break;
3005
-        }
3006
-        // we come back to the process_registration_step route.
3007
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3008
-        return EEH_Template::display_template(
3009
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3010
-            $template_args,
3011
-            true
3012
-        );
3013
-    }
3014
-
3015
-
3016
-    /**
3017
-     * set_reg_event
3018
-     *
3019
-     * @return bool
3020
-     * @throws EE_Error
3021
-     * @throws InvalidArgumentException
3022
-     * @throws InvalidDataTypeException
3023
-     * @throws InvalidInterfaceException
3024
-     * @throws ReflectionException
3025
-     */
3026
-    private function _set_reg_event(): bool
3027
-    {
3028
-        if (is_object($this->_reg_event)) {
3029
-            return true;
3030
-        }
3031
-
3032
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
3033
-        if (! $EVT_ID) {
3034
-            return false;
3035
-        }
3036
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
3037
-        return true;
3038
-    }
3039
-
3040
-
3041
-    /**
3042
-     * process_reg_step
3043
-     *
3044
-     * @return void
3045
-     * @throws DomainException
3046
-     * @throws EE_Error
3047
-     * @throws InvalidArgumentException
3048
-     * @throws InvalidDataTypeException
3049
-     * @throws InvalidInterfaceException
3050
-     * @throws ReflectionException
3051
-     * @throws RuntimeException
3052
-     * @throws Throwable
3053
-     */
3054
-    public function process_reg_step()
3055
-    {
3056
-        EE_System::do_not_cache();
3057
-        $this->_set_reg_event();
3058
-        /** @var CurrentPage $current_page */
3059
-        $current_page = $this->loader->getShared(CurrentPage::class);
3060
-        $current_page->setEspressoPage(true);
3061
-        $this->request->setRequestParam('uts', time());
3062
-        // what step are we on?
3063
-        $cart = $this->getCart();
3064
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3065
-        // if doing ajax then we need to verify the nonce
3066
-        if ($this->request->isAjax()) {
3067
-            $nonce = $this->request->getRequestParam($this->_req_nonce, '');
3068
-            $this->_verify_nonce($nonce, $this->_req_nonce);
3069
-        }
3070
-        switch ($step) {
3071
-            case 'ticket':
3072
-                // process ticket selection
3073
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3074
-                if ($success) {
3075
-                    EE_Error::add_success(
3076
-                        esc_html__(
3077
-                            'Tickets Selected. Now complete the registration.',
3078
-                            'event_espresso'
3079
-                        )
3080
-                    );
3081
-                } else {
3082
-                    $this->request->setRequestParam('step_error', true);
3083
-                    $query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3084
-                }
3085
-                if ($this->request->isAjax()) {
3086
-                    $this->new_registration(); // display next step
3087
-                } else {
3088
-                    $query_args = [
3089
-                        'action'                  => 'new_registration',
3090
-                        'processing_registration' => 1,
3091
-                        'event_id'                => $this->_reg_event->ID(),
3092
-                        'uts'                     => time(),
3093
-                    ];
3094
-                    $this->_redirect_after_action(
3095
-                        false,
3096
-                        '',
3097
-                        '',
3098
-                        $query_args,
3099
-                        true
3100
-                    );
3101
-                }
3102
-                break;
3103
-            case 'questions':
3104
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3105
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3106
-                }
3107
-                // process registration
3108
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3109
-                if ($cart instanceof EE_Cart) {
3110
-                    $grand_total = $cart->get_grand_total();
3111
-                    if ($grand_total instanceof EE_Line_Item) {
3112
-                        $grand_total->save_this_and_descendants_to_txn();
3113
-                    }
3114
-                }
3115
-                if (! $transaction instanceof EE_Transaction) {
3116
-                    $query_args = [
3117
-                        'action'                  => 'new_registration',
3118
-                        'processing_registration' => 2,
3119
-                        'event_id'                => $this->_reg_event->ID(),
3120
-                        'uts'                     => time(),
3121
-                    ];
3122
-                    if ($this->request->isAjax()) {
3123
-                        // display registration form again because there are errors (maybe validation?)
3124
-                        $this->new_registration();
3125
-                        return;
3126
-                    }
3127
-                    $this->_redirect_after_action(
3128
-                        false,
3129
-                        '',
3130
-                        '',
3131
-                        $query_args,
3132
-                        true
3133
-                    );
3134
-                    return;
3135
-                }
3136
-                // maybe update status, and make sure to save transaction if not done already
3137
-                if (! $transaction->update_status_based_on_total_paid()) {
3138
-                    $transaction->save();
3139
-                }
3140
-                $this->clearSession(__CLASS__, __FUNCTION__);
3141
-                $query_args = [
3142
-                    'action'        => 'redirect_to_txn',
3143
-                    'TXN_ID'        => $transaction->ID(),
3144
-                    'EVT_ID'        => $this->_reg_event->ID(),
3145
-                    'event_name'    => urlencode($this->_reg_event->name()),
3146
-                    'redirect_from' => 'new_registration',
3147
-                ];
3148
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3149
-                break;
3150
-        }
3151
-        // what are you looking here for?  Should be nothing to do at this point.
3152
-    }
3153
-
3154
-
3155
-    /**
3156
-     * redirect_to_txn
3157
-     *
3158
-     * @return void
3159
-     * @throws EE_Error
3160
-     * @throws InvalidArgumentException
3161
-     * @throws InvalidDataTypeException
3162
-     * @throws InvalidInterfaceException
3163
-     * @throws ReflectionException
3164
-     */
3165
-    public function redirect_to_txn()
3166
-    {
3167
-        EE_System::do_not_cache();
3168
-        $this->clearSession(__CLASS__, __FUNCTION__);
3169
-        $query_args = [
3170
-            'action' => 'view_transaction',
3171
-            'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3172
-            'page'   => 'espresso_transactions',
3173
-        ];
3174
-        if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3175
-            $query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3176
-            $query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3177
-            $query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3178
-        }
3179
-        EE_Error::add_success(
3180
-            esc_html__(
3181
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3182
-                'event_espresso'
3183
-            )
3184
-        );
3185
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3186
-    }
3187
-
3188
-
3189
-    /**
3190
-     * generates HTML for the Attendee Contact List
3191
-     *
3192
-     * @return void
3193
-     * @throws DomainException
3194
-     * @throws EE_Error
3195
-     */
3196
-    protected function _attendee_contact_list_table()
3197
-    {
3198
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3199
-        $this->display_admin_list_table_page_with_no_sidebar();
3200
-    }
3201
-
3202
-
3203
-    /**
3204
-     * get_attendees
3205
-     *
3206
-     * @param int  $per_page
3207
-     * @param bool $count whether to return count or data.
3208
-     * @param bool $trash
3209
-     * @return array|int
3210
-     * @throws EE_Error
3211
-     * @throws InvalidArgumentException
3212
-     * @throws InvalidDataTypeException
3213
-     * @throws InvalidInterfaceException
3214
-     * @throws ReflectionException
3215
-     */
3216
-    public function get_attendees(int $per_page, bool $count = false, bool $trash = false)
3217
-    {
3218
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3219
-        $orderby = $this->request->getRequestParam('orderby');
3220
-        switch ($orderby) {
3221
-            case 'ATT_ID':
3222
-            case 'ATT_fname':
3223
-            case 'ATT_email':
3224
-            case 'ATT_city':
3225
-            case 'STA_ID':
3226
-            case 'CNT_ID':
3227
-                break;
3228
-            case 'Registration_Count':
3229
-                $orderby = 'Registration_Count';
3230
-                break;
3231
-            default:
3232
-                $orderby = 'ATT_lname';
3233
-        }
3234
-        $sort         = $this->request->getRequestParam('order', 'ASC');
3235
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
3236
-        $per_page     = absint($per_page) ? $per_page : 10;
3237
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3238
-        $_where       = [];
3239
-        $search_term  = $this->request->getRequestParam('s');
3240
-        if ($search_term) {
3241
-            $search_term  = '%' . $search_term . '%';
3242
-            $_where['OR'] = [
3243
-                'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3244
-                'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3245
-                'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3246
-                'ATT_fname'                         => ['LIKE', $search_term],
3247
-                'ATT_lname'                         => ['LIKE', $search_term],
3248
-                'ATT_short_bio'                     => ['LIKE', $search_term],
3249
-                'ATT_email'                         => ['LIKE', $search_term],
3250
-                'ATT_address'                       => ['LIKE', $search_term],
3251
-                'ATT_address2'                      => ['LIKE', $search_term],
3252
-                'ATT_city'                          => ['LIKE', $search_term],
3253
-                'Country.CNT_name'                  => ['LIKE', $search_term],
3254
-                'State.STA_name'                    => ['LIKE', $search_term],
3255
-                'ATT_phone'                         => ['LIKE', $search_term],
3256
-                'Registration.REG_final_price'      => ['LIKE', $search_term],
3257
-                'Registration.REG_code'             => ['LIKE', $search_term],
3258
-                'Registration.REG_group_size'       => ['LIKE', $search_term],
3259
-            ];
3260
-        }
3261
-        $offset     = ($current_page - 1) * $per_page;
3262
-        $limit      = $count ? null : [$offset, $per_page];
3263
-        $query_args = [
3264
-            $_where,
3265
-            'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3266
-            'limit'         => $limit,
3267
-        ];
3268
-        if (! $count) {
3269
-            $query_args['order_by'] = [$orderby => $sort];
3270
-        }
3271
-        $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3272
-        return $count
3273
-            ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3274
-            : $this->getAttendeeModel()->get_all($query_args);
3275
-    }
3276
-
3277
-
3278
-    /**
3279
-     * This is just taking care of resending the registration confirmation
3280
-     *
3281
-     * @return void
3282
-     * @throws EE_Error
3283
-     * @throws InvalidArgumentException
3284
-     * @throws InvalidDataTypeException
3285
-     * @throws InvalidInterfaceException
3286
-     * @throws ReflectionException
3287
-     */
3288
-    protected function _resend_registration()
3289
-    {
3290
-        $this->_process_resend_registration();
3291
-        $REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3292
-        $redirect_to = $this->request->getRequestParam('redirect_to');
3293
-        $query_args  = $redirect_to
3294
-            ? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3295
-            : ['action' => 'default'];
3296
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3297
-    }
3298
-
3299
-
3300
-    /**
3301
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3302
-     * to use when selecting registrations
3303
-     *
3304
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3305
-     *                                                     the query parameters from the request
3306
-     * @return void ends the request with a redirect or download
3307
-     */
3308
-    public function _registrations_report_base(string $method_name_for_getting_query_params)
3309
-    {
3310
-        $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3311
-            ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3312
-            : null;
3313
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3314
-            $return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3315
-            $filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3316
-            $report_params = $this->$method_name_for_getting_query_params($filters);
3317
-            $report_params = $this->convertDatetimeObjectsToStrings($report_params);
3318
-            $use_filters   = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3319
-            wp_redirect(
3320
-                EE_Admin_Page::add_query_args_and_nonce(
3321
-                    [
3322
-                        'page'        => EED_Batch::PAGE_SLUG,
3323
-                        'batch'       => EED_Batch::batch_file_job,
3324
-                        'EVT_ID'      => $EVT_ID,
3325
-                        'filters'     => urlencode(serialize($report_params)),
3326
-                        'use_filters' => urlencode($use_filters),
3327
-                        'job_handler' => urlencode(
3328
-                            'EventEspresso\core\libraries\batch\JobHandlers\RegistrationsReport'
3329
-                        ),
3330
-                        'return_url'  => urlencode($return_url),
3331
-                    ]
3332
-                )
3333
-            );
3334
-        } else {
3335
-            // Pull the current request params
3336
-            $request_args = $this->request->requestParams();
3337
-            $request_args = $this->convertDatetimeObjectsToStrings($request_args);
3338
-            // Set the required request_args to be passed to the export
3339
-            $required_request_args = [
3340
-                'export' => 'report',
3341
-                'action' => 'registrations_report_for_event',
3342
-                'EVT_ID' => $EVT_ID,
3343
-            ];
3344
-            // Merge required request args, overriding any currently set
3345
-            $request_args = array_merge($request_args, $required_request_args);
3346
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3347
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3348
-                $EE_Export = EE_Export::instance($request_args);
3349
-                $EE_Export->export();
3350
-            }
3351
-        }
3352
-    }
3353
-
3354
-
3355
-    /**
3356
-     * recursively convert Datetime objects in query params array to strings using MySQL format
3357
-     *
3358
-     * @param array $query_params
3359
-     * @return array
3360
-     * @since 5.0.19.p
3361
-     */
3362
-    private function convertDatetimeObjectsToStrings(array $query_params): array
3363
-    {
3364
-        foreach ($query_params as $key => $value) {
3365
-            if (is_array($value)) {
3366
-                $query_params[ $key ] = $this->convertDatetimeObjectsToStrings($value);
3367
-            } elseif ($value instanceof DateTime) {
3368
-                $query_params[ $key ] = $value->format('Y-m-d H:i:s');
3369
-            }
3370
-        }
3371
-        return $query_params;
3372
-    }
3373
-
3374
-
3375
-    /**
3376
-     * Creates a registration report using only query parameters in the request
3377
-     *
3378
-     * @return void
3379
-     */
3380
-    public function _registrations_report()
3381
-    {
3382
-        $this->_registrations_report_base('_get_registration_query_parameters');
3383
-    }
3384
-
3385
-
3386
-    /**
3387
-     * @throws EE_Error
3388
-     */
3389
-    public function _contact_list_export()
3390
-    {
3391
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3392
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3393
-            $EE_Export = EE_Export::instance($this->request->requestParams());
3394
-            $EE_Export->export_attendees();
3395
-        }
3396
-    }
3397
-
3398
-
3399
-    public function _contact_list_report()
3400
-    {
3401
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3402
-            wp_redirect(
3403
-                EE_Admin_Page::add_query_args_and_nonce(
3404
-                    [
3405
-                        'page'        => EED_Batch::PAGE_SLUG,
3406
-                        'batch'       => EED_Batch::batch_file_job,
3407
-                        'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\AttendeesReport'),
3408
-                        'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3409
-                    ]
3410
-                )
3411
-            );
3412
-        } else {
3413
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3414
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3415
-                $EE_Export = EE_Export::instance($this->request->requestParams());
3416
-                $EE_Export->report_attendees();
3417
-            }
3418
-        }
3419
-    }
3420
-
3421
-
3422
-
3423
-
3424
-
3425
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3426
-    /**
3427
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3428
-     *
3429
-     * @return void
3430
-     * @throws EE_Error
3431
-     * @throws InvalidArgumentException
3432
-     * @throws InvalidDataTypeException
3433
-     * @throws InvalidInterfaceException
3434
-     * @throws ReflectionException
3435
-     */
3436
-    protected function _duplicate_attendee()
3437
-    {
3438
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3439
-        $action = $this->request->getRequestParam('return', 'default');
3440
-        // verify we have necessary info
3441
-        if (! $REG_ID) {
3442
-            EE_Error::add_error(
3443
-                esc_html__(
3444
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3445
-                    'event_espresso'
3446
-                ),
3447
-                __FILE__,
3448
-                __LINE__,
3449
-                __FUNCTION__
3450
-            );
3451
-            $query_args = ['action' => $action];
3452
-            $this->_redirect_after_action('', '', '', $query_args, true);
3453
-        }
3454
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3455
-        $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3456
-        if (! $registration instanceof EE_Registration) {
3457
-            throw new RuntimeException(
3458
-                sprintf(
3459
-                    esc_html__(
3460
-                        'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3461
-                        'event_espresso'
3462
-                    ),
3463
-                    $REG_ID
3464
-                )
3465
-            );
3466
-        }
3467
-        $attendee = $registration->attendee();
3468
-        // remove relation of existing attendee on registration
3469
-        $registration->_remove_relation_to($attendee, 'Attendee');
3470
-        // new attendee
3471
-        $new_attendee = clone $attendee;
3472
-        $new_attendee->set('ATT_ID', 0);
3473
-        $new_attendee->save();
3474
-        // add new attendee to reg
3475
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3476
-        EE_Error::add_success(
3477
-            esc_html__(
3478
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3479
-                'event_espresso'
3480
-            )
3481
-        );
3482
-        // redirect to edit page for attendee
3483
-        $query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3484
-        $this->_redirect_after_action('', '', '', $query_args, true);
3485
-    }
3486
-
3487
-
3488
-    /**
3489
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3490
-     *
3491
-     * @param int     $post_id
3492
-     * @param WP_Post $post
3493
-     * @throws DomainException
3494
-     * @throws EE_Error
3495
-     * @throws InvalidArgumentException
3496
-     * @throws InvalidDataTypeException
3497
-     * @throws InvalidInterfaceException
3498
-     * @throws LogicException
3499
-     * @throws InvalidFormSubmissionException
3500
-     * @throws ReflectionException
3501
-     */
3502
-    protected function _insert_update_cpt_item($post_id, $post)
3503
-    {
3504
-        $success  = true;
3505
-        $attendee = $post instanceof WP_Post && $post->post_type === EspressoPostType::ATTENDEES
3506
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3507
-            : null;
3508
-        // for attendee updates
3509
-        if ($attendee instanceof EE_Attendee) {
3510
-            // note we should only be UPDATING attendees at this point.
3511
-            $fname          = $this->request->getRequestParam('ATT_fname', '');
3512
-            $lname          = $this->request->getRequestParam('ATT_lname', '');
3513
-            $updated_fields = [
3514
-                'ATT_fname'     => $fname,
3515
-                'ATT_lname'     => $lname,
3516
-                'ATT_full_name' => "$fname $lname",
3517
-                'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3518
-                'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3519
-                'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3520
-                'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3521
-                'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3522
-                'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3523
-            ];
3524
-            foreach ($updated_fields as $field => $value) {
3525
-                $attendee->set($field, $value);
3526
-            }
3527
-
3528
-            // process contact details metabox form handler (which will also save the attendee)
3529
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3530
-            $success              = $contact_details_form->process($this->request->requestParams());
3531
-
3532
-            $attendee_update_callbacks = apply_filters(
3533
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3534
-                []
3535
-            );
3536
-            foreach ($attendee_update_callbacks as $a_callback) {
3537
-                if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3538
-                    throw new EE_Error(
3539
-                        sprintf(
3540
-                            esc_html__(
3541
-                                'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3542
-                                'event_espresso'
3543
-                            ),
3544
-                            $a_callback
3545
-                        )
3546
-                    );
3547
-                }
3548
-            }
3549
-        }
3550
-
3551
-        if ($success === false) {
3552
-            EE_Error::add_error(
3553
-                esc_html__(
3554
-                    'Something went wrong with updating the meta table data for the registration.',
3555
-                    'event_espresso'
3556
-                ),
3557
-                __FILE__,
3558
-                __FUNCTION__,
3559
-                __LINE__
3560
-            );
3561
-        }
3562
-    }
3563
-
3564
-
3565
-    public function trash_cpt_item($post_id)
3566
-    {
3567
-    }
3568
-
3569
-
3570
-    public function delete_cpt_item($post_id)
3571
-    {
3572
-    }
3573
-
3574
-
3575
-    public function restore_cpt_item($post_id)
3576
-    {
3577
-    }
3578
-
3579
-
3580
-    protected function _restore_cpt_item($post_id, $revision_id)
3581
-    {
3582
-    }
3583
-
3584
-
3585
-    /**
3586
-     * @throws EE_Error
3587
-     * @throws ReflectionException
3588
-     * @since 4.10.2.p
3589
-     */
3590
-    public function attendee_editor_metaboxes()
3591
-    {
3592
-        $this->verify_cpt_object();
3593
-        remove_meta_box(
3594
-            'postexcerpt',
3595
-            $this->_cpt_routes[ $this->_req_action ],
3596
-            'normal'
3597
-        );
3598
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3599
-        if (post_type_supports(EspressoPostType::ATTENDEES, 'excerpt')) {
3600
-            $this->addMetaBox(
3601
-                'postexcerpt',
3602
-                esc_html__('Short Biography', 'event_espresso'),
3603
-                'post_excerpt_meta_box',
3604
-                $this->_cpt_routes[ $this->_req_action ]
3605
-            );
3606
-        }
3607
-        if (post_type_supports(EspressoPostType::ATTENDEES, 'comments')) {
3608
-            $this->addMetaBox(
3609
-                'commentsdiv',
3610
-                esc_html__('Notes on the Contact', 'event_espresso'),
3611
-                'post_comment_meta_box',
3612
-                $this->_cpt_routes[ $this->_req_action ],
3613
-                'normal',
3614
-                'core'
3615
-            );
3616
-        }
3617
-        $this->addMetaBox(
3618
-            'attendee_contact_info',
3619
-            esc_html__('Contact Info', 'event_espresso'),
3620
-            [$this, 'attendee_contact_info'],
3621
-            $this->_cpt_routes[ $this->_req_action ],
3622
-            'side',
3623
-            'core'
3624
-        );
3625
-        $this->addMetaBox(
3626
-            'attendee_details_address',
3627
-            esc_html__('Address Details', 'event_espresso'),
3628
-            [$this, 'attendee_address_details'],
3629
-            $this->_cpt_routes[ $this->_req_action ],
3630
-            'normal',
3631
-            'core'
3632
-        );
3633
-        $this->addMetaBox(
3634
-            'attendee_registrations',
3635
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3636
-            [$this, 'attendee_registrations_meta_box'],
3637
-            $this->_cpt_routes[ $this->_req_action ]
3638
-        );
3639
-    }
3640
-
3641
-
3642
-    /**
3643
-     * Metabox for attendee contact info
3644
-     *
3645
-     * @param WP_Post $post wp post object
3646
-     * @return void attendee contact info ( and form )
3647
-     * @throws EE_Error
3648
-     * @throws InvalidArgumentException
3649
-     * @throws InvalidDataTypeException
3650
-     * @throws InvalidInterfaceException
3651
-     * @throws LogicException
3652
-     * @throws DomainException
3653
-     */
3654
-    public function attendee_contact_info(WP_Post $post)
3655
-    {
3656
-        // get attendee object ( should already have it )
3657
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3658
-        $form->enqueueStylesAndScripts();
3659
-        echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3660
-    }
3661
-
3662
-
3663
-    /**
3664
-     * Return form handler for the contact details metabox
3665
-     *
3666
-     * @param EE_Attendee $attendee
3667
-     * @return AttendeeContactDetailsMetaboxFormHandler
3668
-     * @throws DomainException
3669
-     * @throws InvalidArgumentException
3670
-     * @throws InvalidDataTypeException
3671
-     * @throws InvalidInterfaceException
3672
-     */
3673
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee): AttendeeContactDetailsMetaboxFormHandler
3674
-    {
3675
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3676
-    }
3677
-
3678
-
3679
-    /**
3680
-     * Metabox for attendee details
3681
-     *
3682
-     * @param WP_Post $post wp post object
3683
-     * @throws EE_Error
3684
-     * @throws ReflectionException
3685
-     */
3686
-    public function attendee_address_details(WP_Post $post)
3687
-    {
3688
-        // get attendee object (should already have it)
3689
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3690
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3691
-            new EE_Question_Form_Input(
3692
-                EE_Question::new_instance(
3693
-                    [
3694
-                        'QST_ID'           => 0,
3695
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3696
-                        'QST_system'       => 'admin-state',
3697
-                    ]
3698
-                ),
3699
-                EE_Answer::new_instance(
3700
-                    [
3701
-                        'ANS_ID'    => 0,
3702
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3703
-                    ]
3704
-                ),
3705
-                [
3706
-                    'input_id'       => 'STA_ID',
3707
-                    'input_name'     => 'STA_ID',
3708
-                    'input_prefix'   => '',
3709
-                    'append_qstn_id' => false,
3710
-                ]
3711
-            )
3712
-        );
3713
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3714
-            new EE_Question_Form_Input(
3715
-                EE_Question::new_instance(
3716
-                    [
3717
-                        'QST_ID'           => 0,
3718
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3719
-                        'QST_system'       => 'admin-country',
3720
-                    ]
3721
-                ),
3722
-                EE_Answer::new_instance(
3723
-                    [
3724
-                        'ANS_ID'    => 0,
3725
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3726
-                    ]
3727
-                ),
3728
-                [
3729
-                    'input_id'       => 'CNT_ISO',
3730
-                    'input_name'     => 'CNT_ISO',
3731
-                    'input_prefix'   => '',
3732
-                    'append_qstn_id' => false,
3733
-                ]
3734
-            )
3735
-        );
3736
-        $template                             =
3737
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3738
-        EEH_Template::display_template($template, $this->_template_args);
3739
-    }
3740
-
3741
-
3742
-    /**
3743
-     * @param WP_Post $post
3744
-     * @return void
3745
-     * @throws DomainException
3746
-     * @throws EE_Error
3747
-     * @throws InvalidArgumentException
3748
-     * @throws InvalidDataTypeException
3749
-     * @throws InvalidInterfaceException
3750
-     * @throws ReflectionException
3751
-     */
3752
-    public function attendee_registrations_meta_box(WP_Post $post)
3753
-    {
3754
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3755
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3756
-        $template                              =
3757
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3758
-        EEH_Template::display_template($template, $this->_template_args);
3759
-    }
3760
-
3761
-
3762
-    /**
3763
-     * add in the form fields for the attendee edit
3764
-     *
3765
-     * @param WP_Post $post wp post object
3766
-     * @return void echos html for new form.
3767
-     * @throws DomainException
3768
-     */
3769
-    public function after_title_form_fields(WP_Post $post)
3770
-    {
3771
-        if ($post->post_type === EspressoPostType::ATTENDEES) {
3772
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3773
-            $template_args['attendee'] = $this->_cpt_model_obj;
3774
-            EEH_Template::display_template($template, $template_args);
3775
-        }
3776
-    }
3777
-
3778
-
3779
-    /**
3780
-     * _trash_or_restore_attendee
3781
-     *
3782
-     * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3783
-     * @return void
3784
-     * @throws EE_Error
3785
-     * @throws InvalidArgumentException
3786
-     * @throws InvalidDataTypeException
3787
-     * @throws InvalidInterfaceException
3788
-     * @throws ReflectionException
3789
-     */
3790
-    protected function _trash_or_restore_attendees(bool $trash = true)
3791
-    {
3792
-        $status = $trash ? 'trash' : 'publish';
3793
-        // Checkboxes
3794
-        if ($this->request->requestParamIsSet('ATT_IDs')) {
3795
-            $ATT_IDs = $this->request->getRequestParam('ATT_IDs', [], 'int', true);
3796
-            // if array has more than one element than success message should be plural
3797
-            $success = count($ATT_IDs) > 1 ? 2 : 1;
3798
-            // cycle thru checkboxes
3799
-            foreach ($ATT_IDs as $ATT_ID) {
3800
-                $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3801
-                if (! $updated) {
3802
-                    $success = 0;
3803
-                }
3804
-            }
3805
-        } else {
3806
-            // grab single id and delete
3807
-            $ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3808
-            // update attendee
3809
-            $success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3810
-        }
3811
-        $what        = $success > 1
3812
-            ? esc_html__('Contacts', 'event_espresso')
3813
-            : esc_html__('Contact', 'event_espresso');
3814
-        $action_desc = $trash
3815
-            ? esc_html__('moved to the trash', 'event_espresso')
3816
-            : esc_html__('restored', 'event_espresso');
3817
-        $this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3818
-    }
3819
-
3820
-
3821
-    /**
3822
-     * @return void
3823
-     * @throws EE_Error
3824
-     * @throws ReflectionException
3825
-     * @since  :VID:
3826
-     */
3827
-    protected function deleteAttendees()
3828
-    {
3829
-        $success = 0;
3830
-        $att_ids = $this->getAttIdsFromRequest();
3831
-        foreach ($att_ids as $att_id) {
3832
-            $attendee = $this->getAttendeeModel()->get_one_by_ID($att_id);
3833
-            if ($attendee instanceof EE_Attendee) {
3834
-                $deleted = $attendee->delete_permanently();
3835
-                if ($deleted) {
3836
-                    $success++;
3837
-                }
3838
-            }
3839
-        }
3840
-        $what = $success > 1
3841
-            ? esc_html__('Contacts', 'event_espresso')
3842
-            : esc_html__('Contact', 'event_espresso');
3843
-
3844
-        $this->_redirect_after_action(
3845
-            $success,
3846
-            $what,
3847
-            esc_html__('deleted', 'event_espresso'),
3848
-            [
3849
-                'action' => 'contact_list',
3850
-                'status' => 'trash',
3851
-            ],
3852
-            $success == 0
3853
-        );
3854
-    }
3855
-
3856
-
3857
-    /**
3858
-     * @return array
3859
-     * @since  :VID:
3860
-     */
3861
-    private function getAttIdsFromRequest(): array
3862
-    {
3863
-        if ($this->request->requestParamIsSet('ATT_IDs')) {
3864
-            return $this->request->getRequestParam('ATT_IDs', [], 'int', true);
3865
-        } else {
3866
-            return $this->request->getRequestParam('ATT_ID', [], 'int', true);
3867
-        }
3868
-    }
3869
-
3870
-
3871
-    /**
3872
-     * @return EE_Session|null
3873
-     * @since 5.0.20.p
3874
-     */
3875
-    private function getSession(): ?EE_Session
3876
-    {
3877
-        return EE_Registry::instance()->SSN;
3878
-    }
3879
-
3880
-
3881
-    /**
3882
-     * @param string $class
3883
-     * @param string $function
3884
-     * @return void
3885
-     * @throws EE_Error
3886
-     * @throws ReflectionException
3887
-     * @since 5.0.20.p
3888
-     */
3889
-    private function clearSession(string $class, string $function)
3890
-    {
3891
-        $session = $this->getSession();
3892
-        if ($session instanceof EE_Session) {
3893
-            $session->clear_session($class, $function);
3894
-        }
3895
-    }
3896
-
3897
-
3898
-    /**
3899
-     * @return EE_Cart|null
3900
-     * @since 5.0.20.p
3901
-     */
3902
-    private function getCart(): ?EE_Cart
3903
-    {
3904
-        $session = $this->getSession();
3905
-        return $session instanceof EE_Session ? $session->cart() : null;
3906
-    }
2952
+		}
2953
+		$template_args = [
2954
+			'title'                    => '',
2955
+			'content'                  => '',
2956
+			'step_button_text'         => '',
2957
+			'show_notification_toggle' => false,
2958
+		];
2959
+		// to indicate we're processing a new registration
2960
+		$hidden_fields = [
2961
+			'processing_registration' => [
2962
+				'type'  => 'hidden',
2963
+				'value' => 0,
2964
+			],
2965
+			'event_id'                => [
2966
+				'type'  => 'hidden',
2967
+				'value' => $this->_reg_event->ID(),
2968
+			],
2969
+		];
2970
+		// if the cart is empty then we know we're at step one, so we'll display the ticket selector
2971
+		$cart = $this->getCart();
2972
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2973
+		switch ($step) {
2974
+			case 'ticket':
2975
+				$hidden_fields['processing_registration']['value'] = 1;
2976
+				$template_args['title']                            = esc_html__(
2977
+					'Step One: Select the Ticket for this registration',
2978
+					'event_espresso'
2979
+				);
2980
+				$template_args['content']                          =
2981
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2982
+				$template_args['content']                          .= '</div>';
2983
+				$template_args['step_button_text']                 = esc_html__(
2984
+					'Add Tickets and Continue to Registrant Details',
2985
+					'event_espresso'
2986
+				);
2987
+				$template_args['show_notification_toggle']         = false;
2988
+				break;
2989
+			case 'questions':
2990
+				$hidden_fields['processing_registration']['value'] = 2;
2991
+				$template_args['title']                            = esc_html__(
2992
+					'Step Two: Add Registrant Details for this Registration',
2993
+					'event_espresso'
2994
+				);
2995
+				// in theory, we should be able to run EED_SPCO at this point
2996
+				// because the cart should have been set up properly by the first process_reg_step run.
2997
+				$template_args['content']                  =
2998
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2999
+				$template_args['step_button_text']         = esc_html__(
3000
+					'Save Registration and Continue to Details',
3001
+					'event_espresso'
3002
+				);
3003
+				$template_args['show_notification_toggle'] = true;
3004
+				break;
3005
+		}
3006
+		// we come back to the process_registration_step route.
3007
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3008
+		return EEH_Template::display_template(
3009
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3010
+			$template_args,
3011
+			true
3012
+		);
3013
+	}
3014
+
3015
+
3016
+	/**
3017
+	 * set_reg_event
3018
+	 *
3019
+	 * @return bool
3020
+	 * @throws EE_Error
3021
+	 * @throws InvalidArgumentException
3022
+	 * @throws InvalidDataTypeException
3023
+	 * @throws InvalidInterfaceException
3024
+	 * @throws ReflectionException
3025
+	 */
3026
+	private function _set_reg_event(): bool
3027
+	{
3028
+		if (is_object($this->_reg_event)) {
3029
+			return true;
3030
+		}
3031
+
3032
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
3033
+		if (! $EVT_ID) {
3034
+			return false;
3035
+		}
3036
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
3037
+		return true;
3038
+	}
3039
+
3040
+
3041
+	/**
3042
+	 * process_reg_step
3043
+	 *
3044
+	 * @return void
3045
+	 * @throws DomainException
3046
+	 * @throws EE_Error
3047
+	 * @throws InvalidArgumentException
3048
+	 * @throws InvalidDataTypeException
3049
+	 * @throws InvalidInterfaceException
3050
+	 * @throws ReflectionException
3051
+	 * @throws RuntimeException
3052
+	 * @throws Throwable
3053
+	 */
3054
+	public function process_reg_step()
3055
+	{
3056
+		EE_System::do_not_cache();
3057
+		$this->_set_reg_event();
3058
+		/** @var CurrentPage $current_page */
3059
+		$current_page = $this->loader->getShared(CurrentPage::class);
3060
+		$current_page->setEspressoPage(true);
3061
+		$this->request->setRequestParam('uts', time());
3062
+		// what step are we on?
3063
+		$cart = $this->getCart();
3064
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
3065
+		// if doing ajax then we need to verify the nonce
3066
+		if ($this->request->isAjax()) {
3067
+			$nonce = $this->request->getRequestParam($this->_req_nonce, '');
3068
+			$this->_verify_nonce($nonce, $this->_req_nonce);
3069
+		}
3070
+		switch ($step) {
3071
+			case 'ticket':
3072
+				// process ticket selection
3073
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3074
+				if ($success) {
3075
+					EE_Error::add_success(
3076
+						esc_html__(
3077
+							'Tickets Selected. Now complete the registration.',
3078
+							'event_espresso'
3079
+						)
3080
+					);
3081
+				} else {
3082
+					$this->request->setRequestParam('step_error', true);
3083
+					$query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3084
+				}
3085
+				if ($this->request->isAjax()) {
3086
+					$this->new_registration(); // display next step
3087
+				} else {
3088
+					$query_args = [
3089
+						'action'                  => 'new_registration',
3090
+						'processing_registration' => 1,
3091
+						'event_id'                => $this->_reg_event->ID(),
3092
+						'uts'                     => time(),
3093
+					];
3094
+					$this->_redirect_after_action(
3095
+						false,
3096
+						'',
3097
+						'',
3098
+						$query_args,
3099
+						true
3100
+					);
3101
+				}
3102
+				break;
3103
+			case 'questions':
3104
+				if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3105
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3106
+				}
3107
+				// process registration
3108
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3109
+				if ($cart instanceof EE_Cart) {
3110
+					$grand_total = $cart->get_grand_total();
3111
+					if ($grand_total instanceof EE_Line_Item) {
3112
+						$grand_total->save_this_and_descendants_to_txn();
3113
+					}
3114
+				}
3115
+				if (! $transaction instanceof EE_Transaction) {
3116
+					$query_args = [
3117
+						'action'                  => 'new_registration',
3118
+						'processing_registration' => 2,
3119
+						'event_id'                => $this->_reg_event->ID(),
3120
+						'uts'                     => time(),
3121
+					];
3122
+					if ($this->request->isAjax()) {
3123
+						// display registration form again because there are errors (maybe validation?)
3124
+						$this->new_registration();
3125
+						return;
3126
+					}
3127
+					$this->_redirect_after_action(
3128
+						false,
3129
+						'',
3130
+						'',
3131
+						$query_args,
3132
+						true
3133
+					);
3134
+					return;
3135
+				}
3136
+				// maybe update status, and make sure to save transaction if not done already
3137
+				if (! $transaction->update_status_based_on_total_paid()) {
3138
+					$transaction->save();
3139
+				}
3140
+				$this->clearSession(__CLASS__, __FUNCTION__);
3141
+				$query_args = [
3142
+					'action'        => 'redirect_to_txn',
3143
+					'TXN_ID'        => $transaction->ID(),
3144
+					'EVT_ID'        => $this->_reg_event->ID(),
3145
+					'event_name'    => urlencode($this->_reg_event->name()),
3146
+					'redirect_from' => 'new_registration',
3147
+				];
3148
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3149
+				break;
3150
+		}
3151
+		// what are you looking here for?  Should be nothing to do at this point.
3152
+	}
3153
+
3154
+
3155
+	/**
3156
+	 * redirect_to_txn
3157
+	 *
3158
+	 * @return void
3159
+	 * @throws EE_Error
3160
+	 * @throws InvalidArgumentException
3161
+	 * @throws InvalidDataTypeException
3162
+	 * @throws InvalidInterfaceException
3163
+	 * @throws ReflectionException
3164
+	 */
3165
+	public function redirect_to_txn()
3166
+	{
3167
+		EE_System::do_not_cache();
3168
+		$this->clearSession(__CLASS__, __FUNCTION__);
3169
+		$query_args = [
3170
+			'action' => 'view_transaction',
3171
+			'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3172
+			'page'   => 'espresso_transactions',
3173
+		];
3174
+		if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3175
+			$query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3176
+			$query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3177
+			$query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3178
+		}
3179
+		EE_Error::add_success(
3180
+			esc_html__(
3181
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3182
+				'event_espresso'
3183
+			)
3184
+		);
3185
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3186
+	}
3187
+
3188
+
3189
+	/**
3190
+	 * generates HTML for the Attendee Contact List
3191
+	 *
3192
+	 * @return void
3193
+	 * @throws DomainException
3194
+	 * @throws EE_Error
3195
+	 */
3196
+	protected function _attendee_contact_list_table()
3197
+	{
3198
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3199
+		$this->display_admin_list_table_page_with_no_sidebar();
3200
+	}
3201
+
3202
+
3203
+	/**
3204
+	 * get_attendees
3205
+	 *
3206
+	 * @param int  $per_page
3207
+	 * @param bool $count whether to return count or data.
3208
+	 * @param bool $trash
3209
+	 * @return array|int
3210
+	 * @throws EE_Error
3211
+	 * @throws InvalidArgumentException
3212
+	 * @throws InvalidDataTypeException
3213
+	 * @throws InvalidInterfaceException
3214
+	 * @throws ReflectionException
3215
+	 */
3216
+	public function get_attendees(int $per_page, bool $count = false, bool $trash = false)
3217
+	{
3218
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3219
+		$orderby = $this->request->getRequestParam('orderby');
3220
+		switch ($orderby) {
3221
+			case 'ATT_ID':
3222
+			case 'ATT_fname':
3223
+			case 'ATT_email':
3224
+			case 'ATT_city':
3225
+			case 'STA_ID':
3226
+			case 'CNT_ID':
3227
+				break;
3228
+			case 'Registration_Count':
3229
+				$orderby = 'Registration_Count';
3230
+				break;
3231
+			default:
3232
+				$orderby = 'ATT_lname';
3233
+		}
3234
+		$sort         = $this->request->getRequestParam('order', 'ASC');
3235
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
3236
+		$per_page     = absint($per_page) ? $per_page : 10;
3237
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3238
+		$_where       = [];
3239
+		$search_term  = $this->request->getRequestParam('s');
3240
+		if ($search_term) {
3241
+			$search_term  = '%' . $search_term . '%';
3242
+			$_where['OR'] = [
3243
+				'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3244
+				'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3245
+				'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3246
+				'ATT_fname'                         => ['LIKE', $search_term],
3247
+				'ATT_lname'                         => ['LIKE', $search_term],
3248
+				'ATT_short_bio'                     => ['LIKE', $search_term],
3249
+				'ATT_email'                         => ['LIKE', $search_term],
3250
+				'ATT_address'                       => ['LIKE', $search_term],
3251
+				'ATT_address2'                      => ['LIKE', $search_term],
3252
+				'ATT_city'                          => ['LIKE', $search_term],
3253
+				'Country.CNT_name'                  => ['LIKE', $search_term],
3254
+				'State.STA_name'                    => ['LIKE', $search_term],
3255
+				'ATT_phone'                         => ['LIKE', $search_term],
3256
+				'Registration.REG_final_price'      => ['LIKE', $search_term],
3257
+				'Registration.REG_code'             => ['LIKE', $search_term],
3258
+				'Registration.REG_group_size'       => ['LIKE', $search_term],
3259
+			];
3260
+		}
3261
+		$offset     = ($current_page - 1) * $per_page;
3262
+		$limit      = $count ? null : [$offset, $per_page];
3263
+		$query_args = [
3264
+			$_where,
3265
+			'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3266
+			'limit'         => $limit,
3267
+		];
3268
+		if (! $count) {
3269
+			$query_args['order_by'] = [$orderby => $sort];
3270
+		}
3271
+		$query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3272
+		return $count
3273
+			? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3274
+			: $this->getAttendeeModel()->get_all($query_args);
3275
+	}
3276
+
3277
+
3278
+	/**
3279
+	 * This is just taking care of resending the registration confirmation
3280
+	 *
3281
+	 * @return void
3282
+	 * @throws EE_Error
3283
+	 * @throws InvalidArgumentException
3284
+	 * @throws InvalidDataTypeException
3285
+	 * @throws InvalidInterfaceException
3286
+	 * @throws ReflectionException
3287
+	 */
3288
+	protected function _resend_registration()
3289
+	{
3290
+		$this->_process_resend_registration();
3291
+		$REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3292
+		$redirect_to = $this->request->getRequestParam('redirect_to');
3293
+		$query_args  = $redirect_to
3294
+			? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3295
+			: ['action' => 'default'];
3296
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3297
+	}
3298
+
3299
+
3300
+	/**
3301
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3302
+	 * to use when selecting registrations
3303
+	 *
3304
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3305
+	 *                                                     the query parameters from the request
3306
+	 * @return void ends the request with a redirect or download
3307
+	 */
3308
+	public function _registrations_report_base(string $method_name_for_getting_query_params)
3309
+	{
3310
+		$EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3311
+			? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3312
+			: null;
3313
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3314
+			$return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3315
+			$filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3316
+			$report_params = $this->$method_name_for_getting_query_params($filters);
3317
+			$report_params = $this->convertDatetimeObjectsToStrings($report_params);
3318
+			$use_filters   = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3319
+			wp_redirect(
3320
+				EE_Admin_Page::add_query_args_and_nonce(
3321
+					[
3322
+						'page'        => EED_Batch::PAGE_SLUG,
3323
+						'batch'       => EED_Batch::batch_file_job,
3324
+						'EVT_ID'      => $EVT_ID,
3325
+						'filters'     => urlencode(serialize($report_params)),
3326
+						'use_filters' => urlencode($use_filters),
3327
+						'job_handler' => urlencode(
3328
+							'EventEspresso\core\libraries\batch\JobHandlers\RegistrationsReport'
3329
+						),
3330
+						'return_url'  => urlencode($return_url),
3331
+					]
3332
+				)
3333
+			);
3334
+		} else {
3335
+			// Pull the current request params
3336
+			$request_args = $this->request->requestParams();
3337
+			$request_args = $this->convertDatetimeObjectsToStrings($request_args);
3338
+			// Set the required request_args to be passed to the export
3339
+			$required_request_args = [
3340
+				'export' => 'report',
3341
+				'action' => 'registrations_report_for_event',
3342
+				'EVT_ID' => $EVT_ID,
3343
+			];
3344
+			// Merge required request args, overriding any currently set
3345
+			$request_args = array_merge($request_args, $required_request_args);
3346
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3347
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3348
+				$EE_Export = EE_Export::instance($request_args);
3349
+				$EE_Export->export();
3350
+			}
3351
+		}
3352
+	}
3353
+
3354
+
3355
+	/**
3356
+	 * recursively convert Datetime objects in query params array to strings using MySQL format
3357
+	 *
3358
+	 * @param array $query_params
3359
+	 * @return array
3360
+	 * @since 5.0.19.p
3361
+	 */
3362
+	private function convertDatetimeObjectsToStrings(array $query_params): array
3363
+	{
3364
+		foreach ($query_params as $key => $value) {
3365
+			if (is_array($value)) {
3366
+				$query_params[ $key ] = $this->convertDatetimeObjectsToStrings($value);
3367
+			} elseif ($value instanceof DateTime) {
3368
+				$query_params[ $key ] = $value->format('Y-m-d H:i:s');
3369
+			}
3370
+		}
3371
+		return $query_params;
3372
+	}
3373
+
3374
+
3375
+	/**
3376
+	 * Creates a registration report using only query parameters in the request
3377
+	 *
3378
+	 * @return void
3379
+	 */
3380
+	public function _registrations_report()
3381
+	{
3382
+		$this->_registrations_report_base('_get_registration_query_parameters');
3383
+	}
3384
+
3385
+
3386
+	/**
3387
+	 * @throws EE_Error
3388
+	 */
3389
+	public function _contact_list_export()
3390
+	{
3391
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3392
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3393
+			$EE_Export = EE_Export::instance($this->request->requestParams());
3394
+			$EE_Export->export_attendees();
3395
+		}
3396
+	}
3397
+
3398
+
3399
+	public function _contact_list_report()
3400
+	{
3401
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3402
+			wp_redirect(
3403
+				EE_Admin_Page::add_query_args_and_nonce(
3404
+					[
3405
+						'page'        => EED_Batch::PAGE_SLUG,
3406
+						'batch'       => EED_Batch::batch_file_job,
3407
+						'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\AttendeesReport'),
3408
+						'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3409
+					]
3410
+				)
3411
+			);
3412
+		} else {
3413
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3414
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3415
+				$EE_Export = EE_Export::instance($this->request->requestParams());
3416
+				$EE_Export->report_attendees();
3417
+			}
3418
+		}
3419
+	}
3420
+
3421
+
3422
+
3423
+
3424
+
3425
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3426
+	/**
3427
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3428
+	 *
3429
+	 * @return void
3430
+	 * @throws EE_Error
3431
+	 * @throws InvalidArgumentException
3432
+	 * @throws InvalidDataTypeException
3433
+	 * @throws InvalidInterfaceException
3434
+	 * @throws ReflectionException
3435
+	 */
3436
+	protected function _duplicate_attendee()
3437
+	{
3438
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3439
+		$action = $this->request->getRequestParam('return', 'default');
3440
+		// verify we have necessary info
3441
+		if (! $REG_ID) {
3442
+			EE_Error::add_error(
3443
+				esc_html__(
3444
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3445
+					'event_espresso'
3446
+				),
3447
+				__FILE__,
3448
+				__LINE__,
3449
+				__FUNCTION__
3450
+			);
3451
+			$query_args = ['action' => $action];
3452
+			$this->_redirect_after_action('', '', '', $query_args, true);
3453
+		}
3454
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3455
+		$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3456
+		if (! $registration instanceof EE_Registration) {
3457
+			throw new RuntimeException(
3458
+				sprintf(
3459
+					esc_html__(
3460
+						'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3461
+						'event_espresso'
3462
+					),
3463
+					$REG_ID
3464
+				)
3465
+			);
3466
+		}
3467
+		$attendee = $registration->attendee();
3468
+		// remove relation of existing attendee on registration
3469
+		$registration->_remove_relation_to($attendee, 'Attendee');
3470
+		// new attendee
3471
+		$new_attendee = clone $attendee;
3472
+		$new_attendee->set('ATT_ID', 0);
3473
+		$new_attendee->save();
3474
+		// add new attendee to reg
3475
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3476
+		EE_Error::add_success(
3477
+			esc_html__(
3478
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3479
+				'event_espresso'
3480
+			)
3481
+		);
3482
+		// redirect to edit page for attendee
3483
+		$query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3484
+		$this->_redirect_after_action('', '', '', $query_args, true);
3485
+	}
3486
+
3487
+
3488
+	/**
3489
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3490
+	 *
3491
+	 * @param int     $post_id
3492
+	 * @param WP_Post $post
3493
+	 * @throws DomainException
3494
+	 * @throws EE_Error
3495
+	 * @throws InvalidArgumentException
3496
+	 * @throws InvalidDataTypeException
3497
+	 * @throws InvalidInterfaceException
3498
+	 * @throws LogicException
3499
+	 * @throws InvalidFormSubmissionException
3500
+	 * @throws ReflectionException
3501
+	 */
3502
+	protected function _insert_update_cpt_item($post_id, $post)
3503
+	{
3504
+		$success  = true;
3505
+		$attendee = $post instanceof WP_Post && $post->post_type === EspressoPostType::ATTENDEES
3506
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3507
+			: null;
3508
+		// for attendee updates
3509
+		if ($attendee instanceof EE_Attendee) {
3510
+			// note we should only be UPDATING attendees at this point.
3511
+			$fname          = $this->request->getRequestParam('ATT_fname', '');
3512
+			$lname          = $this->request->getRequestParam('ATT_lname', '');
3513
+			$updated_fields = [
3514
+				'ATT_fname'     => $fname,
3515
+				'ATT_lname'     => $lname,
3516
+				'ATT_full_name' => "$fname $lname",
3517
+				'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3518
+				'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3519
+				'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3520
+				'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3521
+				'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3522
+				'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3523
+			];
3524
+			foreach ($updated_fields as $field => $value) {
3525
+				$attendee->set($field, $value);
3526
+			}
3527
+
3528
+			// process contact details metabox form handler (which will also save the attendee)
3529
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3530
+			$success              = $contact_details_form->process($this->request->requestParams());
3531
+
3532
+			$attendee_update_callbacks = apply_filters(
3533
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3534
+				[]
3535
+			);
3536
+			foreach ($attendee_update_callbacks as $a_callback) {
3537
+				if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3538
+					throw new EE_Error(
3539
+						sprintf(
3540
+							esc_html__(
3541
+								'The %s callback given for the "FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update" filter is not a valid callback.  Please check the spelling.',
3542
+								'event_espresso'
3543
+							),
3544
+							$a_callback
3545
+						)
3546
+					);
3547
+				}
3548
+			}
3549
+		}
3550
+
3551
+		if ($success === false) {
3552
+			EE_Error::add_error(
3553
+				esc_html__(
3554
+					'Something went wrong with updating the meta table data for the registration.',
3555
+					'event_espresso'
3556
+				),
3557
+				__FILE__,
3558
+				__FUNCTION__,
3559
+				__LINE__
3560
+			);
3561
+		}
3562
+	}
3563
+
3564
+
3565
+	public function trash_cpt_item($post_id)
3566
+	{
3567
+	}
3568
+
3569
+
3570
+	public function delete_cpt_item($post_id)
3571
+	{
3572
+	}
3573
+
3574
+
3575
+	public function restore_cpt_item($post_id)
3576
+	{
3577
+	}
3578
+
3579
+
3580
+	protected function _restore_cpt_item($post_id, $revision_id)
3581
+	{
3582
+	}
3583
+
3584
+
3585
+	/**
3586
+	 * @throws EE_Error
3587
+	 * @throws ReflectionException
3588
+	 * @since 4.10.2.p
3589
+	 */
3590
+	public function attendee_editor_metaboxes()
3591
+	{
3592
+		$this->verify_cpt_object();
3593
+		remove_meta_box(
3594
+			'postexcerpt',
3595
+			$this->_cpt_routes[ $this->_req_action ],
3596
+			'normal'
3597
+		);
3598
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3599
+		if (post_type_supports(EspressoPostType::ATTENDEES, 'excerpt')) {
3600
+			$this->addMetaBox(
3601
+				'postexcerpt',
3602
+				esc_html__('Short Biography', 'event_espresso'),
3603
+				'post_excerpt_meta_box',
3604
+				$this->_cpt_routes[ $this->_req_action ]
3605
+			);
3606
+		}
3607
+		if (post_type_supports(EspressoPostType::ATTENDEES, 'comments')) {
3608
+			$this->addMetaBox(
3609
+				'commentsdiv',
3610
+				esc_html__('Notes on the Contact', 'event_espresso'),
3611
+				'post_comment_meta_box',
3612
+				$this->_cpt_routes[ $this->_req_action ],
3613
+				'normal',
3614
+				'core'
3615
+			);
3616
+		}
3617
+		$this->addMetaBox(
3618
+			'attendee_contact_info',
3619
+			esc_html__('Contact Info', 'event_espresso'),
3620
+			[$this, 'attendee_contact_info'],
3621
+			$this->_cpt_routes[ $this->_req_action ],
3622
+			'side',
3623
+			'core'
3624
+		);
3625
+		$this->addMetaBox(
3626
+			'attendee_details_address',
3627
+			esc_html__('Address Details', 'event_espresso'),
3628
+			[$this, 'attendee_address_details'],
3629
+			$this->_cpt_routes[ $this->_req_action ],
3630
+			'normal',
3631
+			'core'
3632
+		);
3633
+		$this->addMetaBox(
3634
+			'attendee_registrations',
3635
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3636
+			[$this, 'attendee_registrations_meta_box'],
3637
+			$this->_cpt_routes[ $this->_req_action ]
3638
+		);
3639
+	}
3640
+
3641
+
3642
+	/**
3643
+	 * Metabox for attendee contact info
3644
+	 *
3645
+	 * @param WP_Post $post wp post object
3646
+	 * @return void attendee contact info ( and form )
3647
+	 * @throws EE_Error
3648
+	 * @throws InvalidArgumentException
3649
+	 * @throws InvalidDataTypeException
3650
+	 * @throws InvalidInterfaceException
3651
+	 * @throws LogicException
3652
+	 * @throws DomainException
3653
+	 */
3654
+	public function attendee_contact_info(WP_Post $post)
3655
+	{
3656
+		// get attendee object ( should already have it )
3657
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3658
+		$form->enqueueStylesAndScripts();
3659
+		echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3660
+	}
3661
+
3662
+
3663
+	/**
3664
+	 * Return form handler for the contact details metabox
3665
+	 *
3666
+	 * @param EE_Attendee $attendee
3667
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3668
+	 * @throws DomainException
3669
+	 * @throws InvalidArgumentException
3670
+	 * @throws InvalidDataTypeException
3671
+	 * @throws InvalidInterfaceException
3672
+	 */
3673
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee): AttendeeContactDetailsMetaboxFormHandler
3674
+	{
3675
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3676
+	}
3677
+
3678
+
3679
+	/**
3680
+	 * Metabox for attendee details
3681
+	 *
3682
+	 * @param WP_Post $post wp post object
3683
+	 * @throws EE_Error
3684
+	 * @throws ReflectionException
3685
+	 */
3686
+	public function attendee_address_details(WP_Post $post)
3687
+	{
3688
+		// get attendee object (should already have it)
3689
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3690
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3691
+			new EE_Question_Form_Input(
3692
+				EE_Question::new_instance(
3693
+					[
3694
+						'QST_ID'           => 0,
3695
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3696
+						'QST_system'       => 'admin-state',
3697
+					]
3698
+				),
3699
+				EE_Answer::new_instance(
3700
+					[
3701
+						'ANS_ID'    => 0,
3702
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3703
+					]
3704
+				),
3705
+				[
3706
+					'input_id'       => 'STA_ID',
3707
+					'input_name'     => 'STA_ID',
3708
+					'input_prefix'   => '',
3709
+					'append_qstn_id' => false,
3710
+				]
3711
+			)
3712
+		);
3713
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3714
+			new EE_Question_Form_Input(
3715
+				EE_Question::new_instance(
3716
+					[
3717
+						'QST_ID'           => 0,
3718
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3719
+						'QST_system'       => 'admin-country',
3720
+					]
3721
+				),
3722
+				EE_Answer::new_instance(
3723
+					[
3724
+						'ANS_ID'    => 0,
3725
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3726
+					]
3727
+				),
3728
+				[
3729
+					'input_id'       => 'CNT_ISO',
3730
+					'input_name'     => 'CNT_ISO',
3731
+					'input_prefix'   => '',
3732
+					'append_qstn_id' => false,
3733
+				]
3734
+			)
3735
+		);
3736
+		$template                             =
3737
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3738
+		EEH_Template::display_template($template, $this->_template_args);
3739
+	}
3740
+
3741
+
3742
+	/**
3743
+	 * @param WP_Post $post
3744
+	 * @return void
3745
+	 * @throws DomainException
3746
+	 * @throws EE_Error
3747
+	 * @throws InvalidArgumentException
3748
+	 * @throws InvalidDataTypeException
3749
+	 * @throws InvalidInterfaceException
3750
+	 * @throws ReflectionException
3751
+	 */
3752
+	public function attendee_registrations_meta_box(WP_Post $post)
3753
+	{
3754
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3755
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3756
+		$template                              =
3757
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3758
+		EEH_Template::display_template($template, $this->_template_args);
3759
+	}
3760
+
3761
+
3762
+	/**
3763
+	 * add in the form fields for the attendee edit
3764
+	 *
3765
+	 * @param WP_Post $post wp post object
3766
+	 * @return void echos html for new form.
3767
+	 * @throws DomainException
3768
+	 */
3769
+	public function after_title_form_fields(WP_Post $post)
3770
+	{
3771
+		if ($post->post_type === EspressoPostType::ATTENDEES) {
3772
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3773
+			$template_args['attendee'] = $this->_cpt_model_obj;
3774
+			EEH_Template::display_template($template, $template_args);
3775
+		}
3776
+	}
3777
+
3778
+
3779
+	/**
3780
+	 * _trash_or_restore_attendee
3781
+	 *
3782
+	 * @param bool $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3783
+	 * @return void
3784
+	 * @throws EE_Error
3785
+	 * @throws InvalidArgumentException
3786
+	 * @throws InvalidDataTypeException
3787
+	 * @throws InvalidInterfaceException
3788
+	 * @throws ReflectionException
3789
+	 */
3790
+	protected function _trash_or_restore_attendees(bool $trash = true)
3791
+	{
3792
+		$status = $trash ? 'trash' : 'publish';
3793
+		// Checkboxes
3794
+		if ($this->request->requestParamIsSet('ATT_IDs')) {
3795
+			$ATT_IDs = $this->request->getRequestParam('ATT_IDs', [], 'int', true);
3796
+			// if array has more than one element than success message should be plural
3797
+			$success = count($ATT_IDs) > 1 ? 2 : 1;
3798
+			// cycle thru checkboxes
3799
+			foreach ($ATT_IDs as $ATT_ID) {
3800
+				$updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3801
+				if (! $updated) {
3802
+					$success = 0;
3803
+				}
3804
+			}
3805
+		} else {
3806
+			// grab single id and delete
3807
+			$ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3808
+			// update attendee
3809
+			$success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3810
+		}
3811
+		$what        = $success > 1
3812
+			? esc_html__('Contacts', 'event_espresso')
3813
+			: esc_html__('Contact', 'event_espresso');
3814
+		$action_desc = $trash
3815
+			? esc_html__('moved to the trash', 'event_espresso')
3816
+			: esc_html__('restored', 'event_espresso');
3817
+		$this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3818
+	}
3819
+
3820
+
3821
+	/**
3822
+	 * @return void
3823
+	 * @throws EE_Error
3824
+	 * @throws ReflectionException
3825
+	 * @since  :VID:
3826
+	 */
3827
+	protected function deleteAttendees()
3828
+	{
3829
+		$success = 0;
3830
+		$att_ids = $this->getAttIdsFromRequest();
3831
+		foreach ($att_ids as $att_id) {
3832
+			$attendee = $this->getAttendeeModel()->get_one_by_ID($att_id);
3833
+			if ($attendee instanceof EE_Attendee) {
3834
+				$deleted = $attendee->delete_permanently();
3835
+				if ($deleted) {
3836
+					$success++;
3837
+				}
3838
+			}
3839
+		}
3840
+		$what = $success > 1
3841
+			? esc_html__('Contacts', 'event_espresso')
3842
+			: esc_html__('Contact', 'event_espresso');
3843
+
3844
+		$this->_redirect_after_action(
3845
+			$success,
3846
+			$what,
3847
+			esc_html__('deleted', 'event_espresso'),
3848
+			[
3849
+				'action' => 'contact_list',
3850
+				'status' => 'trash',
3851
+			],
3852
+			$success == 0
3853
+		);
3854
+	}
3855
+
3856
+
3857
+	/**
3858
+	 * @return array
3859
+	 * @since  :VID:
3860
+	 */
3861
+	private function getAttIdsFromRequest(): array
3862
+	{
3863
+		if ($this->request->requestParamIsSet('ATT_IDs')) {
3864
+			return $this->request->getRequestParam('ATT_IDs', [], 'int', true);
3865
+		} else {
3866
+			return $this->request->getRequestParam('ATT_ID', [], 'int', true);
3867
+		}
3868
+	}
3869
+
3870
+
3871
+	/**
3872
+	 * @return EE_Session|null
3873
+	 * @since 5.0.20.p
3874
+	 */
3875
+	private function getSession(): ?EE_Session
3876
+	{
3877
+		return EE_Registry::instance()->SSN;
3878
+	}
3879
+
3880
+
3881
+	/**
3882
+	 * @param string $class
3883
+	 * @param string $function
3884
+	 * @return void
3885
+	 * @throws EE_Error
3886
+	 * @throws ReflectionException
3887
+	 * @since 5.0.20.p
3888
+	 */
3889
+	private function clearSession(string $class, string $function)
3890
+	{
3891
+		$session = $this->getSession();
3892
+		if ($session instanceof EE_Session) {
3893
+			$session->clear_session($class, $function);
3894
+		}
3895
+	}
3896
+
3897
+
3898
+	/**
3899
+	 * @return EE_Cart|null
3900
+	 * @since 5.0.20.p
3901
+	 */
3902
+	private function getCart(): ?EE_Cart
3903
+	{
3904
+		$session = $this->getSession();
3905
+		return $session instanceof EE_Session ? $session->cart() : null;
3906
+	}
3907 3907
 }
Please login to merge, or discard this patch.
Spacing   +108 added lines, -108 removed lines patch added patch discarded remove patch
@@ -77,7 +77,7 @@  discard block
 block discarded – undo
77 77
      */
78 78
     protected function getRegistrationModel(): EEM_Registration
79 79
     {
80
-        if (! $this->registration_model instanceof EEM_Registration) {
80
+        if ( ! $this->registration_model instanceof EEM_Registration) {
81 81
             $this->registration_model = $this->loader->getShared('EEM_Registration');
82 82
         }
83 83
         return $this->registration_model;
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
      */
94 94
     protected function getAttendeeModel(): EEM_Attendee
95 95
     {
96
-        if (! $this->attendee_model instanceof EEM_Attendee) {
96
+        if ( ! $this->attendee_model instanceof EEM_Attendee) {
97 97
             $this->attendee_model = $this->loader->getShared('EEM_Attendee');
98 98
         }
99 99
         return $this->attendee_model;
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
      */
110 110
     protected function getEventModel(): EEM_Event
111 111
     {
112
-        if (! $this->event_model instanceof EEM_Event) {
112
+        if ( ! $this->event_model instanceof EEM_Event) {
113 113
             $this->event_model = $this->loader->getShared('EEM_Event');
114 114
         }
115 115
         return $this->event_model;
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
      */
126 126
     protected function getStatusModel(): EEM_Status
127 127
     {
128
-        if (! $this->status_model instanceof EEM_Status) {
128
+        if ( ! $this->status_model instanceof EEM_Status) {
129 129
             $this->status_model = $this->loader->getShared('EEM_Status');
130 130
         }
131 131
         return $this->status_model;
@@ -758,7 +758,7 @@  discard block
 block discarded – undo
758 758
         // style
759 759
         wp_register_style(
760 760
             'espresso_reg',
761
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
761
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
762 762
             ['ee-admin-css'],
763 763
             EVENT_ESPRESSO_VERSION
764 764
         );
@@ -766,7 +766,7 @@  discard block
 block discarded – undo
766 766
         // script
767 767
         wp_register_script(
768 768
             'espresso_reg',
769
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
769
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
770 770
             ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
771 771
             EVENT_ESPRESSO_VERSION,
772 772
             true
@@ -790,7 +790,7 @@  discard block
 block discarded – undo
790 790
             'att_publish_text' => sprintf(
791 791
             /* translators: The date and time */
792 792
                 wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
793
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
793
+                '<b>'.$this->_cpt_model_obj->get_datetime('ATT_created').'</b>'
794 794
             ),
795 795
         ];
796 796
         wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
@@ -822,7 +822,7 @@  discard block
 block discarded – undo
822 822
         wp_dequeue_style('espresso_reg');
823 823
         wp_register_style(
824 824
             'espresso_att',
825
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
825
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
826 826
             ['ee-admin-css'],
827 827
             EVENT_ESPRESSO_VERSION
828 828
         );
@@ -838,7 +838,7 @@  discard block
 block discarded – undo
838 838
     {
839 839
         wp_register_script(
840 840
             'ee-spco-for-admin',
841
-            REG_ASSETS_URL . 'spco_for_admin.js',
841
+            REG_ASSETS_URL.'spco_for_admin.js',
842 842
             ['underscore', 'jquery'],
843 843
             EVENT_ESPRESSO_VERSION,
844 844
             true
@@ -885,7 +885,7 @@  discard block
 block discarded – undo
885 885
             'no_approve_registrations' => 'not_approved_registration',
886 886
             'cancel_registrations'     => 'cancelled_registration',
887 887
         ];
888
-        $can_send    = $this->capabilities->current_user_can(
888
+        $can_send = $this->capabilities->current_user_can(
889 889
             'ee_send_message',
890 890
             'batch_send_messages'
891 891
         );
@@ -1005,7 +1005,7 @@  discard block
 block discarded – undo
1005 1005
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
1006 1006
                 ],
1007 1007
             ];
1008
-            $this->_views['trash']      = [
1008
+            $this->_views['trash'] = [
1009 1009
                 'slug'        => 'trash',
1010 1010
                 'label'       => esc_html__('Trash', 'event_espresso'),
1011 1011
                 'count'       => 0,
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
         }
1107 1107
         $sc_items = [
1108 1108
             'approved_status'   => [
1109
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::APPROVED,
1109
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::APPROVED,
1110 1110
                 'desc'  => EEH_Template::pretty_status(
1111 1111
                     RegStatus::APPROVED,
1112 1112
                     false,
@@ -1114,7 +1114,7 @@  discard block
 block discarded – undo
1114 1114
                 ),
1115 1115
             ],
1116 1116
             'pending_status'    => [
1117
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::PENDING_PAYMENT,
1117
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::PENDING_PAYMENT,
1118 1118
                 'desc'  => EEH_Template::pretty_status(
1119 1119
                     RegStatus::PENDING_PAYMENT,
1120 1120
                     false,
@@ -1122,7 +1122,7 @@  discard block
 block discarded – undo
1122 1122
                 ),
1123 1123
             ],
1124 1124
             'wait_list'         => [
1125
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::WAIT_LIST,
1125
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::WAIT_LIST,
1126 1126
                 'desc'  => EEH_Template::pretty_status(
1127 1127
                     RegStatus::WAIT_LIST,
1128 1128
                     false,
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
                 ),
1131 1131
             ],
1132 1132
             'incomplete_status' => [
1133
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::INCOMPLETE,
1133
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::INCOMPLETE,
1134 1134
                 'desc'  => EEH_Template::pretty_status(
1135 1135
                     RegStatus::INCOMPLETE,
1136 1136
                     false,
@@ -1138,7 +1138,7 @@  discard block
 block discarded – undo
1138 1138
                 ),
1139 1139
             ],
1140 1140
             'not_approved'      => [
1141
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::AWAITING_REVIEW,
1141
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::AWAITING_REVIEW,
1142 1142
                 'desc'  => EEH_Template::pretty_status(
1143 1143
                     RegStatus::AWAITING_REVIEW,
1144 1144
                     false,
@@ -1146,7 +1146,7 @@  discard block
 block discarded – undo
1146 1146
                 ),
1147 1147
             ],
1148 1148
             'declined_status'   => [
1149
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::DECLINED,
1149
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::DECLINED,
1150 1150
                 'desc'  => EEH_Template::pretty_status(
1151 1151
                     RegStatus::DECLINED,
1152 1152
                     false,
@@ -1154,7 +1154,7 @@  discard block
 block discarded – undo
1154 1154
                 ),
1155 1155
             ],
1156 1156
             'cancelled_status'  => [
1157
-                'class' => 'ee-status-legend ee-status-bg--' . RegStatus::CANCELLED,
1157
+                'class' => 'ee-status-legend ee-status-bg--'.RegStatus::CANCELLED,
1158 1158
                 'desc'  => EEH_Template::pretty_status(
1159 1159
                     RegStatus::CANCELLED,
1160 1160
                     false,
@@ -1214,7 +1214,7 @@  discard block
 block discarded – undo
1214 1214
                 $EVT_ID
1215 1215
             )
1216 1216
         ) {
1217
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1217
+            $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1218 1218
                     'new_registration',
1219 1219
                     'add-registrant',
1220 1220
                     ['event_id' => $EVT_ID],
@@ -1373,7 +1373,7 @@  discard block
 block discarded – undo
1373 1373
                 ],
1374 1374
                 REG_ADMIN_URL
1375 1375
             );
1376
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1376
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1377 1377
                 [
1378 1378
                     'action' => 'default',
1379 1379
                     'EVT_ID' => $event_id,
@@ -1381,7 +1381,7 @@  discard block
 block discarded – undo
1381 1381
                 ],
1382 1382
                 admin_url('admin.php')
1383 1383
             );
1384
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1384
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1385 1385
                 [
1386 1386
                     'page'   => 'espresso_events',
1387 1387
                     'action' => 'edit',
@@ -1390,12 +1390,12 @@  discard block
 block discarded – undo
1390 1390
                 admin_url('admin.php')
1391 1391
             );
1392 1392
             // next and previous links
1393
-            $next_reg                                      = $this->_registration->next(
1393
+            $next_reg = $this->_registration->next(
1394 1394
                 null,
1395 1395
                 [],
1396 1396
                 'REG_ID'
1397 1397
             );
1398
-            $this->_template_args['next_registration']     = $next_reg
1398
+            $this->_template_args['next_registration'] = $next_reg
1399 1399
                 ? $this->_next_link(
1400 1400
                     EE_Admin_Page::add_query_args_and_nonce(
1401 1401
                         [
@@ -1407,7 +1407,7 @@  discard block
 block discarded – undo
1407 1407
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1408 1408
                 )
1409 1409
                 : '';
1410
-            $previous_reg                                  = $this->_registration->previous(
1410
+            $previous_reg = $this->_registration->previous(
1411 1411
                 null,
1412 1412
                 [],
1413 1413
                 'REG_ID'
@@ -1425,7 +1425,7 @@  discard block
 block discarded – undo
1425 1425
                 )
1426 1426
                 : '';
1427 1427
             // grab header
1428
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1428
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1429 1429
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1430 1430
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1431 1431
                 $template_path,
@@ -1462,7 +1462,7 @@  discard block
 block discarded – undo
1462 1462
         );
1463 1463
         $this->addMetaBox(
1464 1464
             'edit-reg-details-mbox',
1465
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1465
+            '<span>'.esc_html__('Registration Details', 'event_espresso')
1466 1466
             . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1467 1467
             [$this, '_reg_details_meta_box'],
1468 1468
             $this->_wp_page_slug
@@ -1556,8 +1556,8 @@  discard block
 block discarded – undo
1556 1556
 
1557 1557
         $status_changes = $this->_registration->get_extra_meta(EE_Registration::META_KEY_REG_STATUS_CHANGE);
1558 1558
 
1559
-        if (! empty($status_changes)) {
1560
-            $date_format = get_option('date_format', 'Y-m-d') . ' ' . get_option('time_format', 'H:i:s');
1559
+        if ( ! empty($status_changes)) {
1560
+            $date_format = get_option('date_format', 'Y-m-d').' '.get_option('time_format', 'H:i:s');
1561 1561
             $html = EEH_HTML::tr();
1562 1562
             $html .= EEH_HTML::th(
1563 1563
                 EEH_HTML::label(esc_html__('Registration Status Changes', 'event_espresso'))
@@ -1565,7 +1565,7 @@  discard block
 block discarded – undo
1565 1565
             $html .= EEH_HTML::td();
1566 1566
             $html .= EEH_HTML::ul();
1567 1567
             foreach ($status_changes as $status_change) {
1568
-                $date = new DateTime('@' . $status_change['date']);
1568
+                $date = new DateTime('@'.$status_change['date']);
1569 1569
                 $reason = $status_change['reason'] ?: esc_html__('not specified', 'event_espresso');
1570 1570
                 $html .= EEH_HTML::li(
1571 1571
                     EEH_HTML::strong($date->format($date_format))
@@ -1602,7 +1602,7 @@  discard block
 block discarded – undo
1602 1602
                 $this->_registration->ID()
1603 1603
             )
1604 1604
         ) {
1605
-            $subsections['reg_status']         = new EE_Select_Input(
1605
+            $subsections['reg_status'] = new EE_Select_Input(
1606 1606
                 $this->_get_reg_statuses(),
1607 1607
                 [
1608 1608
                     'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
@@ -1610,7 +1610,7 @@  discard block
 block discarded – undo
1610 1610
                     'html_class'      => 'ee-input-width--small',
1611 1611
                 ]
1612 1612
             );
1613
-            $subsections['reason']         = new EE_Text_Input(
1613
+            $subsections['reason'] = new EE_Text_Input(
1614 1614
                 [
1615 1615
                     'html_label_text' => esc_html__('Reason for Registration Status Change', 'event_espresso')
1616 1616
                 ]
@@ -1625,7 +1625,7 @@  discard block
 block discarded – undo
1625 1625
                     ),
1626 1626
                 ]
1627 1627
             );
1628
-            $subsections['submit']             = new EE_Submit_Input(
1628
+            $subsections['submit'] = new EE_Submit_Input(
1629 1629
                 [
1630 1630
                     'html_class'      => 'button--primary',
1631 1631
                     'html_label_text' => '&nbsp;',
@@ -1658,7 +1658,7 @@  discard block
 block discarded – undo
1658 1658
     protected function _get_reg_statuses(): array
1659 1659
     {
1660 1660
         $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1661
-        unset($reg_status_array[ RegStatus::INCOMPLETE ]);
1661
+        unset($reg_status_array[RegStatus::INCOMPLETE]);
1662 1662
         // get current reg status
1663 1663
         $current_status = $this->_registration->status_ID();
1664 1664
         // is registration for free event? This will determine whether to display the pending payment option
@@ -1666,7 +1666,7 @@  discard block
 block discarded – undo
1666 1666
             $current_status !== RegStatus::PENDING_PAYMENT
1667 1667
             && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1668 1668
         ) {
1669
-            unset($reg_status_array[ RegStatus::PENDING_PAYMENT ]);
1669
+            unset($reg_status_array[RegStatus::PENDING_PAYMENT]);
1670 1670
         }
1671 1671
         return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1672 1672
     }
@@ -1931,7 +1931,7 @@  discard block
 block discarded – undo
1931 1931
             $action,
1932 1932
             $notify
1933 1933
         );
1934
-        $method = $action . '_registration';
1934
+        $method = $action.'_registration';
1935 1935
         if (method_exists($this, $method)) {
1936 1936
             $this->$method($notify);
1937 1937
         }
@@ -2082,7 +2082,7 @@  discard block
 block discarded – undo
2082 2082
         $filters            = new EE_Line_Item_Filter_Collection();
2083 2083
         $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2084 2084
         $filters->add(new EE_Non_Zero_Line_Item_Filter());
2085
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2085
+        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2086 2086
             $filters,
2087 2087
             $transaction->total_line_item()
2088 2088
         );
@@ -2095,7 +2095,7 @@  discard block
 block discarded – undo
2095 2095
             $filtered_line_item_tree,
2096 2096
             ['EE_Registration' => $this->_registration]
2097 2097
         );
2098
-        $attendee                                = $this->_registration->attendee();
2098
+        $attendee = $this->_registration->attendee();
2099 2099
         if (
2100 2100
             $this->capabilities->current_user_can(
2101 2101
                 'ee_read_transaction',
@@ -2177,7 +2177,7 @@  discard block
 block discarded – undo
2177 2177
                 'Payment method response',
2178 2178
                 'event_espresso'
2179 2179
             );
2180
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2180
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2181 2181
         }
2182 2182
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2183 2183
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2208,7 +2208,7 @@  discard block
 block discarded – undo
2208 2208
         $this->_template_args['REG_ID']   = $this->_registration->ID();
2209 2209
         $this->_template_args['event_id'] = $this->_registration->event_ID();
2210 2210
 
2211
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2211
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2212 2212
         EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2213 2213
     }
2214 2214
 
@@ -2248,7 +2248,7 @@  discard block
 block discarded – undo
2248 2248
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2249 2249
             $this->_template_args['REG_ID']                    = $this->_registration->ID();
2250 2250
             $template_path                                     =
2251
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2251
+                REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2252 2252
             EEH_Template::display_template($template_path, $this->_template_args);
2253 2253
         }
2254 2254
     }
@@ -2264,7 +2264,7 @@  discard block
 block discarded – undo
2264 2264
     public function form_before_question_group(string $output): string
2265 2265
     {
2266 2266
         EE_Error::doing_it_wrong(
2267
-            __CLASS__ . '::' . __FUNCTION__,
2267
+            __CLASS__.'::'.__FUNCTION__,
2268 2268
             esc_html__(
2269 2269
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2270 2270
                 'event_espresso'
@@ -2288,7 +2288,7 @@  discard block
 block discarded – undo
2288 2288
     public function form_after_question_group(string $output): string
2289 2289
     {
2290 2290
         EE_Error::doing_it_wrong(
2291
-            __CLASS__ . '::' . __FUNCTION__,
2291
+            __CLASS__.'::'.__FUNCTION__,
2292 2292
             esc_html__(
2293 2293
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2294 2294
                 'event_espresso'
@@ -2325,7 +2325,7 @@  discard block
 block discarded – undo
2325 2325
     public function form_form_field_label_wrap(string $label): string
2326 2326
     {
2327 2327
         EE_Error::doing_it_wrong(
2328
-            __CLASS__ . '::' . __FUNCTION__,
2328
+            __CLASS__.'::'.__FUNCTION__,
2329 2329
             esc_html__(
2330 2330
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2331 2331
                 'event_espresso'
@@ -2335,7 +2335,7 @@  discard block
 block discarded – undo
2335 2335
         return '
2336 2336
 			<tr>
2337 2337
 				<th>
2338
-					' . $label . '
2338
+					' . $label.'
2339 2339
 				</th>';
2340 2340
     }
2341 2341
 
@@ -2350,7 +2350,7 @@  discard block
 block discarded – undo
2350 2350
     public function form_form_field_input__wrap(string $input): string
2351 2351
     {
2352 2352
         EE_Error::doing_it_wrong(
2353
-            __CLASS__ . '::' . __FUNCTION__,
2353
+            __CLASS__.'::'.__FUNCTION__,
2354 2354
             esc_html__(
2355 2355
                 'This method would have been protected but was used on a filter callback so needed to be public. Please discontinue usage as it will be removed soon.',
2356 2356
                 'event_espresso'
@@ -2359,7 +2359,7 @@  discard block
 block discarded – undo
2359 2359
         );
2360 2360
         return '
2361 2361
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2362
-					' . $input . '
2362
+					' . $input.'
2363 2363
 				</td>
2364 2364
 			</tr>';
2365 2365
     }
@@ -2408,8 +2408,8 @@  discard block
 block discarded – undo
2408 2408
      */
2409 2409
     protected function _get_reg_custom_questions_form(int $REG_ID): EE_Registration_Custom_Questions_Form
2410 2410
     {
2411
-        if (! $this->_reg_custom_questions_form) {
2412
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2411
+        if ( ! $this->_reg_custom_questions_form) {
2412
+            require_once(REG_ADMIN.'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2413 2413
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2414 2414
                 $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2415 2415
             );
@@ -2432,7 +2432,7 @@  discard block
 block discarded – undo
2432 2432
      */
2433 2433
     private function _save_reg_custom_questions_form($REG_ID = 0): bool
2434 2434
     {
2435
-        if (! $REG_ID) {
2435
+        if ( ! $REG_ID) {
2436 2436
             EE_Error::add_error(
2437 2437
                 esc_html__(
2438 2438
                     'An error occurred. No registration ID was received.',
@@ -2449,7 +2449,7 @@  discard block
 block discarded – undo
2449 2449
         if ($form->is_valid()) {
2450 2450
             foreach ($form->subforms() as $question_group_form) {
2451 2451
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2452
-                    $where_conditions    = [
2452
+                    $where_conditions = [
2453 2453
                         'QST_ID' => $question_id,
2454 2454
                         'REG_ID' => $REG_ID,
2455 2455
                     ];
@@ -2490,7 +2490,7 @@  discard block
 block discarded – undo
2490 2490
         $REG = $this->getRegistrationModel();
2491 2491
         // get all other registrations on this transaction, and cache
2492 2492
         // the attendees for them so we don't have to run another query using force_join
2493
-        $registrations                           = $REG->get_all(
2493
+        $registrations = $REG->get_all(
2494 2494
             [
2495 2495
                 [
2496 2496
                     'TXN_ID' => $this->_registration->transaction_ID(),
@@ -2524,23 +2524,23 @@  discard block
 block discarded – undo
2524 2524
                 $attendee                                                      = $registration->attendee()
2525 2525
                     ? $registration->attendee()
2526 2526
                     : $this->getAttendeeModel()->create_default_object();
2527
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2528
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2529
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2530
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2531
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2532
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2527
+                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2528
+                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2529
+                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2530
+                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2531
+                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2532
+                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2533 2533
                     ', ',
2534 2534
                     $attendee->full_address_as_array()
2535 2535
                 );
2536
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2536
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2537 2537
                     [
2538 2538
                         'action' => 'edit_attendee',
2539 2539
                         'post'   => $attendee->ID(),
2540 2540
                     ],
2541 2541
                     REG_ADMIN_URL
2542 2542
                 );
2543
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2543
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] =
2544 2544
                     $registration->event_obj() instanceof EE_Event
2545 2545
                         ? $registration->event_obj()->name()
2546 2546
                         : '';
@@ -2548,7 +2548,7 @@  discard block
 block discarded – undo
2548 2548
             }
2549 2549
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2550 2550
         }
2551
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2551
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2552 2552
         EEH_Template::display_template($template_path, $this->_template_args);
2553 2553
     }
2554 2554
 
@@ -2574,11 +2574,11 @@  discard block
 block discarded – undo
2574 2574
         // now let's determine if this is not the primary registration.  If it isn't then we set the
2575 2575
         // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2576 2576
         // primary registration object (that way we know if we need to show create button or not)
2577
-        if (! $this->_registration->is_primary_registrant()) {
2577
+        if ( ! $this->_registration->is_primary_registrant()) {
2578 2578
             $primary_registration = $this->_registration->get_primary_registration();
2579 2579
             $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2580 2580
                 : null;
2581
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2581
+            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2582 2582
                 // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2583 2583
                 // custom attendee object so let's not worry about the primary reg.
2584 2584
                 $primary_registration = null;
@@ -2593,7 +2593,7 @@  discard block
 block discarded – undo
2593 2593
         $this->_template_args['phone']             = $attendee->phone();
2594 2594
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2595 2595
         // edit link
2596
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2596
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2597 2597
             [
2598 2598
                 'action' => 'edit_attendee',
2599 2599
                 'post'   => $attendee->ID(),
@@ -2603,7 +2603,7 @@  discard block
 block discarded – undo
2603 2603
         $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2604 2604
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2605 2605
         // create link
2606
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2606
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2607 2607
             ? EE_Admin_Page::add_query_args_and_nonce(
2608 2608
                 [
2609 2609
                     'action'  => 'duplicate_attendee',
@@ -2614,7 +2614,7 @@  discard block
 block discarded – undo
2614 2614
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2615 2615
         $this->_template_args['att_check']    = $att_check;
2616 2616
         $template_path                        =
2617
-            REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2617
+            REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2618 2618
         EEH_Template::display_template($template_path, $this->_template_args);
2619 2619
     }
2620 2620
 
@@ -2663,7 +2663,7 @@  discard block
 block discarded – undo
2663 2663
             $REG = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2664 2664
             if ($trash) {
2665 2665
                 $payments = $REG->registration_payments();
2666
-                if (! empty($payments)) {
2666
+                if ( ! empty($payments)) {
2667 2667
                     $name           = $REG->attendee() instanceof EE_Attendee
2668 2668
                         ? $REG->attendee()->full_name()
2669 2669
                         : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2728,17 +2728,17 @@  discard block
 block discarded – undo
2728 2728
         // Checkboxes
2729 2729
         $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2730 2730
 
2731
-        if (! empty($REG_IDs)) {
2731
+        if ( ! empty($REG_IDs)) {
2732 2732
             // if array has more than one element than success message should be plural
2733 2733
             $success = count($REG_IDs) > 1 ? 2 : 1;
2734 2734
             // cycle thru checkboxes
2735 2735
             foreach ($REG_IDs as $REG_ID) {
2736 2736
                 $REG = $REG_MDL->get_one_by_ID($REG_ID);
2737
-                if (! $REG instanceof EE_Registration) {
2737
+                if ( ! $REG instanceof EE_Registration) {
2738 2738
                     continue;
2739 2739
                 }
2740 2740
                 $deleted = $this->_delete_registration($REG);
2741
-                if (! $deleted) {
2741
+                if ( ! $deleted) {
2742 2742
                     $success = 0;
2743 2743
                 }
2744 2744
             }
@@ -2778,11 +2778,11 @@  discard block
 block discarded – undo
2778 2778
         $REGS        = $TXN->get_many_related('Registration');
2779 2779
         $all_trashed = true;
2780 2780
         foreach ($REGS as $registration) {
2781
-            if (! $registration->get('REG_deleted')) {
2781
+            if ( ! $registration->get('REG_deleted')) {
2782 2782
                 $all_trashed = false;
2783 2783
             }
2784 2784
         }
2785
-        if (! $all_trashed) {
2785
+        if ( ! $all_trashed) {
2786 2786
             EE_Error::add_error(
2787 2787
                 esc_html__(
2788 2788
                     'Unable to permanently delete this registration. Before this registration can be permanently deleted, all registrations made in the same transaction must be trashed as well.  These registrations will be permanently deleted in the same action.',
@@ -2845,7 +2845,7 @@  discard block
 block discarded – undo
2845 2845
      */
2846 2846
     public function new_registration()
2847 2847
     {
2848
-        if (! $this->_set_reg_event()) {
2848
+        if ( ! $this->_set_reg_event()) {
2849 2849
             throw new EE_Error(
2850 2850
                 esc_html__(
2851 2851
                     'Unable to continue with registering because there is no Event ID in the request',
@@ -2877,7 +2877,7 @@  discard block
 block discarded – undo
2877 2877
                 ],
2878 2878
                 EVENTS_ADMIN_URL
2879 2879
             );
2880
-            $edit_event_lnk                     = '<a href="'
2880
+            $edit_event_lnk = '<a href="'
2881 2881
                 . $edit_event_url
2882 2882
                 . '" aria-label="'
2883 2883
                 . esc_attr__('Edit ', 'event_espresso')
@@ -2895,7 +2895,7 @@  discard block
 block discarded – undo
2895 2895
         }
2896 2896
         // grab header
2897 2897
         $template_path                              =
2898
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2898
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2899 2899
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2900 2900
             $template_path,
2901 2901
             $this->_template_args,
@@ -2937,7 +2937,7 @@  discard block
 block discarded – undo
2937 2937
                 '</b>'
2938 2938
             );
2939 2939
             return '
2940
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2940
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2941 2941
 	<script >
2942 2942
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2943 2943
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2979,7 +2979,7 @@  discard block
 block discarded – undo
2979 2979
                 );
2980 2980
                 $template_args['content']                          =
2981 2981
                     EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2982
-                $template_args['content']                          .= '</div>';
2982
+                $template_args['content'] .= '</div>';
2983 2983
                 $template_args['step_button_text']                 = esc_html__(
2984 2984
                     'Add Tickets and Continue to Registrant Details',
2985 2985
                     'event_espresso'
@@ -3006,7 +3006,7 @@  discard block
 block discarded – undo
3006 3006
         // we come back to the process_registration_step route.
3007 3007
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
3008 3008
         return EEH_Template::display_template(
3009
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
3009
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
3010 3010
             $template_args,
3011 3011
             true
3012 3012
         );
@@ -3030,7 +3030,7 @@  discard block
 block discarded – undo
3030 3030
         }
3031 3031
 
3032 3032
         $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
3033
-        if (! $EVT_ID) {
3033
+        if ( ! $EVT_ID) {
3034 3034
             return false;
3035 3035
         }
3036 3036
         $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
@@ -3101,7 +3101,7 @@  discard block
 block discarded – undo
3101 3101
                 }
3102 3102
                 break;
3103 3103
             case 'questions':
3104
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3104
+                if ( ! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3105 3105
                     add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3106 3106
                 }
3107 3107
                 // process registration
@@ -3112,7 +3112,7 @@  discard block
 block discarded – undo
3112 3112
                         $grand_total->save_this_and_descendants_to_txn();
3113 3113
                     }
3114 3114
                 }
3115
-                if (! $transaction instanceof EE_Transaction) {
3115
+                if ( ! $transaction instanceof EE_Transaction) {
3116 3116
                     $query_args = [
3117 3117
                         'action'                  => 'new_registration',
3118 3118
                         'processing_registration' => 2,
@@ -3134,7 +3134,7 @@  discard block
 block discarded – undo
3134 3134
                     return;
3135 3135
                 }
3136 3136
                 // maybe update status, and make sure to save transaction if not done already
3137
-                if (! $transaction->update_status_based_on_total_paid()) {
3137
+                if ( ! $transaction->update_status_based_on_total_paid()) {
3138 3138
                     $transaction->save();
3139 3139
                 }
3140 3140
                 $this->clearSession(__CLASS__, __FUNCTION__);
@@ -3215,7 +3215,7 @@  discard block
 block discarded – undo
3215 3215
      */
3216 3216
     public function get_attendees(int $per_page, bool $count = false, bool $trash = false)
3217 3217
     {
3218
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3218
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3219 3219
         $orderby = $this->request->getRequestParam('orderby');
3220 3220
         switch ($orderby) {
3221 3221
             case 'ATT_ID':
@@ -3238,7 +3238,7 @@  discard block
 block discarded – undo
3238 3238
         $_where       = [];
3239 3239
         $search_term  = $this->request->getRequestParam('s');
3240 3240
         if ($search_term) {
3241
-            $search_term  = '%' . $search_term . '%';
3241
+            $search_term  = '%'.$search_term.'%';
3242 3242
             $_where['OR'] = [
3243 3243
                 'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3244 3244
                 'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
@@ -3265,7 +3265,7 @@  discard block
 block discarded – undo
3265 3265
             'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3266 3266
             'limit'         => $limit,
3267 3267
         ];
3268
-        if (! $count) {
3268
+        if ( ! $count) {
3269 3269
             $query_args['order_by'] = [$orderby => $sort];
3270 3270
         }
3271 3271
         $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
@@ -3310,7 +3310,7 @@  discard block
 block discarded – undo
3310 3310
         $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3311 3311
             ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3312 3312
             : null;
3313
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3313
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3314 3314
             $return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3315 3315
             $filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3316 3316
             $report_params = $this->$method_name_for_getting_query_params($filters);
@@ -3343,8 +3343,8 @@  discard block
 block discarded – undo
3343 3343
             ];
3344 3344
             // Merge required request args, overriding any currently set
3345 3345
             $request_args = array_merge($request_args, $required_request_args);
3346
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3347
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3346
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3347
+                require_once(EE_CLASSES.'EE_Export.class.php');
3348 3348
                 $EE_Export = EE_Export::instance($request_args);
3349 3349
                 $EE_Export->export();
3350 3350
             }
@@ -3363,9 +3363,9 @@  discard block
 block discarded – undo
3363 3363
     {
3364 3364
         foreach ($query_params as $key => $value) {
3365 3365
             if (is_array($value)) {
3366
-                $query_params[ $key ] = $this->convertDatetimeObjectsToStrings($value);
3366
+                $query_params[$key] = $this->convertDatetimeObjectsToStrings($value);
3367 3367
             } elseif ($value instanceof DateTime) {
3368
-                $query_params[ $key ] = $value->format('Y-m-d H:i:s');
3368
+                $query_params[$key] = $value->format('Y-m-d H:i:s');
3369 3369
             }
3370 3370
         }
3371 3371
         return $query_params;
@@ -3388,8 +3388,8 @@  discard block
 block discarded – undo
3388 3388
      */
3389 3389
     public function _contact_list_export()
3390 3390
     {
3391
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3392
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3391
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3392
+            require_once(EE_CLASSES.'EE_Export.class.php');
3393 3393
             $EE_Export = EE_Export::instance($this->request->requestParams());
3394 3394
             $EE_Export->export_attendees();
3395 3395
         }
@@ -3398,7 +3398,7 @@  discard block
 block discarded – undo
3398 3398
 
3399 3399
     public function _contact_list_report()
3400 3400
     {
3401
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3401
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3402 3402
             wp_redirect(
3403 3403
                 EE_Admin_Page::add_query_args_and_nonce(
3404 3404
                     [
@@ -3410,8 +3410,8 @@  discard block
 block discarded – undo
3410 3410
                 )
3411 3411
             );
3412 3412
         } else {
3413
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3414
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3413
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3414
+                require_once(EE_CLASSES.'EE_Export.class.php');
3415 3415
                 $EE_Export = EE_Export::instance($this->request->requestParams());
3416 3416
                 $EE_Export->report_attendees();
3417 3417
             }
@@ -3438,7 +3438,7 @@  discard block
 block discarded – undo
3438 3438
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3439 3439
         $action = $this->request->getRequestParam('return', 'default');
3440 3440
         // verify we have necessary info
3441
-        if (! $REG_ID) {
3441
+        if ( ! $REG_ID) {
3442 3442
             EE_Error::add_error(
3443 3443
                 esc_html__(
3444 3444
                     'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
@@ -3453,7 +3453,7 @@  discard block
 block discarded – undo
3453 3453
         }
3454 3454
         // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3455 3455
         $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3456
-        if (! $registration instanceof EE_Registration) {
3456
+        if ( ! $registration instanceof EE_Registration) {
3457 3457
             throw new RuntimeException(
3458 3458
                 sprintf(
3459 3459
                     esc_html__(
@@ -3592,16 +3592,16 @@  discard block
 block discarded – undo
3592 3592
         $this->verify_cpt_object();
3593 3593
         remove_meta_box(
3594 3594
             'postexcerpt',
3595
-            $this->_cpt_routes[ $this->_req_action ],
3595
+            $this->_cpt_routes[$this->_req_action],
3596 3596
             'normal'
3597 3597
         );
3598
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3598
+        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal');
3599 3599
         if (post_type_supports(EspressoPostType::ATTENDEES, 'excerpt')) {
3600 3600
             $this->addMetaBox(
3601 3601
                 'postexcerpt',
3602 3602
                 esc_html__('Short Biography', 'event_espresso'),
3603 3603
                 'post_excerpt_meta_box',
3604
-                $this->_cpt_routes[ $this->_req_action ]
3604
+                $this->_cpt_routes[$this->_req_action]
3605 3605
             );
3606 3606
         }
3607 3607
         if (post_type_supports(EspressoPostType::ATTENDEES, 'comments')) {
@@ -3609,7 +3609,7 @@  discard block
 block discarded – undo
3609 3609
                 'commentsdiv',
3610 3610
                 esc_html__('Notes on the Contact', 'event_espresso'),
3611 3611
                 'post_comment_meta_box',
3612
-                $this->_cpt_routes[ $this->_req_action ],
3612
+                $this->_cpt_routes[$this->_req_action],
3613 3613
                 'normal',
3614 3614
                 'core'
3615 3615
             );
@@ -3618,7 +3618,7 @@  discard block
 block discarded – undo
3618 3618
             'attendee_contact_info',
3619 3619
             esc_html__('Contact Info', 'event_espresso'),
3620 3620
             [$this, 'attendee_contact_info'],
3621
-            $this->_cpt_routes[ $this->_req_action ],
3621
+            $this->_cpt_routes[$this->_req_action],
3622 3622
             'side',
3623 3623
             'core'
3624 3624
         );
@@ -3626,7 +3626,7 @@  discard block
 block discarded – undo
3626 3626
             'attendee_details_address',
3627 3627
             esc_html__('Address Details', 'event_espresso'),
3628 3628
             [$this, 'attendee_address_details'],
3629
-            $this->_cpt_routes[ $this->_req_action ],
3629
+            $this->_cpt_routes[$this->_req_action],
3630 3630
             'normal',
3631 3631
             'core'
3632 3632
         );
@@ -3634,7 +3634,7 @@  discard block
 block discarded – undo
3634 3634
             'attendee_registrations',
3635 3635
             esc_html__('Registrations for this Contact', 'event_espresso'),
3636 3636
             [$this, 'attendee_registrations_meta_box'],
3637
-            $this->_cpt_routes[ $this->_req_action ]
3637
+            $this->_cpt_routes[$this->_req_action]
3638 3638
         );
3639 3639
     }
3640 3640
 
@@ -3733,8 +3733,8 @@  discard block
 block discarded – undo
3733 3733
                 ]
3734 3734
             )
3735 3735
         );
3736
-        $template                             =
3737
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3736
+        $template =
3737
+            REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3738 3738
         EEH_Template::display_template($template, $this->_template_args);
3739 3739
     }
3740 3740
 
@@ -3754,7 +3754,7 @@  discard block
 block discarded – undo
3754 3754
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3755 3755
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3756 3756
         $template                              =
3757
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3757
+            REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3758 3758
         EEH_Template::display_template($template, $this->_template_args);
3759 3759
     }
3760 3760
 
@@ -3769,7 +3769,7 @@  discard block
 block discarded – undo
3769 3769
     public function after_title_form_fields(WP_Post $post)
3770 3770
     {
3771 3771
         if ($post->post_type === EspressoPostType::ATTENDEES) {
3772
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3772
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3773 3773
             $template_args['attendee'] = $this->_cpt_model_obj;
3774 3774
             EEH_Template::display_template($template, $template_args);
3775 3775
         }
@@ -3798,7 +3798,7 @@  discard block
 block discarded – undo
3798 3798
             // cycle thru checkboxes
3799 3799
             foreach ($ATT_IDs as $ATT_ID) {
3800 3800
                 $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3801
-                if (! $updated) {
3801
+                if ( ! $updated) {
3802 3802
                     $success = 0;
3803 3803
                 }
3804 3804
             }
Please login to merge, or discard this patch.
registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php 2 patches
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -20,179 +20,179 @@
 block discarded – undo
20 20
  */
21 21
 class EE_Registration_Custom_Questions_Form extends EE_Form_Section_Proper
22 22
 {
23
-    /**
24
-     *
25
-     * @var EE_Registration
26
-     */
27
-    protected $_registration = null;
23
+	/**
24
+	 *
25
+	 * @var EE_Registration
26
+	 */
27
+	protected $_registration = null;
28 28
 
29 29
 
30
-    /**
31
-     *
32
-     * @param EE_Registration $reg
33
-     * @param array           $options
34
-     * @throws EE_Error
35
-     * @throws ReflectionException
36
-     */
37
-    public function __construct(EE_Registration $reg, $options = array())
38
-    {
39
-        $this->_registration = $reg;
40
-        if (! isset($options['layout_strategy'])) {
41
-            $options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42
-        }
43
-        if (! isset($options['html_id'])) {
44
-            $options['html_id'] = 'reg-admin-attendee-questions-frm';
45
-        }
46
-        $this->build_form_from_registration();
47
-        parent::__construct($options);
48
-    }
30
+	/**
31
+	 *
32
+	 * @param EE_Registration $reg
33
+	 * @param array           $options
34
+	 * @throws EE_Error
35
+	 * @throws ReflectionException
36
+	 */
37
+	public function __construct(EE_Registration $reg, $options = array())
38
+	{
39
+		$this->_registration = $reg;
40
+		if (! isset($options['layout_strategy'])) {
41
+			$options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42
+		}
43
+		if (! isset($options['html_id'])) {
44
+			$options['html_id'] = 'reg-admin-attendee-questions-frm';
45
+		}
46
+		$this->build_form_from_registration();
47
+		parent::__construct($options);
48
+	}
49 49
 
50 50
 
51
-    /**
52
-     * Gets the registration object this form is about
53
-     * @return EE_Registration
54
-     */
55
-    public function get_registration()
56
-    {
57
-        return $this->_registration;
58
-    }
51
+	/**
52
+	 * Gets the registration object this form is about
53
+	 * @return EE_Registration
54
+	 */
55
+	public function get_registration()
56
+	{
57
+		return $this->_registration;
58
+	}
59 59
 
60
-    /**
61
-     * @since 4.10.0.p
62
-     * @throws EE_Error
63
-     * @throws InvalidArgumentException
64
-     * @throws ReflectionException
65
-     * @throws InvalidDataTypeException
66
-     * @throws InvalidInterfaceException
67
-     */
68
-    public function build_form_from_registration()
69
-    {
70
-        $reg = $this->get_registration();
71
-        if (! $reg instanceof EE_Registration) {
72
-            throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73
-        }
74
-        // we want to get all their question groups
75
-        $question_groups = EEM_Question_Group::instance()->get_all(
76
-            [
77
-                [
78
-                    'Event_Question_Group.EVT_ID' => $reg->event_ID(),
79
-                    'OR' => [
80
-                        'Question.QST_system*blank' =>  '',
81
-                        'Question.QST_system*null' => ['IS_NULL']
82
-                    ],
83
-                    'Event_Question_Group.'
84
-                    . EEM_Event_Question_Group::instance()->fieldNameForContext(
85
-                        $reg->is_primary_registrant()
86
-                    ) => true
87
-                ],
88
-                'order_by' => ['QSG_order' => 'ASC']
89
-            ]
90
-        );
91
-        // get each question groups questions
92
-        foreach ($question_groups as $question_group) {
93
-            if ($question_group instanceof EE_Question_Group) {
94
-                $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
95
-                    $question_group,
96
-                    $reg
97
-                );
98
-            }
99
-        }
100
-    }
60
+	/**
61
+	 * @since 4.10.0.p
62
+	 * @throws EE_Error
63
+	 * @throws InvalidArgumentException
64
+	 * @throws ReflectionException
65
+	 * @throws InvalidDataTypeException
66
+	 * @throws InvalidInterfaceException
67
+	 */
68
+	public function build_form_from_registration()
69
+	{
70
+		$reg = $this->get_registration();
71
+		if (! $reg instanceof EE_Registration) {
72
+			throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73
+		}
74
+		// we want to get all their question groups
75
+		$question_groups = EEM_Question_Group::instance()->get_all(
76
+			[
77
+				[
78
+					'Event_Question_Group.EVT_ID' => $reg->event_ID(),
79
+					'OR' => [
80
+						'Question.QST_system*blank' =>  '',
81
+						'Question.QST_system*null' => ['IS_NULL']
82
+					],
83
+					'Event_Question_Group.'
84
+					. EEM_Event_Question_Group::instance()->fieldNameForContext(
85
+						$reg->is_primary_registrant()
86
+					) => true
87
+				],
88
+				'order_by' => ['QSG_order' => 'ASC']
89
+			]
90
+		);
91
+		// get each question groups questions
92
+		foreach ($question_groups as $question_group) {
93
+			if ($question_group instanceof EE_Question_Group) {
94
+				$this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
95
+					$question_group,
96
+					$reg
97
+				);
98
+			}
99
+		}
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     *
105
-     * @param EE_Question_Group $question_group
106
-     * @param EE_Registration   $registration
107
-     * @return EE_Form_Section_Proper
108
-     * @throws EE_Error
109
-     * @throws ReflectionException
110
-     */
111
-    public function build_subform_from_question_group($question_group, $registration)
112
-    {
113
-        if (
114
-            ! $question_group instanceof EE_Question_Group ||
115
-            ! $registration instanceof EE_Registration
116
-        ) {
117
-            throw new EE_Error(esc_html__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso'));
118
-        }
119
-        $parts_of_subsection = array(
120
-            'title' => new EE_Form_Section_HTML(
121
-                EEH_HTML::h5(
122
-                    $question_group->name(),
123
-                    $question_group->identifier(),
124
-                    'espresso-question-group-title-h5 section-title'
125
-                )
126
-            )
127
-        );
128
-        $questions = $question_group->questions(
129
-            array(
130
-                array(
131
-                    'OR' => array(
132
-                        'QST_system*blank' => '',
133
-                        'QST_system*null' => array( 'IS_NULL' )
134
-                    )
135
-                )
136
-            )
137
-        );
138
-        foreach ($questions as $question) {
139
-            $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
140
-        }
141
-        return new EE_Form_Section_Proper(
142
-            array(
143
-                'subsections' => $parts_of_subsection,
144
-                'html_class' => 'question-group-questions',
145
-            )
146
-        );
147
-    }
103
+	/**
104
+	 *
105
+	 * @param EE_Question_Group $question_group
106
+	 * @param EE_Registration   $registration
107
+	 * @return EE_Form_Section_Proper
108
+	 * @throws EE_Error
109
+	 * @throws ReflectionException
110
+	 */
111
+	public function build_subform_from_question_group($question_group, $registration)
112
+	{
113
+		if (
114
+			! $question_group instanceof EE_Question_Group ||
115
+			! $registration instanceof EE_Registration
116
+		) {
117
+			throw new EE_Error(esc_html__('A valid question group and registration must be passed to EE_Registration_Custom_Question_Form', 'event_espresso'));
118
+		}
119
+		$parts_of_subsection = array(
120
+			'title' => new EE_Form_Section_HTML(
121
+				EEH_HTML::h5(
122
+					$question_group->name(),
123
+					$question_group->identifier(),
124
+					'espresso-question-group-title-h5 section-title'
125
+				)
126
+			)
127
+		);
128
+		$questions = $question_group->questions(
129
+			array(
130
+				array(
131
+					'OR' => array(
132
+						'QST_system*blank' => '',
133
+						'QST_system*null' => array( 'IS_NULL' )
134
+					)
135
+				)
136
+			)
137
+		);
138
+		foreach ($questions as $question) {
139
+			$parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
140
+		}
141
+		return new EE_Form_Section_Proper(
142
+			array(
143
+				'subsections' => $parts_of_subsection,
144
+				'html_class' => 'question-group-questions',
145
+			)
146
+		);
147
+	}
148 148
 
149 149
 
150
-    /**
151
-     * Overrides parent so if inputs were disabled, we leave those with their defaults
152
-     * from the answers in the DB
153
-     *
154
-     * @param array $req_data like $_POST
155
-     * @return void
156
-     * @throws EE_Error
157
-     */
158
-    protected function _normalize($req_data)
159
-    {
160
-        $this->_received_submission = true;
161
-        $this->_validation_errors = array();
162
-        foreach ($this->get_validatable_subsections() as $subsection) {
163
-            if ($subsection->form_data_present_in($req_data)) {
164
-                try {
165
-                    $subsection->_normalize($req_data);
166
-                } catch (EE_Validation_Error $e) {
167
-                    $subsection->add_validation_error($e);
168
-                }
169
-            }
170
-        }
171
-    }
150
+	/**
151
+	 * Overrides parent so if inputs were disabled, we leave those with their defaults
152
+	 * from the answers in the DB
153
+	 *
154
+	 * @param array $req_data like $_POST
155
+	 * @return void
156
+	 * @throws EE_Error
157
+	 */
158
+	protected function _normalize($req_data)
159
+	{
160
+		$this->_received_submission = true;
161
+		$this->_validation_errors = array();
162
+		foreach ($this->get_validatable_subsections() as $subsection) {
163
+			if ($subsection->form_data_present_in($req_data)) {
164
+				try {
165
+					$subsection->_normalize($req_data);
166
+				} catch (EE_Validation_Error $e) {
167
+					$subsection->add_validation_error($e);
168
+				}
169
+			}
170
+		}
171
+	}
172 172
 
173 173
 
174
-    /**
175
-     * Performs validation on this form section and its subsections. For each subsection,
176
-     * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls
177
-     * _validate on that subsection. If you need to perform validation on the form as a whole (considering multiple)
178
-     * you would be best to override this _validate method, calling parent::_validate() first.
179
-     *
180
-     * @throws EE_Error
181
-     */
182
-    protected function _validate()
183
-    {
184
-        /** @var RequestInterface $request */
185
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
186
-        $form_data = $request->requestParams();
187
-        foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
188
-            if ($subsection->form_data_present_in($form_data)) {
189
-                if (method_exists($this, '_validate_' . $subsection_name)) {
190
-                    call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
191
-                }
192
-                $subsection->_validate();
193
-            } elseif ($subsection instanceof EE_Form_Section_Proper) {
194
-                $subsection->_received_submission = true;
195
-            }
196
-        }
197
-    }
174
+	/**
175
+	 * Performs validation on this form section and its subsections. For each subsection,
176
+	 * calls _validate_{subsection_name} on THIS form (if the function exists) and passes it the subsection, then calls
177
+	 * _validate on that subsection. If you need to perform validation on the form as a whole (considering multiple)
178
+	 * you would be best to override this _validate method, calling parent::_validate() first.
179
+	 *
180
+	 * @throws EE_Error
181
+	 */
182
+	protected function _validate()
183
+	{
184
+		/** @var RequestInterface $request */
185
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
186
+		$form_data = $request->requestParams();
187
+		foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
188
+			if ($subsection->form_data_present_in($form_data)) {
189
+				if (method_exists($this, '_validate_' . $subsection_name)) {
190
+					call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
191
+				}
192
+				$subsection->_validate();
193
+			} elseif ($subsection instanceof EE_Form_Section_Proper) {
194
+				$subsection->_received_submission = true;
195
+			}
196
+		}
197
+	}
198 198
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -37,10 +37,10 @@  discard block
 block discarded – undo
37 37
     public function __construct(EE_Registration $reg, $options = array())
38 38
     {
39 39
         $this->_registration = $reg;
40
-        if (! isset($options['layout_strategy'])) {
40
+        if ( ! isset($options['layout_strategy'])) {
41 41
             $options['layout_strategy'] = new EE_Admin_Two_Column_Layout();
42 42
         }
43
-        if (! isset($options['html_id'])) {
43
+        if ( ! isset($options['html_id'])) {
44 44
             $options['html_id'] = 'reg-admin-attendee-questions-frm';
45 45
         }
46 46
         $this->build_form_from_registration();
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     public function build_form_from_registration()
69 69
     {
70 70
         $reg = $this->get_registration();
71
-        if (! $reg instanceof EE_Registration) {
71
+        if ( ! $reg instanceof EE_Registration) {
72 72
             throw new EE_Error(esc_html__('We cannot build the registration custom questions form because there is no registration set on it yet', 'event_espresso'));
73 73
         }
74 74
         // we want to get all their question groups
@@ -91,7 +91,7 @@  discard block
 block discarded – undo
91 91
         // get each question groups questions
92 92
         foreach ($question_groups as $question_group) {
93 93
             if ($question_group instanceof EE_Question_Group) {
94
-                $this->_subsections[ $question_group->ID() ] = $this->build_subform_from_question_group(
94
+                $this->_subsections[$question_group->ID()] = $this->build_subform_from_question_group(
95 95
                     $question_group,
96 96
                     $reg
97 97
                 );
@@ -130,13 +130,13 @@  discard block
 block discarded – undo
130 130
                 array(
131 131
                     'OR' => array(
132 132
                         'QST_system*blank' => '',
133
-                        'QST_system*null' => array( 'IS_NULL' )
133
+                        'QST_system*null' => array('IS_NULL')
134 134
                     )
135 135
                 )
136 136
             )
137 137
         );
138 138
         foreach ($questions as $question) {
139
-            $parts_of_subsection[ $question->ID() ] = $question->generate_form_input($registration);
139
+            $parts_of_subsection[$question->ID()] = $question->generate_form_input($registration);
140 140
         }
141 141
         return new EE_Form_Section_Proper(
142 142
             array(
@@ -186,8 +186,8 @@  discard block
 block discarded – undo
186 186
         $form_data = $request->requestParams();
187 187
         foreach ($this->get_validatable_subsections() as $subsection_name => $subsection) {
188 188
             if ($subsection->form_data_present_in($form_data)) {
189
-                if (method_exists($this, '_validate_' . $subsection_name)) {
190
-                    call_user_func_array(array($this,'_validate_' . $subsection_name), array($subsection));
189
+                if (method_exists($this, '_validate_'.$subsection_name)) {
190
+                    call_user_func_array(array($this, '_validate_'.$subsection_name), array($subsection));
191 191
                 }
192 192
                 $subsection->_validate();
193 193
             } elseif ($subsection instanceof EE_Form_Section_Proper) {
Please login to merge, or discard this patch.
admin_pages/about/About_Admin_Page.core.php 1 patch
Indentation   +285 added lines, -285 removed lines patch added patch discarded remove patch
@@ -17,140 +17,140 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class About_Admin_Page extends EE_Admin_Page
19 19
 {
20
-    protected function _init_page_props()
21
-    {
22
-        $this->page_slug = EE_ABOUT_PG_SLUG;
23
-        $this->page_label = esc_html__('About Event Espresso', 'event_espresso');
24
-        $this->_admin_base_url = EE_ABOUT_ADMIN_URL;
25
-        $this->_admin_base_path = EE_ABOUT_ADMIN;
26
-    }
27
-
28
-
29
-    protected function _ajax_hooks()
30
-    {
31
-        // todo: all hooks for ajax goes here.
32
-    }
33
-
34
-
35
-    protected function _define_page_props()
36
-    {
37
-        $this->_labels = array();
38
-        $this->_admin_page_title = $this->page_label;
39
-    }
40
-
41
-
42
-    protected function _set_page_routes()
43
-    {
44
-        $this->_page_routes = array(
45
-            'default' => array(
46
-                'func'       => [$this, '_overview'],
47
-                'capability' => 'manage_options',
48
-            ),
49
-            // 'overview' => '_overview',
50
-            // 'func'       => [$this, '_overview'],
51
-            // 'capability' => 'ee_read_ee'
52
-            // ),
53
-            'credits' => array(
54
-                'func'       => [$this, '_credits'],
55
-                'capability' => 'manage_options',
56
-            ),
57
-
58
-            'decafvpro' => array(
59
-                'func'       => [$this, '_decafvpro'],
60
-                'capability' => 'manage_options',
61
-            ),
62
-            'reviews'   => array(
63
-                'func'       => [$this, '_reviews'],
64
-                'capability' => 'manage_options',
65
-            ),
66
-        );
67
-    }
68
-
69
-
70
-    protected function _set_page_config()
71
-    {
72
-        $this->_page_config = array(
73
-            /*'default' => array(
20
+	protected function _init_page_props()
21
+	{
22
+		$this->page_slug = EE_ABOUT_PG_SLUG;
23
+		$this->page_label = esc_html__('About Event Espresso', 'event_espresso');
24
+		$this->_admin_base_url = EE_ABOUT_ADMIN_URL;
25
+		$this->_admin_base_path = EE_ABOUT_ADMIN;
26
+	}
27
+
28
+
29
+	protected function _ajax_hooks()
30
+	{
31
+		// todo: all hooks for ajax goes here.
32
+	}
33
+
34
+
35
+	protected function _define_page_props()
36
+	{
37
+		$this->_labels = array();
38
+		$this->_admin_page_title = $this->page_label;
39
+	}
40
+
41
+
42
+	protected function _set_page_routes()
43
+	{
44
+		$this->_page_routes = array(
45
+			'default' => array(
46
+				'func'       => [$this, '_overview'],
47
+				'capability' => 'manage_options',
48
+			),
49
+			// 'overview' => '_overview',
50
+			// 'func'       => [$this, '_overview'],
51
+			// 'capability' => 'ee_read_ee'
52
+			// ),
53
+			'credits' => array(
54
+				'func'       => [$this, '_credits'],
55
+				'capability' => 'manage_options',
56
+			),
57
+
58
+			'decafvpro' => array(
59
+				'func'       => [$this, '_decafvpro'],
60
+				'capability' => 'manage_options',
61
+			),
62
+			'reviews'   => array(
63
+				'func'       => [$this, '_reviews'],
64
+				'capability' => 'manage_options',
65
+			),
66
+		);
67
+	}
68
+
69
+
70
+	protected function _set_page_config()
71
+	{
72
+		$this->_page_config = array(
73
+			/*'default' => array(
74 74
                 'nav' => array(
75 75
                     'label' => esc_html__('What\'s New', 'event_espresso'),
76 76
                     'order' => 10),
77 77
                 'require_nonce' => FALSE
78 78
                 ),*/
79
-            // 'overview' => array(
80
-            'default' => array(
81
-                'nav'           => array(
82
-                    'label' => esc_html__('About', 'event_espresso'),
83
-                    'icon' => 'dashicons-welcome-learn-more',
84
-                    'order' => 20,
85
-                ),
86
-                'require_nonce' => false,
87
-            ),
88
-            'credits' => array(
89
-                'nav'           => array(
90
-                    'label' => esc_html__('Credits', 'event_espresso'),
91
-                    'icon' => 'dashicons-thumbs-up',
92
-                    'order' => 30,
93
-                ),
94
-                'require_nonce' => false,
95
-            ),
96
-
97
-            'decafvpro' => array(
98
-                'nav'           => array(
99
-                    'label' => esc_html__('Decaf vs Regular', 'event_espresso'),
100
-                    'icon' => 'dashicons-editor-code',
101
-                    'order' => 40,
102
-                ),
103
-                'require_nonce' => false,
104
-            ),
105
-            'reviews'   => array(
106
-                'nav'           => array(
107
-                    'label' => esc_html__('Reviews', 'event_espresso'),
108
-                    'icon' => 'dashicons-star-filled',
109
-                    'order' => 50,
110
-                ),
111
-                'require_nonce' => false,
112
-            ),
113
-        );
114
-    }
115
-
116
-
117
-    // none of the below group are currently used for Support pages
118
-    protected function _add_screen_options()
119
-    {
120
-    }
121
-
122
-    protected function _add_feature_pointers()
123
-    {
124
-    }
125
-
126
-    public function admin_init()
127
-    {
128
-    }
129
-
130
-    public function admin_notices()
131
-    {
132
-    }
133
-
134
-    public function admin_footer_scripts()
135
-    {
136
-    }
137
-
138
-    public function load_scripts_styles()
139
-    {
140
-        // enqueue style
141
-        wp_register_style(
142
-            'espresso_about_admin',
143
-            EE_ABOUT_ASSETS_URL . 'espresso_about_admin.css',
144
-            [],
145
-            EVENT_ESPRESSO_VERSION
146
-        );
147
-        wp_enqueue_style('espresso_about_admin');
148
-    }
149
-
150
-
151
-    protected function _whats_new()
152
-    {
153
-        /*$steps = EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::STATUS_FULL_SITE ? $this->_get_started_steps() : FALSE;
79
+			// 'overview' => array(
80
+			'default' => array(
81
+				'nav'           => array(
82
+					'label' => esc_html__('About', 'event_espresso'),
83
+					'icon' => 'dashicons-welcome-learn-more',
84
+					'order' => 20,
85
+				),
86
+				'require_nonce' => false,
87
+			),
88
+			'credits' => array(
89
+				'nav'           => array(
90
+					'label' => esc_html__('Credits', 'event_espresso'),
91
+					'icon' => 'dashicons-thumbs-up',
92
+					'order' => 30,
93
+				),
94
+				'require_nonce' => false,
95
+			),
96
+
97
+			'decafvpro' => array(
98
+				'nav'           => array(
99
+					'label' => esc_html__('Decaf vs Regular', 'event_espresso'),
100
+					'icon' => 'dashicons-editor-code',
101
+					'order' => 40,
102
+				),
103
+				'require_nonce' => false,
104
+			),
105
+			'reviews'   => array(
106
+				'nav'           => array(
107
+					'label' => esc_html__('Reviews', 'event_espresso'),
108
+					'icon' => 'dashicons-star-filled',
109
+					'order' => 50,
110
+				),
111
+				'require_nonce' => false,
112
+			),
113
+		);
114
+	}
115
+
116
+
117
+	// none of the below group are currently used for Support pages
118
+	protected function _add_screen_options()
119
+	{
120
+	}
121
+
122
+	protected function _add_feature_pointers()
123
+	{
124
+	}
125
+
126
+	public function admin_init()
127
+	{
128
+	}
129
+
130
+	public function admin_notices()
131
+	{
132
+	}
133
+
134
+	public function admin_footer_scripts()
135
+	{
136
+	}
137
+
138
+	public function load_scripts_styles()
139
+	{
140
+		// enqueue style
141
+		wp_register_style(
142
+			'espresso_about_admin',
143
+			EE_ABOUT_ASSETS_URL . 'espresso_about_admin.css',
144
+			[],
145
+			EVENT_ESPRESSO_VERSION
146
+		);
147
+		wp_enqueue_style('espresso_about_admin');
148
+	}
149
+
150
+
151
+	protected function _whats_new()
152
+	{
153
+		/*$steps = EE_Maintenance_Mode::instance()->level() != EE_Maintenance_Mode::STATUS_FULL_SITE ? $this->_get_started_steps() : FALSE;
154 154
         $steps = $steps !== FALSE ? $steps : '';
155 155
         $this->_admin_page_title = sprintf( esc_html__('Welcome to Event Espresso %s', 'event_espresso'), EVENT_ESPRESSO_VERSION );
156 156
         $settings_message = $steps;
@@ -158,167 +158,167 @@  discard block
 block discarded – undo
158 158
         $template = EE_ABOUT_TEMPLATE_PATH . 'whats_new.template.php';
159 159
         $this->_template_args['about_admin_page_content'] = EEH_Template::display_template( $template, $this->_template_args, TRUE );
160 160
         $this->display_about_admin_page();*/
161
-    }
161
+	}
162 162
 
163 163
 
164
-    protected function _overview()
165
-    {
166
-        /*$this->_template_args['admin_page_title'] = esc_html__('About Event Espresso', 'event_espresso');
164
+	protected function _overview()
165
+	{
166
+		/*$this->_template_args['admin_page_title'] = esc_html__('About Event Espresso', 'event_espresso');
167 167
         $this->_template_args['admin_page_subtitle'] = esc_html__('Thank you for choosing Event Espresso Decaf, the most powerful, and free, Event Management plugin for WordPress.', 'event_espresso');
168 168
         $template = EE_ABOUT_TEMPLATE_PATH . 'ee4-overview.template.php';
169 169
         $this->_template_args['about_admin_page_content'] = EEH_Template::display_template( $template, $this->_template_args, TRUE );
170 170
         $this->display_about_admin_page();*/
171 171
 
172
-        // Copied from _whats_new()
173
-        $steps = DbStatus::isOnline() ? $this->_get_started_steps() : false;
174
-        $steps = $steps !== false ? $steps : '';
175
-        $this->_admin_page_title = sprintf(
176
-            esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
177
-            EVENT_ESPRESSO_VERSION
178
-        );
179
-        $settings_message = $steps;
180
-        $this->_template_args['admin_page_subtitle'] = esc_html__(
181
-            'Thank you for choosing Event Espresso, the most powerful, and free, Event Management plugin for WordPress.',
182
-            'event_espresso'
183
-        ) . $settings_message;
184
-        $template = EE_ABOUT_TEMPLATE_PATH . 'ee4-overview.template.php';
185
-        $this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
186
-            $template,
187
-            $this->_template_args,
188
-            true
189
-        );
190
-        $this->display_about_admin_page();
191
-    }
192
-
193
-
194
-    protected function _get_started_steps()
195
-    {
196
-        $steps = '<h2>' . esc_html__('Getting Started', 'event_espresso') . '</h2>';
197
-        $step_one = '<p>'
198
-                    . sprintf(
199
-                        esc_html__(
200
-                            '%sStep 1%s: Visit your %sOrganization Settings%s and add/update your details.',
201
-                            'event_espresso'
202
-                        ),
203
-                        '<strong>',
204
-                        '</strong>',
205
-                        '<a href="admin.php?page=espresso_general_settings">',
206
-                        '</a>'
207
-                    ) . '</strong></p>';
208
-        $step_two = '<p>'
209
-                    . sprintf(
210
-                        esc_html__('%sStep 2%s: Setup your %sPayment Methods%s.', 'event_espresso'),
211
-                        '<strong>',
212
-                        '</strong>',
213
-                        '<a href="admin.php?page=espresso_payment_settings">',
214
-                        '</a>'
215
-                    ) . '</strong></p>';
216
-        $step_three = '<p>'
217
-                      . sprintf(
218
-                          esc_html__('%sStep 3%s: Create your %sFirst Event%s.', 'event_espresso'),
219
-                          '<strong>',
220
-                          '</strong>',
221
-                          '<a href="admin.php?page=espresso_events&action=create_new">',
222
-                          '</a>'
223
-                      ) . '</strong></p>';
224
-
225
-        // done?
226
-        $done_step_one = EE_Registry::instance()->CFG->organization->address_1 == '123 Onna Road' ? false : true;
227
-        $active_invoice_pm = EEM_Payment_Method::instance()->get_one_active(
228
-            EEM_Payment_Method::scope_cart,
229
-            array(array('PMD_type' => 'Invoice'))
230
-        );
231
-        $active_pms_count = EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart);
232
-        // done step two if a non-invoice paymetn method is active; or there is more than one PM active, or
233
-        // if only the invoice is active but it's clearly been updated
234
-        $done_step_two = $active_pms_count > 1 ||
235
-                         ($active_pms_count === 1 && ! $active_invoice_pm) ||
236
-                         ($active_invoice_pm instanceof EE_Payment_Method && (
237
-                                 $active_invoice_pm->get_extra_meta('pdf_payee_name', true, '') ||
238
-                                 $active_invoice_pm->get_extra_meta('pdf_payee_email', true, '') ||
239
-                                 $active_invoice_pm->get_extra_meta('pdf_payee_tax_number', true, '') ||
240
-                                 $active_invoice_pm->get_extra_meta('pdf_payee_address', true, '') ||
241
-                                 $active_invoice_pm->get_extra_meta('page_extra_info', true, '')
242
-                             )
243
-                         );
244
-        $done_step_three = EE_Registry::instance()->load_model('Event')->count() > 0 ? true : false;
245
-
246
-        // if ALL steps are done, let's just return FALSE so we don't display anything
247
-        if ($done_step_one && $done_step_two && $done_step_three) {
248
-            return false;
249
-        }
250
-
251
-        // now let's put it together
252
-        $steps .= sprintf('%s' . $step_one . '%s', $done_step_one ? '<strike>' : '', $done_step_one ? '</strike>' : '');
253
-        $steps .= sprintf('%s' . $step_two . '%s', $done_step_two ? '<strike>' : '', $done_step_two ? '</strike>' : '');
254
-        $steps .= sprintf(
255
-            '%s' . $step_three . '%s',
256
-            $done_step_three ? '<strike>' : '',
257
-            $done_step_three ? '</strike>' : ''
258
-        );
259
-
260
-        return $steps;
261
-    }
262
-
263
-
264
-    protected function _credits()
265
-    {
266
-        $this->_template_args['admin_page_title'] = sprintf(
267
-            esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
268
-            EVENT_ESPRESSO_VERSION
269
-        );
270
-        $this->_template_args['admin_page_subtitle'] = esc_html__(
271
-            'Thank you for choosing Event Espresso Decaf, the most powerful, and free, Event Management plugin for WordPress.',
272
-            'event_espresso'
273
-        );
274
-        $template = EE_ABOUT_TEMPLATE_PATH . 'credits.template.php';
275
-        $this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
276
-            $template,
277
-            $this->_template_args,
278
-            true
279
-        );
280
-        $this->display_about_admin_page();
281
-    }
282
-
283
-
284
-    protected function _decafvpro()
285
-    {
286
-        $this->_template_args['admin_page_title'] = sprintf(
287
-            esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
288
-            EVENT_ESPRESSO_VERSION
289
-        );
290
-        $this->_template_args['admin_page_subtitle'] = sprintf(
291
-            esc_html__(
292
-                'Event Espresso lets you focus on doing %swhat you love%s — %sorganizing your events%s',
293
-                'event_espresso'
294
-            ),
295
-            '<em>',
296
-            '</em>',
297
-            '<strong>',
298
-            '</strong>'
299
-        );
300
-        $template = EE_ABOUT_TEMPLATE_PATH . 'decafvpro.template.php';
301
-        $this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
302
-            $template,
303
-            $this->_template_args,
304
-            true
305
-        );
306
-        $this->display_about_admin_page();
307
-    }
308
-
309
-    protected function _reviews()
310
-    {
311
-        $this->_template_args['admin_page_title'] = esc_html__('Rave Reviews About Event Espresso 4', 'event_espresso');
312
-        $this->_template_args['admin_page_subtitle'] = esc_html__(
313
-            'At Event Espresso, customer satisfaction is our ultimate goal.',
314
-            'event_espresso'
315
-        );
316
-        $template = EE_ABOUT_TEMPLATE_PATH . 'reviews.template.php';
317
-        $this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
318
-            $template,
319
-            $this->_template_args,
320
-            true
321
-        );
322
-        $this->display_about_admin_page();
323
-    }
172
+		// Copied from _whats_new()
173
+		$steps = DbStatus::isOnline() ? $this->_get_started_steps() : false;
174
+		$steps = $steps !== false ? $steps : '';
175
+		$this->_admin_page_title = sprintf(
176
+			esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
177
+			EVENT_ESPRESSO_VERSION
178
+		);
179
+		$settings_message = $steps;
180
+		$this->_template_args['admin_page_subtitle'] = esc_html__(
181
+			'Thank you for choosing Event Espresso, the most powerful, and free, Event Management plugin for WordPress.',
182
+			'event_espresso'
183
+		) . $settings_message;
184
+		$template = EE_ABOUT_TEMPLATE_PATH . 'ee4-overview.template.php';
185
+		$this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
186
+			$template,
187
+			$this->_template_args,
188
+			true
189
+		);
190
+		$this->display_about_admin_page();
191
+	}
192
+
193
+
194
+	protected function _get_started_steps()
195
+	{
196
+		$steps = '<h2>' . esc_html__('Getting Started', 'event_espresso') . '</h2>';
197
+		$step_one = '<p>'
198
+					. sprintf(
199
+						esc_html__(
200
+							'%sStep 1%s: Visit your %sOrganization Settings%s and add/update your details.',
201
+							'event_espresso'
202
+						),
203
+						'<strong>',
204
+						'</strong>',
205
+						'<a href="admin.php?page=espresso_general_settings">',
206
+						'</a>'
207
+					) . '</strong></p>';
208
+		$step_two = '<p>'
209
+					. sprintf(
210
+						esc_html__('%sStep 2%s: Setup your %sPayment Methods%s.', 'event_espresso'),
211
+						'<strong>',
212
+						'</strong>',
213
+						'<a href="admin.php?page=espresso_payment_settings">',
214
+						'</a>'
215
+					) . '</strong></p>';
216
+		$step_three = '<p>'
217
+					  . sprintf(
218
+						  esc_html__('%sStep 3%s: Create your %sFirst Event%s.', 'event_espresso'),
219
+						  '<strong>',
220
+						  '</strong>',
221
+						  '<a href="admin.php?page=espresso_events&action=create_new">',
222
+						  '</a>'
223
+					  ) . '</strong></p>';
224
+
225
+		// done?
226
+		$done_step_one = EE_Registry::instance()->CFG->organization->address_1 == '123 Onna Road' ? false : true;
227
+		$active_invoice_pm = EEM_Payment_Method::instance()->get_one_active(
228
+			EEM_Payment_Method::scope_cart,
229
+			array(array('PMD_type' => 'Invoice'))
230
+		);
231
+		$active_pms_count = EEM_Payment_Method::instance()->count_active(EEM_Payment_Method::scope_cart);
232
+		// done step two if a non-invoice paymetn method is active; or there is more than one PM active, or
233
+		// if only the invoice is active but it's clearly been updated
234
+		$done_step_two = $active_pms_count > 1 ||
235
+						 ($active_pms_count === 1 && ! $active_invoice_pm) ||
236
+						 ($active_invoice_pm instanceof EE_Payment_Method && (
237
+								 $active_invoice_pm->get_extra_meta('pdf_payee_name', true, '') ||
238
+								 $active_invoice_pm->get_extra_meta('pdf_payee_email', true, '') ||
239
+								 $active_invoice_pm->get_extra_meta('pdf_payee_tax_number', true, '') ||
240
+								 $active_invoice_pm->get_extra_meta('pdf_payee_address', true, '') ||
241
+								 $active_invoice_pm->get_extra_meta('page_extra_info', true, '')
242
+							 )
243
+						 );
244
+		$done_step_three = EE_Registry::instance()->load_model('Event')->count() > 0 ? true : false;
245
+
246
+		// if ALL steps are done, let's just return FALSE so we don't display anything
247
+		if ($done_step_one && $done_step_two && $done_step_three) {
248
+			return false;
249
+		}
250
+
251
+		// now let's put it together
252
+		$steps .= sprintf('%s' . $step_one . '%s', $done_step_one ? '<strike>' : '', $done_step_one ? '</strike>' : '');
253
+		$steps .= sprintf('%s' . $step_two . '%s', $done_step_two ? '<strike>' : '', $done_step_two ? '</strike>' : '');
254
+		$steps .= sprintf(
255
+			'%s' . $step_three . '%s',
256
+			$done_step_three ? '<strike>' : '',
257
+			$done_step_three ? '</strike>' : ''
258
+		);
259
+
260
+		return $steps;
261
+	}
262
+
263
+
264
+	protected function _credits()
265
+	{
266
+		$this->_template_args['admin_page_title'] = sprintf(
267
+			esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
268
+			EVENT_ESPRESSO_VERSION
269
+		);
270
+		$this->_template_args['admin_page_subtitle'] = esc_html__(
271
+			'Thank you for choosing Event Espresso Decaf, the most powerful, and free, Event Management plugin for WordPress.',
272
+			'event_espresso'
273
+		);
274
+		$template = EE_ABOUT_TEMPLATE_PATH . 'credits.template.php';
275
+		$this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
276
+			$template,
277
+			$this->_template_args,
278
+			true
279
+		);
280
+		$this->display_about_admin_page();
281
+	}
282
+
283
+
284
+	protected function _decafvpro()
285
+	{
286
+		$this->_template_args['admin_page_title'] = sprintf(
287
+			esc_html__('Welcome to Event Espresso %s', 'event_espresso'),
288
+			EVENT_ESPRESSO_VERSION
289
+		);
290
+		$this->_template_args['admin_page_subtitle'] = sprintf(
291
+			esc_html__(
292
+				'Event Espresso lets you focus on doing %swhat you love%s — %sorganizing your events%s',
293
+				'event_espresso'
294
+			),
295
+			'<em>',
296
+			'</em>',
297
+			'<strong>',
298
+			'</strong>'
299
+		);
300
+		$template = EE_ABOUT_TEMPLATE_PATH . 'decafvpro.template.php';
301
+		$this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
302
+			$template,
303
+			$this->_template_args,
304
+			true
305
+		);
306
+		$this->display_about_admin_page();
307
+	}
308
+
309
+	protected function _reviews()
310
+	{
311
+		$this->_template_args['admin_page_title'] = esc_html__('Rave Reviews About Event Espresso 4', 'event_espresso');
312
+		$this->_template_args['admin_page_subtitle'] = esc_html__(
313
+			'At Event Espresso, customer satisfaction is our ultimate goal.',
314
+			'event_espresso'
315
+		);
316
+		$template = EE_ABOUT_TEMPLATE_PATH . 'reviews.template.php';
317
+		$this->_template_args['about_admin_page_content'] = EEH_Template::display_template(
318
+			$template,
319
+			$this->_template_args,
320
+			true
321
+		);
322
+		$this->display_about_admin_page();
323
+	}
324 324
 }
Please login to merge, or discard this patch.
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +741 added lines, -741 removed lines patch added patch discarded remove patch
@@ -17,692 +17,692 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class Registration_Form_Admin_Page extends EE_Admin_Page
19 19
 {
20
-    /**
21
-     * holds the specific question object for the question details screen
22
-     */
23
-    protected ?EE_Question $_question = null;
24
-
25
-    /**
26
-     * holds the specific question group object for the question group details screen
27
-     */
28
-    protected ?EE_Question_Group $_question_group = null;
29
-
30
-    protected EEM_Question $_question_model;
31
-
32
-    protected EEM_Question_Group $_question_group_model;
33
-
34
-
35
-    /**
36
-     * @Constructor
37
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
38
-     * @throws EE_Error
39
-     * @throws ReflectionException
40
-     */
41
-    public function __construct($routing = true)
42
-    {
43
-        require_once(EE_MODELS . 'EEM_Question.model.php');
44
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
45
-        $this->_question_model       = EEM_Question::instance();
46
-        $this->_question_group_model = EEM_Question_Group::instance();
47
-        parent::__construct($routing);
48
-    }
49
-
50
-
51
-    protected function _init_page_props()
52
-    {
53
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
54
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
55
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
56
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
57
-    }
58
-
59
-
60
-    protected function _ajax_hooks()
61
-    {
62
-    }
63
-
64
-
65
-    protected function _define_page_props()
66
-    {
67
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
68
-        $this->_labels           = [
69
-            'buttons'    => [
70
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
71
-            ],
72
-            'publishbox' => [
73
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
74
-            ],
75
-        ];
76
-    }
77
-
78
-
79
-    /**
80
-     *_set_page_routes
81
-     */
82
-    protected function _set_page_routes()
83
-    {
84
-        $qst_id             =
85
-            ! empty($this->_req_data['QST_ID'])
86
-                ? $this->_req_data['QST_ID']
87
-                : 0;
88
-        $this->_page_routes = [
89
-            'default' => [
90
-                'func'       => [$this, '_questions_overview_list_table'],
91
-                'capability' => 'ee_read_questions',
92
-            ],
93
-
94
-            'edit_question' => [
95
-                'func'       => [$this, '_edit_question'],
96
-                'capability' => 'ee_edit_question',
97
-                'obj_id'     => $qst_id,
98
-                'args'       => ['edit'],
99
-            ],
100
-
101
-            'question_groups' => [
102
-                'func'       => [$this, '_questions_groups_preview'],
103
-                'capability' => 'ee_read_question_groups',
104
-            ],
105
-
106
-            'update_question' => [
107
-                'func'       => [$this, '_insert_or_update_question'],
108
-                'args'       => ['new_question' => false],
109
-                'capability' => 'ee_edit_question',
110
-                'obj_id'     => $qst_id,
111
-                'noheader'   => true,
112
-            ],
113
-        ];
114
-    }
115
-
116
-
117
-    protected function _set_page_config()
118
-    {
119
-        $this->_page_config = [
120
-            'default' => [
121
-                'nav'           => [
122
-                    'label' => esc_html__('Questions', 'event_espresso'),
123
-                    'icon'  => 'dashicons-editor-help',
124
-                    'order' => 10,
125
-                ],
126
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
127
-                'metaboxes'     => $this->_default_espresso_metaboxes,
128
-                'help_tabs'     => [
129
-                    'registration_form_questions_overview_help_tab'                           => [
130
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
131
-                        'filename' => 'registration_form_questions_overview',
132
-                    ],
133
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => [
134
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
135
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
136
-                    ],
137
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
138
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
139
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
140
-                    ],
141
-                ],
142
-                'require_nonce' => false,
143
-            ],
144
-
145
-            'question_groups' => [
146
-                'nav'           => [
147
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
148
-                    'icon'  => 'dashicons-forms',
149
-                    'order' => 20,
150
-                ],
151
-                'metaboxes'     => $this->_default_espresso_metaboxes,
152
-                'help_tabs'     => [
153
-                    'registration_form_question_groups_help_tab' => [
154
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
155
-                        'filename' => 'registration_form_question_groups',
156
-                    ],
157
-                ],
158
-                'require_nonce' => false,
159
-            ],
160
-
161
-            'edit_question' => [
162
-                'nav'           => [
163
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
164
-                    'icon'       => 'dashicons-edit-large',
165
-                    'order'      => 15,
166
-                    'persistent' => false,
167
-                    'url'        => isset($this->_req_data['question_id'])
168
-                        ? add_query_arg(
169
-                            ['question_id' => $this->_req_data['question_id']],
170
-                            $this->_current_page_view_url
171
-                        )
172
-                        : $this->_admin_base_url,
173
-                ],
174
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
175
-                'help_tabs'     => [
176
-                    'registration_form_edit_question_group_help_tab' => [
177
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
178
-                        'filename' => 'registration_form_edit_question',
179
-                    ],
180
-                ],
181
-                'require_nonce' => false,
182
-            ],
183
-        ];
184
-    }
185
-
186
-
187
-    protected function _add_screen_options()
188
-    {
189
-        // todo
190
-    }
191
-
192
-
193
-    protected function _add_screen_options_default()
194
-    {
195
-        $page_title              = $this->_admin_page_title;
196
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
197
-        $this->_per_page_screen_option();
198
-        $this->_admin_page_title = $page_title;
199
-    }
200
-
201
-
202
-    protected function _add_screen_options_question_groups()
203
-    {
204
-        $page_title              = $this->_admin_page_title;
205
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
206
-        $this->_per_page_screen_option();
207
-        $this->_admin_page_title = $page_title;
208
-    }
209
-
210
-
211
-    // none of the below group are currently used for Event Categories
212
-    protected function _add_feature_pointers()
213
-    {
214
-    }
215
-
216
-
217
-    public function load_scripts_styles()
218
-    {
219
-        wp_register_style(
220
-            'espresso_registration',
221
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
222
-            [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223
-            EVENT_ESPRESSO_VERSION
224
-        );
225
-        wp_enqueue_style('espresso_registration');
226
-    }
227
-
228
-
229
-    public function admin_init()
230
-    {
231
-    }
232
-
233
-
234
-    public function admin_notices()
235
-    {
236
-    }
237
-
238
-
239
-    public function admin_footer_scripts()
240
-    {
241
-    }
242
-
243
-
244
-    public function load_scripts_styles_default()
245
-    {
246
-    }
247
-
248
-
249
-    public function load_scripts_styles_add_question()
250
-    {
251
-        $this->load_scripts_styles_question_details();
252
-    }
253
-
254
-
255
-    public function load_scripts_styles_edit_question()
256
-    {
257
-        $this->load_scripts_styles_question_details();
258
-    }
259
-
260
-
261
-    /**
262
-     * Loads the JS required for adding or editing a question
263
-     */
264
-    protected function load_scripts_styles_question_details()
265
-    {
266
-        $this->load_scripts_styles_forms();
267
-        wp_register_script(
268
-            'espresso_registration_form_single',
269
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
270
-            ['jquery-ui-sortable'],
271
-            EVENT_ESPRESSO_VERSION,
272
-            true
273
-        );
274
-        wp_enqueue_script('espresso_registration_form_single');
275
-        wp_localize_script(
276
-            'espresso_registration_form_single',
277
-            'ee_question_data',
278
-            [
279
-                'question_types_with_max'    => $this->_question_model->questionTypesWithMaxLength(),
280
-                'question_type_with_options' => $this->_question_model->question_types_with_options(),
281
-            ]
282
-        );
283
-    }
284
-
285
-
286
-    public function recaptcha_info_help_tab()
287
-    {
288
-        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
289
-    }
290
-
291
-
292
-    public function load_scripts_styles_forms()
293
-    {
294
-        // styles
295
-        wp_enqueue_style('espresso-ui-theme');
296
-        // scripts
297
-        wp_enqueue_script('ee_admin_js');
298
-    }
299
-
300
-
301
-    protected function _set_list_table_views_default()
302
-    {
303
-        $this->_views = [
304
-            'all' => [
305
-                'slug'  => 'all',
306
-                'label' => esc_html__('View All Questions', 'event_espresso'),
307
-                'count' => 0,
308
-            ],
309
-        ];
310
-
311
-        if (
312
-            $this->capabilities->current_user_can(
313
-                'ee_delete_questions',
314
-                'espresso_registration_form_trash_questions'
315
-            )
316
-        ) {
317
-            $this->_views['trash'] = [
318
-                'slug'  => 'trash',
319
-                'label' => esc_html__('Trash', 'event_espresso'),
320
-                'count' => 0,
321
-            ];
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     * This just previews the question groups tab that comes in caffeinated.
328
-     *
329
-     * @return void html
330
-     * @throws EE_Error
331
-     */
332
-    protected function _questions_groups_preview()
333
-    {
334
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335
-        $this->_template_args['preview_img']  =
336
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
337
-            . esc_attr__(
338
-                'Preview Question Groups Overview List Table screenshot',
339
-                'event_espresso'
340
-            ) . '" />';
341
-        $this->_template_args['preview_text'] = '<strong>'
342
-            . esc_html__(
343
-                'Question Groups 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. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344
-                'event_espresso'
345
-            ) . '</strong>';
346
-        $this->display_admin_caf_preview_page('question_groups_tab');
347
-    }
348
-
349
-
350
-    /**
351
-     * Extracts the question field's values from the POST request to update or insert them
352
-     *
353
-     * @param EEM_Base $model
354
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
355
-     * @throws EE_Error
356
-     * @throws ReflectionException
357
-     */
358
-    protected function _set_column_values_for(EEM_Base $model): array
359
-    {
360
-        $column_values = [];
361
-        // some initial checks for proper values.
362
-        $QST_ID = $this->request->getRequestParam('QST_ID', 0, DataType::INT);
363
-        // if QST_admin_only, then no matter what QST_required is we disable.
364
-        $QST_admin_only = $this->request->getRequestParam('QST_admin_only', false, DataType::BOOL);
365
-        if ($QST_admin_only) {
366
-            $this->request->setRequestParam('QST_required', false);
367
-        }
368
-        // if the question shouldn't have a max length, don't let them set one
369
-        if (
370
-            ! (
371
-                $this->request->requestParamIsSet('QST_type')
372
-                && $this->request->requestParamIsSet('QST_max')
373
-            ) || ! in_array(
374
-                $this->request->getRequestParam('QST_type', '', DataType::STRING),
375
-                $this->_question_model->questionTypesWithMaxLength(),
376
-                true
377
-            )
378
-        ) {
379
-            // they're not allowed to set the max
380
-            $this->request->unSetRequestParam('QST_max', true);
381
-        }
382
-        foreach ($model->field_settings() as $fieldName => $settings) {
383
-            switch($fieldName) {
384
-                case 'QSG_identifier':
385
-                    // basically if QSG_identifier is empty or not set
386
-                    if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387
-                        $QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
-                        $column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
389
-                    }
390
-                    break;
391
-
392
-                case 'QST_admin_label':
393
-                    if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394
-                        // the admin label is blank, use a slug version of the question text
395
-                        $QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
-                        $column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
397
-                    }
398
-                    break;
399
-
400
-                case 'QST_admin_only':
401
-                    if (! $QST_admin_only) {
402
-                        $column_values[ $fieldName ] = false;
403
-                    }
404
-                    break;
405
-
406
-                case 'QST_max':
407
-                    $qst_system = $this->_question_model->get_var(
408
-                        [ [ 'QST_ID' => $QST_ID ] ],
409
-                        'QST_system'
410
-                    );
411
-
412
-                    $max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
413
-                    $QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
414
-                    if ($QST_max === 0 || $QST_max > $max_max) {
415
-                        $column_values[ $fieldName ] = $max_max;
416
-                    }
417
-                    break;
418
-
419
-                default:
420
-                    // only add a property to the array if it's not null (otherwise the model should just use the default value)
421
-                    if ($this->request->requestParamIsSet($fieldName)) {
422
-                        // convert the schema type to the appropriate data type
423
-                        $schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
424
-                        $column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
425
-                    }
426
-            }
427
-        }
428
-        // validation for this data to be performed by the model before insertion.
429
-        return $column_values;
430
-    }
431
-
432
-
433
-    /**
434
-     *_questions_overview_list_table
435
-     *
436
-     * @throws EE_Error
437
-     */
438
-    protected function _questions_overview_list_table()
439
-    {
440
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
441
-        $this->display_admin_list_table_page_with_sidebar();
442
-    }
443
-
444
-
445
-    /**
446
-     * _edit_question
447
-     *
448
-     * @throws EE_Error
449
-     * @throws ReflectionException
450
-     */
451
-    protected function _edit_question()
452
-    {
453
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
454
-            ? absint($this->_req_data['QST_ID'])
455
-            : false;
456
-
457
-        switch ($this->_req_action) {
458
-            case 'add_question':
459
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
460
-                break;
461
-            case 'edit_question':
462
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
463
-                break;
464
-            default:
465
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
466
-        }
467
-
468
-        // add PRC_ID to title if editing
469
-        $this->_admin_page_title =
470
-            $ID
471
-                ? $this->_admin_page_title . ' # ' . $ID
472
-                : $this->_admin_page_title;
473
-        if ($ID) {
474
-            $question                 = $this->_question_model->get_one_by_ID($ID);
475
-            $additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
476
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
477
-        } else {
478
-            $question = EE_Question::new_instance();
479
-            $question->set_order_to_latest();
480
-            $this->_set_add_edit_form_tags('insert_question');
481
-        }
482
-        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
483
-            $question_types = array_intersect_key(
484
-                $this->_question_model->allowed_question_types(),
485
-                array_flip(
486
-                    [
487
-                        EEM_Question::QST_type_text,
488
-                        EEM_Question::QST_type_us_phone,
489
-                    ]
490
-                )
491
-            );
492
-        } else {
493
-            $question_types = $question->has_answers()
494
-                ? $this->_question_model->question_types_in_same_category($question->type())
495
-                : $this->_question_model->allowed_question_types();
496
-        }
497
-        $this->_template_args['QST_ID']                     = $ID;
498
-        $this->_template_args['question']                   = $question;
499
-        $this->_template_args['question_types']             = $question_types;
500
-        $this->_template_args['max_max']                    =
501
-            $this->_question_model->absolute_max_for_system_question(
502
-                $question->system_ID()
503
-            );
504
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
505
-        $this->_set_publish_post_box_vars('id', $ID);
506
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
507
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
508
-            $this->_template_args,
509
-            true
510
-        );
511
-
512
-        // the details template wrapper
513
-        $this->display_admin_page_with_sidebar();
514
-    }
515
-
516
-
517
-    /**
518
-     * @return string
519
-     * @throws EE_Error
520
-     * @throws ReflectionException
521
-     */
522
-    protected function _get_question_type_descriptions(): string
523
-    {
524
-        EE_Registry::instance()->load_helper('HTML');
525
-        $descriptions               = '';
526
-        $question_type_descriptions = $this->_question_model->question_descriptions();
527
-        foreach ($question_type_descriptions as $type => $question_type_description) {
528
-            if ($type == 'HTML_TEXTAREA') {
529
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
530
-                $question_type_description .= sprintf(
531
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
532
-                    '<br/>',
533
-                    $html->get_list_of_allowed_tags()
534
-                );
535
-            }
536
-            $descriptions .= EEH_HTML::p(
537
-                $question_type_description,
538
-                'question_type_description-' . $type,
539
-                'question_type_description description',
540
-                'display:none;'
541
-            );
542
-        }
543
-        return $descriptions;
544
-    }
545
-
546
-
547
-    /**
548
-     * @param bool $new_question
549
-     * @throws EE_Error
550
-     * @throws ReflectionException
551
-     */
552
-    protected function _insert_or_update_question(bool $new_question = true)
553
-    {
554
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
555
-        if ($new_question) {
556
-            $question    = EE_Question::new_instance($set_column_values);
557
-            $action_desc = 'added';
558
-        } else {
559
-            $question = $this->_question_model->get_one_by_ID(
560
-                $this->request->getRequestParam('QST_ID', 0, DataType::INT)
561
-            );
562
-            foreach ($set_column_values as $field => $new_value) {
563
-                $question->set($field, $new_value);
564
-            }
565
-            $action_desc = 'updated';
566
-        }
567
-        $success = $question->save();
568
-        $ID      = $question->ID();
569
-        if ($ID && $question->should_have_question_options()) {
570
-            // save the related options
571
-            // trash removed options, save old ones
572
-            // get list of all options
573
-            $options          = $question->options();
574
-            $question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
575
-            $QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
576
-            if (! empty($options)) {
577
-                foreach ($options as $option_ID => $option) {
578
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
579
-                    if ($option_req_index !== false) {
580
-                        $question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
581
-                        $option->save($question_options[ $option_req_index ]);
582
-                    } else {
583
-                        // not found, remove it
584
-                        $option->delete();
585
-                    }
586
-                }
587
-            }
588
-            // save new related options
589
-            foreach ($question_options as $index => $option_req_data) {
590
-                // skip $index that is from our sample
591
-                if ($index === 'xxcountxx') {
592
-                    continue;
593
-                }
594
-                // note we allow saving blank options.
595
-                if (empty($option_req_data['QSO_ID'])) {
596
-                    // no ID! save it!
597
-                    $new_option = EE_Question_Option::new_instance(
598
-                        [
599
-                            'QSO_value'   => $option_req_data['QSO_value'],
600
-                            'QSO_desc'    => $option_req_data['QSO_desc'],
601
-                            'QSO_default' => $index === $QSO_default,
602
-                            'QSO_order'   => $option_req_data['QSO_order'],
603
-                            'QST_ID'      => $question->ID(),
604
-                        ]
605
-                    );
606
-                    $new_option->save();
607
-                }
608
-            }
609
-        }
610
-
611
-        $success = apply_filters(
612
-            'FHEE__Registration_Form_Admin_Page___insert_or_update_question__success',
613
-            (int) $success,
614
-            $question,
615
-            $this
616
-        );
617
-
618
-        $query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
619
-        if ($success !== 0) {
620
-            $msg = $new_question
621
-                ? sprintf(
622
-                    esc_html__('The %s has been created', 'event_espresso'),
623
-                    $this->_question_model->item_name()
624
-                )
625
-                : sprintf(
626
-                    esc_html__('The %s has been updated', 'event_espresso'),
627
-                    $this->_question_model->item_name()
628
-                );
629
-            EE_Error::add_success($msg);
630
-        }
631
-
632
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
633
-    }
634
-
635
-
636
-    /**
637
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
638
-     * by ID
639
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
640
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
641
-     *
642
-     * @param int $ID of the question option to find
643
-     * @return int index in question_options array if successful, FALSE if unsuccessful
644
-     */
645
-    protected function _get_option_req_data_index(int $ID)
646
-    {
647
-        $req_data_for_question_options = $this->_req_data['question_options'];
648
-        foreach ($req_data_for_question_options as $num => $option_data) {
649
-            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
650
-                return $num;
651
-            }
652
-        }
653
-        return false;
654
-    }
655
-
656
-
657
-
658
-
659
-    /* QUERIES */
660
-    /**
661
-     * For internal use in getting all the query parameters
662
-     * (because it's pretty well the same between question, question groups,
663
-     * and for both when searching for trashed and untrashed ones)
664
-     *
665
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
666
-     * @param int      $per_page
667
-     * @param int      $current_page
668
-     * @return array model query params,
669
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
670
-     */
671
-    protected function get_query_params(EEM_Base $model, int $per_page = 10, int $current_page = 10): array
672
-    {
673
-        $query_params             = [];
674
-        $offset                   = ($current_page - 1) * $per_page;
675
-        $query_params['limit']    = [$offset, $per_page];
676
-
677
-        $order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
678
-            ? $this->_req_data['order']
679
-            : 'ASC';
680
-
681
-        $orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
682
-
683
-        $field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
684
-
685
-        $query_params['order_by'] = [$field_to_order_by => $order];
686
-
687
-        $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
688
-        if (! empty($search_string)) {
689
-            if ($model instanceof EEM_Question_Group) {
690
-                $query_params[0] = [
691
-                    'OR' => [
692
-                        'QSG_name' => ['LIKE', "%$search_string%"],
693
-                        'QSG_desc' => ['LIKE', "%$search_string%"],
694
-                    ],
695
-                ];
696
-            } else {
697
-                $query_params[0] = [
698
-                    'QST_display_text' => ['LIKE', "%$search_string%"],
699
-                ];
700
-            }
701
-        }
702
-
703
-        // capability checks (just leaving this commented out for reference because
704
-        // it illustrates some complicated query params that could be useful when fully implemented)
705
-        /*if ( $model instanceof EEM_Question_Group ) {
20
+	/**
21
+	 * holds the specific question object for the question details screen
22
+	 */
23
+	protected ?EE_Question $_question = null;
24
+
25
+	/**
26
+	 * holds the specific question group object for the question group details screen
27
+	 */
28
+	protected ?EE_Question_Group $_question_group = null;
29
+
30
+	protected EEM_Question $_question_model;
31
+
32
+	protected EEM_Question_Group $_question_group_model;
33
+
34
+
35
+	/**
36
+	 * @Constructor
37
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
38
+	 * @throws EE_Error
39
+	 * @throws ReflectionException
40
+	 */
41
+	public function __construct($routing = true)
42
+	{
43
+		require_once(EE_MODELS . 'EEM_Question.model.php');
44
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
45
+		$this->_question_model       = EEM_Question::instance();
46
+		$this->_question_group_model = EEM_Question_Group::instance();
47
+		parent::__construct($routing);
48
+	}
49
+
50
+
51
+	protected function _init_page_props()
52
+	{
53
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
54
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
55
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
56
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
57
+	}
58
+
59
+
60
+	protected function _ajax_hooks()
61
+	{
62
+	}
63
+
64
+
65
+	protected function _define_page_props()
66
+	{
67
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
68
+		$this->_labels           = [
69
+			'buttons'    => [
70
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
71
+			],
72
+			'publishbox' => [
73
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
74
+			],
75
+		];
76
+	}
77
+
78
+
79
+	/**
80
+	 *_set_page_routes
81
+	 */
82
+	protected function _set_page_routes()
83
+	{
84
+		$qst_id             =
85
+			! empty($this->_req_data['QST_ID'])
86
+				? $this->_req_data['QST_ID']
87
+				: 0;
88
+		$this->_page_routes = [
89
+			'default' => [
90
+				'func'       => [$this, '_questions_overview_list_table'],
91
+				'capability' => 'ee_read_questions',
92
+			],
93
+
94
+			'edit_question' => [
95
+				'func'       => [$this, '_edit_question'],
96
+				'capability' => 'ee_edit_question',
97
+				'obj_id'     => $qst_id,
98
+				'args'       => ['edit'],
99
+			],
100
+
101
+			'question_groups' => [
102
+				'func'       => [$this, '_questions_groups_preview'],
103
+				'capability' => 'ee_read_question_groups',
104
+			],
105
+
106
+			'update_question' => [
107
+				'func'       => [$this, '_insert_or_update_question'],
108
+				'args'       => ['new_question' => false],
109
+				'capability' => 'ee_edit_question',
110
+				'obj_id'     => $qst_id,
111
+				'noheader'   => true,
112
+			],
113
+		];
114
+	}
115
+
116
+
117
+	protected function _set_page_config()
118
+	{
119
+		$this->_page_config = [
120
+			'default' => [
121
+				'nav'           => [
122
+					'label' => esc_html__('Questions', 'event_espresso'),
123
+					'icon'  => 'dashicons-editor-help',
124
+					'order' => 10,
125
+				],
126
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
127
+				'metaboxes'     => $this->_default_espresso_metaboxes,
128
+				'help_tabs'     => [
129
+					'registration_form_questions_overview_help_tab'                           => [
130
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
131
+						'filename' => 'registration_form_questions_overview',
132
+					],
133
+					'registration_form_questions_overview_table_column_headings_help_tab'     => [
134
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
135
+						'filename' => 'registration_form_questions_overview_table_column_headings',
136
+					],
137
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
138
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
139
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
140
+					],
141
+				],
142
+				'require_nonce' => false,
143
+			],
144
+
145
+			'question_groups' => [
146
+				'nav'           => [
147
+					'label' => esc_html__('Question Groups', 'event_espresso'),
148
+					'icon'  => 'dashicons-forms',
149
+					'order' => 20,
150
+				],
151
+				'metaboxes'     => $this->_default_espresso_metaboxes,
152
+				'help_tabs'     => [
153
+					'registration_form_question_groups_help_tab' => [
154
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
155
+						'filename' => 'registration_form_question_groups',
156
+					],
157
+				],
158
+				'require_nonce' => false,
159
+			],
160
+
161
+			'edit_question' => [
162
+				'nav'           => [
163
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
164
+					'icon'       => 'dashicons-edit-large',
165
+					'order'      => 15,
166
+					'persistent' => false,
167
+					'url'        => isset($this->_req_data['question_id'])
168
+						? add_query_arg(
169
+							['question_id' => $this->_req_data['question_id']],
170
+							$this->_current_page_view_url
171
+						)
172
+						: $this->_admin_base_url,
173
+				],
174
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
175
+				'help_tabs'     => [
176
+					'registration_form_edit_question_group_help_tab' => [
177
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
178
+						'filename' => 'registration_form_edit_question',
179
+					],
180
+				],
181
+				'require_nonce' => false,
182
+			],
183
+		];
184
+	}
185
+
186
+
187
+	protected function _add_screen_options()
188
+	{
189
+		// todo
190
+	}
191
+
192
+
193
+	protected function _add_screen_options_default()
194
+	{
195
+		$page_title              = $this->_admin_page_title;
196
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
197
+		$this->_per_page_screen_option();
198
+		$this->_admin_page_title = $page_title;
199
+	}
200
+
201
+
202
+	protected function _add_screen_options_question_groups()
203
+	{
204
+		$page_title              = $this->_admin_page_title;
205
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
206
+		$this->_per_page_screen_option();
207
+		$this->_admin_page_title = $page_title;
208
+	}
209
+
210
+
211
+	// none of the below group are currently used for Event Categories
212
+	protected function _add_feature_pointers()
213
+	{
214
+	}
215
+
216
+
217
+	public function load_scripts_styles()
218
+	{
219
+		wp_register_style(
220
+			'espresso_registration',
221
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
222
+			[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223
+			EVENT_ESPRESSO_VERSION
224
+		);
225
+		wp_enqueue_style('espresso_registration');
226
+	}
227
+
228
+
229
+	public function admin_init()
230
+	{
231
+	}
232
+
233
+
234
+	public function admin_notices()
235
+	{
236
+	}
237
+
238
+
239
+	public function admin_footer_scripts()
240
+	{
241
+	}
242
+
243
+
244
+	public function load_scripts_styles_default()
245
+	{
246
+	}
247
+
248
+
249
+	public function load_scripts_styles_add_question()
250
+	{
251
+		$this->load_scripts_styles_question_details();
252
+	}
253
+
254
+
255
+	public function load_scripts_styles_edit_question()
256
+	{
257
+		$this->load_scripts_styles_question_details();
258
+	}
259
+
260
+
261
+	/**
262
+	 * Loads the JS required for adding or editing a question
263
+	 */
264
+	protected function load_scripts_styles_question_details()
265
+	{
266
+		$this->load_scripts_styles_forms();
267
+		wp_register_script(
268
+			'espresso_registration_form_single',
269
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
270
+			['jquery-ui-sortable'],
271
+			EVENT_ESPRESSO_VERSION,
272
+			true
273
+		);
274
+		wp_enqueue_script('espresso_registration_form_single');
275
+		wp_localize_script(
276
+			'espresso_registration_form_single',
277
+			'ee_question_data',
278
+			[
279
+				'question_types_with_max'    => $this->_question_model->questionTypesWithMaxLength(),
280
+				'question_type_with_options' => $this->_question_model->question_types_with_options(),
281
+			]
282
+		);
283
+	}
284
+
285
+
286
+	public function recaptcha_info_help_tab()
287
+	{
288
+		EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
289
+	}
290
+
291
+
292
+	public function load_scripts_styles_forms()
293
+	{
294
+		// styles
295
+		wp_enqueue_style('espresso-ui-theme');
296
+		// scripts
297
+		wp_enqueue_script('ee_admin_js');
298
+	}
299
+
300
+
301
+	protected function _set_list_table_views_default()
302
+	{
303
+		$this->_views = [
304
+			'all' => [
305
+				'slug'  => 'all',
306
+				'label' => esc_html__('View All Questions', 'event_espresso'),
307
+				'count' => 0,
308
+			],
309
+		];
310
+
311
+		if (
312
+			$this->capabilities->current_user_can(
313
+				'ee_delete_questions',
314
+				'espresso_registration_form_trash_questions'
315
+			)
316
+		) {
317
+			$this->_views['trash'] = [
318
+				'slug'  => 'trash',
319
+				'label' => esc_html__('Trash', 'event_espresso'),
320
+				'count' => 0,
321
+			];
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 * This just previews the question groups tab that comes in caffeinated.
328
+	 *
329
+	 * @return void html
330
+	 * @throws EE_Error
331
+	 */
332
+	protected function _questions_groups_preview()
333
+	{
334
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335
+		$this->_template_args['preview_img']  =
336
+			'<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
337
+			. esc_attr__(
338
+				'Preview Question Groups Overview List Table screenshot',
339
+				'event_espresso'
340
+			) . '" />';
341
+		$this->_template_args['preview_text'] = '<strong>'
342
+			. esc_html__(
343
+				'Question Groups 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. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344
+				'event_espresso'
345
+			) . '</strong>';
346
+		$this->display_admin_caf_preview_page('question_groups_tab');
347
+	}
348
+
349
+
350
+	/**
351
+	 * Extracts the question field's values from the POST request to update or insert them
352
+	 *
353
+	 * @param EEM_Base $model
354
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
355
+	 * @throws EE_Error
356
+	 * @throws ReflectionException
357
+	 */
358
+	protected function _set_column_values_for(EEM_Base $model): array
359
+	{
360
+		$column_values = [];
361
+		// some initial checks for proper values.
362
+		$QST_ID = $this->request->getRequestParam('QST_ID', 0, DataType::INT);
363
+		// if QST_admin_only, then no matter what QST_required is we disable.
364
+		$QST_admin_only = $this->request->getRequestParam('QST_admin_only', false, DataType::BOOL);
365
+		if ($QST_admin_only) {
366
+			$this->request->setRequestParam('QST_required', false);
367
+		}
368
+		// if the question shouldn't have a max length, don't let them set one
369
+		if (
370
+			! (
371
+				$this->request->requestParamIsSet('QST_type')
372
+				&& $this->request->requestParamIsSet('QST_max')
373
+			) || ! in_array(
374
+				$this->request->getRequestParam('QST_type', '', DataType::STRING),
375
+				$this->_question_model->questionTypesWithMaxLength(),
376
+				true
377
+			)
378
+		) {
379
+			// they're not allowed to set the max
380
+			$this->request->unSetRequestParam('QST_max', true);
381
+		}
382
+		foreach ($model->field_settings() as $fieldName => $settings) {
383
+			switch($fieldName) {
384
+				case 'QSG_identifier':
385
+					// basically if QSG_identifier is empty or not set
386
+					if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387
+						$QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
+						$column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
389
+					}
390
+					break;
391
+
392
+				case 'QST_admin_label':
393
+					if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394
+						// the admin label is blank, use a slug version of the question text
395
+						$QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
+						$column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
397
+					}
398
+					break;
399
+
400
+				case 'QST_admin_only':
401
+					if (! $QST_admin_only) {
402
+						$column_values[ $fieldName ] = false;
403
+					}
404
+					break;
405
+
406
+				case 'QST_max':
407
+					$qst_system = $this->_question_model->get_var(
408
+						[ [ 'QST_ID' => $QST_ID ] ],
409
+						'QST_system'
410
+					);
411
+
412
+					$max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
413
+					$QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
414
+					if ($QST_max === 0 || $QST_max > $max_max) {
415
+						$column_values[ $fieldName ] = $max_max;
416
+					}
417
+					break;
418
+
419
+				default:
420
+					// only add a property to the array if it's not null (otherwise the model should just use the default value)
421
+					if ($this->request->requestParamIsSet($fieldName)) {
422
+						// convert the schema type to the appropriate data type
423
+						$schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
424
+						$column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
425
+					}
426
+			}
427
+		}
428
+		// validation for this data to be performed by the model before insertion.
429
+		return $column_values;
430
+	}
431
+
432
+
433
+	/**
434
+	 *_questions_overview_list_table
435
+	 *
436
+	 * @throws EE_Error
437
+	 */
438
+	protected function _questions_overview_list_table()
439
+	{
440
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
441
+		$this->display_admin_list_table_page_with_sidebar();
442
+	}
443
+
444
+
445
+	/**
446
+	 * _edit_question
447
+	 *
448
+	 * @throws EE_Error
449
+	 * @throws ReflectionException
450
+	 */
451
+	protected function _edit_question()
452
+	{
453
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
454
+			? absint($this->_req_data['QST_ID'])
455
+			: false;
456
+
457
+		switch ($this->_req_action) {
458
+			case 'add_question':
459
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
460
+				break;
461
+			case 'edit_question':
462
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
463
+				break;
464
+			default:
465
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
466
+		}
467
+
468
+		// add PRC_ID to title if editing
469
+		$this->_admin_page_title =
470
+			$ID
471
+				? $this->_admin_page_title . ' # ' . $ID
472
+				: $this->_admin_page_title;
473
+		if ($ID) {
474
+			$question                 = $this->_question_model->get_one_by_ID($ID);
475
+			$additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
476
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
477
+		} else {
478
+			$question = EE_Question::new_instance();
479
+			$question->set_order_to_latest();
480
+			$this->_set_add_edit_form_tags('insert_question');
481
+		}
482
+		if ($question->system_ID() === EEM_Attendee::system_question_phone) {
483
+			$question_types = array_intersect_key(
484
+				$this->_question_model->allowed_question_types(),
485
+				array_flip(
486
+					[
487
+						EEM_Question::QST_type_text,
488
+						EEM_Question::QST_type_us_phone,
489
+					]
490
+				)
491
+			);
492
+		} else {
493
+			$question_types = $question->has_answers()
494
+				? $this->_question_model->question_types_in_same_category($question->type())
495
+				: $this->_question_model->allowed_question_types();
496
+		}
497
+		$this->_template_args['QST_ID']                     = $ID;
498
+		$this->_template_args['question']                   = $question;
499
+		$this->_template_args['question_types']             = $question_types;
500
+		$this->_template_args['max_max']                    =
501
+			$this->_question_model->absolute_max_for_system_question(
502
+				$question->system_ID()
503
+			);
504
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
505
+		$this->_set_publish_post_box_vars('id', $ID);
506
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
507
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
508
+			$this->_template_args,
509
+			true
510
+		);
511
+
512
+		// the details template wrapper
513
+		$this->display_admin_page_with_sidebar();
514
+	}
515
+
516
+
517
+	/**
518
+	 * @return string
519
+	 * @throws EE_Error
520
+	 * @throws ReflectionException
521
+	 */
522
+	protected function _get_question_type_descriptions(): string
523
+	{
524
+		EE_Registry::instance()->load_helper('HTML');
525
+		$descriptions               = '';
526
+		$question_type_descriptions = $this->_question_model->question_descriptions();
527
+		foreach ($question_type_descriptions as $type => $question_type_description) {
528
+			if ($type == 'HTML_TEXTAREA') {
529
+				$html                      = new EE_Simple_HTML_Validation_Strategy();
530
+				$question_type_description .= sprintf(
531
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
532
+					'<br/>',
533
+					$html->get_list_of_allowed_tags()
534
+				);
535
+			}
536
+			$descriptions .= EEH_HTML::p(
537
+				$question_type_description,
538
+				'question_type_description-' . $type,
539
+				'question_type_description description',
540
+				'display:none;'
541
+			);
542
+		}
543
+		return $descriptions;
544
+	}
545
+
546
+
547
+	/**
548
+	 * @param bool $new_question
549
+	 * @throws EE_Error
550
+	 * @throws ReflectionException
551
+	 */
552
+	protected function _insert_or_update_question(bool $new_question = true)
553
+	{
554
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
555
+		if ($new_question) {
556
+			$question    = EE_Question::new_instance($set_column_values);
557
+			$action_desc = 'added';
558
+		} else {
559
+			$question = $this->_question_model->get_one_by_ID(
560
+				$this->request->getRequestParam('QST_ID', 0, DataType::INT)
561
+			);
562
+			foreach ($set_column_values as $field => $new_value) {
563
+				$question->set($field, $new_value);
564
+			}
565
+			$action_desc = 'updated';
566
+		}
567
+		$success = $question->save();
568
+		$ID      = $question->ID();
569
+		if ($ID && $question->should_have_question_options()) {
570
+			// save the related options
571
+			// trash removed options, save old ones
572
+			// get list of all options
573
+			$options          = $question->options();
574
+			$question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
575
+			$QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
576
+			if (! empty($options)) {
577
+				foreach ($options as $option_ID => $option) {
578
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
579
+					if ($option_req_index !== false) {
580
+						$question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
581
+						$option->save($question_options[ $option_req_index ]);
582
+					} else {
583
+						// not found, remove it
584
+						$option->delete();
585
+					}
586
+				}
587
+			}
588
+			// save new related options
589
+			foreach ($question_options as $index => $option_req_data) {
590
+				// skip $index that is from our sample
591
+				if ($index === 'xxcountxx') {
592
+					continue;
593
+				}
594
+				// note we allow saving blank options.
595
+				if (empty($option_req_data['QSO_ID'])) {
596
+					// no ID! save it!
597
+					$new_option = EE_Question_Option::new_instance(
598
+						[
599
+							'QSO_value'   => $option_req_data['QSO_value'],
600
+							'QSO_desc'    => $option_req_data['QSO_desc'],
601
+							'QSO_default' => $index === $QSO_default,
602
+							'QSO_order'   => $option_req_data['QSO_order'],
603
+							'QST_ID'      => $question->ID(),
604
+						]
605
+					);
606
+					$new_option->save();
607
+				}
608
+			}
609
+		}
610
+
611
+		$success = apply_filters(
612
+			'FHEE__Registration_Form_Admin_Page___insert_or_update_question__success',
613
+			(int) $success,
614
+			$question,
615
+			$this
616
+		);
617
+
618
+		$query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
619
+		if ($success !== 0) {
620
+			$msg = $new_question
621
+				? sprintf(
622
+					esc_html__('The %s has been created', 'event_espresso'),
623
+					$this->_question_model->item_name()
624
+				)
625
+				: sprintf(
626
+					esc_html__('The %s has been updated', 'event_espresso'),
627
+					$this->_question_model->item_name()
628
+				);
629
+			EE_Error::add_success($msg);
630
+		}
631
+
632
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
633
+	}
634
+
635
+
636
+	/**
637
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
638
+	 * by ID
639
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
640
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
641
+	 *
642
+	 * @param int $ID of the question option to find
643
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
644
+	 */
645
+	protected function _get_option_req_data_index(int $ID)
646
+	{
647
+		$req_data_for_question_options = $this->_req_data['question_options'];
648
+		foreach ($req_data_for_question_options as $num => $option_data) {
649
+			if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
650
+				return $num;
651
+			}
652
+		}
653
+		return false;
654
+	}
655
+
656
+
657
+
658
+
659
+	/* QUERIES */
660
+	/**
661
+	 * For internal use in getting all the query parameters
662
+	 * (because it's pretty well the same between question, question groups,
663
+	 * and for both when searching for trashed and untrashed ones)
664
+	 *
665
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
666
+	 * @param int      $per_page
667
+	 * @param int      $current_page
668
+	 * @return array model query params,
669
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
670
+	 */
671
+	protected function get_query_params(EEM_Base $model, int $per_page = 10, int $current_page = 10): array
672
+	{
673
+		$query_params             = [];
674
+		$offset                   = ($current_page - 1) * $per_page;
675
+		$query_params['limit']    = [$offset, $per_page];
676
+
677
+		$order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
678
+			? $this->_req_data['order']
679
+			: 'ASC';
680
+
681
+		$orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
682
+
683
+		$field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
684
+
685
+		$query_params['order_by'] = [$field_to_order_by => $order];
686
+
687
+		$search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
688
+		if (! empty($search_string)) {
689
+			if ($model instanceof EEM_Question_Group) {
690
+				$query_params[0] = [
691
+					'OR' => [
692
+						'QSG_name' => ['LIKE', "%$search_string%"],
693
+						'QSG_desc' => ['LIKE', "%$search_string%"],
694
+					],
695
+				];
696
+			} else {
697
+				$query_params[0] = [
698
+					'QST_display_text' => ['LIKE', "%$search_string%"],
699
+				];
700
+			}
701
+		}
702
+
703
+		// capability checks (just leaving this commented out for reference because
704
+		// it illustrates some complicated query params that could be useful when fully implemented)
705
+		/*if ( $model instanceof EEM_Question_Group ) {
706 706
             if (
707 707
                 ! $this->capabilities->current_user_can(
708 708
                     'edit_others_question_groups',
@@ -742,59 +742,59 @@  discard block
 block discarded – undo
742 742
             }
743 743
         }/**/
744 744
 
745
-        return $query_params;
746
-    }
747
-
748
-
749
-    /**
750
-     * @param int  $per_page
751
-     * @param int  $current_page
752
-     * @param bool $count
753
-     * @return EE_Question[]|int
754
-     * @throws EE_Error
755
-     * @throws ReflectionException
756
-     */
757
-    public function get_questions(int $per_page = 10, int $current_page = 1, bool $count = false)
758
-    {
759
-        $query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
760
-        if ($count) {
761
-            $where = isset($query_params[0]) ? [$query_params[0]] : [];
762
-            return $this->_question_model->count($where);
763
-        }
764
-        return $this->_question_model->get_all($query_params);
765
-    }
766
-
767
-
768
-    /**
769
-     * @param int  $per_page
770
-     * @param int  $current_page
771
-     * @param bool $count
772
-     * @return EE_Soft_Delete_Base_Class[]|int
773
-     * @throws EE_Error
774
-     */
775
-    public function get_trashed_questions(int $per_page, int $current_page = 1, bool $count = false)
776
-    {
777
-        $query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
778
-        $where        = isset($query_params[0]) ? [$query_params[0]] : [];
779
-        return $count
780
-            ? $this->_question_model->count_deleted($where)
781
-            : $this->_question_model->get_all_deleted($query_params);
782
-    }
783
-
784
-
785
-    /**
786
-     * @param int  $per_page
787
-     * @param int  $current_page
788
-     * @param bool $count
789
-     * @return EE_Question_Group[]|int
790
-     * @throws EE_Error
791
-     * @throws ReflectionException
792
-     */
793
-    public function get_question_groups(int $per_page, int $current_page = 1, bool $count = false)
794
-    {
795
-        // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
796
-        return $this->_question_group_model->get_all(
797
-            $this->get_query_params($this->_question_group_model, $per_page, $current_page)
798
-        );
799
-    }
745
+		return $query_params;
746
+	}
747
+
748
+
749
+	/**
750
+	 * @param int  $per_page
751
+	 * @param int  $current_page
752
+	 * @param bool $count
753
+	 * @return EE_Question[]|int
754
+	 * @throws EE_Error
755
+	 * @throws ReflectionException
756
+	 */
757
+	public function get_questions(int $per_page = 10, int $current_page = 1, bool $count = false)
758
+	{
759
+		$query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
760
+		if ($count) {
761
+			$where = isset($query_params[0]) ? [$query_params[0]] : [];
762
+			return $this->_question_model->count($where);
763
+		}
764
+		return $this->_question_model->get_all($query_params);
765
+	}
766
+
767
+
768
+	/**
769
+	 * @param int  $per_page
770
+	 * @param int  $current_page
771
+	 * @param bool $count
772
+	 * @return EE_Soft_Delete_Base_Class[]|int
773
+	 * @throws EE_Error
774
+	 */
775
+	public function get_trashed_questions(int $per_page, int $current_page = 1, bool $count = false)
776
+	{
777
+		$query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
778
+		$where        = isset($query_params[0]) ? [$query_params[0]] : [];
779
+		return $count
780
+			? $this->_question_model->count_deleted($where)
781
+			: $this->_question_model->get_all_deleted($query_params);
782
+	}
783
+
784
+
785
+	/**
786
+	 * @param int  $per_page
787
+	 * @param int  $current_page
788
+	 * @param bool $count
789
+	 * @return EE_Question_Group[]|int
790
+	 * @throws EE_Error
791
+	 * @throws ReflectionException
792
+	 */
793
+	public function get_question_groups(int $per_page, int $current_page = 1, bool $count = false)
794
+	{
795
+		// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
796
+		return $this->_question_group_model->get_all(
797
+			$this->get_query_params($this->_question_group_model, $per_page, $current_page)
798
+		);
799
+	}
800 800
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -40,8 +40,8 @@  discard block
 block discarded – undo
40 40
      */
41 41
     public function __construct($routing = true)
42 42
     {
43
-        require_once(EE_MODELS . 'EEM_Question.model.php');
44
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
43
+        require_once(EE_MODELS.'EEM_Question.model.php');
44
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
45 45
         $this->_question_model       = EEM_Question::instance();
46 46
         $this->_question_group_model = EEM_Question_Group::instance();
47 47
         parent::__construct($routing);
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
      */
82 82
     protected function _set_page_routes()
83 83
     {
84
-        $qst_id             =
84
+        $qst_id =
85 85
             ! empty($this->_req_data['QST_ID'])
86 86
                 ? $this->_req_data['QST_ID']
87 87
                 : 0;
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
     {
219 219
         wp_register_style(
220 220
             'espresso_registration',
221
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
221
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css',
222 222
             [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223 223
             EVENT_ESPRESSO_VERSION
224 224
         );
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
         $this->load_scripts_styles_forms();
267 267
         wp_register_script(
268 268
             'espresso_registration_form_single',
269
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
269
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js',
270 270
             ['jquery-ui-sortable'],
271 271
             EVENT_ESPRESSO_VERSION,
272 272
             true
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
 
286 286
     public function recaptcha_info_help_tab()
287 287
     {
288
-        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
288
+        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php');
289 289
     }
290 290
 
291 291
 
@@ -333,16 +333,16 @@  discard block
 block discarded – undo
333 333
     {
334 334
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335 335
         $this->_template_args['preview_img']  =
336
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
336
+            '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'
337 337
             . esc_attr__(
338 338
                 'Preview Question Groups Overview List Table screenshot',
339 339
                 'event_espresso'
340
-            ) . '" />';
340
+            ).'" />';
341 341
         $this->_template_args['preview_text'] = '<strong>'
342 342
             . esc_html__(
343 343
                 'Question Groups 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. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344 344
                 'event_espresso'
345
-            ) . '</strong>';
345
+            ).'</strong>';
346 346
         $this->display_admin_caf_preview_page('question_groups_tab');
347 347
     }
348 348
 
@@ -380,39 +380,39 @@  discard block
 block discarded – undo
380 380
             $this->request->unSetRequestParam('QST_max', true);
381 381
         }
382 382
         foreach ($model->field_settings() as $fieldName => $settings) {
383
-            switch($fieldName) {
383
+            switch ($fieldName) {
384 384
                 case 'QSG_identifier':
385 385
                     // basically if QSG_identifier is empty or not set
386
-                    if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
386
+                    if ( ! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387 387
                         $QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
-                        $column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
388
+                        $column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
389 389
                     }
390 390
                     break;
391 391
 
392 392
                 case 'QST_admin_label':
393
-                    if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
393
+                    if ( ! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394 394
                         // the admin label is blank, use a slug version of the question text
395 395
                         $QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
-                        $column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
396
+                        $column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
397 397
                     }
398 398
                     break;
399 399
 
400 400
                 case 'QST_admin_only':
401
-                    if (! $QST_admin_only) {
402
-                        $column_values[ $fieldName ] = false;
401
+                    if ( ! $QST_admin_only) {
402
+                        $column_values[$fieldName] = false;
403 403
                     }
404 404
                     break;
405 405
 
406 406
                 case 'QST_max':
407 407
                     $qst_system = $this->_question_model->get_var(
408
-                        [ [ 'QST_ID' => $QST_ID ] ],
408
+                        [['QST_ID' => $QST_ID]],
409 409
                         'QST_system'
410 410
                     );
411 411
 
412 412
                     $max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
413 413
                     $QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
414 414
                     if ($QST_max === 0 || $QST_max > $max_max) {
415
-                        $column_values[ $fieldName ] = $max_max;
415
+                        $column_values[$fieldName] = $max_max;
416 416
                     }
417 417
                     break;
418 418
 
@@ -421,7 +421,7 @@  discard block
 block discarded – undo
421 421
                     if ($this->request->requestParamIsSet($fieldName)) {
422 422
                         // convert the schema type to the appropriate data type
423 423
                         $schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
424
-                        $column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
424
+                        $column_values[$fieldName] = $this->request->getRequestParam($fieldName, null, $schema_type);
425 425
                     }
426 426
             }
427 427
         }
@@ -468,7 +468,7 @@  discard block
 block discarded – undo
468 468
         // add PRC_ID to title if editing
469 469
         $this->_admin_page_title =
470 470
             $ID
471
-                ? $this->_admin_page_title . ' # ' . $ID
471
+                ? $this->_admin_page_title.' # '.$ID
472 472
                 : $this->_admin_page_title;
473 473
         if ($ID) {
474 474
             $question                 = $this->_question_model->get_one_by_ID($ID);
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
505 505
         $this->_set_publish_post_box_vars('id', $ID);
506 506
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
507
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
507
+            REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
508 508
             $this->_template_args,
509 509
             true
510 510
         );
@@ -526,7 +526,7 @@  discard block
 block discarded – undo
526 526
         $question_type_descriptions = $this->_question_model->question_descriptions();
527 527
         foreach ($question_type_descriptions as $type => $question_type_description) {
528 528
             if ($type == 'HTML_TEXTAREA') {
529
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
529
+                $html = new EE_Simple_HTML_Validation_Strategy();
530 530
                 $question_type_description .= sprintf(
531 531
                     esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
532 532
                     '<br/>',
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
             }
536 536
             $descriptions .= EEH_HTML::p(
537 537
                 $question_type_description,
538
-                'question_type_description-' . $type,
538
+                'question_type_description-'.$type,
539 539
                 'question_type_description description',
540 540
                 'display:none;'
541 541
             );
@@ -573,12 +573,12 @@  discard block
 block discarded – undo
573 573
             $options          = $question->options();
574 574
             $question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
575 575
             $QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
576
-            if (! empty($options)) {
576
+            if ( ! empty($options)) {
577 577
                 foreach ($options as $option_ID => $option) {
578 578
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
579 579
                     if ($option_req_index !== false) {
580
-                        $question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
581
-                        $option->save($question_options[ $option_req_index ]);
580
+                        $question_options[$option_req_index]['QSO_default'] = $option_req_index === $QSO_default;
581
+                        $option->save($question_options[$option_req_index]);
582 582
                     } else {
583 583
                         // not found, remove it
584 584
                         $option->delete();
@@ -674,7 +674,7 @@  discard block
 block discarded – undo
674 674
         $offset                   = ($current_page - 1) * $per_page;
675 675
         $query_params['limit']    = [$offset, $per_page];
676 676
 
677
-        $order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
677
+        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
678 678
             ? $this->_req_data['order']
679 679
             : 'ASC';
680 680
 
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
         $query_params['order_by'] = [$field_to_order_by => $order];
686 686
 
687 687
         $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
688
-        if (! empty($search_string)) {
688
+        if ( ! empty($search_string)) {
689 689
             if ($model instanceof EEM_Question_Group) {
690 690
                 $query_params[0] = [
691 691
                     'OR' => [
Please login to merge, or discard this patch.
registration_form/templates/questions_main_meta_box.template.php 2 patches
Indentation   +195 added lines, -195 removed lines patch added patch discarded remove patch
@@ -13,48 +13,48 @@  discard block
 block discarded – undo
13 13
  */
14 14
 
15 15
 try {
16
-    // the following are already escaped
17
-    echo wp_kses(
18
-        EEH_Form_Fields::hidden_input('QST_system', $question->system_ID()),
19
-        AllowedTags::getWithFormTags()
20
-    );
21
-    echo wp_kses(
22
-        EEH_Form_Fields::hidden_input('QST_wp_user', $question->wp_user()),
23
-        AllowedTags::getWithFormTags()
24
-    );
25
-    echo wp_kses(
26
-        EEH_Form_Fields::hidden_input('QST_deleted', $question->deleted()),
27
-        AllowedTags::getWithFormTags()
28
-    );
16
+	// the following are already escaped
17
+	echo wp_kses(
18
+		EEH_Form_Fields::hidden_input('QST_system', $question->system_ID()),
19
+		AllowedTags::getWithFormTags()
20
+	);
21
+	echo wp_kses(
22
+		EEH_Form_Fields::hidden_input('QST_wp_user', $question->wp_user()),
23
+		AllowedTags::getWithFormTags()
24
+	);
25
+	echo wp_kses(
26
+		EEH_Form_Fields::hidden_input('QST_deleted', $question->deleted()),
27
+		AllowedTags::getWithFormTags()
28
+	);
29 29
 
30
-    $QST_system = $question->system_ID();
31
-    $fields     = $question->get_model()->field_settings();
30
+	$QST_system = $question->system_ID();
31
+	$fields     = $question->get_model()->field_settings();
32 32
 
33
-    do_action('AHEE__questions_main_meta_box__template__before_admin_page_content', $question);
33
+	do_action('AHEE__questions_main_meta_box__template__before_admin_page_content', $question);
34 34
 
35
-    // does question have any answers? cause if it does then we have to disable type
36
-    $has_answers = $question->has_answers();
37
-    global $allowedposttags;
38
-    $info_box = '';
39
-    if ($QST_system === 'country') {
40
-        $info_box = EEH_HTML::div(
41
-            EEH_HTML::h3(
42
-                '<span class="dashicons dashicons-info"></span> '
43
-                . esc_html__('Did you know...', 'event_espresso'),
44
-                '',
45
-                'ee-status--info'
46
-            ) .
47
-            EEH_HTML::p(
48
-                esc_html__(
49
-                    '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.',
50
-                    'event_espresso'
51
-                )
52
-            ),
53
-            '',
54
-            'ee-info-box'
55
-        );
56
-    }
57
-    do_action('AHEE__questions_main_meta_box__template__inner_admin_page_content', $question);
35
+	// does question have any answers? cause if it does then we have to disable type
36
+	$has_answers = $question->has_answers();
37
+	global $allowedposttags;
38
+	$info_box = '';
39
+	if ($QST_system === 'country') {
40
+		$info_box = EEH_HTML::div(
41
+			EEH_HTML::h3(
42
+				'<span class="dashicons dashicons-info"></span> '
43
+				. esc_html__('Did you know...', 'event_espresso'),
44
+				'',
45
+				'ee-status--info'
46
+			) .
47
+			EEH_HTML::p(
48
+				esc_html__(
49
+					'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.',
50
+					'event_espresso'
51
+				)
52
+			),
53
+			'',
54
+			'ee-info-box'
55
+		);
56
+	}
57
+	do_action('AHEE__questions_main_meta_box__template__inner_admin_page_content', $question);
58 58
 ?>
59 59
 
60 60
 <div class="padding">
@@ -67,8 +67,8 @@  discard block
 block discarded – undo
67 67
                     <label for="QST_display_text">
68 68
                         <?php echo wp_kses($fields['QST_display_text']->get_nicename(), AllowedTags::getAllowedTags()); ?>
69 69
                         <?php echo wp_kses(
70
-                            EEH_Template::get_help_tab_link('question_text_info'), AllowedTags::getAllowedTags()
71
-                        ); ?>
70
+							EEH_Template::get_help_tab_link('question_text_info'), AllowedTags::getAllowedTags()
71
+						); ?>
72 72
                             <span class="ee-required-text">*</span>
73 73
                     </label>
74 74
                 </th>
@@ -84,16 +84,16 @@  discard block
 block discarded – undo
84 84
             </tr>
85 85
 
86 86
             <?php
87
-            $id            = ! empty($QST_system) ? '_disabled' : '';
88
-            $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
89
-            ?>
87
+			$id            = ! empty($QST_system) ? '_disabled' : '';
88
+			$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
89
+			?>
90 90
             <tr>
91 91
                 <th>
92 92
                     <label for="QST_admin_label<?php esc_attr_e($id); ?>">
93 93
                         <?php echo wp_kses($fields['QST_admin_label']->get_nicename(), AllowedTags::getAllowedTags()); ?>
94 94
                         <?php echo wp_kses(
95
-                            EEH_Template::get_help_tab_link('question_label_info'), AllowedTags::getAllowedTags()
96
-                        ); ?>
95
+							EEH_Template::get_help_tab_link('question_label_info'), AllowedTags::getAllowedTags()
96
+						); ?>
97 97
                     </label>
98 98
                 </th>
99 99
                 <td>
@@ -128,11 +128,11 @@  discard block
 block discarded – undo
128 128
             </tr>
129 129
 
130 130
             <?php
131
-            $id            = ! empty($QST_system) ? '_disabled' : '';
132
-            $disabled_attr = ! empty($QST_system) ? 'disabled' : '';
133
-            $admin_only    = $question->get('QST_admin_only');
134
-            $checked       = ! empty($admin_only) ? ' checked' : '';
135
-            ?>
131
+			$id            = ! empty($QST_system) ? '_disabled' : '';
132
+			$disabled_attr = ! empty($QST_system) ? 'disabled' : '';
133
+			$admin_only    = $question->get('QST_admin_only');
134
+			$checked       = ! empty($admin_only) ? ' checked' : '';
135
+			?>
136 136
             <tr>
137 137
                 <th>
138 138
                     <label for="QST_admin_only<?php esc_attr_e($id); ?>">
@@ -147,18 +147,18 @@  discard block
 block discarded – undo
147 147
                            type="checkbox"
148 148
                            value="1"
149 149
                         <?php
150
-                        esc_attr_e($disabled_attr);
151
-                        esc_attr_e($checked);
152
-                        ?>
150
+						esc_attr_e($disabled_attr);
151
+						esc_attr_e($checked);
152
+						?>
153 153
                     />
154 154
                     <br>
155 155
                         <?php
156
-                        if (! empty($QST_system)) { ?>
156
+						if (! empty($QST_system)) { ?>
157 157
                             <p class="description ee-system-question" >
158 158
                                 <?php esc_html_e(
159
-                                    'System question! This field cannot be changed.',
160
-                                    'event_espresso'
161
-                                ); ?>
159
+									'System question! This field cannot be changed.',
160
+									'event_espresso'
161
+								); ?>
162 162
                             </p>
163 163
                         <?php } ?>
164 164
                 </td>
@@ -173,40 +173,40 @@  discard block
 block discarded – undo
173 173
                 </th>
174 174
                 <td>
175 175
                     <?php
176
-                    $disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
177
-                    $id       = $disabled ? '_disabled' : '';
176
+					$disabled = ! empty($QST_system) && $QST_system !== EEM_Attendee::system_question_phone;
177
+					$id       = $disabled ? '_disabled' : '';
178 178
 
179
-                    if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
180
-                        unset($question_types[ EEM_Question::QST_type_email_confirm ]);
181
-                    }
179
+					if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
180
+						unset($question_types[ EEM_Question::QST_type_email_confirm ]);
181
+					}
182 182
 
183
-                    echo wp_kses(
184
-                        EEH_Form_Fields::select_input(
185
-                            'QST_type' . $id,
186
-                            $question_types,
187
-                            $question->type(),
188
-                            'id="QST_type' . $id . '" ' . $disabled_attr
189
-                        ),
190
-                        AllowedTags::getWithFormTags()
191
-                    );
192
-                    if ($disabled) { ?>
183
+					echo wp_kses(
184
+						EEH_Form_Fields::select_input(
185
+							'QST_type' . $id,
186
+							$question_types,
187
+							$question->type(),
188
+							'id="QST_type' . $id . '" ' . $disabled_attr
189
+						),
190
+						AllowedTags::getWithFormTags()
191
+					);
192
+					if ($disabled) { ?>
193 193
                         <input id='QST_type'
194 194
                                name="QST_type"
195 195
                                type="hidden"
196 196
                                value="<?php esc_attr_e($question->type()); ?>"
197 197
                         />
198 198
                         <?php
199
-                        $explanatory_text = esc_html__(
200
-                            'System question! This field cannot be changed.',
201
-                            'event_espresso'
202
-                        );
203
-                    } else {
204
-                        $explanatory_text = esc_html__(
205
-                            '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.',
206
-                            'event_espresso'
207
-                        );
208
-                    }
209
-                    if ($disabled || $has_answers) { ?>
199
+						$explanatory_text = esc_html__(
200
+							'System question! This field cannot be changed.',
201
+							'event_espresso'
202
+						);
203
+					} else {
204
+						$explanatory_text = esc_html__(
205
+							'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.',
206
+							'event_espresso'
207
+						);
208
+					}
209
+					if ($disabled || $has_answers) { ?>
210 210
                         <p class="description ee-system-question" >
211 211
                                 <?php echo esc_html($explanatory_text); ?>
212 212
                         </p>
@@ -236,19 +236,19 @@  discard block
 block discarded – undo
236 236
                     />
237 237
                     <p class="description">
238 238
                         <?php esc_html_e(
239
-                            'Maximum number of characters allowed when answering this question',
240
-                            'event_espresso'
241
-                        ); ?>
239
+							'Maximum number of characters allowed when answering this question',
240
+							'event_espresso'
241
+						); ?>
242 242
                     </p>
243 243
                     <?php if ($QST_system) { ?>
244 244
                     <p class="description ee-system-question" >
245 245
                         <?php printf(
246
-                            esc_html__(
247
-                                'System question! The maximum number of characters that can be used for this question is %1$s',
248
-                                'event_espresso'
249
-                            ),
250
-                            $max_max
251
-                        ); ?>
246
+							esc_html__(
247
+								'System question! The maximum number of characters that can be used for this question is %1$s',
248
+								'event_espresso'
249
+							),
250
+							$max_max
251
+						); ?>
252 252
                     </p>
253 253
                     <?php } ?>
254 254
                 </td>
@@ -274,9 +274,9 @@  discard block
 block discarded – undo
274 274
                                         <?php esc_html_e('Description', 'event_espresso') ?>
275 275
                                         </label>
276 276
                                         <span class="tiny-text"><?php esc_html_e(
277
-                                                '(optional, only shown on registration form)',
278
-                                                'event_espresso'
279
-                                            ) ?></span>
277
+												'(optional, only shown on registration form)',
278
+												'event_espresso'
279
+											) ?></span>
280 280
                                     </th>
281 281
                                     <th class="option-default-header">
282 282
                                         <label>
@@ -334,24 +334,24 @@  discard block
 block discarded – undo
334 334
                                         </a>
335 335
                                         <a class="button button--icon-only sortable-drag-handle ee-aria-tooltip"
336 336
                                            aria-label="<?php esc_html_e(
337
-                                               'click and drag to change the order of this option',
338
-                                               'event_espresso'
339
-                                           ) ?>"
337
+											   'click and drag to change the order of this option',
338
+											   'event_espresso'
339
+										   ) ?>"
340 340
                                         >
341 341
                                             <span class='dashicons dashicons-image-flip-vertical '></span>
342 342
                                         </a>
343 343
                                     </td>
344 344
                                 </tr>
345 345
                                 <?php
346
-                                $count            = 0;
347
-                                $hasDefault       = false;
348
-                                $question_options = $question->options();
349
-                                if (! empty($question_options)) {
350
-                                    foreach ($question_options as $option_id => $option) {
351
-                                        $disabled_attr = $has_answers || $option->get('QSO_system')
352
-                                            ? 'disabled'
353
-                                            : '';
354
-                                        ?>
346
+								$count            = 0;
347
+								$hasDefault       = false;
348
+								$question_options = $question->options();
349
+								if (! empty($question_options)) {
350
+									foreach ($question_options as $option_id => $option) {
351
+										$disabled_attr = $has_answers || $option->get('QSO_system')
352
+											? 'disabled'
353
+											: '';
354
+										?>
355 355
                                         <tr class="question-option ee-options-sortable">
356 356
                                             <td class="option-value-cell">
357 357
                                                 <label class='screen-reader-text'
@@ -396,9 +396,9 @@  discard block
 block discarded – undo
396 396
                                                     <?php esc_html_e('Check if this is the default value', 'event_espresso') ?>
397 397
                                                 </label>
398 398
                                                 <?php
399
-                                                $isDefault = $option->isDefault() ? ' checked' : '';
400
-                                                $hasDefault = $isDefault ? true : $hasDefault;
401
-                                                ?>
399
+												$isDefault = $option->isDefault() ? ' checked' : '';
400
+												$hasDefault = $isDefault ? true : $hasDefault;
401
+												?>
402 402
                                                 <input type="radio"
403 403
                                                        class="option-default"
404 404
                                                        id="question_options-<?php esc_attr_e($count); ?>-QSO_default"
@@ -411,44 +411,44 @@  discard block
 block discarded – undo
411 411
                                             <?php if (! $option->system()) { ?>
412 412
                                                 <a class='button button--icon-only remove-option remove-item ee-aria-tooltip'
413 413
                                                    aria-label="<?php esc_html_e(
414
-                                                       'click to delete this option',
415
-                                                       'event_espresso'
416
-                                                   ) ?>"
414
+													   'click to delete this option',
415
+													   'event_espresso'
416
+												   ) ?>"
417 417
                                                 >
418 418
                                                     <span class='dashicons clickable dashicons-post-trash'></span>
419 419
                                                 </a>
420 420
                                             <?php } ?>
421 421
                                                 <a class='button button--icon-only sortable-drag-handle ee-aria-tooltip'
422 422
                                                    aria-label="<?php esc_html_e(
423
-                                                       'click and drag to change the order of this option',
424
-                                                       'event_espresso'
425
-                                                   ) ?>"
423
+													   'click and drag to change the order of this option',
424
+													   'event_espresso'
425
+												   ) ?>"
426 426
                                                 >
427 427
                                                     <span class='dashicons dashicons-image-flip-vertical '></span>
428 428
                                                 </a>
429 429
                                                 <?php
430
-                                                echo wp_kses(
431
-                                                    EEH_Form_Fields::hidden_input(
432
-                                                        "question_options[$count][QST_ID])",
433
-                                                        $option->question_ID()
434
-                                                    ),
435
-                                                    AllowedTags::getWithFormTags()
436
-                                                );
437
-                                                echo wp_kses(
438
-                                                    EEH_Form_Fields::hidden_input(
439
-                                                        "question_options[$count][QSO_ID])",
440
-                                                        $option->ID()
441
-                                                    ),
442
-                                                    AllowedTags::getWithFormTags()
443
-                                                );
444
-                                                $count++;
445
-                                                ?>
430
+												echo wp_kses(
431
+													EEH_Form_Fields::hidden_input(
432
+														"question_options[$count][QST_ID])",
433
+														$option->question_ID()
434
+													),
435
+													AllowedTags::getWithFormTags()
436
+												);
437
+												echo wp_kses(
438
+													EEH_Form_Fields::hidden_input(
439
+														"question_options[$count][QSO_ID])",
440
+														$option->ID()
441
+													),
442
+													AllowedTags::getWithFormTags()
443
+												);
444
+												$count++;
445
+												?>
446 446
                                             </td>
447 447
                                         </tr>
448 448
                                         <?php
449
-                                    }
450
-                                } else {
451
-                                    ?>
449
+									}
450
+								} else {
451
+									?>
452 452
                                     <tr class="question-option ee-options-sortable">
453 453
                                         <td class="option-value-cell">
454 454
                                             <label class='screen-reader-text' for='question_options[0][QSO_value]'
@@ -491,21 +491,21 @@  discard block
 block discarded – undo
491 491
                                         </td>
492 492
                                         <td class="option-actions-cell">
493 493
                                             <?php echo wp_kses(
494
-                                                EEH_Form_Fields::hidden_input(
495
-                                                    "question_options_count",
496
-                                                    $count
497
-                                                ),
498
-                                                AllowedTags::getWithFormTags()
499
-                                            ); ?>
494
+												EEH_Form_Fields::hidden_input(
495
+													"question_options_count",
496
+													$count
497
+												),
498
+												AllowedTags::getWithFormTags()
499
+											); ?>
500 500
                                         </td>
501 501
                                     </tr>
502 502
                                     <?php
503
-                                }
504
-                                if (
505
-                                    $question->type() === EEM_Question::QST_type_checkbox
506
-                                    || $question->type() === EEM_Question::QST_type_radio
507
-                                ) :
508
-                                ?>
503
+								}
504
+								if (
505
+									$question->type() === EEM_Question::QST_type_checkbox
506
+									|| $question->type() === EEM_Question::QST_type_radio
507
+								) :
508
+								?>
509 509
                                 <tr class="question-option">
510 510
                                     <td class="option-value-cell">
511 511
                                     </td>
@@ -534,34 +534,34 @@  discard block
 block discarded – undo
534 534
                                 <?php esc_html_e('Add Another Answer Option', 'event_espresso'); ?>
535 535
                             </a>
536 536
                             <?php echo wp_kses(
537
-                                EEH_Form_Fields::hidden_input(
538
-                                    "question_options_count",
539
-                                    $count
540
-                                ),
541
-                                AllowedTags::getWithFormTags()
542
-                            ); ?>
537
+								EEH_Form_Fields::hidden_input(
538
+									"question_options_count",
539
+									$count
540
+								),
541
+								AllowedTags::getWithFormTags()
542
+							); ?>
543 543
                         </div>
544 544
                         <br/>
545 545
 
546 546
                         <p class="description">
547 547
                             <?php esc_html_e(
548
-                                '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.',
549
-                                'event_espresso'
550
-                            ) ?>
548
+								'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.',
549
+								'event_espresso'
550
+							) ?>
551 551
                             <br />
552 552
                             <strong>
553 553
                                 <?php esc_html_e(
554
-                                    'The Default Answer Option will be automatically selected when the registration form is initially displayed, unless "no default value" is selected.',
555
-                                    'event_espresso'
556
-                                ) ?>
554
+									'The Default Answer Option will be automatically selected when the registration form is initially displayed, unless "no default value" is selected.',
555
+									'event_espresso'
556
+								) ?>
557 557
                             </strong>
558 558
                         </p>
559 559
                         <?php if ($has_answers) : ?>
560 560
                             <p class="description ee-system-question">
561 561
                                 <?php esc_html_e(
562
-                                    '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.',
563
-                                    'event_espresso'
564
-                                ); ?>
562
+									'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.',
563
+									'event_espresso'
564
+								); ?>
565 565
                             </p>
566 566
                         <?php endif; ?>
567 567
                     </td>
@@ -576,44 +576,44 @@  discard block
 block discarded – undo
576 576
                 </th>
577 577
                 <td>
578 578
                     <?php
579
-                    $system_required   = ['fname', 'email'];
580
-                    $disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
581
-                    $required_on       = $question->get('QST_admin_only');
582
-                    $show_required_class = $admin_only && $required_on ? '' : ' hidden';
583
-                    $disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
584
-                    $id                =
585
-                        ! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
586
-                    $requiredOptions   = [
587
-                        ['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
588
-                        ['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
589
-                    ];
590
-                    echo wp_kses(
591
-                        EEH_Form_Fields::select_input(
592
-                            'QST_required' . $id,
593
-                            $requiredOptions,
594
-                            $question->required(),
595
-                            'id="QST_required' . $id . '"' . $disabled_attr,
596
-                            'ee-input-width--small'
597
-                        ),
598
-                        AllowedTags::getWithFormTags()
599
-                    );
600
-                    ?>
579
+					$system_required   = ['fname', 'email'];
580
+					$disabled_attr     = in_array($QST_system, $system_required) ? ' disabled' : '';
581
+					$required_on       = $question->get('QST_admin_only');
582
+					$show_required_class = $admin_only && $required_on ? '' : ' hidden';
583
+					$disabled_attr     = $required_on || ! empty($disabled_attr) ? ' disabled' : '';
584
+					$id                =
585
+						! empty($disabled_attr) && in_array($QST_system, $system_required) ? '_disabled' : '';
586
+					$requiredOptions   = [
587
+						['text' => esc_html__('Optional', 'event_espresso'), 'id' => 0],
588
+						['text' => esc_html__('Required', 'event_espresso'), 'id' => 1],
589
+					];
590
+					echo wp_kses(
591
+						EEH_Form_Fields::select_input(
592
+							'QST_required' . $id,
593
+							$requiredOptions,
594
+							$question->required(),
595
+							'id="QST_required' . $id . '"' . $disabled_attr,
596
+							'ee-input-width--small'
597
+						),
598
+						AllowedTags::getWithFormTags()
599
+					);
600
+					?>
601 601
                     <p id="required_toggled_on"
602 602
                        class="description<?php esc_attr_e($show_required_class); ?>"
603 603
                     >
604 604
                         <?php esc_html_e(
605
-                            'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
606
-                            'event_espresso'
607
-                        ) ?>
605
+							'Required is set to optional, and this field is disabled, because the question is Admin-Only.',
606
+							'event_espresso'
607
+						) ?>
608 608
                     </p>
609 609
                     <p id="required_toggled_off"
610 610
                        class="description ee-system-question"
611 611
                        style="color:#D54E21; display: none;"
612 612
                     >
613 613
                             <?php esc_html_e(
614
-                                'Required option field is no longer disabled because the question is not Admin-Only',
615
-                                'event_espresso'
616
-                            ) ?>
614
+								'Required option field is no longer disabled because the question is not Admin-Only',
615
+								'event_espresso'
616
+							) ?>
617 617
                     </p>
618 618
                     <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
619 619
                         <input id="QST_required"
@@ -647,8 +647,8 @@  discard block
 block discarded – undo
647 647
                 </td>
648 648
             </tr>
649 649
             <?php
650
-            do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
651
-            ?>
650
+			do_action('AHEE__questions_main_meta_box__template__after_table_form_table', $question);
651
+			?>
652 652
         </tbody>
653 653
     </table>
654 654
 
@@ -656,7 +656,7 @@  discard block
 block discarded – undo
656 656
 </div>
657 657
 
658 658
     <?php
659
-    do_action('AHEE__questions_main_meta_box__template__after_admin_page_content', $question);
659
+	do_action('AHEE__questions_main_meta_box__template__after_admin_page_content', $question);
660 660
 } catch (Exception $e) {
661
-    EE_Error::add_error($e->getMessage(), __FILE__, __LINE__, __METHOD__);
661
+	EE_Error::add_error($e->getMessage(), __FILE__, __LINE__, __METHOD__);
662 662
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -43,7 +43,7 @@  discard block
 block discarded – undo
43 43
                 . esc_html__('Did you know...', 'event_espresso'),
44 44
                 '',
45 45
                 'ee-status--info'
46
-            ) .
46
+            ).
47 47
             EEH_HTML::p(
48 48
                 esc_html__(
49 49
                     '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.',
@@ -104,7 +104,7 @@  discard block
 block discarded – undo
104 104
                            value="<?php esc_attr_e($question->get_f('QST_admin_label')); ?>"
105 105
                            <?php esc_attr_e($disabled_attr); ?>
106 106
                     />
107
-                    <?php if (! empty($QST_system)) { ?>
107
+                    <?php if ( ! empty($QST_system)) { ?>
108 108
                         <input class="ee-input-width--reg"
109 109
                                id='QST_admin_label'
110 110
                                name="QST_admin_label"
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
                         />
114 114
                     <?php } ?>
115 115
                     <br>
116
-                    <?php if (! empty($QST_system)) { ?>
116
+                    <?php if ( ! empty($QST_system)) { ?>
117 117
                         <p class="description ee-system-question" >
118 118
                             <?php esc_html_e('System question! This field cannot be changed.', 'event_espresso') ?>
119 119
                         </p>
@@ -153,7 +153,7 @@  discard block
 block discarded – undo
153 153
                     />
154 154
                     <br>
155 155
                         <?php
156
-                        if (! empty($QST_system)) { ?>
156
+                        if ( ! empty($QST_system)) { ?>
157 157
                             <p class="description ee-system-question" >
158 158
                                 <?php esc_html_e(
159 159
                                     'System question! This field cannot be changed.',
@@ -177,15 +177,15 @@  discard block
 block discarded – undo
177 177
                     $id       = $disabled ? '_disabled' : '';
178 178
 
179 179
                     if (empty($QST_system) || $QST_system !== EEM_Attendee::system_question_email_confirm) {
180
-                        unset($question_types[ EEM_Question::QST_type_email_confirm ]);
180
+                        unset($question_types[EEM_Question::QST_type_email_confirm]);
181 181
                     }
182 182
 
183 183
                     echo wp_kses(
184 184
                         EEH_Form_Fields::select_input(
185
-                            'QST_type' . $id,
185
+                            'QST_type'.$id,
186 186
                             $question_types,
187 187
                             $question->type(),
188
-                            'id="QST_type' . $id . '" ' . $disabled_attr
188
+                            'id="QST_type'.$id.'" '.$disabled_attr
189 189
                         ),
190 190
                         AllowedTags::getWithFormTags()
191 191
                     );
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
                     <input id="QST_max<?php esc_attr_e($id); ?>"
227 227
                         class="ee-input-width--tiny"
228 228
                     <?php if ($max_max !== EE_INF) :?>
229
-                        max="<?php esc_attr_e($max_max);?>"
229
+                        max="<?php esc_attr_e($max_max); ?>"
230 230
                     <?php  endif; ?>
231 231
                         min="1"
232 232
                         name="QST_max"
@@ -346,7 +346,7 @@  discard block
 block discarded – undo
346 346
                                 $count            = 0;
347 347
                                 $hasDefault       = false;
348 348
                                 $question_options = $question->options();
349
-                                if (! empty($question_options)) {
349
+                                if ( ! empty($question_options)) {
350 350
                                     foreach ($question_options as $option_id => $option) {
351 351
                                         $disabled_attr = $has_answers || $option->get('QSO_system')
352 352
                                             ? 'disabled'
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
                                                 />
409 409
                                             </td>
410 410
                                             <td class="option-actions-cell">
411
-                                            <?php if (! $option->system()) { ?>
411
+                                            <?php if ( ! $option->system()) { ?>
412 412
                                                 <a class='button button--icon-only remove-option remove-item ee-aria-tooltip'
413 413
                                                    aria-label="<?php esc_html_e(
414 414
                                                        'click to delete this option',
@@ -589,10 +589,10 @@  discard block
 block discarded – undo
589 589
                     ];
590 590
                     echo wp_kses(
591 591
                         EEH_Form_Fields::select_input(
592
-                            'QST_required' . $id,
592
+                            'QST_required'.$id,
593 593
                             $requiredOptions,
594 594
                             $question->required(),
595
-                            'id="QST_required' . $id . '"' . $disabled_attr,
595
+                            'id="QST_required'.$id.'"'.$disabled_attr,
596 596
                             'ee-input-width--small'
597 597
                         ),
598 598
                         AllowedTags::getWithFormTags()
@@ -615,7 +615,7 @@  discard block
 block discarded – undo
615 615
                                 'event_espresso'
616 616
                             ) ?>
617 617
                     </p>
618
-                    <?php if (! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
618
+                    <?php if ( ! empty($disabled_attr) && in_array($QST_system, $system_required)) { ?>
619 619
                         <input id="QST_required"
620 620
                                name="QST_required"
621 621
                                type='hidden'
Please login to merge, or discard this patch.
admin_pages/general_settings/AdminOptionsSettings.php 1 patch
Indentation   +188 added lines, -188 removed lines patch added patch discarded remove patch
@@ -26,204 +26,204 @@
 block discarded – undo
26 26
  */
27 27
 class AdminOptionsSettings extends FormHandler
28 28
 {
29
-    protected $template_args = array();
29
+	protected $template_args = array();
30 30
 
31
-    /**
32
-     * Form constructor.
33
-     *
34
-     * @param EE_Registry $registry
35
-     */
36
-    public function __construct(EE_Registry $registry)
37
-    {
38
-        parent::__construct(
39
-            esc_html__('Admin Options', 'event_espresso'),
40
-            esc_html__('Admin Options', 'event_espresso'),
41
-            'admin_option_settings',
42
-            '',
43
-            FormHandler::DO_NOT_SETUP_FORM,
44
-            $registry
45
-        );
46
-    }
31
+	/**
32
+	 * Form constructor.
33
+	 *
34
+	 * @param EE_Registry $registry
35
+	 */
36
+	public function __construct(EE_Registry $registry)
37
+	{
38
+		parent::__construct(
39
+			esc_html__('Admin Options', 'event_espresso'),
40
+			esc_html__('Admin Options', 'event_espresso'),
41
+			'admin_option_settings',
42
+			'',
43
+			FormHandler::DO_NOT_SETUP_FORM,
44
+			$registry
45
+		);
46
+	}
47 47
 
48 48
 
49
-    /**
50
-     * @param array $template_args
51
-     */
52
-    public function setTemplateArgs(array $template_args)
53
-    {
54
-        $this->template_args = $template_args;
55
-    }
49
+	/**
50
+	 * @param array $template_args
51
+	 */
52
+	public function setTemplateArgs(array $template_args)
53
+	{
54
+		$this->template_args = $template_args;
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * creates and returns the actual form
60
-     *
61
-     * @return EE_Form_Section_Proper
62
-     * @throws EE_Error
63
-     */
64
-    public function generate()
65
-    {
66
-        $form = new EE_Form_Section_Proper(
67
-            array(
68
-                'name'            => 'admin_option_settings',
69
-                'html_id'         => 'admin_option_settings',
70
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
71
-                'subsections'     => array(
72
-                    'compatibility_hdr'        => new EE_Form_Section_HTML(
73
-                        EEH_HTML::h2(
74
-                            esc_html__('Compatibility Settings', 'event_espresso'),
75
-                            '',
76
-                            'ee-admin-settings-hdr'
77
-                        )
78
-                    ),
79
-                    'encode_session_data'      => new EE_Yes_No_Input(
80
-                        array(
81
-                            'html_label_text' => esc_html__('Encode Session Data?', 'event_espresso'),
82
-                            'html_help_text'  => sprintf(
83
-                                esc_html__(
84
-                                    'Some servers and database configurations can cause problems when saving the Event Espresso session data. Setting this option to "Yes" adds an extra layer of encoding to session data to prevent serialization errors, but can be incompatible with some server configurations.%1$sIf you receive "500 internal server" type errors during registration, try turning this option on.%1$sIf you get fatal PHP errors regarding missing base64 functions, then turn this option off.',
85
-                                    'event_espresso'
86
-                                ),
87
-                                '<br>'
88
-                            ),
89
-                            'default'         => $this->registry->CFG->admin->encode_session_data(),
90
-                            'required'        => false,
91
-                        )
92
-                    ),
93
-                ),
94
-            )
95
-        );
96
-        if (
97
-            $this->registry->CAP->current_user_can(
98
-                'manage_options',
99
-                'display_admin_settings_options_promote_and_affiliate'
100
-            )
101
-        ) {
102
-            $form->add_subsections(
103
-                array(
104
-                    'promote_ee_hdr'  => new EE_Form_Section_HTML(
105
-                        EEH_HTML::h2(
106
-                            esc_html__('Promote Event Espresso', 'event_espresso')
107
-                            . ' '
108
-                            . EEH_HTML::span(
109
-                                EEH_Template::get_help_tab_link('affiliate_info'),
110
-                                'affiliate_info'
111
-                            ),
112
-                            '',
113
-                            'ee-admin-settings-hdr'
114
-                        )
115
-                    ),
116
-                    'show_reg_footer' => new EE_Yes_No_Input(
117
-                        array(
118
-                            'html_label_text' => esc_html__(
119
-                                'Link to Event Espresso in your Registration Page?',
120
-                                'event_espresso'
121
-                            )
122
-                            . EEH_Template::get_help_tab_link('email_validation_info'),
123
-                            'html_help_text'  => esc_html__(
124
-                                'adds an unobtrusive link to Event Espresso\'s website in the footer of your registration form. Get an affiliate link (see below) and make money if people click the link and purchase Event Espresso.',
125
-                                'event_espresso'
126
-                            ),
127
-                            'default'         => filter_var($this->registry->CFG->admin->show_reg_footer, FILTER_VALIDATE_BOOLEAN),
128
-                            'required'        => false,
129
-                        )
130
-                    ),
131
-                    'affiliate_id'    => new EE_Text_Input(
132
-                        array(
133
-                            'html_label_text' => sprintf(
134
-                                esc_html__('Event Espresso %1$sAffiliate%2$s ID', 'event_espresso'),
135
-                                '<a href="https://eventespresso.com/affiliates/" target="_blank">',
136
-                                '</a>'
137
-                            ),
138
-                            'html_help_text'  => esc_html__(
139
-                                'Earn cash for promoting Event Espresso.',
140
-                                'event_espresso'
141
-                            ),
142
-                            'html_class'      => 'regular-text',
143
-                            'default'         => isset($this->registry->CFG->admin->affiliate_id)
144
-                                ? $this->registry->CFG->admin->get_pretty('affiliate_id')
145
-                                : '',
146
-                            'required'        => false,
147
-                        )
148
-                    ),
149
-                ),
150
-                'compatibility_hdr'
151
-            );
152
-        }
153
-        do_action(
154
-            'AHEE__EventEspresso_admin_pages_general_settings_AdminOptionsSettings__generate__form',
155
-            $form,
156
-            $this->registry->CFG->admin,
157
-            $this
158
-        );
159
-        return $form;
160
-    }
58
+	/**
59
+	 * creates and returns the actual form
60
+	 *
61
+	 * @return EE_Form_Section_Proper
62
+	 * @throws EE_Error
63
+	 */
64
+	public function generate()
65
+	{
66
+		$form = new EE_Form_Section_Proper(
67
+			array(
68
+				'name'            => 'admin_option_settings',
69
+				'html_id'         => 'admin_option_settings',
70
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
71
+				'subsections'     => array(
72
+					'compatibility_hdr'        => new EE_Form_Section_HTML(
73
+						EEH_HTML::h2(
74
+							esc_html__('Compatibility Settings', 'event_espresso'),
75
+							'',
76
+							'ee-admin-settings-hdr'
77
+						)
78
+					),
79
+					'encode_session_data'      => new EE_Yes_No_Input(
80
+						array(
81
+							'html_label_text' => esc_html__('Encode Session Data?', 'event_espresso'),
82
+							'html_help_text'  => sprintf(
83
+								esc_html__(
84
+									'Some servers and database configurations can cause problems when saving the Event Espresso session data. Setting this option to "Yes" adds an extra layer of encoding to session data to prevent serialization errors, but can be incompatible with some server configurations.%1$sIf you receive "500 internal server" type errors during registration, try turning this option on.%1$sIf you get fatal PHP errors regarding missing base64 functions, then turn this option off.',
85
+									'event_espresso'
86
+								),
87
+								'<br>'
88
+							),
89
+							'default'         => $this->registry->CFG->admin->encode_session_data(),
90
+							'required'        => false,
91
+						)
92
+					),
93
+				),
94
+			)
95
+		);
96
+		if (
97
+			$this->registry->CAP->current_user_can(
98
+				'manage_options',
99
+				'display_admin_settings_options_promote_and_affiliate'
100
+			)
101
+		) {
102
+			$form->add_subsections(
103
+				array(
104
+					'promote_ee_hdr'  => new EE_Form_Section_HTML(
105
+						EEH_HTML::h2(
106
+							esc_html__('Promote Event Espresso', 'event_espresso')
107
+							. ' '
108
+							. EEH_HTML::span(
109
+								EEH_Template::get_help_tab_link('affiliate_info'),
110
+								'affiliate_info'
111
+							),
112
+							'',
113
+							'ee-admin-settings-hdr'
114
+						)
115
+					),
116
+					'show_reg_footer' => new EE_Yes_No_Input(
117
+						array(
118
+							'html_label_text' => esc_html__(
119
+								'Link to Event Espresso in your Registration Page?',
120
+								'event_espresso'
121
+							)
122
+							. EEH_Template::get_help_tab_link('email_validation_info'),
123
+							'html_help_text'  => esc_html__(
124
+								'adds an unobtrusive link to Event Espresso\'s website in the footer of your registration form. Get an affiliate link (see below) and make money if people click the link and purchase Event Espresso.',
125
+								'event_espresso'
126
+							),
127
+							'default'         => filter_var($this->registry->CFG->admin->show_reg_footer, FILTER_VALIDATE_BOOLEAN),
128
+							'required'        => false,
129
+						)
130
+					),
131
+					'affiliate_id'    => new EE_Text_Input(
132
+						array(
133
+							'html_label_text' => sprintf(
134
+								esc_html__('Event Espresso %1$sAffiliate%2$s ID', 'event_espresso'),
135
+								'<a href="https://eventespresso.com/affiliates/" target="_blank">',
136
+								'</a>'
137
+							),
138
+							'html_help_text'  => esc_html__(
139
+								'Earn cash for promoting Event Espresso.',
140
+								'event_espresso'
141
+							),
142
+							'html_class'      => 'regular-text',
143
+							'default'         => isset($this->registry->CFG->admin->affiliate_id)
144
+								? $this->registry->CFG->admin->get_pretty('affiliate_id')
145
+								: '',
146
+							'required'        => false,
147
+						)
148
+					),
149
+				),
150
+				'compatibility_hdr'
151
+			);
152
+		}
153
+		do_action(
154
+			'AHEE__EventEspresso_admin_pages_general_settings_AdminOptionsSettings__generate__form',
155
+			$form,
156
+			$this->registry->CFG->admin,
157
+			$this
158
+		);
159
+		return $form;
160
+	}
161 161
 
162 162
 
163
-    /**
164
-     * takes the generated form and displays it along with ony other non-form HTML that may be required
165
-     * returns a string of HTML that can be directly echoed in a template
166
-     *
167
-     * @return string
168
-     * @throws LogicException
169
-     * @throws EE_Error
170
-     */
171
-    public function display()
172
-    {
173
-        add_filter(
174
-            'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__before_form',
175
-            array($this, 'handleOldAdminOptionsSettingsAction')
176
-        );
177
-        return parent::display();
178
-    }
163
+	/**
164
+	 * takes the generated form and displays it along with ony other non-form HTML that may be required
165
+	 * returns a string of HTML that can be directly echoed in a template
166
+	 *
167
+	 * @return string
168
+	 * @throws LogicException
169
+	 * @throws EE_Error
170
+	 */
171
+	public function display()
172
+	{
173
+		add_filter(
174
+			'FHEE__EventEspresso_core_libraries_form_sections_form_handlers_FormHandler__display__before_form',
175
+			array($this, 'handleOldAdminOptionsSettingsAction')
176
+		);
177
+		return parent::display();
178
+	}
179 179
 
180 180
 
181
-    /**
182
-     * @return string
183
-     */
184
-    public function handleOldAdminOptionsSettingsAction()
185
-    {
186
-        ob_start();
187
-        do_action('AHEE__admin_option_settings__template__before', $this->template_args);
188
-        return ob_get_clean();
189
-    }
181
+	/**
182
+	 * @return string
183
+	 */
184
+	public function handleOldAdminOptionsSettingsAction()
185
+	{
186
+		ob_start();
187
+		do_action('AHEE__admin_option_settings__template__before', $this->template_args);
188
+		return ob_get_clean();
189
+	}
190 190
 
191 191
 
192
-    /**
193
-     * handles processing the form submission
194
-     * returns true or false depending on whether the form was processed successfully or not
195
-     *
196
-     * @param array $form_data
197
-     * @return bool
198
-     * @throws InvalidFormSubmissionException
199
-     * @throws EE_Error
200
-     * @throws LogicException
201
-     * @throws InvalidArgumentException
202
-     * @throws InvalidDataTypeException
203
-     */
204
-    public function process($form_data = array())
205
-    {
206
-        // process form
207
-        $valid_data = (array) parent::process($form_data);
208
-        if (empty($valid_data)) {
209
-            return false;
210
-        }
211
-        $this->registry->CFG->admin->show_reg_footer = isset($valid_data['show_reg_footer'])
212
-            ? absint($valid_data['show_reg_footer'])
213
-            : $this->registry->CFG->admin->show_reg_footer;
214
-        $this->registry->CFG->admin->affiliate_id = isset($valid_data['affiliate_id'])
215
-            ? sanitize_text_field($valid_data['affiliate_id'])
216
-            : $this->registry->CFG->admin->affiliate_id;
217
-        if (isset($valid_data['encode_session_data'])) {
218
-            $this->registry->CFG->admin->set_encode_session_data($valid_data['encode_session_data']);
219
-        }
192
+	/**
193
+	 * handles processing the form submission
194
+	 * returns true or false depending on whether the form was processed successfully or not
195
+	 *
196
+	 * @param array $form_data
197
+	 * @return bool
198
+	 * @throws InvalidFormSubmissionException
199
+	 * @throws EE_Error
200
+	 * @throws LogicException
201
+	 * @throws InvalidArgumentException
202
+	 * @throws InvalidDataTypeException
203
+	 */
204
+	public function process($form_data = array())
205
+	{
206
+		// process form
207
+		$valid_data = (array) parent::process($form_data);
208
+		if (empty($valid_data)) {
209
+			return false;
210
+		}
211
+		$this->registry->CFG->admin->show_reg_footer = isset($valid_data['show_reg_footer'])
212
+			? absint($valid_data['show_reg_footer'])
213
+			: $this->registry->CFG->admin->show_reg_footer;
214
+		$this->registry->CFG->admin->affiliate_id = isset($valid_data['affiliate_id'])
215
+			? sanitize_text_field($valid_data['affiliate_id'])
216
+			: $this->registry->CFG->admin->affiliate_id;
217
+		if (isset($valid_data['encode_session_data'])) {
218
+			$this->registry->CFG->admin->set_encode_session_data($valid_data['encode_session_data']);
219
+		}
220 220
 
221
-        return apply_filters(
222
-            'FHEE__EventEspresso_admin_pages_general_settings_AdminOptionsSettings__process__form_processed',
223
-            true, // form processed successfully
224
-            $valid_data,
225
-            $this->registry->CFG->admin,
226
-            $this
227
-        );
228
-    }
221
+		return apply_filters(
222
+			'FHEE__EventEspresso_admin_pages_general_settings_AdminOptionsSettings__process__form_processed',
223
+			true, // form processed successfully
224
+			$valid_data,
225
+			$this->registry->CFG->admin,
226
+			$this
227
+		);
228
+	}
229 229
 }
Please login to merge, or discard this patch.
admin_pages/maintenance/Maintenance_Admin_Page.core.php 1 patch
Indentation   +959 added lines, -959 removed lines patch added patch discarded remove patch
@@ -15,963 +15,963 @@
 block discarded – undo
15 15
  */
16 16
 class Maintenance_Admin_Page extends EE_Admin_Page
17 17
 {
18
-    /**
19
-     * @var EE_Data_Migration_Manager
20
-     */
21
-    protected $migration_manager;
22
-
23
-    /**
24
-     * @var EE_Maintenance_Mode
25
-     */
26
-    protected $maintenance_mode;
27
-
28
-    /**
29
-     * @var EE_Form_Section_Proper
30
-     */
31
-    protected $datetime_fix_offset_form;
32
-
33
-
34
-    /**
35
-     * @param bool $routing
36
-     * @throws EE_Error
37
-     * @throws ReflectionException
38
-     */
39
-    public function __construct($routing = true)
40
-    {
41
-        $this->migration_manager = EE_Data_Migration_Manager::instance();
42
-        $this->maintenance_mode  = EE_Maintenance_Mode::instance();
43
-        parent::__construct($routing);
44
-    }
45
-
46
-
47
-    protected function _init_page_props()
48
-    {
49
-        $this->page_slug        = EE_MAINTENANCE_PG_SLUG;
50
-        $this->page_label       = EE_MAINTENANCE_LABEL;
51
-        $this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
52
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
53
-    }
54
-
55
-
56
-    protected function _ajax_hooks()
57
-    {
58
-        if (! $this->capabilities->current_user_can('manage_options', 'perform-migrations')) {
59
-            return;
60
-        }
61
-        add_action('wp_ajax_migration_step', [$this, 'migration_step']);
62
-        add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
63
-    }
64
-
65
-
66
-    protected function _define_page_props()
67
-    {
68
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
69
-        $this->_labels           = [
70
-            'buttons' => [
71
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
72
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
73
-            ],
74
-        ];
75
-    }
76
-
77
-
78
-    protected function _set_page_routes()
79
-    {
80
-        $this->_page_routes = [
81
-            'default'                             => [
82
-                'func'       => [$this, '_maintenance'],
83
-                'capability' => 'manage_options',
84
-            ],
85
-            'change_maintenance_level'            => [
86
-                'func'       => [$this, '_change_maintenance_level'],
87
-                'capability' => 'manage_options',
88
-                'noheader'   => true,
89
-            ],
90
-            'system_status'                       => [
91
-                'func'       => [$this, '_system_status'],
92
-                'capability' => 'manage_options',
93
-            ],
94
-            'download_system_status'              => [
95
-                'func'       => [$this, '_download_system_status'],
96
-                'capability' => 'manage_options',
97
-                'noheader'   => true,
98
-            ],
99
-            'send_migration_crash_report'         => [
100
-                'func'       => [$this, '_send_migration_crash_report'],
101
-                'capability' => 'manage_options',
102
-                'noheader'   => true,
103
-            ],
104
-            'confirm_migration_crash_report_sent' => [
105
-                'func'       => [$this, '_confirm_migration_crash_report_sent'],
106
-                'capability' => 'manage_options',
107
-            ],
108
-            'data_reset'                          => [
109
-                'func'       => [$this, '_data_reset_and_delete'],
110
-                'capability' => 'manage_options',
111
-            ],
112
-            'reset_db'                            => [
113
-                'func'       => [$this, '_reset_db'],
114
-                'capability' => 'manage_options',
115
-                'noheader'   => true,
116
-                'args'       => ['nuke_old_ee4_data' => true],
117
-            ],
118
-            'start_with_fresh_ee4_db'             => [
119
-                'func'       => [$this, '_reset_db'],
120
-                'capability' => 'manage_options',
121
-                'noheader'   => true,
122
-                'args'       => ['nuke_old_ee4_data' => false],
123
-            ],
124
-            'delete_db'                           => [
125
-                'func'       => [$this, '_delete_db'],
126
-                'capability' => 'manage_options',
127
-                'noheader'   => true,
128
-            ],
129
-            'rerun_migration_from_ee3'            => [
130
-                'func'       => [$this, '_rerun_migration_from_ee3'],
131
-                'capability' => 'manage_options',
132
-                'noheader'   => true,
133
-            ],
134
-            'reset_reservations'                  => [
135
-                'func'       => [$this, '_reset_reservations'],
136
-                'capability' => 'manage_options',
137
-                'noheader'   => true,
138
-            ],
139
-            'reset_capabilities'                  => [
140
-                'func'       => [$this, '_reset_capabilities'],
141
-                'capability' => 'manage_options',
142
-                'noheader'   => true,
143
-            ],
144
-            'reattempt_migration'                 => [
145
-                'func'       => [$this, '_reattempt_migration'],
146
-                'capability' => 'manage_options',
147
-                'noheader'   => true,
148
-            ],
149
-            'datetime_tools'                      => [
150
-                'func'       => [$this, '_datetime_tools'],
151
-                'capability' => 'manage_options',
152
-            ],
153
-            'run_datetime_offset_fix'             => [
154
-                'func'               => [$this, '_apply_datetime_offset'],
155
-                'noheader'           => true,
156
-                'headers_sent_route' => 'datetime_tools',
157
-                'capability'         => 'manage_options',
158
-            ],
159
-        ];
160
-    }
161
-
162
-
163
-    protected function _set_page_config()
164
-    {
165
-        $this->_page_config = [
166
-            'default'        => [
167
-                'nav'           => [
168
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
169
-                    'icon'  => 'dashicons-admin-tools',
170
-                    'order' => 10,
171
-                ],
172
-                'require_nonce' => false,
173
-            ],
174
-            'data_reset'     => [
175
-                'nav'           => [
176
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
177
-                    'icon'  => 'dashicons-trash',
178
-                    'order' => 20,
179
-                ],
180
-                'require_nonce' => false,
181
-            ],
182
-            'datetime_tools' => [
183
-                'nav'           => [
184
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
185
-                    'icon'  => 'dashicons-calendar-alt',
186
-                    'order' => 25,
187
-                ],
188
-                'require_nonce' => false,
189
-            ],
190
-            'system_status'  => [
191
-                'nav'           => [
192
-                    'label' => esc_html__("System Information", "event_espresso"),
193
-                    'icon'  => 'dashicons-info',
194
-                    'order' => 30,
195
-                ],
196
-                'require_nonce' => false,
197
-            ],
198
-        ];
199
-    }
200
-
201
-
202
-    /**
203
-     * default maintenance page.
204
-     * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
205
-     *
206
-     * @throws EE_Error
207
-     */
208
-    public function _maintenance()
209
-    {
210
-        $show_maintenance_switch         = true;
211
-        $show_backup_db_text             = false;
212
-        $show_migration_progress         = false;
213
-        $script_names                    = [];
214
-        $addons_should_be_upgraded_first = false;
215
-        // it all depends on if we're in maintenance model level 1 (frontend-only) or
216
-        // level 2 (everything except maintenance page)
217
-        try {
218
-            // get the current maintenance level and check if we are removed
219
-            $was_full_site_maintenence_mode = MaintenanceStatus::isFullSite();
220
-            $no_longer_in_maintenence_mode = ! $this->maintenance_mode->set_maintenance_mode_if_db_old();
221
-            if ($was_full_site_maintenence_mode && $no_longer_in_maintenence_mode) {
222
-                // we just took the site out of maintenance mode, so notify the user.
223
-                // unfortunately this message appears to be echoed on the NEXT page load...
224
-                // oh well, we should really be checking for this on addon deactivation anyways
225
-                EE_Error::add_attention(
226
-                    esc_html__(
227
-                        'Site taken out of maintenance mode because no data migration scripts are required',
228
-                        'event_espresso'
229
-                    )
230
-                );
231
-                $this->_process_notices(['page' => 'espresso_maintenance_settings']);
232
-            }
233
-            // in case an exception is thrown while trying to handle migrations
234
-            if (MaintenanceStatus::isFullSite()) {
235
-                $show_maintenance_switch = false;
236
-                $show_migration_progress = true;
237
-                if (! isset($this->_req_data['continue_migration'])) {
238
-                    $show_backup_db_text = true;
239
-                }
240
-                $scripts_needing_to_run          =
241
-                    $this->migration_manager->check_for_applicable_data_migration_scripts();
242
-                $addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
243
-                $script_names                    = [];
244
-                $current_script                  = null;
245
-                foreach ($scripts_needing_to_run as $script) {
246
-                    if ($script instanceof EE_Data_Migration_Script_Base) {
247
-                        if (! $current_script) {
248
-                            $current_script = $script;
249
-                            $current_script->migration_page_hooks();
250
-                        }
251
-                        $script_names[] = $script->pretty_name();
252
-                    }
253
-                }
254
-            }
255
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
256
-            $exception_thrown      = false;
257
-        } catch (EE_Error $e) {
258
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
259
-            // now, just so we can display the page correctly, make an error migration script stage object
260
-            // and also put the error on it. It only persists for the duration of this request
261
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
262
-            $most_recent_migration->add_error($e->getMessage());
263
-            $exception_thrown = true;
264
-        }
265
-        $current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
266
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
267
-        if (
268
-            $exception_thrown
269
-            || (
270
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
271
-                && $most_recent_migration->is_broken()
272
-            )
273
-        ) {
274
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
-
276
-            $this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
277
-            $this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
278
-                [
279
-                    'action'  => 'confirm_migration_crash_report_sent',
280
-                    'success' => '0',
281
-                ],
282
-                EE_MAINTENANCE_ADMIN_URL
283
-            );
284
-        } elseif ($addons_should_be_upgraded_first) {
285
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
286
-        } else {
287
-            if (
288
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
289
-                && $most_recent_migration->can_continue()
290
-            ) {
291
-                $show_backup_db_text                    = false;
292
-                $show_continue_current_migration_script = true;
293
-                $show_most_recent_migration             = true;
294
-            } elseif (isset($this->_req_data['continue_migration'])) {
295
-                $show_most_recent_migration             = true;
296
-                $show_continue_current_migration_script = false;
297
-            } else {
298
-                $show_most_recent_migration             = false;
299
-                $show_continue_current_migration_script = false;
300
-            }
301
-            if (isset($current_script)) {
302
-                $migrates_to          = $current_script->migrates_to_version();
303
-                $plugin_slug          = $migrates_to['slug'];
304
-                $new_version          = $migrates_to['version'];
305
-                $this->_template_args = array_merge(
306
-                    $this->_template_args,
307
-                    [
308
-                        'current_db_state' => sprintf(
309
-                            esc_html__("EE%s (%s)", "event_espresso"),
310
-                            $current_db_state[ $plugin_slug ] ?? 3,
311
-                            $plugin_slug
312
-                        ),
313
-                        'next_db_state'    => sprintf(
314
-                            esc_html__("EE%s (%s)", 'event_espresso'),
315
-                            $new_version,
316
-                            $plugin_slug
317
-                        ),
318
-                    ]
319
-                );
320
-            } else {
321
-                $this->_template_args['current_db_state'] = '';
322
-                $this->_template_args['next_db_state']    = '';
323
-            }
324
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
325
-            $this->_template_args = array_merge(
326
-                $this->_template_args,
327
-                [
328
-                    'show_most_recent_migration'             => $show_most_recent_migration,
329
-                    // flag for showing the most recent migration's status and/or errors
330
-                    'show_migration_progress'                => $show_migration_progress,
331
-                    // flag for showing the option to run migrations and see their progress
332
-                    'show_backup_db_text'                    => $show_backup_db_text,
333
-                    // flag for showing text telling the user to back up their DB
334
-                    'show_maintenance_switch'                => $show_maintenance_switch,
335
-                    // flag for showing the option to change maintenance mode between levels 0 and 1
336
-                    'script_names'                           => $script_names,
337
-                    // array of names of scripts that have run
338
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
339
-                    // flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
340
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
341
-                        ['action' => 'reset_db'],
342
-                        EE_MAINTENANCE_ADMIN_URL
343
-                    ),
344
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
345
-                        ['action' => 'data_reset'],
346
-                        EE_MAINTENANCE_ADMIN_URL
347
-                    ),
348
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
349
-                        ['action' => 'change_maintenance_level'],
350
-                        EE_MAINTENANCE_ADMIN_URL
351
-                    ),
352
-                    'ultimate_db_state'                      => sprintf(
353
-                        esc_html__("EE%s", 'event_espresso'),
354
-                        espresso_version()
355
-                    ),
356
-                    'real_level'                             => $this->maintenance_mode->real_level(),
357
-                ]
358
-            );
359
-        }
360
-        $this->_template_args['most_recent_migration'] =
361
-            $most_recent_migration;// the actual most recently ran migration
362
-        // now render the migration options part, and put it in a variable
363
-        $migration_options_template_file                = apply_filters(
364
-            'FHEE__ee_migration_page__migration_options_template',
365
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
366
-        );
367
-        $migration_options_html                         = EEH_Template::display_template(
368
-            $migration_options_template_file,
369
-            $this->_template_args,
370
-            true
371
-        );
372
-        $this->_template_args['migration_options_html'] = $migration_options_html;
373
-        $this->_template_args['admin_page_content']     = EEH_Template::display_template(
374
-            $this->_template_path,
375
-            $this->_template_args,
376
-            true
377
-        );
378
-        $this->display_admin_page_with_sidebar();
379
-    }
380
-
381
-
382
-    /**
383
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
384
-     *
385
-     * @throws EE_Error
386
-     */
387
-    public function migration_step()
388
-    {
389
-        if (! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
390
-            wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
391
-        }
392
-        $this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
393
-        $this->_return_json();
394
-    }
395
-
396
-
397
-    /**
398
-     * Can be used by js when it notices a response with HTML in it in order
399
-     * to log the malformed response
400
-     *
401
-     * @throws EE_Error
402
-     */
403
-    public function add_error_to_migrations_ran()
404
-    {
405
-        $this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
406
-        $this->_template_args['data'] = ['ok' => true];
407
-        $this->_return_json();
408
-    }
409
-
410
-
411
-    /**
412
-     * changes the maintenance level, provided there are still no migration scripts that should run
413
-     *
414
-     * @throws EE_Error
415
-     */
416
-    public function _change_maintenance_level()
417
-    {
418
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
419
-        if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
420
-            $this->maintenance_mode->set_maintenance_level($new_level);
421
-            $success = true;
422
-        } else {
423
-            $this->maintenance_mode->set_maintenance_mode_if_db_old();
424
-            $success = false;
425
-        }
426
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
427
-    }
428
-
429
-
430
-    /**
431
-     * a tab with options for resetting and/or deleting EE data
432
-     *
433
-     * @throws EE_Error
434
-     * @throws DomainException
435
-     */
436
-    public function _data_reset_and_delete()
437
-    {
438
-        $this->_template_path                              =
439
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
440
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
441
-            'reset_reservations',
442
-            'reset_reservations',
443
-            [],
444
-            'button button--caution ee-confirm'
445
-        );
446
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
447
-            'reset_capabilities',
448
-            'reset_capabilities',
449
-            [],
450
-            'button button--caution ee-confirm'
451
-        );
452
-        $this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
453
-            ['action' => 'delete_db'],
454
-            EE_MAINTENANCE_ADMIN_URL
455
-        );
456
-        $this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
457
-            ['action' => 'reset_db'],
458
-            EE_MAINTENANCE_ADMIN_URL
459
-        );
460
-        $this->_template_args['admin_page_content']        = EEH_Template::display_template(
461
-            $this->_template_path,
462
-            $this->_template_args,
463
-            true
464
-        );
465
-        $this->display_admin_page_with_no_sidebar();
466
-    }
467
-
468
-
469
-    /**
470
-     * @throws EE_Error
471
-     * @throws ReflectionException
472
-     */
473
-    protected function _reset_reservations()
474
-    {
475
-        if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
476
-            EE_Error::add_success(
477
-                esc_html__(
478
-                    'Ticket and datetime reserved counts have been successfully reset.',
479
-                    'event_espresso'
480
-                )
481
-            );
482
-        } else {
483
-            EE_Error::add_success(
484
-                esc_html__(
485
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
486
-                    'event_espresso'
487
-                )
488
-            );
489
-        }
490
-        $this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
491
-    }
492
-
493
-
494
-    /**
495
-     * @throws EE_Error
496
-     */
497
-    protected function _reset_capabilities()
498
-    {
499
-        $this->capabilities->init_caps(true);
500
-        EE_Error::add_success(
501
-            esc_html__(
502
-                'Default Event Espresso capabilities have been restored for all current roles.',
503
-                'event_espresso'
504
-            )
505
-        );
506
-        $this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
507
-    }
508
-
509
-
510
-    /**
511
-     * resets the DMSs, so we can attempt to continue migrating after a fatal error
512
-     * (only a good idea when someone has somehow tried ot fix whatever caused
513
-     * the fatal error in teh first place)
514
-     *
515
-     * @throws EE_Error
516
-     */
517
-    protected function _reattempt_migration()
518
-    {
519
-        $this->migration_manager->reattempt();
520
-        $this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
521
-    }
522
-
523
-
524
-    /**
525
-     * shows the big ol' System Information page
526
-     *
527
-     * @throws EE_Error
528
-     */
529
-    public function _system_status()
530
-    {
531
-        $this->_template_path                               =
532
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
533
-        $this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
534
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
535
-            [
536
-                'action' => 'download_system_status',
537
-            ],
538
-            EE_MAINTENANCE_ADMIN_URL
539
-        );
540
-        $this->_template_args['admin_page_content']         = EEH_Template::display_template(
541
-            $this->_template_path,
542
-            $this->_template_args,
543
-            true
544
-        );
545
-        $this->display_admin_page_with_no_sidebar();
546
-    }
547
-
548
-
549
-    /**
550
-     * Downloads an HTML file of the system status that can be easily stored or emailed
551
-     */
552
-    public function _download_system_status()
553
-    {
554
-        $status_info = EEM_System_Status::instance()->get_system_stati();
555
-        header('Content-Disposition: attachment');
556
-        header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
557
-        $output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
558
-        $output .= '<h1>' . sprintf(
559
-            __('System Information for %1$s', 'event_espresso'),
560
-            esc_url_raw(site_url())
561
-        ) . '</h1>';
562
-        $output .= EEH_Template::layout_array_as_table($status_info);
563
-        echo esc_html($output);
564
-        die;
565
-    }
566
-
567
-
568
-    /**
569
-     * @throws EE_Error
570
-     */
571
-    public function _send_migration_crash_report()
572
-    {
573
-        $from      = $this->_req_data['from'];
574
-        $from_name = $this->_req_data['from_name'];
575
-        $body      = $this->_req_data['body'];
576
-        try {
577
-            $success = wp_mail(
578
-                EE_SUPPORT_EMAIL,
579
-                'Migration Crash Report',
580
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
581
-                [
582
-                    "from:$from_name<$from>",
583
-                ]
584
-            );
585
-        } catch (Exception $e) {
586
-            $success = false;
587
-        }
588
-        $this->_redirect_after_action(
589
-            $success,
590
-            esc_html__("Migration Crash Report", "event_espresso"),
591
-            esc_html__("sent", "event_espresso"),
592
-            ['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
593
-        );
594
-    }
595
-
596
-
597
-    /**
598
-     * @throws EE_Error
599
-     */
600
-    public function _confirm_migration_crash_report_sent()
601
-    {
602
-        try {
603
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
604
-        } catch (EE_Error $e) {
605
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
606
-            // now, just so we can display the page correctly, make an error migration script stage object
607
-            // and also put the error on it. It only persists for the duration of this request
608
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
609
-            $most_recent_migration->add_error($e->getMessage());
610
-        }
611
-        $success                                       = $this->_req_data['success'] === '1';
612
-        $this->_template_args['success']               = $success;
613
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
614
-        $this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
615
-            ['action' => 'reset_db'],
616
-            EE_MAINTENANCE_ADMIN_URL
617
-        );
618
-        $this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
619
-            ['action' => 'data_reset'],
620
-            EE_MAINTENANCE_ADMIN_URL
621
-        );
622
-        $this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
623
-            ['action' => 'reattempt_migration'],
624
-            EE_MAINTENANCE_ADMIN_URL
625
-        );
626
-        $this->_template_path                          =
627
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
628
-        $this->_template_args['admin_page_content']    = EEH_Template::display_template(
629
-            $this->_template_path,
630
-            $this->_template_args,
631
-            true
632
-        );
633
-        $this->display_admin_page_with_sidebar();
634
-    }
635
-
636
-
637
-    /**
638
-     * Resets the entire EE4 database.
639
-     * only sets up ee4 database for a fresh install-
640
-     * doesn't actually clean out the old wp options, or cpts
641
-     * (although it does erase old ee table data)
642
-     *
643
-     * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
644
-     *                                   or just try initializing ee4 default data
645
-     * @throws EE_Error
646
-     * @throws ReflectionException
647
-     */
648
-    public function _reset_db($nuke_old_ee4_data = true)
649
-    {
650
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
651
-        if ($nuke_old_ee4_data) {
652
-            EEH_Activation::delete_all_espresso_cpt_data();
653
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
654
-            EEH_Activation::remove_cron_tasks();
655
-        }
656
-        // make sure when we reset the registry's config that it
657
-        // switches to using the new singleton
658
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
659
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
660
-        EE_System::instance()->redirect_to_about_ee();
661
-    }
662
-
663
-
664
-    /**
665
-     * Deletes ALL EE tables, Records, and Options from the database.
666
-     *
667
-     * @throws EE_Error
668
-     * @throws ReflectionException
669
-     */
670
-    public function _delete_db()
671
-    {
672
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
673
-        EEH_Activation::delete_all_espresso_cpt_data();
674
-        EEH_Activation::delete_all_espresso_tables_and_data();
675
-        EEH_Activation::remove_cron_tasks();
676
-        EEH_Activation::deactivate_event_espresso();
677
-        wp_safe_redirect(admin_url('plugins.php'));
678
-        exit;
679
-    }
680
-
681
-
682
-    /**
683
-     * sets up EE4 to rerun the migrations from ee3 to ee4
684
-     *
685
-     * @throws EE_Error
686
-     * @throws ReflectionException
687
-     */
688
-    public function _rerun_migration_from_ee3()
689
-    {
690
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
691
-        EEH_Activation::delete_all_espresso_cpt_data();
692
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
693
-        // set the db state to something that will require migrations
694
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
695
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_FULL_SITE);
696
-        $this->_redirect_after_action(
697
-            true,
698
-            esc_html__("Database", 'event_espresso'),
699
-            esc_html__("reset", 'event_espresso')
700
-        );
701
-    }
702
-
703
-
704
-    // none of the below group are currently used for Gateway Settings
705
-    protected function _add_screen_options()
706
-    {
707
-    }
708
-
709
-
710
-    protected function _add_feature_pointers()
711
-    {
712
-    }
713
-
714
-
715
-    public function admin_init()
716
-    {
717
-    }
718
-
719
-
720
-    public function admin_notices()
721
-    {
722
-    }
723
-
724
-
725
-    public function admin_footer_scripts()
726
-    {
727
-    }
728
-
729
-
730
-    public function load_scripts_styles()
731
-    {
732
-        wp_enqueue_script('ee_admin_js');
733
-        wp_enqueue_script(
734
-            'ee-maintenance',
735
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
736
-            ['jquery'],
737
-            EVENT_ESPRESSO_VERSION,
738
-            true
739
-        );
740
-        wp_register_style(
741
-            'espresso_maintenance',
742
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
743
-            [],
744
-            EVENT_ESPRESSO_VERSION
745
-        );
746
-        wp_enqueue_style('espresso_maintenance');
747
-        // localize script stuff
748
-        wp_localize_script(
749
-            'ee-maintenance',
750
-            'ee_maintenance',
751
-            [
752
-                'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
753
-                'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
754
-                'fatal_error'                      => wp_strip_all_tags(
755
-                    __(
756
-                        "A Fatal Error Has Occurred",
757
-                        "event_espresso"
758
-                    )
759
-                ),
760
-                'click_next_when_ready'            => wp_strip_all_tags(
761
-                    __(
762
-                        "The current Database Update has ended. Click 'next' when ready to proceed",
763
-                        "event_espresso"
764
-                    )
765
-                ),
766
-                'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
767
-                'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
768
-                'status_completed'                 => EE_Data_Migration_Manager::status_completed,
769
-                'confirm'                          => wp_strip_all_tags(
770
-                    __(
771
-                        'Are you sure you want to do this? It CANNOT be undone!',
772
-                        'event_espresso'
773
-                    )
774
-                ),
775
-                'confirm_skip_migration'           => wp_strip_all_tags(
776
-                    __(
777
-                        'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
778
-                        'event_espresso'
779
-                    )
780
-                ),
781
-            ]
782
-        );
783
-    }
784
-
785
-
786
-    public function load_scripts_styles_default()
787
-    {
788
-    }
789
-
790
-
791
-    /**
792
-     * Enqueue scripts and styles for the datetime tools page.
793
-     */
794
-    public function load_scripts_styles_datetime_tools()
795
-    {
796
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
797
-    }
798
-
799
-
800
-    /**
801
-     * @throws EE_Error
802
-     */
803
-    protected function _datetime_tools()
804
-    {
805
-        $form_action                                = EE_Admin_Page::add_query_args_and_nonce(
806
-            [
807
-                'action'        => 'run_datetime_offset_fix',
808
-                'return_action' => $this->_req_action,
809
-            ],
810
-            EE_MAINTENANCE_ADMIN_URL
811
-        );
812
-        $form                                       = $this->_get_datetime_offset_fix_form();
813
-        $this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
814
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
815
-                                                      . $form->get_html_and_js()
816
-                                                      . $form->form_close();
817
-        $this->display_admin_page_with_sidebar();
818
-    }
819
-
820
-
821
-    /**
822
-     * @throws EE_Error
823
-     */
824
-    protected function _get_datetime_offset_fix_form()
825
-    {
826
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
827
-            $this->datetime_fix_offset_form = new EE_Form_Section_Proper(
828
-                [
829
-                    'name'            => 'datetime_offset_fix_option',
830
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
831
-                    'subsections'     => [
832
-                        'title'                  => new EE_Form_Section_HTML(
833
-                            EEH_HTML::h2(
834
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
835
-                            )
836
-                        ),
837
-                        'explanation'            => new EE_Form_Section_HTML(
838
-                            EEH_HTML::p(
839
-                                esc_html__(
840
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
841
-                                    'event_espresso'
842
-                                )
843
-                            )
844
-                            . EEH_HTML::p(
845
-                                esc_html__(
846
-                                    'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
847
-                                    'event_espresso'
848
-                                )
849
-                            )
850
-                        ),
851
-                        'offset_input'           => new EE_Float_Input(
852
-                            [
853
-                                'html_name'       => 'offset_for_datetimes',
854
-                                'html_label_text' => esc_html__(
855
-                                    'Offset to apply (in hours):',
856
-                                    'event_espresso'
857
-                                ),
858
-                                'min_value'       => '-12',
859
-                                'max_value'       => '14',
860
-                                'step_value'      => '.25',
861
-                                'default'         => DatetimeOffsetFix::getOffset(),
862
-                            ]
863
-                        ),
864
-                        'date_range_explanation' => new EE_Form_Section_HTML(
865
-                            EEH_HTML::p(
866
-                                esc_html__(
867
-                                    'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
868
-                                    'event_espresso'
869
-                                )
870
-                            )
871
-                            . EEH_HTML::p(
872
-                                EEH_HTML::strong(
873
-                                    sprintf(
874
-                                        esc_html__(
875
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
876
-                                            'event_espresso'
877
-                                        ),
878
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
879
-                                        '</a>'
880
-                                    )
881
-                                )
882
-                            )
883
-                        ),
884
-                        'date_range_start_date'  => new EE_Datepicker_Input(
885
-                            [
886
-                                'html_name'       => 'offset_date_start_range',
887
-                                'html_label_text' => esc_html__(
888
-                                    'Start Date for dates the offset applied to:',
889
-                                    'event_espresso'
890
-                                ),
891
-                            ]
892
-                        ),
893
-                        'date_range_end_date'    => new EE_Datepicker_Input(
894
-                            [
895
-                                'html_name'       => 'offset_date_end_range',
896
-                                'html_label_text' => esc_html__(
897
-                                    'End Date for dates the offset is applied to:',
898
-                                    'event_espresso'
899
-                                ),
900
-                            ]
901
-                        ),
902
-                        'submit'                 => new EE_Submit_Input(
903
-                            [
904
-                                'html_label_text' => '',
905
-                                'default'         => esc_html__('Apply Offset', 'event_espresso'),
906
-                            ]
907
-                        ),
908
-                    ],
909
-                ]
910
-            );
911
-        }
912
-        return $this->datetime_fix_offset_form;
913
-    }
914
-
915
-
916
-    /**
917
-     * Callback for the run_datetime_offset_fix route.
918
-     *
919
-     * @throws EE_Error
920
-     */
921
-    protected function _apply_datetime_offset()
922
-    {
923
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
924
-            $form = $this->_get_datetime_offset_fix_form();
925
-            $form->receive_form_submission($this->_req_data);
926
-            if ($form->is_valid()) {
927
-                // save offset data so batch processor can get it.
928
-                DatetimeOffsetFix::updateOffset((float) $form->get_input_value('offset_input'));
929
-                $utc_timezone          = new DateTimeZone('UTC');
930
-                $date_range_start_date = DateTime::createFromFormat(
931
-                    'm/d/Y H:i:s',
932
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
933
-                    $utc_timezone
934
-                );
935
-                $date_range_end_date   = DateTime::createFromFormat(
936
-                    'm/d/Y H:i:s',
937
-                    $form->get_input_value('date_range_end_date') . ' 23:59:59',
938
-                    $utc_timezone
939
-                );
940
-                if ($date_range_start_date instanceof DateTime) {
941
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
942
-                }
943
-                if ($date_range_end_date instanceof DateTime) {
944
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
945
-                }
946
-                // redirect to batch tool
947
-                wp_redirect(
948
-                    EE_Admin_Page::add_query_args_and_nonce(
949
-                        [
950
-                            'page'        => EED_Batch::PAGE_SLUG,
951
-                            'batch'       => EED_Batch::batch_job,
952
-                            'label'       => esc_html__('Applying Offset', 'event_espresso'),
953
-                            'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\DatetimeOffsetFix'),
954
-                            'return_url'  => urlencode(
955
-                                add_query_arg(
956
-                                    [
957
-                                        'action' => 'datetime_tools',
958
-                                    ],
959
-                                    EEH_URL::current_url_without_query_paramaters(
960
-                                        [
961
-                                            'return_action',
962
-                                            'run_datetime_offset_fix_nonce',
963
-                                            'return',
964
-                                            'datetime_tools_nonce',
965
-                                        ]
966
-                                    )
967
-                                )
968
-                            ),
969
-                        ],
970
-                        admin_url()
971
-                    )
972
-                );
973
-                exit;
974
-            }
975
-        }
976
-    }
18
+	/**
19
+	 * @var EE_Data_Migration_Manager
20
+	 */
21
+	protected $migration_manager;
22
+
23
+	/**
24
+	 * @var EE_Maintenance_Mode
25
+	 */
26
+	protected $maintenance_mode;
27
+
28
+	/**
29
+	 * @var EE_Form_Section_Proper
30
+	 */
31
+	protected $datetime_fix_offset_form;
32
+
33
+
34
+	/**
35
+	 * @param bool $routing
36
+	 * @throws EE_Error
37
+	 * @throws ReflectionException
38
+	 */
39
+	public function __construct($routing = true)
40
+	{
41
+		$this->migration_manager = EE_Data_Migration_Manager::instance();
42
+		$this->maintenance_mode  = EE_Maintenance_Mode::instance();
43
+		parent::__construct($routing);
44
+	}
45
+
46
+
47
+	protected function _init_page_props()
48
+	{
49
+		$this->page_slug        = EE_MAINTENANCE_PG_SLUG;
50
+		$this->page_label       = EE_MAINTENANCE_LABEL;
51
+		$this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
52
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
53
+	}
54
+
55
+
56
+	protected function _ajax_hooks()
57
+	{
58
+		if (! $this->capabilities->current_user_can('manage_options', 'perform-migrations')) {
59
+			return;
60
+		}
61
+		add_action('wp_ajax_migration_step', [$this, 'migration_step']);
62
+		add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
63
+	}
64
+
65
+
66
+	protected function _define_page_props()
67
+	{
68
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
69
+		$this->_labels           = [
70
+			'buttons' => [
71
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
72
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
73
+			],
74
+		];
75
+	}
76
+
77
+
78
+	protected function _set_page_routes()
79
+	{
80
+		$this->_page_routes = [
81
+			'default'                             => [
82
+				'func'       => [$this, '_maintenance'],
83
+				'capability' => 'manage_options',
84
+			],
85
+			'change_maintenance_level'            => [
86
+				'func'       => [$this, '_change_maintenance_level'],
87
+				'capability' => 'manage_options',
88
+				'noheader'   => true,
89
+			],
90
+			'system_status'                       => [
91
+				'func'       => [$this, '_system_status'],
92
+				'capability' => 'manage_options',
93
+			],
94
+			'download_system_status'              => [
95
+				'func'       => [$this, '_download_system_status'],
96
+				'capability' => 'manage_options',
97
+				'noheader'   => true,
98
+			],
99
+			'send_migration_crash_report'         => [
100
+				'func'       => [$this, '_send_migration_crash_report'],
101
+				'capability' => 'manage_options',
102
+				'noheader'   => true,
103
+			],
104
+			'confirm_migration_crash_report_sent' => [
105
+				'func'       => [$this, '_confirm_migration_crash_report_sent'],
106
+				'capability' => 'manage_options',
107
+			],
108
+			'data_reset'                          => [
109
+				'func'       => [$this, '_data_reset_and_delete'],
110
+				'capability' => 'manage_options',
111
+			],
112
+			'reset_db'                            => [
113
+				'func'       => [$this, '_reset_db'],
114
+				'capability' => 'manage_options',
115
+				'noheader'   => true,
116
+				'args'       => ['nuke_old_ee4_data' => true],
117
+			],
118
+			'start_with_fresh_ee4_db'             => [
119
+				'func'       => [$this, '_reset_db'],
120
+				'capability' => 'manage_options',
121
+				'noheader'   => true,
122
+				'args'       => ['nuke_old_ee4_data' => false],
123
+			],
124
+			'delete_db'                           => [
125
+				'func'       => [$this, '_delete_db'],
126
+				'capability' => 'manage_options',
127
+				'noheader'   => true,
128
+			],
129
+			'rerun_migration_from_ee3'            => [
130
+				'func'       => [$this, '_rerun_migration_from_ee3'],
131
+				'capability' => 'manage_options',
132
+				'noheader'   => true,
133
+			],
134
+			'reset_reservations'                  => [
135
+				'func'       => [$this, '_reset_reservations'],
136
+				'capability' => 'manage_options',
137
+				'noheader'   => true,
138
+			],
139
+			'reset_capabilities'                  => [
140
+				'func'       => [$this, '_reset_capabilities'],
141
+				'capability' => 'manage_options',
142
+				'noheader'   => true,
143
+			],
144
+			'reattempt_migration'                 => [
145
+				'func'       => [$this, '_reattempt_migration'],
146
+				'capability' => 'manage_options',
147
+				'noheader'   => true,
148
+			],
149
+			'datetime_tools'                      => [
150
+				'func'       => [$this, '_datetime_tools'],
151
+				'capability' => 'manage_options',
152
+			],
153
+			'run_datetime_offset_fix'             => [
154
+				'func'               => [$this, '_apply_datetime_offset'],
155
+				'noheader'           => true,
156
+				'headers_sent_route' => 'datetime_tools',
157
+				'capability'         => 'manage_options',
158
+			],
159
+		];
160
+	}
161
+
162
+
163
+	protected function _set_page_config()
164
+	{
165
+		$this->_page_config = [
166
+			'default'        => [
167
+				'nav'           => [
168
+					'label' => esc_html__('Maintenance', 'event_espresso'),
169
+					'icon'  => 'dashicons-admin-tools',
170
+					'order' => 10,
171
+				],
172
+				'require_nonce' => false,
173
+			],
174
+			'data_reset'     => [
175
+				'nav'           => [
176
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
177
+					'icon'  => 'dashicons-trash',
178
+					'order' => 20,
179
+				],
180
+				'require_nonce' => false,
181
+			],
182
+			'datetime_tools' => [
183
+				'nav'           => [
184
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
185
+					'icon'  => 'dashicons-calendar-alt',
186
+					'order' => 25,
187
+				],
188
+				'require_nonce' => false,
189
+			],
190
+			'system_status'  => [
191
+				'nav'           => [
192
+					'label' => esc_html__("System Information", "event_espresso"),
193
+					'icon'  => 'dashicons-info',
194
+					'order' => 30,
195
+				],
196
+				'require_nonce' => false,
197
+			],
198
+		];
199
+	}
200
+
201
+
202
+	/**
203
+	 * default maintenance page.
204
+	 * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
205
+	 *
206
+	 * @throws EE_Error
207
+	 */
208
+	public function _maintenance()
209
+	{
210
+		$show_maintenance_switch         = true;
211
+		$show_backup_db_text             = false;
212
+		$show_migration_progress         = false;
213
+		$script_names                    = [];
214
+		$addons_should_be_upgraded_first = false;
215
+		// it all depends on if we're in maintenance model level 1 (frontend-only) or
216
+		// level 2 (everything except maintenance page)
217
+		try {
218
+			// get the current maintenance level and check if we are removed
219
+			$was_full_site_maintenence_mode = MaintenanceStatus::isFullSite();
220
+			$no_longer_in_maintenence_mode = ! $this->maintenance_mode->set_maintenance_mode_if_db_old();
221
+			if ($was_full_site_maintenence_mode && $no_longer_in_maintenence_mode) {
222
+				// we just took the site out of maintenance mode, so notify the user.
223
+				// unfortunately this message appears to be echoed on the NEXT page load...
224
+				// oh well, we should really be checking for this on addon deactivation anyways
225
+				EE_Error::add_attention(
226
+					esc_html__(
227
+						'Site taken out of maintenance mode because no data migration scripts are required',
228
+						'event_espresso'
229
+					)
230
+				);
231
+				$this->_process_notices(['page' => 'espresso_maintenance_settings']);
232
+			}
233
+			// in case an exception is thrown while trying to handle migrations
234
+			if (MaintenanceStatus::isFullSite()) {
235
+				$show_maintenance_switch = false;
236
+				$show_migration_progress = true;
237
+				if (! isset($this->_req_data['continue_migration'])) {
238
+					$show_backup_db_text = true;
239
+				}
240
+				$scripts_needing_to_run          =
241
+					$this->migration_manager->check_for_applicable_data_migration_scripts();
242
+				$addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
243
+				$script_names                    = [];
244
+				$current_script                  = null;
245
+				foreach ($scripts_needing_to_run as $script) {
246
+					if ($script instanceof EE_Data_Migration_Script_Base) {
247
+						if (! $current_script) {
248
+							$current_script = $script;
249
+							$current_script->migration_page_hooks();
250
+						}
251
+						$script_names[] = $script->pretty_name();
252
+					}
253
+				}
254
+			}
255
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
256
+			$exception_thrown      = false;
257
+		} catch (EE_Error $e) {
258
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
259
+			// now, just so we can display the page correctly, make an error migration script stage object
260
+			// and also put the error on it. It only persists for the duration of this request
261
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
262
+			$most_recent_migration->add_error($e->getMessage());
263
+			$exception_thrown = true;
264
+		}
265
+		$current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
266
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
267
+		if (
268
+			$exception_thrown
269
+			|| (
270
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
271
+				&& $most_recent_migration->is_broken()
272
+			)
273
+		) {
274
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
+
276
+			$this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
277
+			$this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
278
+				[
279
+					'action'  => 'confirm_migration_crash_report_sent',
280
+					'success' => '0',
281
+				],
282
+				EE_MAINTENANCE_ADMIN_URL
283
+			);
284
+		} elseif ($addons_should_be_upgraded_first) {
285
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
286
+		} else {
287
+			if (
288
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
289
+				&& $most_recent_migration->can_continue()
290
+			) {
291
+				$show_backup_db_text                    = false;
292
+				$show_continue_current_migration_script = true;
293
+				$show_most_recent_migration             = true;
294
+			} elseif (isset($this->_req_data['continue_migration'])) {
295
+				$show_most_recent_migration             = true;
296
+				$show_continue_current_migration_script = false;
297
+			} else {
298
+				$show_most_recent_migration             = false;
299
+				$show_continue_current_migration_script = false;
300
+			}
301
+			if (isset($current_script)) {
302
+				$migrates_to          = $current_script->migrates_to_version();
303
+				$plugin_slug          = $migrates_to['slug'];
304
+				$new_version          = $migrates_to['version'];
305
+				$this->_template_args = array_merge(
306
+					$this->_template_args,
307
+					[
308
+						'current_db_state' => sprintf(
309
+							esc_html__("EE%s (%s)", "event_espresso"),
310
+							$current_db_state[ $plugin_slug ] ?? 3,
311
+							$plugin_slug
312
+						),
313
+						'next_db_state'    => sprintf(
314
+							esc_html__("EE%s (%s)", 'event_espresso'),
315
+							$new_version,
316
+							$plugin_slug
317
+						),
318
+					]
319
+				);
320
+			} else {
321
+				$this->_template_args['current_db_state'] = '';
322
+				$this->_template_args['next_db_state']    = '';
323
+			}
324
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
325
+			$this->_template_args = array_merge(
326
+				$this->_template_args,
327
+				[
328
+					'show_most_recent_migration'             => $show_most_recent_migration,
329
+					// flag for showing the most recent migration's status and/or errors
330
+					'show_migration_progress'                => $show_migration_progress,
331
+					// flag for showing the option to run migrations and see their progress
332
+					'show_backup_db_text'                    => $show_backup_db_text,
333
+					// flag for showing text telling the user to back up their DB
334
+					'show_maintenance_switch'                => $show_maintenance_switch,
335
+					// flag for showing the option to change maintenance mode between levels 0 and 1
336
+					'script_names'                           => $script_names,
337
+					// array of names of scripts that have run
338
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
339
+					// flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
340
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
341
+						['action' => 'reset_db'],
342
+						EE_MAINTENANCE_ADMIN_URL
343
+					),
344
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
345
+						['action' => 'data_reset'],
346
+						EE_MAINTENANCE_ADMIN_URL
347
+					),
348
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
349
+						['action' => 'change_maintenance_level'],
350
+						EE_MAINTENANCE_ADMIN_URL
351
+					),
352
+					'ultimate_db_state'                      => sprintf(
353
+						esc_html__("EE%s", 'event_espresso'),
354
+						espresso_version()
355
+					),
356
+					'real_level'                             => $this->maintenance_mode->real_level(),
357
+				]
358
+			);
359
+		}
360
+		$this->_template_args['most_recent_migration'] =
361
+			$most_recent_migration;// the actual most recently ran migration
362
+		// now render the migration options part, and put it in a variable
363
+		$migration_options_template_file                = apply_filters(
364
+			'FHEE__ee_migration_page__migration_options_template',
365
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
366
+		);
367
+		$migration_options_html                         = EEH_Template::display_template(
368
+			$migration_options_template_file,
369
+			$this->_template_args,
370
+			true
371
+		);
372
+		$this->_template_args['migration_options_html'] = $migration_options_html;
373
+		$this->_template_args['admin_page_content']     = EEH_Template::display_template(
374
+			$this->_template_path,
375
+			$this->_template_args,
376
+			true
377
+		);
378
+		$this->display_admin_page_with_sidebar();
379
+	}
380
+
381
+
382
+	/**
383
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
384
+	 *
385
+	 * @throws EE_Error
386
+	 */
387
+	public function migration_step()
388
+	{
389
+		if (! $this->capabilities->current_user_can('manage_options', __FUNCTION__)) {
390
+			wp_die(esc_html__('You do not have the required privileges to perform this action', 'event_espresso'));
391
+		}
392
+		$this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
393
+		$this->_return_json();
394
+	}
395
+
396
+
397
+	/**
398
+	 * Can be used by js when it notices a response with HTML in it in order
399
+	 * to log the malformed response
400
+	 *
401
+	 * @throws EE_Error
402
+	 */
403
+	public function add_error_to_migrations_ran()
404
+	{
405
+		$this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
406
+		$this->_template_args['data'] = ['ok' => true];
407
+		$this->_return_json();
408
+	}
409
+
410
+
411
+	/**
412
+	 * changes the maintenance level, provided there are still no migration scripts that should run
413
+	 *
414
+	 * @throws EE_Error
415
+	 */
416
+	public function _change_maintenance_level()
417
+	{
418
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
419
+		if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
420
+			$this->maintenance_mode->set_maintenance_level($new_level);
421
+			$success = true;
422
+		} else {
423
+			$this->maintenance_mode->set_maintenance_mode_if_db_old();
424
+			$success = false;
425
+		}
426
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
427
+	}
428
+
429
+
430
+	/**
431
+	 * a tab with options for resetting and/or deleting EE data
432
+	 *
433
+	 * @throws EE_Error
434
+	 * @throws DomainException
435
+	 */
436
+	public function _data_reset_and_delete()
437
+	{
438
+		$this->_template_path                              =
439
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
440
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
441
+			'reset_reservations',
442
+			'reset_reservations',
443
+			[],
444
+			'button button--caution ee-confirm'
445
+		);
446
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
447
+			'reset_capabilities',
448
+			'reset_capabilities',
449
+			[],
450
+			'button button--caution ee-confirm'
451
+		);
452
+		$this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
453
+			['action' => 'delete_db'],
454
+			EE_MAINTENANCE_ADMIN_URL
455
+		);
456
+		$this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
457
+			['action' => 'reset_db'],
458
+			EE_MAINTENANCE_ADMIN_URL
459
+		);
460
+		$this->_template_args['admin_page_content']        = EEH_Template::display_template(
461
+			$this->_template_path,
462
+			$this->_template_args,
463
+			true
464
+		);
465
+		$this->display_admin_page_with_no_sidebar();
466
+	}
467
+
468
+
469
+	/**
470
+	 * @throws EE_Error
471
+	 * @throws ReflectionException
472
+	 */
473
+	protected function _reset_reservations()
474
+	{
475
+		if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
476
+			EE_Error::add_success(
477
+				esc_html__(
478
+					'Ticket and datetime reserved counts have been successfully reset.',
479
+					'event_espresso'
480
+				)
481
+			);
482
+		} else {
483
+			EE_Error::add_success(
484
+				esc_html__(
485
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
486
+					'event_espresso'
487
+				)
488
+			);
489
+		}
490
+		$this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
491
+	}
492
+
493
+
494
+	/**
495
+	 * @throws EE_Error
496
+	 */
497
+	protected function _reset_capabilities()
498
+	{
499
+		$this->capabilities->init_caps(true);
500
+		EE_Error::add_success(
501
+			esc_html__(
502
+				'Default Event Espresso capabilities have been restored for all current roles.',
503
+				'event_espresso'
504
+			)
505
+		);
506
+		$this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
507
+	}
508
+
509
+
510
+	/**
511
+	 * resets the DMSs, so we can attempt to continue migrating after a fatal error
512
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
513
+	 * the fatal error in teh first place)
514
+	 *
515
+	 * @throws EE_Error
516
+	 */
517
+	protected function _reattempt_migration()
518
+	{
519
+		$this->migration_manager->reattempt();
520
+		$this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
521
+	}
522
+
523
+
524
+	/**
525
+	 * shows the big ol' System Information page
526
+	 *
527
+	 * @throws EE_Error
528
+	 */
529
+	public function _system_status()
530
+	{
531
+		$this->_template_path                               =
532
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
533
+		$this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
534
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
535
+			[
536
+				'action' => 'download_system_status',
537
+			],
538
+			EE_MAINTENANCE_ADMIN_URL
539
+		);
540
+		$this->_template_args['admin_page_content']         = EEH_Template::display_template(
541
+			$this->_template_path,
542
+			$this->_template_args,
543
+			true
544
+		);
545
+		$this->display_admin_page_with_no_sidebar();
546
+	}
547
+
548
+
549
+	/**
550
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
551
+	 */
552
+	public function _download_system_status()
553
+	{
554
+		$status_info = EEM_System_Status::instance()->get_system_stati();
555
+		header('Content-Disposition: attachment');
556
+		header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
557
+		$output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
558
+		$output .= '<h1>' . sprintf(
559
+			__('System Information for %1$s', 'event_espresso'),
560
+			esc_url_raw(site_url())
561
+		) . '</h1>';
562
+		$output .= EEH_Template::layout_array_as_table($status_info);
563
+		echo esc_html($output);
564
+		die;
565
+	}
566
+
567
+
568
+	/**
569
+	 * @throws EE_Error
570
+	 */
571
+	public function _send_migration_crash_report()
572
+	{
573
+		$from      = $this->_req_data['from'];
574
+		$from_name = $this->_req_data['from_name'];
575
+		$body      = $this->_req_data['body'];
576
+		try {
577
+			$success = wp_mail(
578
+				EE_SUPPORT_EMAIL,
579
+				'Migration Crash Report',
580
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
581
+				[
582
+					"from:$from_name<$from>",
583
+				]
584
+			);
585
+		} catch (Exception $e) {
586
+			$success = false;
587
+		}
588
+		$this->_redirect_after_action(
589
+			$success,
590
+			esc_html__("Migration Crash Report", "event_espresso"),
591
+			esc_html__("sent", "event_espresso"),
592
+			['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
593
+		);
594
+	}
595
+
596
+
597
+	/**
598
+	 * @throws EE_Error
599
+	 */
600
+	public function _confirm_migration_crash_report_sent()
601
+	{
602
+		try {
603
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
604
+		} catch (EE_Error $e) {
605
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
606
+			// now, just so we can display the page correctly, make an error migration script stage object
607
+			// and also put the error on it. It only persists for the duration of this request
608
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
609
+			$most_recent_migration->add_error($e->getMessage());
610
+		}
611
+		$success                                       = $this->_req_data['success'] === '1';
612
+		$this->_template_args['success']               = $success;
613
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
614
+		$this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
615
+			['action' => 'reset_db'],
616
+			EE_MAINTENANCE_ADMIN_URL
617
+		);
618
+		$this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
619
+			['action' => 'data_reset'],
620
+			EE_MAINTENANCE_ADMIN_URL
621
+		);
622
+		$this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
623
+			['action' => 'reattempt_migration'],
624
+			EE_MAINTENANCE_ADMIN_URL
625
+		);
626
+		$this->_template_path                          =
627
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
628
+		$this->_template_args['admin_page_content']    = EEH_Template::display_template(
629
+			$this->_template_path,
630
+			$this->_template_args,
631
+			true
632
+		);
633
+		$this->display_admin_page_with_sidebar();
634
+	}
635
+
636
+
637
+	/**
638
+	 * Resets the entire EE4 database.
639
+	 * only sets up ee4 database for a fresh install-
640
+	 * doesn't actually clean out the old wp options, or cpts
641
+	 * (although it does erase old ee table data)
642
+	 *
643
+	 * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
644
+	 *                                   or just try initializing ee4 default data
645
+	 * @throws EE_Error
646
+	 * @throws ReflectionException
647
+	 */
648
+	public function _reset_db($nuke_old_ee4_data = true)
649
+	{
650
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
651
+		if ($nuke_old_ee4_data) {
652
+			EEH_Activation::delete_all_espresso_cpt_data();
653
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
654
+			EEH_Activation::remove_cron_tasks();
655
+		}
656
+		// make sure when we reset the registry's config that it
657
+		// switches to using the new singleton
658
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
659
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
660
+		EE_System::instance()->redirect_to_about_ee();
661
+	}
662
+
663
+
664
+	/**
665
+	 * Deletes ALL EE tables, Records, and Options from the database.
666
+	 *
667
+	 * @throws EE_Error
668
+	 * @throws ReflectionException
669
+	 */
670
+	public function _delete_db()
671
+	{
672
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
673
+		EEH_Activation::delete_all_espresso_cpt_data();
674
+		EEH_Activation::delete_all_espresso_tables_and_data();
675
+		EEH_Activation::remove_cron_tasks();
676
+		EEH_Activation::deactivate_event_espresso();
677
+		wp_safe_redirect(admin_url('plugins.php'));
678
+		exit;
679
+	}
680
+
681
+
682
+	/**
683
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
684
+	 *
685
+	 * @throws EE_Error
686
+	 * @throws ReflectionException
687
+	 */
688
+	public function _rerun_migration_from_ee3()
689
+	{
690
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_OFF);
691
+		EEH_Activation::delete_all_espresso_cpt_data();
692
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
693
+		// set the db state to something that will require migrations
694
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
695
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::STATUS_FULL_SITE);
696
+		$this->_redirect_after_action(
697
+			true,
698
+			esc_html__("Database", 'event_espresso'),
699
+			esc_html__("reset", 'event_espresso')
700
+		);
701
+	}
702
+
703
+
704
+	// none of the below group are currently used for Gateway Settings
705
+	protected function _add_screen_options()
706
+	{
707
+	}
708
+
709
+
710
+	protected function _add_feature_pointers()
711
+	{
712
+	}
713
+
714
+
715
+	public function admin_init()
716
+	{
717
+	}
718
+
719
+
720
+	public function admin_notices()
721
+	{
722
+	}
723
+
724
+
725
+	public function admin_footer_scripts()
726
+	{
727
+	}
728
+
729
+
730
+	public function load_scripts_styles()
731
+	{
732
+		wp_enqueue_script('ee_admin_js');
733
+		wp_enqueue_script(
734
+			'ee-maintenance',
735
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
736
+			['jquery'],
737
+			EVENT_ESPRESSO_VERSION,
738
+			true
739
+		);
740
+		wp_register_style(
741
+			'espresso_maintenance',
742
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
743
+			[],
744
+			EVENT_ESPRESSO_VERSION
745
+		);
746
+		wp_enqueue_style('espresso_maintenance');
747
+		// localize script stuff
748
+		wp_localize_script(
749
+			'ee-maintenance',
750
+			'ee_maintenance',
751
+			[
752
+				'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
753
+				'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
754
+				'fatal_error'                      => wp_strip_all_tags(
755
+					__(
756
+						"A Fatal Error Has Occurred",
757
+						"event_espresso"
758
+					)
759
+				),
760
+				'click_next_when_ready'            => wp_strip_all_tags(
761
+					__(
762
+						"The current Database Update has ended. Click 'next' when ready to proceed",
763
+						"event_espresso"
764
+					)
765
+				),
766
+				'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
767
+				'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
768
+				'status_completed'                 => EE_Data_Migration_Manager::status_completed,
769
+				'confirm'                          => wp_strip_all_tags(
770
+					__(
771
+						'Are you sure you want to do this? It CANNOT be undone!',
772
+						'event_espresso'
773
+					)
774
+				),
775
+				'confirm_skip_migration'           => wp_strip_all_tags(
776
+					__(
777
+						'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
778
+						'event_espresso'
779
+					)
780
+				),
781
+			]
782
+		);
783
+	}
784
+
785
+
786
+	public function load_scripts_styles_default()
787
+	{
788
+	}
789
+
790
+
791
+	/**
792
+	 * Enqueue scripts and styles for the datetime tools page.
793
+	 */
794
+	public function load_scripts_styles_datetime_tools()
795
+	{
796
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
797
+	}
798
+
799
+
800
+	/**
801
+	 * @throws EE_Error
802
+	 */
803
+	protected function _datetime_tools()
804
+	{
805
+		$form_action                                = EE_Admin_Page::add_query_args_and_nonce(
806
+			[
807
+				'action'        => 'run_datetime_offset_fix',
808
+				'return_action' => $this->_req_action,
809
+			],
810
+			EE_MAINTENANCE_ADMIN_URL
811
+		);
812
+		$form                                       = $this->_get_datetime_offset_fix_form();
813
+		$this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
814
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
815
+													  . $form->get_html_and_js()
816
+													  . $form->form_close();
817
+		$this->display_admin_page_with_sidebar();
818
+	}
819
+
820
+
821
+	/**
822
+	 * @throws EE_Error
823
+	 */
824
+	protected function _get_datetime_offset_fix_form()
825
+	{
826
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
827
+			$this->datetime_fix_offset_form = new EE_Form_Section_Proper(
828
+				[
829
+					'name'            => 'datetime_offset_fix_option',
830
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
831
+					'subsections'     => [
832
+						'title'                  => new EE_Form_Section_HTML(
833
+							EEH_HTML::h2(
834
+								esc_html__('Datetime Offset Tool', 'event_espresso')
835
+							)
836
+						),
837
+						'explanation'            => new EE_Form_Section_HTML(
838
+							EEH_HTML::p(
839
+								esc_html__(
840
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
841
+									'event_espresso'
842
+								)
843
+							)
844
+							. EEH_HTML::p(
845
+								esc_html__(
846
+									'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
847
+									'event_espresso'
848
+								)
849
+							)
850
+						),
851
+						'offset_input'           => new EE_Float_Input(
852
+							[
853
+								'html_name'       => 'offset_for_datetimes',
854
+								'html_label_text' => esc_html__(
855
+									'Offset to apply (in hours):',
856
+									'event_espresso'
857
+								),
858
+								'min_value'       => '-12',
859
+								'max_value'       => '14',
860
+								'step_value'      => '.25',
861
+								'default'         => DatetimeOffsetFix::getOffset(),
862
+							]
863
+						),
864
+						'date_range_explanation' => new EE_Form_Section_HTML(
865
+							EEH_HTML::p(
866
+								esc_html__(
867
+									'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
868
+									'event_espresso'
869
+								)
870
+							)
871
+							. EEH_HTML::p(
872
+								EEH_HTML::strong(
873
+									sprintf(
874
+										esc_html__(
875
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
876
+											'event_espresso'
877
+										),
878
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
879
+										'</a>'
880
+									)
881
+								)
882
+							)
883
+						),
884
+						'date_range_start_date'  => new EE_Datepicker_Input(
885
+							[
886
+								'html_name'       => 'offset_date_start_range',
887
+								'html_label_text' => esc_html__(
888
+									'Start Date for dates the offset applied to:',
889
+									'event_espresso'
890
+								),
891
+							]
892
+						),
893
+						'date_range_end_date'    => new EE_Datepicker_Input(
894
+							[
895
+								'html_name'       => 'offset_date_end_range',
896
+								'html_label_text' => esc_html__(
897
+									'End Date for dates the offset is applied to:',
898
+									'event_espresso'
899
+								),
900
+							]
901
+						),
902
+						'submit'                 => new EE_Submit_Input(
903
+							[
904
+								'html_label_text' => '',
905
+								'default'         => esc_html__('Apply Offset', 'event_espresso'),
906
+							]
907
+						),
908
+					],
909
+				]
910
+			);
911
+		}
912
+		return $this->datetime_fix_offset_form;
913
+	}
914
+
915
+
916
+	/**
917
+	 * Callback for the run_datetime_offset_fix route.
918
+	 *
919
+	 * @throws EE_Error
920
+	 */
921
+	protected function _apply_datetime_offset()
922
+	{
923
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
924
+			$form = $this->_get_datetime_offset_fix_form();
925
+			$form->receive_form_submission($this->_req_data);
926
+			if ($form->is_valid()) {
927
+				// save offset data so batch processor can get it.
928
+				DatetimeOffsetFix::updateOffset((float) $form->get_input_value('offset_input'));
929
+				$utc_timezone          = new DateTimeZone('UTC');
930
+				$date_range_start_date = DateTime::createFromFormat(
931
+					'm/d/Y H:i:s',
932
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
933
+					$utc_timezone
934
+				);
935
+				$date_range_end_date   = DateTime::createFromFormat(
936
+					'm/d/Y H:i:s',
937
+					$form->get_input_value('date_range_end_date') . ' 23:59:59',
938
+					$utc_timezone
939
+				);
940
+				if ($date_range_start_date instanceof DateTime) {
941
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
942
+				}
943
+				if ($date_range_end_date instanceof DateTime) {
944
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
945
+				}
946
+				// redirect to batch tool
947
+				wp_redirect(
948
+					EE_Admin_Page::add_query_args_and_nonce(
949
+						[
950
+							'page'        => EED_Batch::PAGE_SLUG,
951
+							'batch'       => EED_Batch::batch_job,
952
+							'label'       => esc_html__('Applying Offset', 'event_espresso'),
953
+							'job_handler' => urlencode('EventEspresso\core\libraries\batch\JobHandlers\DatetimeOffsetFix'),
954
+							'return_url'  => urlencode(
955
+								add_query_arg(
956
+									[
957
+										'action' => 'datetime_tools',
958
+									],
959
+									EEH_URL::current_url_without_query_paramaters(
960
+										[
961
+											'return_action',
962
+											'run_datetime_offset_fix_nonce',
963
+											'return',
964
+											'datetime_tools_nonce',
965
+										]
966
+									)
967
+								)
968
+							),
969
+						],
970
+						admin_url()
971
+					)
972
+				);
973
+				exit;
974
+			}
975
+		}
976
+	}
977 977
 }
Please login to merge, or discard this patch.
admin_pages/payments/Payments_Admin_Page.core.php 1 patch
Indentation   +1295 added lines, -1295 removed lines patch added patch discarded remove patch
@@ -18,286 +18,286 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class Payments_Admin_Page extends EE_Admin_Page
20 20
 {
21
-    /**
22
-     * Variables used for when we're re-sorting the logs results,
23
-     * in case we needed to do two queries, and we need to resort
24
-     *
25
-     * @var string
26
-     */
27
-    private $_sort_logs_again_direction;
28
-
29
-
30
-    /**
31
-     * @Constructor
32
-     * @access public
33
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
34
-     * @throws EE_Error
35
-     * @throws InvalidArgumentException
36
-     * @throws InvalidDataTypeException
37
-     * @throws InvalidInterfaceException
38
-     * @throws ReflectionException
39
-     */
40
-    public function __construct($routing = true)
41
-    {
42
-        parent::__construct($routing);
43
-    }
44
-
45
-
46
-    protected function _init_page_props()
47
-    {
48
-        $this->page_slug        = EE_PAYMENTS_PG_SLUG;
49
-        $this->page_label       = esc_html__('Payment Methods', 'event_espresso');
50
-        $this->_admin_base_url  = EE_PAYMENTS_ADMIN_URL;
51
-        $this->_admin_base_path = EE_PAYMENTS_ADMIN;
52
-    }
53
-
54
-
55
-    protected function _ajax_hooks()
56
-    {
57
-        // todo: all hooks for ajax goes here.
58
-    }
59
-
60
-
61
-    protected function _define_page_props()
62
-    {
63
-        $this->_admin_page_title = $this->page_label;
64
-        $this->_labels           = [
65
-            'publishbox' => esc_html__('Update Settings', 'event_espresso'),
66
-        ];
67
-    }
68
-
69
-
70
-    /**
71
-     * @param string $sort_logs_again_direction
72
-     */
73
-    public function setSortLogsAgainDirection(string $sort_logs_again_direction): void
74
-    {
75
-        $this->_sort_logs_again_direction = $sort_logs_again_direction;
76
-    }
77
-
78
-
79
-    protected function _set_page_routes()
80
-    {
81
-        /**
82
-         * note that with payment method capabilities, although we've implemented
83
-         * capability mapping which will be used for accessing payment methods owned by
84
-         * other users.  This is not fully implemented yet in the payment method ui.
85
-         * Currently, only the "plural" caps are in active use.
86
-         * When cap mapping is implemented, some routes will need to use the singular form of
87
-         * capability method and also include the $id of the payment method for the route.
88
-         **/
89
-        $this->_page_routes = [
90
-            'default'                   => [
91
-                'func'       => [$this, '_payment_methods_list'],
92
-                'capability' => 'ee_edit_payment_methods',
93
-            ],
94
-            'payment_settings'          => [
95
-                'func'       => [$this, '_payment_settings'],
96
-                'capability' => 'ee_manage_gateways',
97
-            ],
98
-            'activate_payment_method'   => [
99
-                'func'       => [$this, '_activate_payment_method'],
100
-                'noheader'   => true,
101
-                'capability' => 'ee_edit_payment_methods',
102
-            ],
103
-            'deactivate_payment_method' => [
104
-                'func'       => [$this, '_deactivate_payment_method'],
105
-                'noheader'   => true,
106
-                'capability' => 'ee_delete_payment_methods',
107
-            ],
108
-            'update_payment_method'     => [
109
-                'func'       => [$this, '_update_payment_method'],
110
-                'noheader'           => true,
111
-                'headers_sent_route' => 'default',
112
-                'capability'         => 'ee_edit_payment_methods',
113
-            ],
114
-            'update_payment_settings'   => [
115
-                'func'       => [$this, '_update_payment_settings'],
116
-                'noheader'   => true,
117
-                'capability' => 'ee_manage_gateways',
118
-            ],
119
-            'payment_log'               => [
120
-                'func'       => [$this, '_payment_log_overview_list_table'],
121
-                'capability' => 'ee_read_payment_methods',
122
-            ],
123
-            'payment_log_details'       => [
124
-                'func'       => [$this, '_payment_log_details'],
125
-                'capability' => 'ee_read_payment_methods',
126
-            ],
127
-        ];
128
-    }
129
-
130
-
131
-    /**
132
-     * @throws EE_Error
133
-     * @throws ReflectionException
134
-     */
135
-    protected function _set_page_config()
136
-    {
137
-        $payment_method_list_config = [
138
-            'nav'           => [
139
-                'label' => esc_html__('Payment Methods', 'event_espresso'),
140
-                'icon'  => 'dashicons-bank',
141
-                'order' => 10,
142
-            ],
143
-            'metaboxes'     => $this->_default_espresso_metaboxes,
144
-            'help_tabs'     => array_merge(
145
-                [
146
-                    'payment_methods_overview_help_tab' => [
147
-                        'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
148
-                        'filename' => 'payment_methods_overview',
149
-                    ],
150
-                ],
151
-                $this->_add_payment_method_help_tabs()
152
-            ),
153
-            'require_nonce' => false,
154
-        ];
155
-        $this->_page_config         = [
156
-            'default'          => $payment_method_list_config,
157
-            'payment_settings' => [
158
-                'nav'           => [
159
-                    'label' => esc_html__('Settings', 'event_espresso'),
160
-                    'icon'  => 'dashicons-admin-generic',
161
-                    'order' => 20,
162
-                ],
163
-                'help_tabs'     => [
164
-                    'payment_methods_settings_help_tab' => [
165
-                        'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
166
-                        'filename' => 'payment_methods_settings',
167
-                    ],
168
-                ],
169
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
170
-                'require_nonce' => false,
171
-            ],
172
-            'payment_log'      => [
173
-                'nav'           => [
174
-                    'label' => esc_html__("Logs", 'event_espresso'),
175
-                    'icon'  => 'dashicons-text-page',
176
-                    'order' => 30,
177
-                ],
178
-                'list_table'    => 'Payment_Log_Admin_List_Table',
179
-                'metaboxes'     => $this->_default_espresso_metaboxes,
180
-                'require_nonce' => false,
181
-            ],
182
-        ];
183
-    }
184
-
185
-
186
-    /**
187
-     * @return array
188
-     * @throws DomainException
189
-     * @throws EE_Error
190
-     * @throws InvalidArgumentException
191
-     * @throws InvalidDataTypeException
192
-     * @throws InvalidInterfaceException
193
-     * @throws ReflectionException
194
-     */
195
-    protected function _add_payment_method_help_tabs(): array
196
-    {
197
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
198
-        $payment_method_types     = EE_Payment_Method_Manager::instance()->payment_method_types();
199
-        $all_pmt_help_tabs_config = [];
200
-        foreach ($payment_method_types as $payment_method_type) {
201
-            if (
202
-                ! $this->capabilities->current_user_can(
203
-                    $payment_method_type->cap_name(),
204
-                    'specific_payment_method_type_access'
205
-                )
206
-            ) {
207
-                continue;
208
-            }
209
-            foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210
-                $template_args                              = $config['template_args'] ?? [];
211
-                $template_args['admin_page_obj']            = $this;
212
-                $all_pmt_help_tabs_config[ $help_tab_name ] = [
213
-                    'title'   => $config['title'],
214
-                    'content' => EEH_Template::display_template(
215
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
216
-                        $template_args,
217
-                        true
218
-                    ),
219
-                ];
220
-            }
221
-        }
222
-        return $all_pmt_help_tabs_config;
223
-    }
224
-
225
-
226
-    // none of the below group are currently used for Gateway Settings
227
-    protected function _add_screen_options()
228
-    {
229
-    }
230
-
231
-
232
-    protected function _add_feature_pointers()
233
-    {
234
-    }
235
-
236
-
237
-    public function admin_init()
238
-    {
239
-    }
240
-
241
-
242
-    public function admin_notices()
243
-    {
244
-    }
245
-
246
-
247
-    public function admin_footer_scripts()
248
-    {
249
-    }
250
-
251
-
252
-    public function load_scripts_styles()
253
-    {
254
-        // styles
255
-        wp_enqueue_style('espresso-ui-theme');
256
-        wp_register_style(
257
-            'espresso_payments',
258
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
259
-            [],
260
-            EVENT_ESPRESSO_VERSION
261
-        );
262
-        // scripts
263
-        wp_enqueue_script('ee_admin_js');
264
-        wp_enqueue_script('ee-text-links');
265
-        wp_enqueue_script(
266
-            'espresso_payments',
267
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
268
-            ['ee-datepicker'],
269
-            EVENT_ESPRESSO_VERSION,
270
-            true
271
-        );
272
-    }
273
-
274
-
275
-    public function load_scripts_styles_default()
276
-    {
277
-        wp_enqueue_style('espresso_payments');
278
-        wp_enqueue_style('ee-text-links');
279
-    }
280
-
281
-
282
-    public function load_scripts_styles_payment_log_details()
283
-    {
284
-        wp_enqueue_style('espresso_payments');
285
-    }
286
-
287
-
288
-    /**
289
-     * @throws EE_Error
290
-     */
291
-    private function veryifyTablesExist()
292
-    {
293
-        /** @var TableAnalysis $table_analysis */
294
-        $table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295
-        /** @var TableManager $table_manager */
296
-        $table_manager = LoaderFactory::getShared(TableManager::class);
297
-        if (! $table_analysis->tableExists('esp_payment_method')) {
298
-            $table_manager->createTable(
299
-                'esp_payment_method',
300
-                "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
21
+	/**
22
+	 * Variables used for when we're re-sorting the logs results,
23
+	 * in case we needed to do two queries, and we need to resort
24
+	 *
25
+	 * @var string
26
+	 */
27
+	private $_sort_logs_again_direction;
28
+
29
+
30
+	/**
31
+	 * @Constructor
32
+	 * @access public
33
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
34
+	 * @throws EE_Error
35
+	 * @throws InvalidArgumentException
36
+	 * @throws InvalidDataTypeException
37
+	 * @throws InvalidInterfaceException
38
+	 * @throws ReflectionException
39
+	 */
40
+	public function __construct($routing = true)
41
+	{
42
+		parent::__construct($routing);
43
+	}
44
+
45
+
46
+	protected function _init_page_props()
47
+	{
48
+		$this->page_slug        = EE_PAYMENTS_PG_SLUG;
49
+		$this->page_label       = esc_html__('Payment Methods', 'event_espresso');
50
+		$this->_admin_base_url  = EE_PAYMENTS_ADMIN_URL;
51
+		$this->_admin_base_path = EE_PAYMENTS_ADMIN;
52
+	}
53
+
54
+
55
+	protected function _ajax_hooks()
56
+	{
57
+		// todo: all hooks for ajax goes here.
58
+	}
59
+
60
+
61
+	protected function _define_page_props()
62
+	{
63
+		$this->_admin_page_title = $this->page_label;
64
+		$this->_labels           = [
65
+			'publishbox' => esc_html__('Update Settings', 'event_espresso'),
66
+		];
67
+	}
68
+
69
+
70
+	/**
71
+	 * @param string $sort_logs_again_direction
72
+	 */
73
+	public function setSortLogsAgainDirection(string $sort_logs_again_direction): void
74
+	{
75
+		$this->_sort_logs_again_direction = $sort_logs_again_direction;
76
+	}
77
+
78
+
79
+	protected function _set_page_routes()
80
+	{
81
+		/**
82
+		 * note that with payment method capabilities, although we've implemented
83
+		 * capability mapping which will be used for accessing payment methods owned by
84
+		 * other users.  This is not fully implemented yet in the payment method ui.
85
+		 * Currently, only the "plural" caps are in active use.
86
+		 * When cap mapping is implemented, some routes will need to use the singular form of
87
+		 * capability method and also include the $id of the payment method for the route.
88
+		 **/
89
+		$this->_page_routes = [
90
+			'default'                   => [
91
+				'func'       => [$this, '_payment_methods_list'],
92
+				'capability' => 'ee_edit_payment_methods',
93
+			],
94
+			'payment_settings'          => [
95
+				'func'       => [$this, '_payment_settings'],
96
+				'capability' => 'ee_manage_gateways',
97
+			],
98
+			'activate_payment_method'   => [
99
+				'func'       => [$this, '_activate_payment_method'],
100
+				'noheader'   => true,
101
+				'capability' => 'ee_edit_payment_methods',
102
+			],
103
+			'deactivate_payment_method' => [
104
+				'func'       => [$this, '_deactivate_payment_method'],
105
+				'noheader'   => true,
106
+				'capability' => 'ee_delete_payment_methods',
107
+			],
108
+			'update_payment_method'     => [
109
+				'func'       => [$this, '_update_payment_method'],
110
+				'noheader'           => true,
111
+				'headers_sent_route' => 'default',
112
+				'capability'         => 'ee_edit_payment_methods',
113
+			],
114
+			'update_payment_settings'   => [
115
+				'func'       => [$this, '_update_payment_settings'],
116
+				'noheader'   => true,
117
+				'capability' => 'ee_manage_gateways',
118
+			],
119
+			'payment_log'               => [
120
+				'func'       => [$this, '_payment_log_overview_list_table'],
121
+				'capability' => 'ee_read_payment_methods',
122
+			],
123
+			'payment_log_details'       => [
124
+				'func'       => [$this, '_payment_log_details'],
125
+				'capability' => 'ee_read_payment_methods',
126
+			],
127
+		];
128
+	}
129
+
130
+
131
+	/**
132
+	 * @throws EE_Error
133
+	 * @throws ReflectionException
134
+	 */
135
+	protected function _set_page_config()
136
+	{
137
+		$payment_method_list_config = [
138
+			'nav'           => [
139
+				'label' => esc_html__('Payment Methods', 'event_espresso'),
140
+				'icon'  => 'dashicons-bank',
141
+				'order' => 10,
142
+			],
143
+			'metaboxes'     => $this->_default_espresso_metaboxes,
144
+			'help_tabs'     => array_merge(
145
+				[
146
+					'payment_methods_overview_help_tab' => [
147
+						'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
148
+						'filename' => 'payment_methods_overview',
149
+					],
150
+				],
151
+				$this->_add_payment_method_help_tabs()
152
+			),
153
+			'require_nonce' => false,
154
+		];
155
+		$this->_page_config         = [
156
+			'default'          => $payment_method_list_config,
157
+			'payment_settings' => [
158
+				'nav'           => [
159
+					'label' => esc_html__('Settings', 'event_espresso'),
160
+					'icon'  => 'dashicons-admin-generic',
161
+					'order' => 20,
162
+				],
163
+				'help_tabs'     => [
164
+					'payment_methods_settings_help_tab' => [
165
+						'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
166
+						'filename' => 'payment_methods_settings',
167
+					],
168
+				],
169
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
170
+				'require_nonce' => false,
171
+			],
172
+			'payment_log'      => [
173
+				'nav'           => [
174
+					'label' => esc_html__("Logs", 'event_espresso'),
175
+					'icon'  => 'dashicons-text-page',
176
+					'order' => 30,
177
+				],
178
+				'list_table'    => 'Payment_Log_Admin_List_Table',
179
+				'metaboxes'     => $this->_default_espresso_metaboxes,
180
+				'require_nonce' => false,
181
+			],
182
+		];
183
+	}
184
+
185
+
186
+	/**
187
+	 * @return array
188
+	 * @throws DomainException
189
+	 * @throws EE_Error
190
+	 * @throws InvalidArgumentException
191
+	 * @throws InvalidDataTypeException
192
+	 * @throws InvalidInterfaceException
193
+	 * @throws ReflectionException
194
+	 */
195
+	protected function _add_payment_method_help_tabs(): array
196
+	{
197
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
198
+		$payment_method_types     = EE_Payment_Method_Manager::instance()->payment_method_types();
199
+		$all_pmt_help_tabs_config = [];
200
+		foreach ($payment_method_types as $payment_method_type) {
201
+			if (
202
+				! $this->capabilities->current_user_can(
203
+					$payment_method_type->cap_name(),
204
+					'specific_payment_method_type_access'
205
+				)
206
+			) {
207
+				continue;
208
+			}
209
+			foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210
+				$template_args                              = $config['template_args'] ?? [];
211
+				$template_args['admin_page_obj']            = $this;
212
+				$all_pmt_help_tabs_config[ $help_tab_name ] = [
213
+					'title'   => $config['title'],
214
+					'content' => EEH_Template::display_template(
215
+						$payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
216
+						$template_args,
217
+						true
218
+					),
219
+				];
220
+			}
221
+		}
222
+		return $all_pmt_help_tabs_config;
223
+	}
224
+
225
+
226
+	// none of the below group are currently used for Gateway Settings
227
+	protected function _add_screen_options()
228
+	{
229
+	}
230
+
231
+
232
+	protected function _add_feature_pointers()
233
+	{
234
+	}
235
+
236
+
237
+	public function admin_init()
238
+	{
239
+	}
240
+
241
+
242
+	public function admin_notices()
243
+	{
244
+	}
245
+
246
+
247
+	public function admin_footer_scripts()
248
+	{
249
+	}
250
+
251
+
252
+	public function load_scripts_styles()
253
+	{
254
+		// styles
255
+		wp_enqueue_style('espresso-ui-theme');
256
+		wp_register_style(
257
+			'espresso_payments',
258
+			EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
259
+			[],
260
+			EVENT_ESPRESSO_VERSION
261
+		);
262
+		// scripts
263
+		wp_enqueue_script('ee_admin_js');
264
+		wp_enqueue_script('ee-text-links');
265
+		wp_enqueue_script(
266
+			'espresso_payments',
267
+			EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
268
+			['ee-datepicker'],
269
+			EVENT_ESPRESSO_VERSION,
270
+			true
271
+		);
272
+	}
273
+
274
+
275
+	public function load_scripts_styles_default()
276
+	{
277
+		wp_enqueue_style('espresso_payments');
278
+		wp_enqueue_style('ee-text-links');
279
+	}
280
+
281
+
282
+	public function load_scripts_styles_payment_log_details()
283
+	{
284
+		wp_enqueue_style('espresso_payments');
285
+	}
286
+
287
+
288
+	/**
289
+	 * @throws EE_Error
290
+	 */
291
+	private function veryifyTablesExist()
292
+	{
293
+		/** @var TableAnalysis $table_analysis */
294
+		$table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295
+		/** @var TableManager $table_manager */
296
+		$table_manager = LoaderFactory::getShared(TableManager::class);
297
+		if (! $table_analysis->tableExists('esp_payment_method')) {
298
+			$table_manager->createTable(
299
+				'esp_payment_method',
300
+				"PMD_ID int(11) NOT NULL AUTO_INCREMENT,
301 301
 				PMD_type varchar(124) DEFAULT NULL,
302 302
 				PMD_name varchar(255) DEFAULT NULL,
303 303
 				PMD_desc text,
@@ -313,1023 +313,1023 @@  discard block
 block discarded – undo
313 313
 				PRIMARY KEY  (PMD_ID),
314 314
 				UNIQUE KEY PMD_slug_UNIQUE (PMD_slug),
315 315
 				KEY PMD_type (PMD_type)",
316
-                'InnoDB'
317
-            );
318
-        }
319
-        if (! $table_analysis->tableExists('esp_currency_payment_method')) {
320
-            $table_manager->createTable(
321
-                'esp_currency_payment_method',
322
-                "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
316
+				'InnoDB'
317
+			);
318
+		}
319
+		if (! $table_analysis->tableExists('esp_currency_payment_method')) {
320
+			$table_manager->createTable(
321
+				'esp_currency_payment_method',
322
+				"CPM_ID int(11) NOT NULL AUTO_INCREMENT,
323 323
 				CUR_code varchar(6) NOT NULL,
324 324
 				PMD_ID int(11) NOT NULL,
325 325
 				PRIMARY KEY  (CPM_ID),
326 326
 				KEY PMD_ID (PMD_ID)",
327
-                'InnoDB'
328
-            );
329
-        }
330
-    }
331
-
332
-
333
-    /**
334
-     * @throws EE_Error
335
-     * @throws ReflectionException
336
-     */
337
-    protected function _payment_methods_list()
338
-    {
339
-        $this->veryifyTablesExist();
340
-        /**
341
-         * first let's ensure payment methods have been set up.
342
-         * We do this here because when people activate a payment method for the first time (as an addon),
343
-         * it may not set up its capabilities or get registered correctly due to the loading process.
344
-         * However, people MUST set up the details for the payment method,
345
-         * so it's safe to do a recheck here.
346
-         */
347
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
348
-        EEM_Payment_Method::instance()->verify_button_urls();
349
-        // set up tabs, one for each payment method type
350
-        $tabs            = [];
351
-        $payment_methods = [];
352
-        foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
353
-            // we don't want to show admin-only PMTs for now
354
-            if ($pmt_obj instanceof EE_PMT_Admin_Only) {
355
-                continue;
356
-            }
357
-            // check access
358
-            if (
359
-                ! $this->capabilities->current_user_can(
360
-                    $pmt_obj->cap_name(),
361
-                    'specific_payment_method_type_access'
362
-                )
363
-            ) {
364
-                continue;
365
-            }
366
-            // check for any active pms of that type
367
-            $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
-            if (! $payment_method instanceof EE_Payment_Method) {
369
-                $payment_method = EE_Payment_Method::new_instance(
370
-                    [
371
-                        'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
372
-                        'PMD_type'       => $pmt_obj->system_name(),
373
-                        'PMD_name'       => $pmt_obj->pretty_name(),
374
-                        'PMD_admin_name' => $pmt_obj->pretty_name(),
375
-                    ]
376
-                );
377
-            }
378
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
379
-        }
380
-        $payment_methods = apply_filters(
381
-            'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
382
-            $payment_methods
383
-        );
384
-        foreach ($payment_methods as $payment_method) {
385
-            if ($payment_method instanceof EE_Payment_Method) {
386
-                $this->addMetaBox(
387
-                // html id
388
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
389
-                    // title
390
-                    sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391
-                    // callback
392
-                    [$this, 'payment_method_settings_meta_box'],
393
-                    // post type
394
-                    null,
395
-                    // context
396
-                    'normal',
397
-                    // priority
398
-                    'default',
399
-                    // callback args
400
-                    ['payment_method' => $payment_method]
401
-                );
402
-                // setup for tabbed content
403
-                $tabs[ $payment_method->slug() ] = [
404
-                    'label' => $payment_method->admin_name(),
405
-                    'class' => $payment_method->active()
406
-                        ? 'gateway-active'
407
-                        : '',
408
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
409
-                    'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410
-                    'slug'  => $payment_method->slug(),
411
-                    'icon'  => $payment_method->active()
412
-                        ? '<span class="dashicons dashicons-yes-alt"></span>'
413
-                        : '<span class="dashicons dashicons-remove"></span>',
414
-                ];
415
-            }
416
-        }
417
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
418
-            $tabs,
419
-            'payment_method_links',
420
-            '',
421
-            $this->_get_active_payment_method_slug()
422
-        );
423
-        $this->display_admin_page_with_sidebar();
424
-    }
425
-
426
-
427
-    /**
428
-     *   _get_active_payment_method_slug
429
-     *
430
-     * @return string
431
-     * @throws EE_Error
432
-     * @throws ReflectionException
433
-     */
434
-    protected function _get_active_payment_method_slug()
435
-    {
436
-        $payment_method_slug = false;
437
-        // decide which payment method tab to open first, as dictated by the request's 'payment_method'
438
-        if (isset($this->_req_data['payment_method'])) {
439
-            // if they provided the current payment method, use it
440
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
441
-        }
442
-
443
-        $payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444
-        // if that didn't work or wasn't provided, find another way to select the current pm
445
-        if (! $this->_verify_payment_method($payment_method)) {
446
-            // like, looking for an active one
447
-            $payment_method = EEM_Payment_Method::instance()->get_one_active(EEM_Payment_Method::scope_cart);
448
-            // test that one as well
449
-            if ($this->_verify_payment_method($payment_method)) {
450
-                $payment_method_slug = $payment_method->slug();
451
-            } else {
452
-                $payment_method_slug = 'paypal_standard';
453
-            }
454
-        }
455
-        return $payment_method_slug;
456
-    }
457
-
458
-
459
-    /**
460
-     *    payment_method_settings_meta_box
461
-     *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
462
-     *    capabilities to access it
463
-     *
464
-     * @param EE_Payment_Method|null $payment_method
465
-     * @return boolean
466
-     * @throws EE_Error
467
-     */
468
-    protected function _verify_payment_method(?EE_Payment_Method $payment_method): bool
469
-    {
470
-        return $payment_method instanceof EE_Payment_Method
471
-               && $payment_method->type_obj() instanceof EE_PMT_Base
472
-               && $this->capabilities->current_user_can(
473
-                   $payment_method->type_obj()->cap_name(),
474
-                   'specific_payment_method_type_access'
475
-               );
476
-    }
477
-
478
-
479
-    /**
480
-     *    payment_method_settings_meta_box
481
-     *
482
-     * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
483
-     * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
484
-     *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
485
-     * @return void
486
-     * @throws EE_Error
487
-     * @throws ReflectionException
488
-     */
489
-    public function payment_method_settings_meta_box($post_obj_which_is_null, array $metabox)
490
-    {
491
-        $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492
-            ? $metabox['args']['payment_method']
493
-            : null;
494
-        if (! $payment_method instanceof EE_Payment_Method) {
495
-            throw new EE_Error(
496
-                esc_html__(
497
-                    'Payment method metabox setup incorrectly. No Payment method object was supplied',
498
-                    'event_espresso'
499
-                )
500
-            );
501
-        }
502
-        $payment_method_scopes = $payment_method->active();
503
-        // if the payment method really exists show its form, otherwise the activation template
504
-        if ($payment_method->ID() && ! empty($payment_method_scopes)) {
505
-            $form = $this->_generate_payment_method_settings_form($payment_method);
506
-            if ($form->form_data_present_in($this->_req_data)) {
507
-                $form->receive_form_submission($this->_req_data);
508
-            }
509
-            echo wp_kses(
510
-                $form->form_open() . $form->get_html_and_js() . $form->form_close(),
511
-                AllowedTags::getWithFormTags()
512
-            );
513
-        } else {
514
-            echo wp_kses(
515
-                $this->_activate_payment_method_button($payment_method)->get_html_and_js(),
516
-                AllowedTags::getWithFormTags()
517
-            );
518
-        }
519
-    }
520
-
521
-
522
-    /**
523
-     * Gets the form for all the settings related to this payment method type
524
-     *
525
-     * @access protected
526
-     * @param EE_Payment_Method|null $payment_method
527
-     * @return EE_Form_Section_Proper
528
-     * @throws EE_Error
529
-     * @throws ReflectionException
530
-     */
531
-    protected function _generate_payment_method_settings_form(
532
-        ?EE_Payment_Method $payment_method
533
-    ): EE_Form_Section_Proper {
534
-        if (! $payment_method instanceof EE_Payment_Method) {
535
-            return new EE_Form_Section_Proper();
536
-        }
537
-        $subsections = apply_filters(
538
-            'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
539
-            [
540
-                'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
541
-                'currency_support'        => $this->_currency_support($payment_method),
542
-                'payment_method_settings' => $this->_payment_method_settings($payment_method),
543
-                'update'                  => $this->_update_payment_method_button($payment_method),
544
-                'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
545
-                'fine_print'              => $this->_fine_print(),
546
-            ],
547
-            $payment_method
548
-        );
549
-        return new EE_Form_Section_Proper(
550
-            [
551
-                'name'            => $payment_method->slug() . '_settings_form',
552
-                'html_id'         => $payment_method->slug() . '_settings_form',
553
-                'action'          => EE_Admin_Page::add_query_args_and_nonce(
554
-                    [
555
-                        'action'         => 'update_payment_method',
556
-                        'payment_method' => $payment_method->slug(),
557
-                    ],
558
-                    EE_PAYMENTS_ADMIN_URL
559
-                ),
560
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
561
-                'subsections'     => array_filter($subsections),
562
-            ]
563
-        );
564
-    }
565
-
566
-
567
-    /**
568
-     * _pci_dss_compliance
569
-     *
570
-     * @access protected
571
-     * @param EE_Payment_Method $payment_method
572
-     * @return EE_Form_Section_HTML|null
573
-     * @throws EE_Error
574
-     */
575
-    protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576
-    {
577
-        if (! $payment_method->type_obj()->requires_https()) {
578
-            return null;
579
-        }
580
-        return new EE_Form_Section_HTML(
581
-            EEH_HTML::tr(
582
-                EEH_HTML::th(
583
-                    EEH_HTML::label(
584
-                        EEH_HTML::strong(
585
-                            esc_html__('IMPORTANT', 'event_espresso'),
586
-                            '',
587
-                            'important-notice'
588
-                        )
589
-                    )
590
-                ) .
591
-                EEH_HTML::td(
592
-                    EEH_HTML::div(
593
-                        EEH_HTML::strong(
594
-                            esc_html__(
595
-                                'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
596
-                                'event_espresso'
597
-                            )
598
-                        ),
599
-                        '',
600
-                        'ee-status-outline ee-status-bg--warning'
601
-                    )
602
-                    . EEH_HTML::br()
603
-
604
-                    . EEH_HTML::div(
605
-                        esc_html__('Learn more about ', 'event_espresso')
606
-                        . EEH_HTML::link(
607
-                            'https://www.pcisecuritystandards.org/merchants/index.php',
608
-                            esc_html__('PCI DSS compliance', 'event_espresso')
609
-                        ),
610
-                        '',
611
-                        'ee-status-outline ee-status-bg--info'
612
-                    )
613
-                )
614
-            )
615
-        );
616
-    }
617
-
618
-
619
-    /**
620
-     * _currency_support
621
-     *
622
-     * @access protected
623
-     * @param EE_Payment_Method $payment_method
624
-     * @return EE_Form_Section_HTML|null
625
-     * @throws EE_Error
626
-     */
627
-    protected function _currency_support(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
628
-    {
629
-        if ($payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
630
-            return null;
631
-        }
632
-        return new EE_Form_Section_HTML(
633
-            EEH_HTML::tr(
634
-                EEH_HTML::th(
635
-                    EEH_HTML::label(
636
-                        EEH_HTML::strong(
637
-                            esc_html__('IMPORTANT', 'event_espresso'),
638
-                            '',
639
-                            'important-notice'
640
-                        )
641
-                    )
642
-                ) .
643
-                EEH_HTML::td(
644
-                    EEH_HTML::div(
645
-                        EEH_HTML::strong(
646
-                            sprintf(
647
-                                esc_html__(
648
-                                    'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
649
-                                    'event_espresso'
650
-                                ),
651
-                                EE_Config::instance()->currency->code
652
-                            )
653
-                        ),
654
-                        '',
655
-                        'ee-status-outline ee-status-bg--warning'
656
-                    )
657
-                )
658
-            )
659
-        );
660
-    }
661
-
662
-
663
-    /**
664
-     * _update_payment_method_button
665
-     *
666
-     * @access protected
667
-     * @param EE_Payment_Method $payment_method
668
-     * @return EE_Payment_Method_Form
669
-     * @throws EE_Error
670
-     * @throws ReflectionException
671
-     */
672
-    protected function _payment_method_settings(EE_Payment_Method $payment_method): EE_Payment_Method_Form
673
-    {
674
-        // modify the form, so we only have/show fields that will be implemented for this version
675
-        return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
676
-    }
677
-
678
-
679
-    /**
680
-     * Simplifies the form to merely reproduce 4.1's gateway settings functionality
681
-     *
682
-     * @param EE_Form_Section_Proper $form_section
683
-     * @param string                 $payment_method_name
684
-     * @return EE_Payment_Method_Form
685
-     * @throws EE_Error
686
-     */
687
-    protected function _simplify_form(
688
-        EE_Form_Section_Proper $form_section,
689
-        string $payment_method_name = ''
690
-    ): EE_Payment_Method_Form {
691
-        if ($form_section instanceof EE_Payment_Method_Form) {
692
-            $form_section->exclude(
693
-                [
694
-                    'PMD_type', // don't want them changing the type
695
-                    'PMD_slug', // or the slug (probably never)
696
-                    'PMD_wp_user', // or the user's ID
697
-                    'Currency', // or the currency, until the rest of EE supports simultaneous currencies
698
-                ]
699
-            );
700
-            return $form_section;
701
-        }
702
-        throw new EE_Error(
703
-            sprintf(
704
-                esc_html__(
705
-                    'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
706
-                    'event_espresso'
707
-                ),
708
-                $payment_method_name
709
-            )
710
-        );
711
-    }
712
-
713
-
714
-    /**
715
-     * _update_payment_method_button
716
-     *
717
-     * @access protected
718
-     * @param EE_Payment_Method $payment_method
719
-     * @return EE_Form_Section_HTML
720
-     * @throws EE_Error
721
-     */
722
-    protected function _update_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
723
-    {
724
-        $update_button = new EE_Submit_Input(
725
-            [
726
-                'name'       => 'submit',
727
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
728
-                'default'    => sprintf(
729
-                    esc_html__('Update %s Payment Settings', 'event_espresso'),
730
-                    $payment_method->admin_name()
731
-                ),
732
-                'html_label' => EEH_HTML::nbsp(),
733
-            ]
734
-        );
735
-        return new EE_Form_Section_HTML(
736
-            EEH_HTML::tr(
737
-                EEH_HTML::th(
738
-                // esc_html__('Update Settings', 'event_espresso'),
739
-                    '&nbsp;',
740
-                    '',
741
-                    'ee-update-' . $payment_method->slug() . '-settings__label'
742
-                ) .
743
-                EEH_HTML::td(
744
-                    $update_button->get_html_for_input(),
745
-                    '',
746
-                    'ee-update-' . $payment_method->slug() . '-settings__input'
747
-                ),
748
-                '',
749
-                'ee-update-' . $payment_method->slug() . '-settings'
750
-            )
751
-        );
752
-    }
753
-
754
-
755
-    /**
756
-     * _deactivate_payment_method_button
757
-     *
758
-     * @access protected
759
-     * @param EE_Payment_Method $payment_method
760
-     * @return EE_Form_Section_HTML
761
-     */
762
-    protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
763
-    {
764
-        $link_text_and_title = sprintf(
765
-            esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
766
-            $payment_method->admin_name()
767
-        );
768
-        return new EE_Form_Section_HTML(
769
-            EEH_HTML::tr(
770
-                EEH_HTML::th(
771
-                // esc_html__('Deactivate Payment Method', 'event_espresso'),
772
-                    '&nbsp;',
773
-                    '',
774
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
-                ) .
776
-                EEH_HTML::td(
777
-                    EEH_HTML::link(
778
-                        EE_Admin_Page::add_query_args_and_nonce(
779
-                            [
780
-                                'action'         => 'deactivate_payment_method',
781
-                                'payment_method' => $payment_method->slug(),
782
-                            ],
783
-                            EE_PAYMENTS_ADMIN_URL
784
-                        ),
785
-                        $link_text_and_title,
786
-                        $link_text_and_title,
787
-                        'deactivate_' . $payment_method->slug(),
788
-                        'button button--secondary'
789
-                    ),
790
-                    '',
791
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__input'
792
-                ),
793
-                '',
794
-                'ee-deactivate-' . $payment_method->slug() . '-settings'
795
-            )
796
-        );
797
-    }
798
-
799
-
800
-    /**
801
-     * _activate_payment_method_button
802
-     *
803
-     * @access protected
804
-     * @param EE_Payment_Method $payment_method
805
-     * @return EE_Form_Section_Proper
806
-     * @throws EE_Error
807
-     */
808
-    protected function _activate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_Proper
809
-    {
810
-        $link_text_and_title = sprintf(
811
-            esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
812
-            $payment_method->admin_name()
813
-        );
814
-        return new EE_Form_Section_Proper(
815
-            [
816
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
818
-                'action'          => '#',
819
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820
-                'subsections'     => apply_filters(
821
-                    'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
822
-                    [
823
-                        new EE_Form_Section_HTML(
824
-                            EEH_HTML::table(
825
-                                EEH_HTML::tr(
826
-                                    EEH_HTML::td(
827
-                                        $payment_method->type_obj()->introductory_html(),
828
-                                        '',
829
-                                        '',
830
-                                        '',
831
-                                        'colspan="2"'
832
-                                    )
833
-                                ) .
834
-                                EEH_HTML::tr(
835
-                                    EEH_HTML::th(
836
-                                        EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
-                                    ) .
838
-                                    EEH_HTML::td(
839
-                                        EEH_HTML::link(
840
-                                            EE_Admin_Page::add_query_args_and_nonce(
841
-                                                [
842
-                                                    'action'              => 'activate_payment_method',
843
-                                                    'payment_method_type' => $payment_method->type(),
844
-                                                ],
845
-                                                EE_PAYMENTS_ADMIN_URL
846
-                                            ),
847
-                                            $link_text_and_title,
848
-                                            $link_text_and_title,
849
-                                            'activate_' . $payment_method->slug(),
850
-                                            'button button--primary-alt'
851
-                                        )
852
-                                    )
853
-                                )
854
-                            )
855
-                        ),
856
-                    ],
857
-                    $payment_method
858
-                ),
859
-            ]
860
-        );
861
-    }
862
-
863
-
864
-    /**
865
-     * _fine_print
866
-     *
867
-     * @access protected
868
-     * @return EE_Form_Section_HTML
869
-     */
870
-    protected function _fine_print(): EE_Form_Section_HTML
871
-    {
872
-        return new EE_Form_Section_HTML(
873
-            EEH_HTML::tr(
874
-                EEH_HTML::th()
875
-                . EEH_HTML::thx()
876
-                . EEH_HTML::td(
877
-                    EEH_HTML::p(
878
-                        esc_html__('All fields marked with a * are required fields', 'event_espresso'),
879
-                        '',
880
-                        'grey-text'
881
-                    )
882
-                )
883
-            )
884
-        );
885
-    }
886
-
887
-
888
-    /**
889
-     * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
890
-     *
891
-     * @throws EE_Error
892
-     * @throws ReflectionException
893
-     * @global WP_User $current_user
894
-     */
895
-    protected function _activate_payment_method()
896
-    {
897
-        if (isset($this->_req_data['payment_method_type'])) {
898
-            $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
899
-            // see if one exists
900
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
901
-            $payment_method = EE_Payment_Method_Manager::instance()
902
-                                                       ->activate_a_payment_method_of_type($payment_method_type);
903
-            $this->_redirect_after_action(
904
-                1,
905
-                'Payment Method',
906
-                'activated',
907
-                ['action' => 'default', 'payment_method' => $payment_method->slug()]
908
-            );
909
-        } else {
910
-            $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
911
-        }
912
-    }
913
-
914
-
915
-    /**
916
-     * @throws EE_Error
917
-     * @throws ReflectionException
918
-     */
919
-    protected function _deactivate_payment_method()
920
-    {
921
-        if (isset($this->_req_data['payment_method'])) {
922
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
923
-            // deactivate it
924
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
925
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
926
-            $this->_redirect_after_action(
927
-                $count_updated,
928
-                'Payment Method',
929
-                'deactivated',
930
-                ['action' => 'default', 'payment_method' => $payment_method_slug]
931
-            );
932
-        } else {
933
-            $this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
934
-        }
935
-    }
936
-
937
-
938
-    /**
939
-     * Processes the payment method form that was submitted. This is slightly trickier than usual form
940
-     * processing because we first need to identify WHICH form was processed and which payment method
941
-     * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
942
-     * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
943
-     * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
944
-     * subsequently called 'headers_sent_func' which is _payment_methods_list)
945
-     *
946
-     * @return void
947
-     * @throws EE_Error
948
-     * @throws ReflectionException
949
-     */
950
-    protected function _update_payment_method()
951
-    {
952
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
953
-            // ok let's find which gateway form to use based on the form input
954
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
955
-            /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
956
-            $correct_pmt_form_to_use = null;
957
-            $payment_method          = null;
958
-            foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
959
-                if ($payment_method instanceof EE_Payment_Method) {
960
-                    // get the form and simplify it, like what we do when we display it
961
-                    $pmt_form = $this->_generate_payment_method_settings_form($payment_method);
962
-                    if ($pmt_form->form_data_present_in($this->_req_data)) {
963
-                        $correct_pmt_form_to_use = $pmt_form;
964
-                        break;
965
-                    }
966
-                }
967
-            }
968
-            // if we couldn't find the correct payment method type...
969
-            if (! $correct_pmt_form_to_use) {
970
-                EE_Error::add_error(
971
-                    esc_html__(
972
-                        "We could not find which payment method type your form submission related to. Please contact support",
973
-                        'event_espresso'
974
-                    ),
975
-                    __FILE__,
976
-                    __FUNCTION__,
977
-                    __LINE__
978
-                );
979
-                $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
980
-            }
981
-            $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
982
-            if ($correct_pmt_form_to_use->is_valid()) {
983
-                $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
984
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
985
-                    throw new EE_Error(
986
-                        sprintf(
987
-                            esc_html__(
988
-                                'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
989
-                                'event_espresso'
990
-                            ),
991
-                            'payment_method_settings'
992
-                        )
993
-                    );
994
-                }
995
-                $payment_settings_subform->save();
996
-                /** @var $pm EE_Payment_Method */
997
-                $this->_redirect_after_action(
998
-                    true,
999
-                    'Payment Method',
1000
-                    'updated',
1001
-                    ['action' => 'default', 'payment_method' => $payment_method->slug()]
1002
-                );
1003
-            } else {
1004
-                EE_Error::add_error(
1005
-                    sprintf(
1006
-                        esc_html__(
1007
-                            'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1008
-                            'event_espresso'
1009
-                        ),
1010
-                        $payment_method instanceof EE_Payment_Method
1011
-                            ? $payment_method->type_obj()->pretty_name()
1012
-                            : esc_html__('"(unknown)"', 'event_espresso')
1013
-                    ),
1014
-                    __FILE__,
1015
-                    __FUNCTION__,
1016
-                    __LINE__
1017
-                );
1018
-            }
1019
-        }
1020
-    }
1021
-
1022
-
1023
-    /**
1024
-     * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1025
-     *
1026
-     * @throws DomainException
1027
-     * @throws EE_Error
1028
-     * @throws InvalidArgumentException
1029
-     * @throws InvalidDataTypeException
1030
-     * @throws InvalidInterfaceException
1031
-     */
1032
-    protected function _payment_settings()
1033
-    {
1034
-        $form = $this->getPaymentSettingsForm();
1035
-        $this->_set_add_edit_form_tags('update_payment_settings');
1036
-        $this->_set_publish_post_box_vars();
1037
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
1038
-            $form->get_html_and_js(),
1039
-            '',
1040
-            'padding'
1041
-        );
1042
-        $this->display_admin_page_with_sidebar();
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     *        _update_payment_settings
1048
-     *
1049
-     * @access protected
1050
-     * @return void
1051
-     * @throws EE_Error
1052
-     * @throws InvalidArgumentException
1053
-     * @throws InvalidDataTypeException
1054
-     * @throws InvalidInterfaceException
1055
-     */
1056
-    protected function _update_payment_settings()
1057
-    {
1058
-        $form = $this->getPaymentSettingsForm();
1059
-        if ($form->was_submitted($this->_req_data)) {
1060
-            $form->receive_form_submission($this->_req_data);
1061
-            if ($form->is_valid()) {
1062
-                /**
1063
-                 * @var $reg_config EE_Registration_Config
1064
-                 */
1065
-                $loader                                   = LoaderFactory::getLoader();
1066
-                $reg_config                               = $loader->getShared('EE_Registration_Config');
1067
-                $valid_data                               = $form->valid_data();
1068
-                $show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1069
-                $reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1070
-                $reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1071
-            }
1072
-        }
1073
-        EE_Registry::instance()->CFG = apply_filters(
1074
-            'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1075
-            EE_Registry::instance()->CFG
1076
-        );
1077
-
1078
-        $what    = esc_html__('Payment Settings', 'event_espresso');
1079
-        $success = $this->_update_espresso_configuration(
1080
-            $what,
1081
-            EE_Registry::instance()->CFG,
1082
-            __FILE__,
1083
-            __FUNCTION__,
1084
-            __LINE__
1085
-        );
1086
-        $this->_redirect_after_action(
1087
-            $success,
1088
-            $what,
1089
-            esc_html__('updated', 'event_espresso'),
1090
-            ['action' => 'payment_settings']
1091
-        );
1092
-    }
1093
-
1094
-
1095
-    /**
1096
-     * Gets the form used for updating payment settings
1097
-     *
1098
-     * @return EE_Form_Section_Proper
1099
-     * @throws EE_Error
1100
-     * @throws InvalidArgumentException
1101
-     * @throws InvalidDataTypeException
1102
-     * @throws InvalidInterfaceException
1103
-     */
1104
-    protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1105
-    {
1106
-        /**
1107
-         * @var $reg_config EE_Registration_Config
1108
-         */
1109
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1110
-        return new EE_Form_Section_Proper(
1111
-            [
1112
-                'name'            => 'payment-settings',
1113
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1114
-                'subsections'     => [
1115
-                    'show_pending_payment_options' => new EE_Switch_Input(
1116
-                        [
1117
-                            'default'        => $reg_config->show_pending_payment_options
1118
-                                ? EE_Switch_Input::OPTION_ON
1119
-                                : EE_Switch_Input::OPTION_OFF,
1120
-                            'html_name'      => 'show_pending_payment_options',
1121
-                            'html_help_text' => esc_html__(
1122
-                                "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1123
-                                'event_espresso'
1124
-                            ),
1125
-                        ],
1126
-                        [
1127
-                            EE_Switch_Input::OPTION_OFF => esc_html__(
1128
-                                'pending payment options are NOT displayed',
1129
-                                'event_espresso'
1130
-                            ),
1131
-                            EE_Switch_Input::OPTION_ON  => esc_html__(
1132
-                                'pending payment options are displayed',
1133
-                                'event_espresso'
1134
-                            ),
1135
-                        ]
1136
-                    ),
1137
-                    'gateway_log_lifespan'         => new EE_Select_Input(
1138
-                        $reg_config->gatewayLogLifespanOptions(),
1139
-                        [
1140
-                            'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1141
-                            'html_help_text'  => esc_html__(
1142
-                                'If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.',
1143
-                                'event_espresso'
1144
-                            ),
1145
-                            'default'         => $reg_config->gateway_log_lifespan,
1146
-                        ]
1147
-                    ),
1148
-                ],
1149
-            ]
1150
-        );
1151
-    }
1152
-
1153
-
1154
-    /**
1155
-     * @throws EE_Error
1156
-     */
1157
-    protected function _payment_log_overview_list_table()
1158
-    {
1159
-        $this->display_admin_list_table_page_with_sidebar();
1160
-    }
1161
-
1162
-
1163
-    protected function _set_list_table_views_payment_log()
1164
-    {
1165
-        $this->_views = [
1166
-            'all' => [
1167
-                'slug'  => 'all',
1168
-                'label' => esc_html__('View All Logs', 'event_espresso'),
1169
-                'count' => 0,
1170
-            ],
1171
-        ];
1172
-    }
1173
-
1174
-
1175
-    /**
1176
-     * @param int  $per_page
1177
-     * @param int  $current_page
1178
-     * @param bool $count
1179
-     * @return array|int
1180
-     * @throws EE_Error
1181
-     * @throws ReflectionException
1182
-     */
1183
-    public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1184
-    {
1185
-        EE_Registry::instance()->load_model('Change_Log');
1186
-        // we may need to do multiple queries (joining differently), so we actually want an array of query params
1187
-        $query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1188
-        // check if they've selected a specific payment method
1189
-        if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1190
-            $query_params[0]['OR*pm_or_pay_pm'] = [
1191
-                'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1192
-                'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1193
-            ];
1194
-        }
1195
-        // take into account search
1196
-        if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1197
-            $similarity_string                                                              =
1198
-                ['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1199
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1200
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1201
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1202
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1203
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1204
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1205
-            $query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1206
-            $query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1207
-            $query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1208
-            $query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1209
-        }
1210
-        if (
1211
-            isset($this->_req_data['payment-filter-start-date'])
1212
-            && isset($this->_req_data['payment-filter-end-date'])
1213
-        ) {
1214
-            // add date
1215
-            $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1216
-            $end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1217
-            // make sure our timestamps start and end right at the boundaries for each day
1218
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1219
-            $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1220
-            // convert to timestamps
1221
-            $start_date = strtotime($start_date);
1222
-            $end_date   = strtotime($end_date);
1223
-            // makes sure start date is the lowest value and vice versa
1224
-            $start_date = min($start_date, $end_date);
1225
-            $end_date   = max($start_date, $end_date);
1226
-            // convert for query
1227
-            $start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1228
-                'LOG_time',
1229
-                date('Y-m-d H:i:s', $start_date),
1230
-                'Y-m-d H:i:s'
1231
-            );
1232
-            $end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1233
-                'LOG_time',
1234
-                date('Y-m-d H:i:s', $end_date),
1235
-                'Y-m-d H:i:s'
1236
-            );
1237
-            $query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1238
-        }
1239
-        if ($count) {
1240
-            return EEM_Change_Log::instance()->count($query_params);
1241
-        }
1242
-        if (isset($this->_req_data['order'])) {
1243
-            $sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1244
-                ? $this->_req_data['order']
1245
-                : 'DESC';
1246
-            $query_params['order_by'] = ['LOG_time' => $sort];
1247
-        } else {
1248
-            $query_params['order_by'] = ['LOG_time' => 'DESC'];
1249
-        }
1250
-        $offset = ($current_page - 1) * $per_page;
1251
-        if (! isset($this->_req_data['download_results'])) {
1252
-            $query_params['limit'] = [$offset, $per_page];
1253
-        }
1254
-        // now they've requested to instead just download the file instead of viewing it.
1255
-        if (isset($this->_req_data['download_results'])) {
1256
-            $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1257
-            header('Content-Disposition: attachment');
1258
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1259
-            echo '<h1> '
1260
-                 . sprintf(
1261
-                     esc_html__('Payment Logs for %1$s', 'event_espresso'),
1262
-                     esc_url_raw(site_url())
1263
-                 )
1264
-                 . '</h1 >';
1265
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1266
-            echo esc_html(var_export($query_params, true));
1267
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1268
-            echo esc_html(var_export($wpdb_results, true));
1269
-            die;
1270
-        }
1271
-        return EEM_Change_Log::instance()->get_all($query_params);
1272
-    }
1273
-
1274
-
1275
-    /**
1276
-     * Used by usort to RE-sort log query results, because we lose the ordering
1277
-     * because we're possibly combining the results from two queries
1278
-     *
1279
-     * @param EE_Change_Log $logA
1280
-     * @param EE_Change_Log $logB
1281
-     * @return int
1282
-     * @throws EE_Error
1283
-     * @throws ReflectionException
1284
-     */
1285
-    protected function _sort_logs_again($logA, $logB)
1286
-    {
1287
-        $timeA = $logA->get_raw('LOG_time');
1288
-        $timeB = $logB->get_raw('LOG_time');
1289
-        if ($timeA == $timeB) {
1290
-            return 0;
1291
-        }
1292
-        $comparison = $timeA < $timeB
1293
-            ? -1
1294
-            : 1;
1295
-        if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1296
-            return $comparison * -1;
1297
-        }
1298
-        return $comparison;
1299
-    }
1300
-
1301
-
1302
-    /**
1303
-     * @throws EE_Error
1304
-     * @throws ReflectionException
1305
-     */
1306
-    protected function _payment_log_details()
1307
-    {
1308
-        EE_Registry::instance()->load_model('Change_Log');
1309
-        /** @var $payment_log EE_Change_Log */
1310
-        $payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1311
-        $payment_method = null;
1312
-        $transaction    = null;
1313
-        if ($payment_log instanceof EE_Change_Log) {
1314
-            if ($payment_log->object() instanceof EE_Payment) {
1315
-                $payment_method = $payment_log->object()->payment_method();
1316
-                $transaction    = $payment_log->object()->transaction();
1317
-            } elseif ($payment_log->object() instanceof EE_Payment_Method) {
1318
-                $payment_method = $payment_log->object();
1319
-            } elseif ($payment_log->object() instanceof EE_Transaction) {
1320
-                $transaction    = $payment_log->object();
1321
-                $payment_method = $transaction->payment_method();
1322
-            }
1323
-        }
1324
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1325
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1326
-            [
1327
-                'payment_log'    => $payment_log,
1328
-                'payment_method' => $payment_method,
1329
-                'transaction'    => $transaction,
1330
-            ],
1331
-            true
1332
-        );
1333
-        $this->display_admin_page_with_no_sidebar();
1334
-    }
327
+				'InnoDB'
328
+			);
329
+		}
330
+	}
331
+
332
+
333
+	/**
334
+	 * @throws EE_Error
335
+	 * @throws ReflectionException
336
+	 */
337
+	protected function _payment_methods_list()
338
+	{
339
+		$this->veryifyTablesExist();
340
+		/**
341
+		 * first let's ensure payment methods have been set up.
342
+		 * We do this here because when people activate a payment method for the first time (as an addon),
343
+		 * it may not set up its capabilities or get registered correctly due to the loading process.
344
+		 * However, people MUST set up the details for the payment method,
345
+		 * so it's safe to do a recheck here.
346
+		 */
347
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
348
+		EEM_Payment_Method::instance()->verify_button_urls();
349
+		// set up tabs, one for each payment method type
350
+		$tabs            = [];
351
+		$payment_methods = [];
352
+		foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
353
+			// we don't want to show admin-only PMTs for now
354
+			if ($pmt_obj instanceof EE_PMT_Admin_Only) {
355
+				continue;
356
+			}
357
+			// check access
358
+			if (
359
+				! $this->capabilities->current_user_can(
360
+					$pmt_obj->cap_name(),
361
+					'specific_payment_method_type_access'
362
+				)
363
+			) {
364
+				continue;
365
+			}
366
+			// check for any active pms of that type
367
+			$payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
+			if (! $payment_method instanceof EE_Payment_Method) {
369
+				$payment_method = EE_Payment_Method::new_instance(
370
+					[
371
+						'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
372
+						'PMD_type'       => $pmt_obj->system_name(),
373
+						'PMD_name'       => $pmt_obj->pretty_name(),
374
+						'PMD_admin_name' => $pmt_obj->pretty_name(),
375
+					]
376
+				);
377
+			}
378
+			$payment_methods[ $payment_method->slug() ] = $payment_method;
379
+		}
380
+		$payment_methods = apply_filters(
381
+			'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
382
+			$payment_methods
383
+		);
384
+		foreach ($payment_methods as $payment_method) {
385
+			if ($payment_method instanceof EE_Payment_Method) {
386
+				$this->addMetaBox(
387
+				// html id
388
+					'espresso_' . $payment_method->slug() . '_payment_settings',
389
+					// title
390
+					sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391
+					// callback
392
+					[$this, 'payment_method_settings_meta_box'],
393
+					// post type
394
+					null,
395
+					// context
396
+					'normal',
397
+					// priority
398
+					'default',
399
+					// callback args
400
+					['payment_method' => $payment_method]
401
+				);
402
+				// setup for tabbed content
403
+				$tabs[ $payment_method->slug() ] = [
404
+					'label' => $payment_method->admin_name(),
405
+					'class' => $payment_method->active()
406
+						? 'gateway-active'
407
+						: '',
408
+					'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
409
+					'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410
+					'slug'  => $payment_method->slug(),
411
+					'icon'  => $payment_method->active()
412
+						? '<span class="dashicons dashicons-yes-alt"></span>'
413
+						: '<span class="dashicons dashicons-remove"></span>',
414
+				];
415
+			}
416
+		}
417
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
418
+			$tabs,
419
+			'payment_method_links',
420
+			'',
421
+			$this->_get_active_payment_method_slug()
422
+		);
423
+		$this->display_admin_page_with_sidebar();
424
+	}
425
+
426
+
427
+	/**
428
+	 *   _get_active_payment_method_slug
429
+	 *
430
+	 * @return string
431
+	 * @throws EE_Error
432
+	 * @throws ReflectionException
433
+	 */
434
+	protected function _get_active_payment_method_slug()
435
+	{
436
+		$payment_method_slug = false;
437
+		// decide which payment method tab to open first, as dictated by the request's 'payment_method'
438
+		if (isset($this->_req_data['payment_method'])) {
439
+			// if they provided the current payment method, use it
440
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
441
+		}
442
+
443
+		$payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444
+		// if that didn't work or wasn't provided, find another way to select the current pm
445
+		if (! $this->_verify_payment_method($payment_method)) {
446
+			// like, looking for an active one
447
+			$payment_method = EEM_Payment_Method::instance()->get_one_active(EEM_Payment_Method::scope_cart);
448
+			// test that one as well
449
+			if ($this->_verify_payment_method($payment_method)) {
450
+				$payment_method_slug = $payment_method->slug();
451
+			} else {
452
+				$payment_method_slug = 'paypal_standard';
453
+			}
454
+		}
455
+		return $payment_method_slug;
456
+	}
457
+
458
+
459
+	/**
460
+	 *    payment_method_settings_meta_box
461
+	 *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
462
+	 *    capabilities to access it
463
+	 *
464
+	 * @param EE_Payment_Method|null $payment_method
465
+	 * @return boolean
466
+	 * @throws EE_Error
467
+	 */
468
+	protected function _verify_payment_method(?EE_Payment_Method $payment_method): bool
469
+	{
470
+		return $payment_method instanceof EE_Payment_Method
471
+			   && $payment_method->type_obj() instanceof EE_PMT_Base
472
+			   && $this->capabilities->current_user_can(
473
+				   $payment_method->type_obj()->cap_name(),
474
+				   'specific_payment_method_type_access'
475
+			   );
476
+	}
477
+
478
+
479
+	/**
480
+	 *    payment_method_settings_meta_box
481
+	 *
482
+	 * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
483
+	 * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
484
+	 *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
485
+	 * @return void
486
+	 * @throws EE_Error
487
+	 * @throws ReflectionException
488
+	 */
489
+	public function payment_method_settings_meta_box($post_obj_which_is_null, array $metabox)
490
+	{
491
+		$payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492
+			? $metabox['args']['payment_method']
493
+			: null;
494
+		if (! $payment_method instanceof EE_Payment_Method) {
495
+			throw new EE_Error(
496
+				esc_html__(
497
+					'Payment method metabox setup incorrectly. No Payment method object was supplied',
498
+					'event_espresso'
499
+				)
500
+			);
501
+		}
502
+		$payment_method_scopes = $payment_method->active();
503
+		// if the payment method really exists show its form, otherwise the activation template
504
+		if ($payment_method->ID() && ! empty($payment_method_scopes)) {
505
+			$form = $this->_generate_payment_method_settings_form($payment_method);
506
+			if ($form->form_data_present_in($this->_req_data)) {
507
+				$form->receive_form_submission($this->_req_data);
508
+			}
509
+			echo wp_kses(
510
+				$form->form_open() . $form->get_html_and_js() . $form->form_close(),
511
+				AllowedTags::getWithFormTags()
512
+			);
513
+		} else {
514
+			echo wp_kses(
515
+				$this->_activate_payment_method_button($payment_method)->get_html_and_js(),
516
+				AllowedTags::getWithFormTags()
517
+			);
518
+		}
519
+	}
520
+
521
+
522
+	/**
523
+	 * Gets the form for all the settings related to this payment method type
524
+	 *
525
+	 * @access protected
526
+	 * @param EE_Payment_Method|null $payment_method
527
+	 * @return EE_Form_Section_Proper
528
+	 * @throws EE_Error
529
+	 * @throws ReflectionException
530
+	 */
531
+	protected function _generate_payment_method_settings_form(
532
+		?EE_Payment_Method $payment_method
533
+	): EE_Form_Section_Proper {
534
+		if (! $payment_method instanceof EE_Payment_Method) {
535
+			return new EE_Form_Section_Proper();
536
+		}
537
+		$subsections = apply_filters(
538
+			'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
539
+			[
540
+				'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
541
+				'currency_support'        => $this->_currency_support($payment_method),
542
+				'payment_method_settings' => $this->_payment_method_settings($payment_method),
543
+				'update'                  => $this->_update_payment_method_button($payment_method),
544
+				'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
545
+				'fine_print'              => $this->_fine_print(),
546
+			],
547
+			$payment_method
548
+		);
549
+		return new EE_Form_Section_Proper(
550
+			[
551
+				'name'            => $payment_method->slug() . '_settings_form',
552
+				'html_id'         => $payment_method->slug() . '_settings_form',
553
+				'action'          => EE_Admin_Page::add_query_args_and_nonce(
554
+					[
555
+						'action'         => 'update_payment_method',
556
+						'payment_method' => $payment_method->slug(),
557
+					],
558
+					EE_PAYMENTS_ADMIN_URL
559
+				),
560
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
561
+				'subsections'     => array_filter($subsections),
562
+			]
563
+		);
564
+	}
565
+
566
+
567
+	/**
568
+	 * _pci_dss_compliance
569
+	 *
570
+	 * @access protected
571
+	 * @param EE_Payment_Method $payment_method
572
+	 * @return EE_Form_Section_HTML|null
573
+	 * @throws EE_Error
574
+	 */
575
+	protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576
+	{
577
+		if (! $payment_method->type_obj()->requires_https()) {
578
+			return null;
579
+		}
580
+		return new EE_Form_Section_HTML(
581
+			EEH_HTML::tr(
582
+				EEH_HTML::th(
583
+					EEH_HTML::label(
584
+						EEH_HTML::strong(
585
+							esc_html__('IMPORTANT', 'event_espresso'),
586
+							'',
587
+							'important-notice'
588
+						)
589
+					)
590
+				) .
591
+				EEH_HTML::td(
592
+					EEH_HTML::div(
593
+						EEH_HTML::strong(
594
+							esc_html__(
595
+								'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
596
+								'event_espresso'
597
+							)
598
+						),
599
+						'',
600
+						'ee-status-outline ee-status-bg--warning'
601
+					)
602
+					. EEH_HTML::br()
603
+
604
+					. EEH_HTML::div(
605
+						esc_html__('Learn more about ', 'event_espresso')
606
+						. EEH_HTML::link(
607
+							'https://www.pcisecuritystandards.org/merchants/index.php',
608
+							esc_html__('PCI DSS compliance', 'event_espresso')
609
+						),
610
+						'',
611
+						'ee-status-outline ee-status-bg--info'
612
+					)
613
+				)
614
+			)
615
+		);
616
+	}
617
+
618
+
619
+	/**
620
+	 * _currency_support
621
+	 *
622
+	 * @access protected
623
+	 * @param EE_Payment_Method $payment_method
624
+	 * @return EE_Form_Section_HTML|null
625
+	 * @throws EE_Error
626
+	 */
627
+	protected function _currency_support(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
628
+	{
629
+		if ($payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
630
+			return null;
631
+		}
632
+		return new EE_Form_Section_HTML(
633
+			EEH_HTML::tr(
634
+				EEH_HTML::th(
635
+					EEH_HTML::label(
636
+						EEH_HTML::strong(
637
+							esc_html__('IMPORTANT', 'event_espresso'),
638
+							'',
639
+							'important-notice'
640
+						)
641
+					)
642
+				) .
643
+				EEH_HTML::td(
644
+					EEH_HTML::div(
645
+						EEH_HTML::strong(
646
+							sprintf(
647
+								esc_html__(
648
+									'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
649
+									'event_espresso'
650
+								),
651
+								EE_Config::instance()->currency->code
652
+							)
653
+						),
654
+						'',
655
+						'ee-status-outline ee-status-bg--warning'
656
+					)
657
+				)
658
+			)
659
+		);
660
+	}
661
+
662
+
663
+	/**
664
+	 * _update_payment_method_button
665
+	 *
666
+	 * @access protected
667
+	 * @param EE_Payment_Method $payment_method
668
+	 * @return EE_Payment_Method_Form
669
+	 * @throws EE_Error
670
+	 * @throws ReflectionException
671
+	 */
672
+	protected function _payment_method_settings(EE_Payment_Method $payment_method): EE_Payment_Method_Form
673
+	{
674
+		// modify the form, so we only have/show fields that will be implemented for this version
675
+		return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
676
+	}
677
+
678
+
679
+	/**
680
+	 * Simplifies the form to merely reproduce 4.1's gateway settings functionality
681
+	 *
682
+	 * @param EE_Form_Section_Proper $form_section
683
+	 * @param string                 $payment_method_name
684
+	 * @return EE_Payment_Method_Form
685
+	 * @throws EE_Error
686
+	 */
687
+	protected function _simplify_form(
688
+		EE_Form_Section_Proper $form_section,
689
+		string $payment_method_name = ''
690
+	): EE_Payment_Method_Form {
691
+		if ($form_section instanceof EE_Payment_Method_Form) {
692
+			$form_section->exclude(
693
+				[
694
+					'PMD_type', // don't want them changing the type
695
+					'PMD_slug', // or the slug (probably never)
696
+					'PMD_wp_user', // or the user's ID
697
+					'Currency', // or the currency, until the rest of EE supports simultaneous currencies
698
+				]
699
+			);
700
+			return $form_section;
701
+		}
702
+		throw new EE_Error(
703
+			sprintf(
704
+				esc_html__(
705
+					'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
706
+					'event_espresso'
707
+				),
708
+				$payment_method_name
709
+			)
710
+		);
711
+	}
712
+
713
+
714
+	/**
715
+	 * _update_payment_method_button
716
+	 *
717
+	 * @access protected
718
+	 * @param EE_Payment_Method $payment_method
719
+	 * @return EE_Form_Section_HTML
720
+	 * @throws EE_Error
721
+	 */
722
+	protected function _update_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
723
+	{
724
+		$update_button = new EE_Submit_Input(
725
+			[
726
+				'name'       => 'submit',
727
+				'html_id'    => 'save_' . $payment_method->slug() . '_settings',
728
+				'default'    => sprintf(
729
+					esc_html__('Update %s Payment Settings', 'event_espresso'),
730
+					$payment_method->admin_name()
731
+				),
732
+				'html_label' => EEH_HTML::nbsp(),
733
+			]
734
+		);
735
+		return new EE_Form_Section_HTML(
736
+			EEH_HTML::tr(
737
+				EEH_HTML::th(
738
+				// esc_html__('Update Settings', 'event_espresso'),
739
+					'&nbsp;',
740
+					'',
741
+					'ee-update-' . $payment_method->slug() . '-settings__label'
742
+				) .
743
+				EEH_HTML::td(
744
+					$update_button->get_html_for_input(),
745
+					'',
746
+					'ee-update-' . $payment_method->slug() . '-settings__input'
747
+				),
748
+				'',
749
+				'ee-update-' . $payment_method->slug() . '-settings'
750
+			)
751
+		);
752
+	}
753
+
754
+
755
+	/**
756
+	 * _deactivate_payment_method_button
757
+	 *
758
+	 * @access protected
759
+	 * @param EE_Payment_Method $payment_method
760
+	 * @return EE_Form_Section_HTML
761
+	 */
762
+	protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_HTML
763
+	{
764
+		$link_text_and_title = sprintf(
765
+			esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
766
+			$payment_method->admin_name()
767
+		);
768
+		return new EE_Form_Section_HTML(
769
+			EEH_HTML::tr(
770
+				EEH_HTML::th(
771
+				// esc_html__('Deactivate Payment Method', 'event_espresso'),
772
+					'&nbsp;',
773
+					'',
774
+					'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
+				) .
776
+				EEH_HTML::td(
777
+					EEH_HTML::link(
778
+						EE_Admin_Page::add_query_args_and_nonce(
779
+							[
780
+								'action'         => 'deactivate_payment_method',
781
+								'payment_method' => $payment_method->slug(),
782
+							],
783
+							EE_PAYMENTS_ADMIN_URL
784
+						),
785
+						$link_text_and_title,
786
+						$link_text_and_title,
787
+						'deactivate_' . $payment_method->slug(),
788
+						'button button--secondary'
789
+					),
790
+					'',
791
+					'ee-deactivate-' . $payment_method->slug() . '-settings__input'
792
+				),
793
+				'',
794
+				'ee-deactivate-' . $payment_method->slug() . '-settings'
795
+			)
796
+		);
797
+	}
798
+
799
+
800
+	/**
801
+	 * _activate_payment_method_button
802
+	 *
803
+	 * @access protected
804
+	 * @param EE_Payment_Method $payment_method
805
+	 * @return EE_Form_Section_Proper
806
+	 * @throws EE_Error
807
+	 */
808
+	protected function _activate_payment_method_button(EE_Payment_Method $payment_method): EE_Form_Section_Proper
809
+	{
810
+		$link_text_and_title = sprintf(
811
+			esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
812
+			$payment_method->admin_name()
813
+		);
814
+		return new EE_Form_Section_Proper(
815
+			[
816
+				'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
+				'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
818
+				'action'          => '#',
819
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820
+				'subsections'     => apply_filters(
821
+					'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
822
+					[
823
+						new EE_Form_Section_HTML(
824
+							EEH_HTML::table(
825
+								EEH_HTML::tr(
826
+									EEH_HTML::td(
827
+										$payment_method->type_obj()->introductory_html(),
828
+										'',
829
+										'',
830
+										'',
831
+										'colspan="2"'
832
+									)
833
+								) .
834
+								EEH_HTML::tr(
835
+									EEH_HTML::th(
836
+										EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
+									) .
838
+									EEH_HTML::td(
839
+										EEH_HTML::link(
840
+											EE_Admin_Page::add_query_args_and_nonce(
841
+												[
842
+													'action'              => 'activate_payment_method',
843
+													'payment_method_type' => $payment_method->type(),
844
+												],
845
+												EE_PAYMENTS_ADMIN_URL
846
+											),
847
+											$link_text_and_title,
848
+											$link_text_and_title,
849
+											'activate_' . $payment_method->slug(),
850
+											'button button--primary-alt'
851
+										)
852
+									)
853
+								)
854
+							)
855
+						),
856
+					],
857
+					$payment_method
858
+				),
859
+			]
860
+		);
861
+	}
862
+
863
+
864
+	/**
865
+	 * _fine_print
866
+	 *
867
+	 * @access protected
868
+	 * @return EE_Form_Section_HTML
869
+	 */
870
+	protected function _fine_print(): EE_Form_Section_HTML
871
+	{
872
+		return new EE_Form_Section_HTML(
873
+			EEH_HTML::tr(
874
+				EEH_HTML::th()
875
+				. EEH_HTML::thx()
876
+				. EEH_HTML::td(
877
+					EEH_HTML::p(
878
+						esc_html__('All fields marked with a * are required fields', 'event_espresso'),
879
+						'',
880
+						'grey-text'
881
+					)
882
+				)
883
+			)
884
+		);
885
+	}
886
+
887
+
888
+	/**
889
+	 * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
890
+	 *
891
+	 * @throws EE_Error
892
+	 * @throws ReflectionException
893
+	 * @global WP_User $current_user
894
+	 */
895
+	protected function _activate_payment_method()
896
+	{
897
+		if (isset($this->_req_data['payment_method_type'])) {
898
+			$payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
899
+			// see if one exists
900
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
901
+			$payment_method = EE_Payment_Method_Manager::instance()
902
+													   ->activate_a_payment_method_of_type($payment_method_type);
903
+			$this->_redirect_after_action(
904
+				1,
905
+				'Payment Method',
906
+				'activated',
907
+				['action' => 'default', 'payment_method' => $payment_method->slug()]
908
+			);
909
+		} else {
910
+			$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
911
+		}
912
+	}
913
+
914
+
915
+	/**
916
+	 * @throws EE_Error
917
+	 * @throws ReflectionException
918
+	 */
919
+	protected function _deactivate_payment_method()
920
+	{
921
+		if (isset($this->_req_data['payment_method'])) {
922
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
923
+			// deactivate it
924
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
925
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
926
+			$this->_redirect_after_action(
927
+				$count_updated,
928
+				'Payment Method',
929
+				'deactivated',
930
+				['action' => 'default', 'payment_method' => $payment_method_slug]
931
+			);
932
+		} else {
933
+			$this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
934
+		}
935
+	}
936
+
937
+
938
+	/**
939
+	 * Processes the payment method form that was submitted. This is slightly trickier than usual form
940
+	 * processing because we first need to identify WHICH form was processed and which payment method
941
+	 * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
942
+	 * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
943
+	 * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
944
+	 * subsequently called 'headers_sent_func' which is _payment_methods_list)
945
+	 *
946
+	 * @return void
947
+	 * @throws EE_Error
948
+	 * @throws ReflectionException
949
+	 */
950
+	protected function _update_payment_method()
951
+	{
952
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
953
+			// ok let's find which gateway form to use based on the form input
954
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
955
+			/** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
956
+			$correct_pmt_form_to_use = null;
957
+			$payment_method          = null;
958
+			foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
959
+				if ($payment_method instanceof EE_Payment_Method) {
960
+					// get the form and simplify it, like what we do when we display it
961
+					$pmt_form = $this->_generate_payment_method_settings_form($payment_method);
962
+					if ($pmt_form->form_data_present_in($this->_req_data)) {
963
+						$correct_pmt_form_to_use = $pmt_form;
964
+						break;
965
+					}
966
+				}
967
+			}
968
+			// if we couldn't find the correct payment method type...
969
+			if (! $correct_pmt_form_to_use) {
970
+				EE_Error::add_error(
971
+					esc_html__(
972
+						"We could not find which payment method type your form submission related to. Please contact support",
973
+						'event_espresso'
974
+					),
975
+					__FILE__,
976
+					__FUNCTION__,
977
+					__LINE__
978
+				);
979
+				$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
980
+			}
981
+			$correct_pmt_form_to_use->receive_form_submission($this->_req_data);
982
+			if ($correct_pmt_form_to_use->is_valid()) {
983
+				$payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
984
+				if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
985
+					throw new EE_Error(
986
+						sprintf(
987
+							esc_html__(
988
+								'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
989
+								'event_espresso'
990
+							),
991
+							'payment_method_settings'
992
+						)
993
+					);
994
+				}
995
+				$payment_settings_subform->save();
996
+				/** @var $pm EE_Payment_Method */
997
+				$this->_redirect_after_action(
998
+					true,
999
+					'Payment Method',
1000
+					'updated',
1001
+					['action' => 'default', 'payment_method' => $payment_method->slug()]
1002
+				);
1003
+			} else {
1004
+				EE_Error::add_error(
1005
+					sprintf(
1006
+						esc_html__(
1007
+							'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1008
+							'event_espresso'
1009
+						),
1010
+						$payment_method instanceof EE_Payment_Method
1011
+							? $payment_method->type_obj()->pretty_name()
1012
+							: esc_html__('"(unknown)"', 'event_espresso')
1013
+					),
1014
+					__FILE__,
1015
+					__FUNCTION__,
1016
+					__LINE__
1017
+				);
1018
+			}
1019
+		}
1020
+	}
1021
+
1022
+
1023
+	/**
1024
+	 * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1025
+	 *
1026
+	 * @throws DomainException
1027
+	 * @throws EE_Error
1028
+	 * @throws InvalidArgumentException
1029
+	 * @throws InvalidDataTypeException
1030
+	 * @throws InvalidInterfaceException
1031
+	 */
1032
+	protected function _payment_settings()
1033
+	{
1034
+		$form = $this->getPaymentSettingsForm();
1035
+		$this->_set_add_edit_form_tags('update_payment_settings');
1036
+		$this->_set_publish_post_box_vars();
1037
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
1038
+			$form->get_html_and_js(),
1039
+			'',
1040
+			'padding'
1041
+		);
1042
+		$this->display_admin_page_with_sidebar();
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 *        _update_payment_settings
1048
+	 *
1049
+	 * @access protected
1050
+	 * @return void
1051
+	 * @throws EE_Error
1052
+	 * @throws InvalidArgumentException
1053
+	 * @throws InvalidDataTypeException
1054
+	 * @throws InvalidInterfaceException
1055
+	 */
1056
+	protected function _update_payment_settings()
1057
+	{
1058
+		$form = $this->getPaymentSettingsForm();
1059
+		if ($form->was_submitted($this->_req_data)) {
1060
+			$form->receive_form_submission($this->_req_data);
1061
+			if ($form->is_valid()) {
1062
+				/**
1063
+				 * @var $reg_config EE_Registration_Config
1064
+				 */
1065
+				$loader                                   = LoaderFactory::getLoader();
1066
+				$reg_config                               = $loader->getShared('EE_Registration_Config');
1067
+				$valid_data                               = $form->valid_data();
1068
+				$show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1069
+				$reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1070
+				$reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1071
+			}
1072
+		}
1073
+		EE_Registry::instance()->CFG = apply_filters(
1074
+			'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1075
+			EE_Registry::instance()->CFG
1076
+		);
1077
+
1078
+		$what    = esc_html__('Payment Settings', 'event_espresso');
1079
+		$success = $this->_update_espresso_configuration(
1080
+			$what,
1081
+			EE_Registry::instance()->CFG,
1082
+			__FILE__,
1083
+			__FUNCTION__,
1084
+			__LINE__
1085
+		);
1086
+		$this->_redirect_after_action(
1087
+			$success,
1088
+			$what,
1089
+			esc_html__('updated', 'event_espresso'),
1090
+			['action' => 'payment_settings']
1091
+		);
1092
+	}
1093
+
1094
+
1095
+	/**
1096
+	 * Gets the form used for updating payment settings
1097
+	 *
1098
+	 * @return EE_Form_Section_Proper
1099
+	 * @throws EE_Error
1100
+	 * @throws InvalidArgumentException
1101
+	 * @throws InvalidDataTypeException
1102
+	 * @throws InvalidInterfaceException
1103
+	 */
1104
+	protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1105
+	{
1106
+		/**
1107
+		 * @var $reg_config EE_Registration_Config
1108
+		 */
1109
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1110
+		return new EE_Form_Section_Proper(
1111
+			[
1112
+				'name'            => 'payment-settings',
1113
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1114
+				'subsections'     => [
1115
+					'show_pending_payment_options' => new EE_Switch_Input(
1116
+						[
1117
+							'default'        => $reg_config->show_pending_payment_options
1118
+								? EE_Switch_Input::OPTION_ON
1119
+								: EE_Switch_Input::OPTION_OFF,
1120
+							'html_name'      => 'show_pending_payment_options',
1121
+							'html_help_text' => esc_html__(
1122
+								"If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1123
+								'event_espresso'
1124
+							),
1125
+						],
1126
+						[
1127
+							EE_Switch_Input::OPTION_OFF => esc_html__(
1128
+								'pending payment options are NOT displayed',
1129
+								'event_espresso'
1130
+							),
1131
+							EE_Switch_Input::OPTION_ON  => esc_html__(
1132
+								'pending payment options are displayed',
1133
+								'event_espresso'
1134
+							),
1135
+						]
1136
+					),
1137
+					'gateway_log_lifespan'         => new EE_Select_Input(
1138
+						$reg_config->gatewayLogLifespanOptions(),
1139
+						[
1140
+							'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1141
+							'html_help_text'  => esc_html__(
1142
+								'If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.',
1143
+								'event_espresso'
1144
+							),
1145
+							'default'         => $reg_config->gateway_log_lifespan,
1146
+						]
1147
+					),
1148
+				],
1149
+			]
1150
+		);
1151
+	}
1152
+
1153
+
1154
+	/**
1155
+	 * @throws EE_Error
1156
+	 */
1157
+	protected function _payment_log_overview_list_table()
1158
+	{
1159
+		$this->display_admin_list_table_page_with_sidebar();
1160
+	}
1161
+
1162
+
1163
+	protected function _set_list_table_views_payment_log()
1164
+	{
1165
+		$this->_views = [
1166
+			'all' => [
1167
+				'slug'  => 'all',
1168
+				'label' => esc_html__('View All Logs', 'event_espresso'),
1169
+				'count' => 0,
1170
+			],
1171
+		];
1172
+	}
1173
+
1174
+
1175
+	/**
1176
+	 * @param int  $per_page
1177
+	 * @param int  $current_page
1178
+	 * @param bool $count
1179
+	 * @return array|int
1180
+	 * @throws EE_Error
1181
+	 * @throws ReflectionException
1182
+	 */
1183
+	public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1184
+	{
1185
+		EE_Registry::instance()->load_model('Change_Log');
1186
+		// we may need to do multiple queries (joining differently), so we actually want an array of query params
1187
+		$query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1188
+		// check if they've selected a specific payment method
1189
+		if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1190
+			$query_params[0]['OR*pm_or_pay_pm'] = [
1191
+				'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1192
+				'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1193
+			];
1194
+		}
1195
+		// take into account search
1196
+		if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1197
+			$similarity_string                                                              =
1198
+				['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1199
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1200
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1201
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1202
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1203
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1204
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1205
+			$query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1206
+			$query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1207
+			$query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1208
+			$query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1209
+		}
1210
+		if (
1211
+			isset($this->_req_data['payment-filter-start-date'])
1212
+			&& isset($this->_req_data['payment-filter-end-date'])
1213
+		) {
1214
+			// add date
1215
+			$start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1216
+			$end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1217
+			// make sure our timestamps start and end right at the boundaries for each day
1218
+			$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1219
+			$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1220
+			// convert to timestamps
1221
+			$start_date = strtotime($start_date);
1222
+			$end_date   = strtotime($end_date);
1223
+			// makes sure start date is the lowest value and vice versa
1224
+			$start_date = min($start_date, $end_date);
1225
+			$end_date   = max($start_date, $end_date);
1226
+			// convert for query
1227
+			$start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1228
+				'LOG_time',
1229
+				date('Y-m-d H:i:s', $start_date),
1230
+				'Y-m-d H:i:s'
1231
+			);
1232
+			$end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1233
+				'LOG_time',
1234
+				date('Y-m-d H:i:s', $end_date),
1235
+				'Y-m-d H:i:s'
1236
+			);
1237
+			$query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1238
+		}
1239
+		if ($count) {
1240
+			return EEM_Change_Log::instance()->count($query_params);
1241
+		}
1242
+		if (isset($this->_req_data['order'])) {
1243
+			$sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1244
+				? $this->_req_data['order']
1245
+				: 'DESC';
1246
+			$query_params['order_by'] = ['LOG_time' => $sort];
1247
+		} else {
1248
+			$query_params['order_by'] = ['LOG_time' => 'DESC'];
1249
+		}
1250
+		$offset = ($current_page - 1) * $per_page;
1251
+		if (! isset($this->_req_data['download_results'])) {
1252
+			$query_params['limit'] = [$offset, $per_page];
1253
+		}
1254
+		// now they've requested to instead just download the file instead of viewing it.
1255
+		if (isset($this->_req_data['download_results'])) {
1256
+			$wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1257
+			header('Content-Disposition: attachment');
1258
+			header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1259
+			echo '<h1> '
1260
+				 . sprintf(
1261
+					 esc_html__('Payment Logs for %1$s', 'event_espresso'),
1262
+					 esc_url_raw(site_url())
1263
+				 )
1264
+				 . '</h1 >';
1265
+			echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1266
+			echo esc_html(var_export($query_params, true));
1267
+			echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1268
+			echo esc_html(var_export($wpdb_results, true));
1269
+			die;
1270
+		}
1271
+		return EEM_Change_Log::instance()->get_all($query_params);
1272
+	}
1273
+
1274
+
1275
+	/**
1276
+	 * Used by usort to RE-sort log query results, because we lose the ordering
1277
+	 * because we're possibly combining the results from two queries
1278
+	 *
1279
+	 * @param EE_Change_Log $logA
1280
+	 * @param EE_Change_Log $logB
1281
+	 * @return int
1282
+	 * @throws EE_Error
1283
+	 * @throws ReflectionException
1284
+	 */
1285
+	protected function _sort_logs_again($logA, $logB)
1286
+	{
1287
+		$timeA = $logA->get_raw('LOG_time');
1288
+		$timeB = $logB->get_raw('LOG_time');
1289
+		if ($timeA == $timeB) {
1290
+			return 0;
1291
+		}
1292
+		$comparison = $timeA < $timeB
1293
+			? -1
1294
+			: 1;
1295
+		if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1296
+			return $comparison * -1;
1297
+		}
1298
+		return $comparison;
1299
+	}
1300
+
1301
+
1302
+	/**
1303
+	 * @throws EE_Error
1304
+	 * @throws ReflectionException
1305
+	 */
1306
+	protected function _payment_log_details()
1307
+	{
1308
+		EE_Registry::instance()->load_model('Change_Log');
1309
+		/** @var $payment_log EE_Change_Log */
1310
+		$payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1311
+		$payment_method = null;
1312
+		$transaction    = null;
1313
+		if ($payment_log instanceof EE_Change_Log) {
1314
+			if ($payment_log->object() instanceof EE_Payment) {
1315
+				$payment_method = $payment_log->object()->payment_method();
1316
+				$transaction    = $payment_log->object()->transaction();
1317
+			} elseif ($payment_log->object() instanceof EE_Payment_Method) {
1318
+				$payment_method = $payment_log->object();
1319
+			} elseif ($payment_log->object() instanceof EE_Transaction) {
1320
+				$transaction    = $payment_log->object();
1321
+				$payment_method = $transaction->payment_method();
1322
+			}
1323
+		}
1324
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1325
+			EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1326
+			[
1327
+				'payment_log'    => $payment_log,
1328
+				'payment_method' => $payment_method,
1329
+				'transaction'    => $transaction,
1330
+			],
1331
+			true
1332
+		);
1333
+		$this->display_admin_page_with_no_sidebar();
1334
+	}
1335 1335
 }
Please login to merge, or discard this patch.
admin_pages/support/Support_Admin_Page.core.php 1 patch
Indentation   +240 added lines, -240 removed lines patch added patch discarded remove patch
@@ -11,244 +11,244 @@
 block discarded – undo
11 11
  */
12 12
 class Support_Admin_Page extends EE_Admin_Page
13 13
 {
14
-    protected function _init_page_props()
15
-    {
16
-        $this->page_slug = EE_SUPPORT_PG_SLUG;
17
-        $this->page_label = esc_html__('Help & Support', 'event_espresso');
18
-        $this->_admin_base_url = EE_SUPPORT_ADMIN_URL;
19
-        $this->_admin_base_path = EE_SUPPORT_ADMIN;
20
-    }
21
-
22
-
23
-    protected function _ajax_hooks()
24
-    {
25
-    }
26
-
27
-
28
-    protected function _define_page_props()
29
-    {
30
-        $this->_labels = array();
31
-        $this->_admin_page_title = $this->page_label;
32
-    }
33
-
34
-
35
-    protected function _set_page_routes()
36
-    {
37
-        $this->_page_routes = array(
38
-            'default'    => array(
39
-                'func'       => [$this, '_contact_support'],
40
-                'capability' => 'ee_read_ee',
41
-            ),
42
-            'developers' => array(
43
-                'func'       => [$this, '_developers'],
44
-                'capability' => 'ee_read_ee',
45
-            ),
46
-            'shortcodes' => array(
47
-                'func'       => [$this, '_shortcodes'],
48
-                'capability' => 'ee_read_ee',
49
-            ),
50
-        );
51
-    }
52
-
53
-
54
-    protected function _set_page_config()
55
-    {
56
-        $this->_page_config = array(
57
-            'default'    => array(
58
-                'nav'           => array(
59
-                    'label' => esc_html__('Support', 'event_espresso'),
60
-                    'icon' => 'dashicons-sos',
61
-                    'order' => 30,
62
-                ),
63
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_support_boxes')),
64
-                'require_nonce' => false,
65
-            ),
66
-            'developers' => array(
67
-                'nav'           => array(
68
-                    'label' => esc_html__('Developers', 'event_espresso'),
69
-                    'icon' => 'dashicons-coffee',
70
-                    'order' => 50,
71
-                ),
72
-                'metaboxes'     => $this->_default_espresso_metaboxes,
73
-                'require_nonce' => false,
74
-            ),
75
-            'shortcodes' => array(
76
-                'nav'           => array(
77
-                    'label' => esc_html__('Shortcodes', 'event_espresso'),
78
-                    'icon' => 'dashicons-shortcode',
79
-                    'order' => 60,
80
-                ),
81
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_shortcodes_boxes')),
82
-                'require_nonce' => false,
83
-            ),
84
-        );
85
-    }
86
-
87
-
88
-    // none of the below group are currently used for Support pages
89
-    protected function _add_screen_options()
90
-    {
91
-    }
92
-
93
-
94
-    protected function _add_feature_pointers()
95
-    {
96
-    }
97
-
98
-
99
-    public function admin_init()
100
-    {
101
-    }
102
-
103
-
104
-    public function admin_notices()
105
-    {
106
-    }
107
-
108
-
109
-    public function admin_footer_scripts()
110
-    {
111
-    }
112
-
113
-
114
-    public function load_scripts_styles()
115
-    {
116
-    }
117
-
118
-
119
-    protected function _installation()
120
-    {
121
-        $template_path = EE_SUPPORT_ADMIN_TEMPLATE_PATH . 'support_admin_details_installation.template.php';
122
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
123
-            $template_path,
124
-            '',
125
-            true
126
-        );
127
-        $this->display_admin_page_with_sidebar();
128
-    }
129
-
130
-
131
-    protected function _resources()
132
-    {
133
-        $this->display_admin_page_with_sidebar();
134
-    }
135
-
136
-
137
-    protected function _add_settings_metabox($box, $label, array $args)
138
-    {
139
-        $this->addMetaBox(
140
-            "espresso_{$box}_settings",
141
-            $label,
142
-            function ($post, $metabox) {
143
-                EEH_Template::display_template(
144
-                    $metabox['args']['template_path'],
145
-                    $metabox['args']['template_args']
146
-                );
147
-            },
148
-            $this->_current_screen->id,
149
-            'normal',
150
-            'high',
151
-            apply_filters(
152
-                "FHEE__Support_Admin_Page___add_settings_metabox__{$box}_args_array",
153
-                $args
154
-            )
155
-        );
156
-    }
157
-
158
-
159
-    protected function _resources_boxes()
160
-    {
161
-        $boxes = apply_filters(
162
-            'FHEE__Support_Admin_Page___resources_boxes__boxes_array',
163
-            array(
164
-                'favorite_theme_developers' => esc_html__('Favorite Theme Developers', 'event_espresso'),
165
-                'highly_recommended_themes' => esc_html__('Highly Recommended Themes', 'event_espresso'),
166
-                'hire_developer'            => esc_html__('Hire a Developer', 'event_espresso'),
167
-                'partners'                  => esc_html__('Partners', 'event_espresso'),
168
-                'recommended_plugins'       => esc_html__('Recommended Plugins', 'event_espresso'),
169
-                'other_resources'           => esc_html__('Other Resources', 'event_espresso'),
170
-            )
171
-        );
172
-        foreach ($boxes as $box => $label) {
173
-            $this->_add_settings_metabox(
174
-                $box,
175
-                $label,
176
-                array(
177
-                    'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
178
-                    'template_args' => $this->_template_args,
179
-                )
180
-            );
181
-        }
182
-    }
183
-
184
-
185
-    protected function _shortcodes()
186
-    {
187
-        $this->display_admin_page_with_sidebar();
188
-    }
189
-
190
-
191
-    protected function _shortcodes_boxes()
192
-    {
193
-        $boxes = apply_filters(
194
-            'FHEE__Support_Admin_Page___shortcodes_boxes__boxes_array',
195
-            array(
196
-                'shortcodes_event_listings'  => esc_html__('Event Listings', 'event_espresso'),
197
-                'shortcodes_ticket_selector' => esc_html__('Event Ticket Selector', 'event_espresso'),
198
-                'shortcodes_category'        => esc_html__('Event Categories', 'event_espresso'),
199
-                'shortcodes_attendee'        => esc_html__('Event Attendees', 'event_espresso')
200
-                /*'shortcodes_single_events' => esc_html__('Single Events', 'event_espresso'),*/
201
-                /*'shortcodes_attendee_listings' => esc_html__('Attendee Listings', 'event_espresso'),*/
202
-            )
203
-        );
204
-        foreach ($boxes as $box => $label) {
205
-            $this->_add_settings_metabox(
206
-                $box,
207
-                $label,
208
-                array(
209
-                    'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
210
-                    'template_args' => $this->_template_args,
211
-                )
212
-            );
213
-        }
214
-    }
215
-
216
-
217
-    protected function _contact_support()
218
-    {
219
-        $this->display_admin_page_with_sidebar();
220
-    }
221
-
222
-
223
-    protected function _support_boxes()
224
-    {
225
-        $boxes = apply_filters(
226
-            'FHEE__Support_Admin_Page___support_boxes__boxes_array',
227
-            array(
228
-                'contact_support'       => esc_html__('Contact Support', 'event_espresso'),
229
-                'important_information' => esc_html__('Important Information', 'event_espresso'),
230
-            )
231
-        );
232
-        foreach ($boxes as $box => $label) {
233
-            $this->_add_settings_metabox(
234
-                $box,
235
-                $label,
236
-                array(
237
-                    'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
238
-                    'template_args' => $this->_template_args,
239
-                )
240
-            );
241
-        }
242
-    }
243
-
244
-
245
-    protected function _developers()
246
-    {
247
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
248
-            EE_SUPPORT_ADMIN_TEMPLATE_PATH . 'developers_admin_details.template.php',
249
-            array(),
250
-            true
251
-        );
252
-        $this->display_admin_page_with_sidebar();
253
-    }
14
+	protected function _init_page_props()
15
+	{
16
+		$this->page_slug = EE_SUPPORT_PG_SLUG;
17
+		$this->page_label = esc_html__('Help & Support', 'event_espresso');
18
+		$this->_admin_base_url = EE_SUPPORT_ADMIN_URL;
19
+		$this->_admin_base_path = EE_SUPPORT_ADMIN;
20
+	}
21
+
22
+
23
+	protected function _ajax_hooks()
24
+	{
25
+	}
26
+
27
+
28
+	protected function _define_page_props()
29
+	{
30
+		$this->_labels = array();
31
+		$this->_admin_page_title = $this->page_label;
32
+	}
33
+
34
+
35
+	protected function _set_page_routes()
36
+	{
37
+		$this->_page_routes = array(
38
+			'default'    => array(
39
+				'func'       => [$this, '_contact_support'],
40
+				'capability' => 'ee_read_ee',
41
+			),
42
+			'developers' => array(
43
+				'func'       => [$this, '_developers'],
44
+				'capability' => 'ee_read_ee',
45
+			),
46
+			'shortcodes' => array(
47
+				'func'       => [$this, '_shortcodes'],
48
+				'capability' => 'ee_read_ee',
49
+			),
50
+		);
51
+	}
52
+
53
+
54
+	protected function _set_page_config()
55
+	{
56
+		$this->_page_config = array(
57
+			'default'    => array(
58
+				'nav'           => array(
59
+					'label' => esc_html__('Support', 'event_espresso'),
60
+					'icon' => 'dashicons-sos',
61
+					'order' => 30,
62
+				),
63
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_support_boxes')),
64
+				'require_nonce' => false,
65
+			),
66
+			'developers' => array(
67
+				'nav'           => array(
68
+					'label' => esc_html__('Developers', 'event_espresso'),
69
+					'icon' => 'dashicons-coffee',
70
+					'order' => 50,
71
+				),
72
+				'metaboxes'     => $this->_default_espresso_metaboxes,
73
+				'require_nonce' => false,
74
+			),
75
+			'shortcodes' => array(
76
+				'nav'           => array(
77
+					'label' => esc_html__('Shortcodes', 'event_espresso'),
78
+					'icon' => 'dashicons-shortcode',
79
+					'order' => 60,
80
+				),
81
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_shortcodes_boxes')),
82
+				'require_nonce' => false,
83
+			),
84
+		);
85
+	}
86
+
87
+
88
+	// none of the below group are currently used for Support pages
89
+	protected function _add_screen_options()
90
+	{
91
+	}
92
+
93
+
94
+	protected function _add_feature_pointers()
95
+	{
96
+	}
97
+
98
+
99
+	public function admin_init()
100
+	{
101
+	}
102
+
103
+
104
+	public function admin_notices()
105
+	{
106
+	}
107
+
108
+
109
+	public function admin_footer_scripts()
110
+	{
111
+	}
112
+
113
+
114
+	public function load_scripts_styles()
115
+	{
116
+	}
117
+
118
+
119
+	protected function _installation()
120
+	{
121
+		$template_path = EE_SUPPORT_ADMIN_TEMPLATE_PATH . 'support_admin_details_installation.template.php';
122
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
123
+			$template_path,
124
+			'',
125
+			true
126
+		);
127
+		$this->display_admin_page_with_sidebar();
128
+	}
129
+
130
+
131
+	protected function _resources()
132
+	{
133
+		$this->display_admin_page_with_sidebar();
134
+	}
135
+
136
+
137
+	protected function _add_settings_metabox($box, $label, array $args)
138
+	{
139
+		$this->addMetaBox(
140
+			"espresso_{$box}_settings",
141
+			$label,
142
+			function ($post, $metabox) {
143
+				EEH_Template::display_template(
144
+					$metabox['args']['template_path'],
145
+					$metabox['args']['template_args']
146
+				);
147
+			},
148
+			$this->_current_screen->id,
149
+			'normal',
150
+			'high',
151
+			apply_filters(
152
+				"FHEE__Support_Admin_Page___add_settings_metabox__{$box}_args_array",
153
+				$args
154
+			)
155
+		);
156
+	}
157
+
158
+
159
+	protected function _resources_boxes()
160
+	{
161
+		$boxes = apply_filters(
162
+			'FHEE__Support_Admin_Page___resources_boxes__boxes_array',
163
+			array(
164
+				'favorite_theme_developers' => esc_html__('Favorite Theme Developers', 'event_espresso'),
165
+				'highly_recommended_themes' => esc_html__('Highly Recommended Themes', 'event_espresso'),
166
+				'hire_developer'            => esc_html__('Hire a Developer', 'event_espresso'),
167
+				'partners'                  => esc_html__('Partners', 'event_espresso'),
168
+				'recommended_plugins'       => esc_html__('Recommended Plugins', 'event_espresso'),
169
+				'other_resources'           => esc_html__('Other Resources', 'event_espresso'),
170
+			)
171
+		);
172
+		foreach ($boxes as $box => $label) {
173
+			$this->_add_settings_metabox(
174
+				$box,
175
+				$label,
176
+				array(
177
+					'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
178
+					'template_args' => $this->_template_args,
179
+				)
180
+			);
181
+		}
182
+	}
183
+
184
+
185
+	protected function _shortcodes()
186
+	{
187
+		$this->display_admin_page_with_sidebar();
188
+	}
189
+
190
+
191
+	protected function _shortcodes_boxes()
192
+	{
193
+		$boxes = apply_filters(
194
+			'FHEE__Support_Admin_Page___shortcodes_boxes__boxes_array',
195
+			array(
196
+				'shortcodes_event_listings'  => esc_html__('Event Listings', 'event_espresso'),
197
+				'shortcodes_ticket_selector' => esc_html__('Event Ticket Selector', 'event_espresso'),
198
+				'shortcodes_category'        => esc_html__('Event Categories', 'event_espresso'),
199
+				'shortcodes_attendee'        => esc_html__('Event Attendees', 'event_espresso')
200
+				/*'shortcodes_single_events' => esc_html__('Single Events', 'event_espresso'),*/
201
+				/*'shortcodes_attendee_listings' => esc_html__('Attendee Listings', 'event_espresso'),*/
202
+			)
203
+		);
204
+		foreach ($boxes as $box => $label) {
205
+			$this->_add_settings_metabox(
206
+				$box,
207
+				$label,
208
+				array(
209
+					'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
210
+					'template_args' => $this->_template_args,
211
+				)
212
+			);
213
+		}
214
+	}
215
+
216
+
217
+	protected function _contact_support()
218
+	{
219
+		$this->display_admin_page_with_sidebar();
220
+	}
221
+
222
+
223
+	protected function _support_boxes()
224
+	{
225
+		$boxes = apply_filters(
226
+			'FHEE__Support_Admin_Page___support_boxes__boxes_array',
227
+			array(
228
+				'contact_support'       => esc_html__('Contact Support', 'event_espresso'),
229
+				'important_information' => esc_html__('Important Information', 'event_espresso'),
230
+			)
231
+		);
232
+		foreach ($boxes as $box => $label) {
233
+			$this->_add_settings_metabox(
234
+				$box,
235
+				$label,
236
+				array(
237
+					'template_path' => EE_SUPPORT_ADMIN_TEMPLATE_PATH . "support_admin_details_{$box}.template.php",
238
+					'template_args' => $this->_template_args,
239
+				)
240
+			);
241
+		}
242
+	}
243
+
244
+
245
+	protected function _developers()
246
+	{
247
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
248
+			EE_SUPPORT_ADMIN_TEMPLATE_PATH . 'developers_admin_details.template.php',
249
+			array(),
250
+			true
251
+		);
252
+		$this->display_admin_page_with_sidebar();
253
+	}
254 254
 }
Please login to merge, or discard this patch.