Completed
Branch master (44537d)
by
unknown
14:30 queued 10:03
created
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +758 added lines, -758 removed lines patch added patch discarded remove patch
@@ -17,701 +17,701 @@  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
-     * @var EE_Question $_question
24
-     */
25
-    protected $_question;
26
-
27
-    /**
28
-     * holds the specific question group object for the question group details screen
29
-     *
30
-     * @var EE_Question_Group $_question_group
31
-     */
32
-    protected $_question_group;
33
-
34
-    /**
35
-     *_question_model EEM_Question model instance (for queries)
36
-     *
37
-     * @var EEM_Question $_question_model ;
38
-     */
39
-    protected $_question_model;
40
-
41
-    /**
42
-     * _question_group_model EEM_Question_group instance (for queries)
43
-     *
44
-     * @var EEM_Question_Group $_question_group_model
45
-     */
46
-    protected $_question_group_model;
47
-
48
-
49
-    /**
50
-     * @Constructor
51
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
52
-     * @throws EE_Error
53
-     * @throws ReflectionException
54
-     */
55
-    public function __construct($routing = true)
56
-    {
57
-        require_once(EE_MODELS . 'EEM_Question.model.php');
58
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
59
-        $this->_question_model       = EEM_Question::instance();
60
-        $this->_question_group_model = EEM_Question_Group::instance();
61
-        parent::__construct($routing);
62
-    }
63
-
64
-
65
-    protected function _init_page_props()
66
-    {
67
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
68
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
69
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
70
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
71
-    }
72
-
73
-
74
-    protected function _ajax_hooks()
75
-    {
76
-    }
77
-
78
-
79
-    protected function _define_page_props()
80
-    {
81
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
82
-        $this->_labels           = [
83
-            'buttons'    => [
84
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
85
-            ],
86
-            'publishbox' => [
87
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
88
-            ],
89
-        ];
90
-    }
91
-
92
-
93
-    /**
94
-     *_set_page_routes
95
-     */
96
-    protected function _set_page_routes()
97
-    {
98
-        $qst_id             =
99
-            ! empty($this->_req_data['QST_ID'])
100
-                ? $this->_req_data['QST_ID']
101
-                : 0;
102
-        $this->_page_routes = [
103
-            'default' => [
104
-                'func'       => '_questions_overview_list_table',
105
-                'capability' => 'ee_read_questions',
106
-            ],
107
-
108
-            'edit_question' => [
109
-                'func'       => '_edit_question',
110
-                'capability' => 'ee_edit_question',
111
-                'obj_id'     => $qst_id,
112
-                'args'       => ['edit'],
113
-            ],
114
-
115
-            'question_groups' => [
116
-                'func'       => '_questions_groups_preview',
117
-                'capability' => 'ee_read_question_groups',
118
-            ],
119
-
120
-            'update_question' => [
121
-                'func'       => '_insert_or_update_question',
122
-                'args'       => ['new_question' => false],
123
-                'capability' => 'ee_edit_question',
124
-                'obj_id'     => $qst_id,
125
-                'noheader'   => true,
126
-            ],
127
-        ];
128
-    }
129
-
130
-
131
-    protected function _set_page_config()
132
-    {
133
-        $this->_page_config = [
134
-            'default' => [
135
-                'nav'           => [
136
-                    'label' => esc_html__('Questions', 'event_espresso'),
137
-                    'icon'  => 'dashicons-editor-help',
138
-                    'order' => 10,
139
-                ],
140
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
141
-                'metaboxes'     => $this->_default_espresso_metaboxes,
142
-                'help_tabs'     => [
143
-                    'registration_form_questions_overview_help_tab'                           => [
144
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
145
-                        'filename' => 'registration_form_questions_overview',
146
-                    ],
147
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => [
148
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
149
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
150
-                    ],
151
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
152
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
153
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
154
-                    ],
155
-                ],
156
-                'require_nonce' => false,
157
-            ],
158
-
159
-            'question_groups' => [
160
-                'nav'           => [
161
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
162
-                    'icon'  => 'dashicons-forms',
163
-                    'order' => 20,
164
-                ],
165
-                'metaboxes'     => $this->_default_espresso_metaboxes,
166
-                'help_tabs'     => [
167
-                    'registration_form_question_groups_help_tab' => [
168
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
169
-                        'filename' => 'registration_form_question_groups',
170
-                    ],
171
-                ],
172
-                'require_nonce' => false,
173
-            ],
174
-
175
-            'edit_question' => [
176
-                'nav'           => [
177
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
178
-                    'icon'       => 'dashicons-edit-large',
179
-                    'order'      => 15,
180
-                    'persistent' => false,
181
-                    'url'        => isset($this->_req_data['question_id'])
182
-                        ? add_query_arg(
183
-                            ['question_id' => $this->_req_data['question_id']],
184
-                            $this->_current_page_view_url
185
-                        )
186
-                        : $this->_admin_base_url,
187
-                ],
188
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
189
-                'help_tabs'     => [
190
-                    'registration_form_edit_question_group_help_tab' => [
191
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
192
-                        'filename' => 'registration_form_edit_question',
193
-                    ],
194
-                ],
195
-                'require_nonce' => false,
196
-            ],
197
-        ];
198
-    }
199
-
200
-
201
-    protected function _add_screen_options()
202
-    {
203
-        // todo
204
-    }
205
-
206
-
207
-    protected function _add_screen_options_default()
208
-    {
209
-        $page_title              = $this->_admin_page_title;
210
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
211
-        $this->_per_page_screen_option();
212
-        $this->_admin_page_title = $page_title;
213
-    }
214
-
215
-
216
-    protected function _add_screen_options_question_groups()
217
-    {
218
-        $page_title              = $this->_admin_page_title;
219
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
220
-        $this->_per_page_screen_option();
221
-        $this->_admin_page_title = $page_title;
222
-    }
223
-
224
-
225
-    // none of the below group are currently used for Event Categories
226
-    protected function _add_feature_pointers()
227
-    {
228
-    }
229
-
230
-
231
-    public function load_scripts_styles()
232
-    {
233
-        wp_register_style(
234
-            'espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
236
-            [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
237
-            EVENT_ESPRESSO_VERSION
238
-        );
239
-        wp_enqueue_style('espresso_registration');
240
-    }
241
-
242
-
243
-    public function admin_init()
244
-    {
245
-    }
246
-
247
-
248
-    public function admin_notices()
249
-    {
250
-    }
251
-
252
-
253
-    public function admin_footer_scripts()
254
-    {
255
-    }
256
-
257
-
258
-    public function load_scripts_styles_default()
259
-    {
260
-    }
261
-
262
-
263
-    /**
264
-     * @throws EE_Error
265
-     */
266
-    public function load_scripts_styles_add_question()
267
-    {
268
-        $this->load_scripts_styles_question_details();
269
-    }
270
-
271
-
272
-    /**
273
-     * @throws EE_Error
274
-     */
275
-    public function load_scripts_styles_edit_question()
276
-    {
277
-        $this->load_scripts_styles_question_details();
278
-    }
279
-
280
-
281
-    /**
282
-     * Loads the JS required for adding or editing a question
283
-     *
284
-     * @throws EE_Error
285
-     * @throws EE_Error
286
-     */
287
-    protected function load_scripts_styles_question_details()
288
-    {
289
-        $this->load_scripts_styles_forms();
290
-        wp_register_script(
291
-            'espresso_registration_form_single',
292
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
293
-            ['jquery-ui-sortable'],
294
-            EVENT_ESPRESSO_VERSION,
295
-            true
296
-        );
297
-        wp_enqueue_script('espresso_registration_form_single');
298
-        wp_localize_script(
299
-            'espresso_registration_form_single',
300
-            'ee_question_data',
301
-            [
302
-                'question_types_with_max'    => EEM_Question::instance()->questionTypesWithMaxLength(),
303
-                'question_type_with_options' => EEM_Question::instance()->question_types_with_options(),
304
-            ]
305
-        );
306
-    }
307
-
308
-
309
-    public function recaptcha_info_help_tab()
310
-    {
311
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
312
-        EEH_Template::display_template($template, []);
313
-    }
314
-
315
-
316
-    public function load_scripts_styles_forms()
317
-    {
318
-        // styles
319
-        wp_enqueue_style('espresso-ui-theme');
320
-        // scripts
321
-        wp_enqueue_script('ee_admin_js');
322
-    }
323
-
324
-
325
-    protected function _set_list_table_views_default()
326
-    {
327
-        $this->_views = [
328
-            'all' => [
329
-                'slug'  => 'all',
330
-                'label' => esc_html__('View All Questions', 'event_espresso'),
331
-                'count' => 0,
332
-            ],
333
-        ];
334
-
335
-        if (
336
-            $this->capabilities->current_user_can(
337
-                'ee_delete_questions',
338
-                'espresso_registration_form_trash_questions'
339
-            )
340
-        ) {
341
-            $this->_views['trash'] = [
342
-                'slug'  => 'trash',
343
-                'label' => esc_html__('Trash', 'event_espresso'),
344
-                'count' => 0,
345
-            ];
346
-        }
347
-    }
348
-
349
-
350
-    /**
351
-     * This just previews the question groups tab that comes in caffeinated.
352
-     *
353
-     * @return void html
354
-     * @throws EE_Error
355
-     */
356
-    protected function _questions_groups_preview()
357
-    {
358
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
359
-        $this->_template_args['preview_img']  =
360
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
361
-            . esc_attr__(
362
-                'Preview Question Groups Overview List Table screenshot',
363
-                'event_espresso'
364
-            ) . '" />';
365
-        $this->_template_args['preview_text'] = '<strong>'
366
-                                                . esc_html__(
367
-                                                    '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.',
368
-                                                    'event_espresso'
369
-                                                ) . '</strong>';
370
-        $this->display_admin_caf_preview_page('question_groups_tab');
371
-    }
372
-
373
-
374
-    /**
375
-     * Extracts the question field's values from the POST request to update or insert them
376
-     *
377
-     * @param EEM_Base $model
378
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
379
-     * @throws EE_Error
380
-     */
381
-    protected function _set_column_values_for(EEM_Base $model)
382
-    {
383
-        $question_model    = EEM_Question::instance();
384
-        $set_column_values = [];
385
-
386
-        // some initial checks for proper values.
387
-        // if QST_admin_only, then no matter what QST_required is we disable.
388
-        if (! empty($this->_req_data['QST_admin_only'])) {
389
-            $this->_req_data['QST_required'] = 0;
390
-        }
391
-        // if the question shouldn't have a max length, don't let them set one
392
-        if (
393
-            ! isset(
394
-                $this->_req_data['QST_type'],
395
-                $this->_req_data['QST_max']
396
-            )
397
-            || ! in_array(
398
-                $this->_req_data['QST_type'],
399
-                $question_model->questionTypesWithMaxLength(),
400
-                true
401
-            )
402
-        ) {
403
-            // they're not allowed to set the max
404
-            $this->_req_data['QST_max'] = null;
405
-        }
406
-        foreach ($model->field_settings() as $fieldName => $settings) {
407
-            // basically if QSG_identifier is empty or not set
408
-            if (
409
-                $fieldName === 'QSG_identifier'
410
-                && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))
411
-            ) {
412
-                $QSG_name                        = $this->_req_data['QSG_name'] ?? '';
413
-                $set_column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
414
-            } elseif (
415
-                $fieldName === 'QST_admin_label'
416
-                && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))
417
-            ) {
418
-                // the admin label is blank, use a slug version of the question text
419
-                $QST_text                        = $this->_req_data['QST_display_text'] ?? '';
420
-                $set_column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
421
-            } elseif ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
422
-                $set_column_values[ $fieldName ] = 0;
423
-            } elseif ($fieldName === 'QST_max') {
424
-                $qst_system = $question_model->get_var(
425
-                    [
426
-                        [
427
-                            'QST_ID' => $this->_req_data['QST_ID'] ?? 0,
428
-                        ],
429
-                    ],
430
-                    'QST_system'
431
-                );
432
-                $max_max    = $question_model->absolute_max_for_system_question((string) $qst_system);
433
-                if (empty($this->_req_data['QST_max']) || $this->_req_data['QST_max'] > $max_max) {
434
-                    $set_column_values[ $fieldName ] = $max_max;
435
-                }
436
-            }
437
-
438
-
439
-            // only add a property to the array if it's not null (otherwise the model should just use the default value)
440
-            if (
441
-                ! isset($set_column_values[ $fieldName ]) && isset($this->_req_data[ $fieldName ])
442
-            ) {
443
-                $set_column_values[ $fieldName ] = $this->_req_data[ $fieldName ];
444
-            }
445
-        }
446
-        // validation fo this data to be performed by the model before insertion.
447
-        return $set_column_values;
448
-    }
449
-
450
-
451
-    /**
452
-     *_questions_overview_list_table
453
-     *
454
-     * @throws EE_Error
455
-     */
456
-    protected function _questions_overview_list_table()
457
-    {
458
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
459
-        $this->display_admin_list_table_page_with_sidebar();
460
-    }
461
-
462
-
463
-    /**
464
-     * _edit_question
465
-     *
466
-     * @throws EE_Error
467
-     * @throws ReflectionException
468
-     */
469
-    protected function _edit_question()
470
-    {
471
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
472
-            ? absint($this->_req_data['QST_ID'])
473
-            : false;
474
-
475
-        switch ($this->_req_action) {
476
-            case 'add_question':
477
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
478
-                break;
479
-            case 'edit_question':
480
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
481
-                break;
482
-            default:
483
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
484
-        }
485
-
486
-        // add PRC_ID to title if editing
487
-        $this->_admin_page_title =
488
-            $ID
489
-                ? $this->_admin_page_title . ' # ' . $ID
490
-                : $this->_admin_page_title;
491
-        if ($ID) {
492
-            $question                 = $this->_question_model->get_one_by_ID($ID);
493
-            $additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
494
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
495
-        } else {
496
-            $question = EE_Question::new_instance();
497
-            $question->set_order_to_latest();
498
-            $this->_set_add_edit_form_tags('insert_question');
499
-        }
500
-        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
501
-            $question_types = array_intersect_key(
502
-                EEM_Question::instance()->allowed_question_types(),
503
-                array_flip(
504
-                    [
505
-                        EEM_Question::QST_type_text,
506
-                        EEM_Question::QST_type_us_phone,
507
-                    ]
508
-                )
509
-            );
510
-        } else {
511
-            $question_types = $question->has_answers()
512
-                ? $this->_question_model->question_types_in_same_category($question->type())
513
-                : $this->_question_model->allowed_question_types();
514
-        }
515
-        $this->_template_args['QST_ID']                     = $ID;
516
-        $this->_template_args['question']                   = $question;
517
-        $this->_template_args['question_types']             = $question_types;
518
-        $this->_template_args['max_max']                    =
519
-            EEM_Question::instance()->absolute_max_for_system_question(
520
-                $question->system_ID()
521
-            );
522
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
523
-        $this->_set_publish_post_box_vars('id', $ID, '', '', true);
524
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
525
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
526
-            $this->_template_args,
527
-            true
528
-        );
529
-
530
-        // the details template wrapper
531
-        $this->display_admin_page_with_sidebar();
532
-    }
533
-
534
-
535
-    /**
536
-     * @return string
537
-     * @throws EE_Error
538
-     * @throws ReflectionException
539
-     */
540
-    protected function _get_question_type_descriptions()
541
-    {
542
-        EE_Registry::instance()->load_helper('HTML');
543
-        $descriptions               = '';
544
-        $question_type_descriptions = EEM_Question::instance()->question_descriptions();
545
-        foreach ($question_type_descriptions as $type => $question_type_description) {
546
-            if ($type == 'HTML_TEXTAREA') {
547
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
548
-                $question_type_description .= sprintf(
549
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
550
-                    '<br/>',
551
-                    $html->get_list_of_allowed_tags()
552
-                );
553
-            }
554
-            $descriptions .= EEH_HTML::p(
555
-                $question_type_description,
556
-                'question_type_description-' . $type,
557
-                'question_type_description description',
558
-                'display:none;'
559
-            );
560
-        }
561
-        return $descriptions;
562
-    }
563
-
564
-
565
-    /**
566
-     * @param bool|true $new_question
567
-     * @throws EE_Error
568
-     * @throws ReflectionException
569
-     */
570
-    protected function _insert_or_update_question($new_question = true)
571
-    {
572
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
573
-        if ($new_question) {
574
-            $question    = EE_Question::new_instance($set_column_values);
575
-            $action_desc = 'added';
576
-        } else {
577
-            $question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
578
-            foreach ($set_column_values as $field => $new_value) {
579
-                $question->set($field, $new_value);
580
-            }
581
-            $action_desc = 'updated';
582
-        }
583
-        $success = $question->save();
584
-        $ID      = $question->ID();
585
-        if ($ID && $question->should_have_question_options()) {
586
-            // save the related options
587
-            // trash removed options, save old ones
588
-            // get list of all options
589
-            $options = $question->options();
590
-            if (! empty($options)) {
591
-                foreach ($options as $option_ID => $option) {
592
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
593
-                    if ($option_req_index !== false) {
594
-                        $option->save($this->_req_data['question_options'][ $option_req_index ]);
595
-                    } else {
596
-                        // not found, remove it
597
-                        $option->delete();
598
-                    }
599
-                }
600
-            }
601
-            // save new related options
602
-            foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
603
-                // skip $index that is from our sample
604
-                if ($index === 'xxcountxx') {
605
-                    continue;
606
-                }
607
-                // note we allow saving blank options.
608
-                if (empty($option_req_data['QSO_ID'])) {
609
-                    // no ID! save it!
610
-                    $new_option = EE_Question_Option::new_instance(
611
-                        [
612
-                            'QSO_value' => $option_req_data['QSO_value'],
613
-                            'QSO_desc'  => $option_req_data['QSO_desc'],
614
-                            'QSO_order' => $option_req_data['QSO_order'],
615
-                            'QST_ID'    => $question->ID(),
616
-                        ]
617
-                    );
618
-                    $new_option->save();
619
-                }
620
-            }
621
-        }
622
-        $query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
623
-        if ($success !== 0) {
624
-            $msg = $new_question
625
-                ? sprintf(
626
-                    esc_html__('The %s has been created', 'event_espresso'),
627
-                    $this->_question_model->item_name()
628
-                )
629
-                : sprintf(
630
-                    esc_html__('The %s has been updated', 'event_espresso'),
631
-                    $this->_question_model->item_name()
632
-                );
633
-            EE_Error::add_success($msg);
634
-        }
635
-
636
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
637
-    }
638
-
639
-
640
-    /**
641
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
642
-     * by ID
643
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
644
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
645
-     *
646
-     * @param int $ID of the question option to find
647
-     * @return int index in question_options array if successful, FALSE if unsuccessful
648
-     */
649
-    protected function _get_option_req_data_index($ID)
650
-    {
651
-        $req_data_for_question_options = $this->_req_data['question_options'];
652
-        foreach ($req_data_for_question_options as $num => $option_data) {
653
-            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
654
-                return $num;
655
-            }
656
-        }
657
-        return false;
658
-    }
659
-
660
-
661
-
662
-
663
-    /***********/
664
-    /* QUERIES */
665
-    /**
666
-     * For internal use in getting all the query parameters
667
-     * (because it's pretty well the same between question, question groups,
668
-     * and for both when searching for trashed and untrashed ones)
669
-     *
670
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
671
-     * @param int      $per_page
672
-     * @param int      $current_page
673
-     * @return array model query params, @see
674
-     *                        https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
675
-     */
676
-    protected function get_query_params($model, $per_page = 10, $current_page = 10)
677
-    {
678
-        $query_params             = [];
679
-        $offset                   = ($current_page - 1) * $per_page;
680
-        $query_params['limit']    = [$offset, $per_page];
681
-        $order                    =
682
-            (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
683
-                ? $this->_req_data['order']
684
-                : 'ASC';
685
-        $orderby_field            =
686
-            $model instanceof EEM_Question
687
-                ? 'QST_ID'
688
-                : 'QSG_order';
689
-        $field_to_order_by        =
690
-            empty($this->_req_data['orderby'])
691
-                ? $orderby_field
692
-                : $this->_req_data['orderby'];
693
-        $query_params['order_by'] = [$field_to_order_by => $order];
694
-        $search_string            =
695
-            array_key_exists('s', $this->_req_data)
696
-                ? $this->_req_data['s']
697
-                : null;
698
-        if (! empty($search_string)) {
699
-            if ($model instanceof EEM_Question_Group) {
700
-                $query_params[0] = [
701
-                    'OR' => [
702
-                        'QSG_name' => ['LIKE', "%$search_string%"],
703
-                        'QSG_desc' => ['LIKE', "%$search_string%"],
704
-                    ],
705
-                ];
706
-            } else {
707
-                $query_params[0] = [
708
-                    'QST_display_text' => ['LIKE', "%$search_string%"],
709
-                ];
710
-            }
711
-        }
712
-
713
-        // capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
714
-        /*if ( $model instanceof EEM_Question_Group ) {
20
+	/**
21
+	 * holds the specific question object for the question details screen
22
+	 *
23
+	 * @var EE_Question $_question
24
+	 */
25
+	protected $_question;
26
+
27
+	/**
28
+	 * holds the specific question group object for the question group details screen
29
+	 *
30
+	 * @var EE_Question_Group $_question_group
31
+	 */
32
+	protected $_question_group;
33
+
34
+	/**
35
+	 *_question_model EEM_Question model instance (for queries)
36
+	 *
37
+	 * @var EEM_Question $_question_model ;
38
+	 */
39
+	protected $_question_model;
40
+
41
+	/**
42
+	 * _question_group_model EEM_Question_group instance (for queries)
43
+	 *
44
+	 * @var EEM_Question_Group $_question_group_model
45
+	 */
46
+	protected $_question_group_model;
47
+
48
+
49
+	/**
50
+	 * @Constructor
51
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
52
+	 * @throws EE_Error
53
+	 * @throws ReflectionException
54
+	 */
55
+	public function __construct($routing = true)
56
+	{
57
+		require_once(EE_MODELS . 'EEM_Question.model.php');
58
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
59
+		$this->_question_model       = EEM_Question::instance();
60
+		$this->_question_group_model = EEM_Question_Group::instance();
61
+		parent::__construct($routing);
62
+	}
63
+
64
+
65
+	protected function _init_page_props()
66
+	{
67
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
68
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
69
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
70
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
71
+	}
72
+
73
+
74
+	protected function _ajax_hooks()
75
+	{
76
+	}
77
+
78
+
79
+	protected function _define_page_props()
80
+	{
81
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
82
+		$this->_labels           = [
83
+			'buttons'    => [
84
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
85
+			],
86
+			'publishbox' => [
87
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
88
+			],
89
+		];
90
+	}
91
+
92
+
93
+	/**
94
+	 *_set_page_routes
95
+	 */
96
+	protected function _set_page_routes()
97
+	{
98
+		$qst_id             =
99
+			! empty($this->_req_data['QST_ID'])
100
+				? $this->_req_data['QST_ID']
101
+				: 0;
102
+		$this->_page_routes = [
103
+			'default' => [
104
+				'func'       => '_questions_overview_list_table',
105
+				'capability' => 'ee_read_questions',
106
+			],
107
+
108
+			'edit_question' => [
109
+				'func'       => '_edit_question',
110
+				'capability' => 'ee_edit_question',
111
+				'obj_id'     => $qst_id,
112
+				'args'       => ['edit'],
113
+			],
114
+
115
+			'question_groups' => [
116
+				'func'       => '_questions_groups_preview',
117
+				'capability' => 'ee_read_question_groups',
118
+			],
119
+
120
+			'update_question' => [
121
+				'func'       => '_insert_or_update_question',
122
+				'args'       => ['new_question' => false],
123
+				'capability' => 'ee_edit_question',
124
+				'obj_id'     => $qst_id,
125
+				'noheader'   => true,
126
+			],
127
+		];
128
+	}
129
+
130
+
131
+	protected function _set_page_config()
132
+	{
133
+		$this->_page_config = [
134
+			'default' => [
135
+				'nav'           => [
136
+					'label' => esc_html__('Questions', 'event_espresso'),
137
+					'icon'  => 'dashicons-editor-help',
138
+					'order' => 10,
139
+				],
140
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
141
+				'metaboxes'     => $this->_default_espresso_metaboxes,
142
+				'help_tabs'     => [
143
+					'registration_form_questions_overview_help_tab'                           => [
144
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
145
+						'filename' => 'registration_form_questions_overview',
146
+					],
147
+					'registration_form_questions_overview_table_column_headings_help_tab'     => [
148
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
149
+						'filename' => 'registration_form_questions_overview_table_column_headings',
150
+					],
151
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
152
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
153
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
154
+					],
155
+				],
156
+				'require_nonce' => false,
157
+			],
158
+
159
+			'question_groups' => [
160
+				'nav'           => [
161
+					'label' => esc_html__('Question Groups', 'event_espresso'),
162
+					'icon'  => 'dashicons-forms',
163
+					'order' => 20,
164
+				],
165
+				'metaboxes'     => $this->_default_espresso_metaboxes,
166
+				'help_tabs'     => [
167
+					'registration_form_question_groups_help_tab' => [
168
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
169
+						'filename' => 'registration_form_question_groups',
170
+					],
171
+				],
172
+				'require_nonce' => false,
173
+			],
174
+
175
+			'edit_question' => [
176
+				'nav'           => [
177
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
178
+					'icon'       => 'dashicons-edit-large',
179
+					'order'      => 15,
180
+					'persistent' => false,
181
+					'url'        => isset($this->_req_data['question_id'])
182
+						? add_query_arg(
183
+							['question_id' => $this->_req_data['question_id']],
184
+							$this->_current_page_view_url
185
+						)
186
+						: $this->_admin_base_url,
187
+				],
188
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
189
+				'help_tabs'     => [
190
+					'registration_form_edit_question_group_help_tab' => [
191
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
192
+						'filename' => 'registration_form_edit_question',
193
+					],
194
+				],
195
+				'require_nonce' => false,
196
+			],
197
+		];
198
+	}
199
+
200
+
201
+	protected function _add_screen_options()
202
+	{
203
+		// todo
204
+	}
205
+
206
+
207
+	protected function _add_screen_options_default()
208
+	{
209
+		$page_title              = $this->_admin_page_title;
210
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
211
+		$this->_per_page_screen_option();
212
+		$this->_admin_page_title = $page_title;
213
+	}
214
+
215
+
216
+	protected function _add_screen_options_question_groups()
217
+	{
218
+		$page_title              = $this->_admin_page_title;
219
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
220
+		$this->_per_page_screen_option();
221
+		$this->_admin_page_title = $page_title;
222
+	}
223
+
224
+
225
+	// none of the below group are currently used for Event Categories
226
+	protected function _add_feature_pointers()
227
+	{
228
+	}
229
+
230
+
231
+	public function load_scripts_styles()
232
+	{
233
+		wp_register_style(
234
+			'espresso_registration',
235
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
236
+			[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
237
+			EVENT_ESPRESSO_VERSION
238
+		);
239
+		wp_enqueue_style('espresso_registration');
240
+	}
241
+
242
+
243
+	public function admin_init()
244
+	{
245
+	}
246
+
247
+
248
+	public function admin_notices()
249
+	{
250
+	}
251
+
252
+
253
+	public function admin_footer_scripts()
254
+	{
255
+	}
256
+
257
+
258
+	public function load_scripts_styles_default()
259
+	{
260
+	}
261
+
262
+
263
+	/**
264
+	 * @throws EE_Error
265
+	 */
266
+	public function load_scripts_styles_add_question()
267
+	{
268
+		$this->load_scripts_styles_question_details();
269
+	}
270
+
271
+
272
+	/**
273
+	 * @throws EE_Error
274
+	 */
275
+	public function load_scripts_styles_edit_question()
276
+	{
277
+		$this->load_scripts_styles_question_details();
278
+	}
279
+
280
+
281
+	/**
282
+	 * Loads the JS required for adding or editing a question
283
+	 *
284
+	 * @throws EE_Error
285
+	 * @throws EE_Error
286
+	 */
287
+	protected function load_scripts_styles_question_details()
288
+	{
289
+		$this->load_scripts_styles_forms();
290
+		wp_register_script(
291
+			'espresso_registration_form_single',
292
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
293
+			['jquery-ui-sortable'],
294
+			EVENT_ESPRESSO_VERSION,
295
+			true
296
+		);
297
+		wp_enqueue_script('espresso_registration_form_single');
298
+		wp_localize_script(
299
+			'espresso_registration_form_single',
300
+			'ee_question_data',
301
+			[
302
+				'question_types_with_max'    => EEM_Question::instance()->questionTypesWithMaxLength(),
303
+				'question_type_with_options' => EEM_Question::instance()->question_types_with_options(),
304
+			]
305
+		);
306
+	}
307
+
308
+
309
+	public function recaptcha_info_help_tab()
310
+	{
311
+		$template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
312
+		EEH_Template::display_template($template, []);
313
+	}
314
+
315
+
316
+	public function load_scripts_styles_forms()
317
+	{
318
+		// styles
319
+		wp_enqueue_style('espresso-ui-theme');
320
+		// scripts
321
+		wp_enqueue_script('ee_admin_js');
322
+	}
323
+
324
+
325
+	protected function _set_list_table_views_default()
326
+	{
327
+		$this->_views = [
328
+			'all' => [
329
+				'slug'  => 'all',
330
+				'label' => esc_html__('View All Questions', 'event_espresso'),
331
+				'count' => 0,
332
+			],
333
+		];
334
+
335
+		if (
336
+			$this->capabilities->current_user_can(
337
+				'ee_delete_questions',
338
+				'espresso_registration_form_trash_questions'
339
+			)
340
+		) {
341
+			$this->_views['trash'] = [
342
+				'slug'  => 'trash',
343
+				'label' => esc_html__('Trash', 'event_espresso'),
344
+				'count' => 0,
345
+			];
346
+		}
347
+	}
348
+
349
+
350
+	/**
351
+	 * This just previews the question groups tab that comes in caffeinated.
352
+	 *
353
+	 * @return void html
354
+	 * @throws EE_Error
355
+	 */
356
+	protected function _questions_groups_preview()
357
+	{
358
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
359
+		$this->_template_args['preview_img']  =
360
+			'<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
361
+			. esc_attr__(
362
+				'Preview Question Groups Overview List Table screenshot',
363
+				'event_espresso'
364
+			) . '" />';
365
+		$this->_template_args['preview_text'] = '<strong>'
366
+												. esc_html__(
367
+													'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.',
368
+													'event_espresso'
369
+												) . '</strong>';
370
+		$this->display_admin_caf_preview_page('question_groups_tab');
371
+	}
372
+
373
+
374
+	/**
375
+	 * Extracts the question field's values from the POST request to update or insert them
376
+	 *
377
+	 * @param EEM_Base $model
378
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
379
+	 * @throws EE_Error
380
+	 */
381
+	protected function _set_column_values_for(EEM_Base $model)
382
+	{
383
+		$question_model    = EEM_Question::instance();
384
+		$set_column_values = [];
385
+
386
+		// some initial checks for proper values.
387
+		// if QST_admin_only, then no matter what QST_required is we disable.
388
+		if (! empty($this->_req_data['QST_admin_only'])) {
389
+			$this->_req_data['QST_required'] = 0;
390
+		}
391
+		// if the question shouldn't have a max length, don't let them set one
392
+		if (
393
+			! isset(
394
+				$this->_req_data['QST_type'],
395
+				$this->_req_data['QST_max']
396
+			)
397
+			|| ! in_array(
398
+				$this->_req_data['QST_type'],
399
+				$question_model->questionTypesWithMaxLength(),
400
+				true
401
+			)
402
+		) {
403
+			// they're not allowed to set the max
404
+			$this->_req_data['QST_max'] = null;
405
+		}
406
+		foreach ($model->field_settings() as $fieldName => $settings) {
407
+			// basically if QSG_identifier is empty or not set
408
+			if (
409
+				$fieldName === 'QSG_identifier'
410
+				&& (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))
411
+			) {
412
+				$QSG_name                        = $this->_req_data['QSG_name'] ?? '';
413
+				$set_column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
414
+			} elseif (
415
+				$fieldName === 'QST_admin_label'
416
+				&& (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))
417
+			) {
418
+				// the admin label is blank, use a slug version of the question text
419
+				$QST_text                        = $this->_req_data['QST_display_text'] ?? '';
420
+				$set_column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
421
+			} elseif ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
422
+				$set_column_values[ $fieldName ] = 0;
423
+			} elseif ($fieldName === 'QST_max') {
424
+				$qst_system = $question_model->get_var(
425
+					[
426
+						[
427
+							'QST_ID' => $this->_req_data['QST_ID'] ?? 0,
428
+						],
429
+					],
430
+					'QST_system'
431
+				);
432
+				$max_max    = $question_model->absolute_max_for_system_question((string) $qst_system);
433
+				if (empty($this->_req_data['QST_max']) || $this->_req_data['QST_max'] > $max_max) {
434
+					$set_column_values[ $fieldName ] = $max_max;
435
+				}
436
+			}
437
+
438
+
439
+			// only add a property to the array if it's not null (otherwise the model should just use the default value)
440
+			if (
441
+				! isset($set_column_values[ $fieldName ]) && isset($this->_req_data[ $fieldName ])
442
+			) {
443
+				$set_column_values[ $fieldName ] = $this->_req_data[ $fieldName ];
444
+			}
445
+		}
446
+		// validation fo this data to be performed by the model before insertion.
447
+		return $set_column_values;
448
+	}
449
+
450
+
451
+	/**
452
+	 *_questions_overview_list_table
453
+	 *
454
+	 * @throws EE_Error
455
+	 */
456
+	protected function _questions_overview_list_table()
457
+	{
458
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
459
+		$this->display_admin_list_table_page_with_sidebar();
460
+	}
461
+
462
+
463
+	/**
464
+	 * _edit_question
465
+	 *
466
+	 * @throws EE_Error
467
+	 * @throws ReflectionException
468
+	 */
469
+	protected function _edit_question()
470
+	{
471
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
472
+			? absint($this->_req_data['QST_ID'])
473
+			: false;
474
+
475
+		switch ($this->_req_action) {
476
+			case 'add_question':
477
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
478
+				break;
479
+			case 'edit_question':
480
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
481
+				break;
482
+			default:
483
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
484
+		}
485
+
486
+		// add PRC_ID to title if editing
487
+		$this->_admin_page_title =
488
+			$ID
489
+				? $this->_admin_page_title . ' # ' . $ID
490
+				: $this->_admin_page_title;
491
+		if ($ID) {
492
+			$question                 = $this->_question_model->get_one_by_ID($ID);
493
+			$additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
494
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
495
+		} else {
496
+			$question = EE_Question::new_instance();
497
+			$question->set_order_to_latest();
498
+			$this->_set_add_edit_form_tags('insert_question');
499
+		}
500
+		if ($question->system_ID() === EEM_Attendee::system_question_phone) {
501
+			$question_types = array_intersect_key(
502
+				EEM_Question::instance()->allowed_question_types(),
503
+				array_flip(
504
+					[
505
+						EEM_Question::QST_type_text,
506
+						EEM_Question::QST_type_us_phone,
507
+					]
508
+				)
509
+			);
510
+		} else {
511
+			$question_types = $question->has_answers()
512
+				? $this->_question_model->question_types_in_same_category($question->type())
513
+				: $this->_question_model->allowed_question_types();
514
+		}
515
+		$this->_template_args['QST_ID']                     = $ID;
516
+		$this->_template_args['question']                   = $question;
517
+		$this->_template_args['question_types']             = $question_types;
518
+		$this->_template_args['max_max']                    =
519
+			EEM_Question::instance()->absolute_max_for_system_question(
520
+				$question->system_ID()
521
+			);
522
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
523
+		$this->_set_publish_post_box_vars('id', $ID, '', '', true);
524
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
525
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
526
+			$this->_template_args,
527
+			true
528
+		);
529
+
530
+		// the details template wrapper
531
+		$this->display_admin_page_with_sidebar();
532
+	}
533
+
534
+
535
+	/**
536
+	 * @return string
537
+	 * @throws EE_Error
538
+	 * @throws ReflectionException
539
+	 */
540
+	protected function _get_question_type_descriptions()
541
+	{
542
+		EE_Registry::instance()->load_helper('HTML');
543
+		$descriptions               = '';
544
+		$question_type_descriptions = EEM_Question::instance()->question_descriptions();
545
+		foreach ($question_type_descriptions as $type => $question_type_description) {
546
+			if ($type == 'HTML_TEXTAREA') {
547
+				$html                      = new EE_Simple_HTML_Validation_Strategy();
548
+				$question_type_description .= sprintf(
549
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
550
+					'<br/>',
551
+					$html->get_list_of_allowed_tags()
552
+				);
553
+			}
554
+			$descriptions .= EEH_HTML::p(
555
+				$question_type_description,
556
+				'question_type_description-' . $type,
557
+				'question_type_description description',
558
+				'display:none;'
559
+			);
560
+		}
561
+		return $descriptions;
562
+	}
563
+
564
+
565
+	/**
566
+	 * @param bool|true $new_question
567
+	 * @throws EE_Error
568
+	 * @throws ReflectionException
569
+	 */
570
+	protected function _insert_or_update_question($new_question = true)
571
+	{
572
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
573
+		if ($new_question) {
574
+			$question    = EE_Question::new_instance($set_column_values);
575
+			$action_desc = 'added';
576
+		} else {
577
+			$question = EEM_Question::instance()->get_one_by_ID(absint($this->_req_data['QST_ID']));
578
+			foreach ($set_column_values as $field => $new_value) {
579
+				$question->set($field, $new_value);
580
+			}
581
+			$action_desc = 'updated';
582
+		}
583
+		$success = $question->save();
584
+		$ID      = $question->ID();
585
+		if ($ID && $question->should_have_question_options()) {
586
+			// save the related options
587
+			// trash removed options, save old ones
588
+			// get list of all options
589
+			$options = $question->options();
590
+			if (! empty($options)) {
591
+				foreach ($options as $option_ID => $option) {
592
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
593
+					if ($option_req_index !== false) {
594
+						$option->save($this->_req_data['question_options'][ $option_req_index ]);
595
+					} else {
596
+						// not found, remove it
597
+						$option->delete();
598
+					}
599
+				}
600
+			}
601
+			// save new related options
602
+			foreach ($this->_req_data['question_options'] as $index => $option_req_data) {
603
+				// skip $index that is from our sample
604
+				if ($index === 'xxcountxx') {
605
+					continue;
606
+				}
607
+				// note we allow saving blank options.
608
+				if (empty($option_req_data['QSO_ID'])) {
609
+					// no ID! save it!
610
+					$new_option = EE_Question_Option::new_instance(
611
+						[
612
+							'QSO_value' => $option_req_data['QSO_value'],
613
+							'QSO_desc'  => $option_req_data['QSO_desc'],
614
+							'QSO_order' => $option_req_data['QSO_order'],
615
+							'QST_ID'    => $question->ID(),
616
+						]
617
+					);
618
+					$new_option->save();
619
+				}
620
+			}
621
+		}
622
+		$query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
623
+		if ($success !== 0) {
624
+			$msg = $new_question
625
+				? sprintf(
626
+					esc_html__('The %s has been created', 'event_espresso'),
627
+					$this->_question_model->item_name()
628
+				)
629
+				: sprintf(
630
+					esc_html__('The %s has been updated', 'event_espresso'),
631
+					$this->_question_model->item_name()
632
+				);
633
+			EE_Error::add_success($msg);
634
+		}
635
+
636
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
637
+	}
638
+
639
+
640
+	/**
641
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
642
+	 * by ID
643
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
644
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
645
+	 *
646
+	 * @param int $ID of the question option to find
647
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
648
+	 */
649
+	protected function _get_option_req_data_index($ID)
650
+	{
651
+		$req_data_for_question_options = $this->_req_data['question_options'];
652
+		foreach ($req_data_for_question_options as $num => $option_data) {
653
+			if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
654
+				return $num;
655
+			}
656
+		}
657
+		return false;
658
+	}
659
+
660
+
661
+
662
+
663
+	/***********/
664
+	/* QUERIES */
665
+	/**
666
+	 * For internal use in getting all the query parameters
667
+	 * (because it's pretty well the same between question, question groups,
668
+	 * and for both when searching for trashed and untrashed ones)
669
+	 *
670
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
671
+	 * @param int      $per_page
672
+	 * @param int      $current_page
673
+	 * @return array model query params, @see
674
+	 *                        https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
675
+	 */
676
+	protected function get_query_params($model, $per_page = 10, $current_page = 10)
677
+	{
678
+		$query_params             = [];
679
+		$offset                   = ($current_page - 1) * $per_page;
680
+		$query_params['limit']    = [$offset, $per_page];
681
+		$order                    =
682
+			(isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
683
+				? $this->_req_data['order']
684
+				: 'ASC';
685
+		$orderby_field            =
686
+			$model instanceof EEM_Question
687
+				? 'QST_ID'
688
+				: 'QSG_order';
689
+		$field_to_order_by        =
690
+			empty($this->_req_data['orderby'])
691
+				? $orderby_field
692
+				: $this->_req_data['orderby'];
693
+		$query_params['order_by'] = [$field_to_order_by => $order];
694
+		$search_string            =
695
+			array_key_exists('s', $this->_req_data)
696
+				? $this->_req_data['s']
697
+				: null;
698
+		if (! empty($search_string)) {
699
+			if ($model instanceof EEM_Question_Group) {
700
+				$query_params[0] = [
701
+					'OR' => [
702
+						'QSG_name' => ['LIKE', "%$search_string%"],
703
+						'QSG_desc' => ['LIKE', "%$search_string%"],
704
+					],
705
+				];
706
+			} else {
707
+				$query_params[0] = [
708
+					'QST_display_text' => ['LIKE', "%$search_string%"],
709
+				];
710
+			}
711
+		}
712
+
713
+		// capability checks (just leaving this commented out for reference because it illustrates some complicated query params that could be useful when fully implemented)
714
+		/*if ( $model instanceof EEM_Question_Group ) {
715 715
             if ( ! $this->capabilities->current_user_can( 'edit_others_question_groups', 'espresso_registration_form_edit_question_group' ) ) {
716 716
                 $query_params[0] = array(
717 717
                     'AND' => array(
@@ -741,67 +741,67 @@  discard block
 block discarded – undo
741 741
             }
742 742
         }/**/
743 743
 
744
-        return $query_params;
745
-    }
746
-
747
-
748
-    /**
749
-     * @param int        $per_page
750
-     * @param int        $current_page
751
-     * @param bool|false $count
752
-     * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]|int
753
-     * @throws EE_Error
754
-     */
755
-    public function get_questions($per_page = 10, $current_page = 1, $count = false)
756
-    {
757
-        $QST          = EEM_Question::instance();
758
-        $query_params = $this->get_query_params($QST, $per_page, $current_page);
759
-        if ($count) {
760
-            $where   =
761
-                isset($query_params[0])
762
-                    ? [$query_params[0]]
763
-                    : [];
764
-            $results = $QST->count($where);
765
-        } else {
766
-            $results = $QST->get_all($query_params);
767
-        }
768
-        return $results;
769
-    }
770
-
771
-
772
-    /**
773
-     * @param            $per_page
774
-     * @param int        $current_page
775
-     * @param bool|false $count
776
-     * @return EE_Soft_Delete_Base_Class[]|int
777
-     * @throws EE_Error
778
-     */
779
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
780
-    {
781
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
782
-        $where        =
783
-            isset($query_params[0])
784
-                ? [$query_params[0]]
785
-                : [];
786
-        return $count
787
-            ? EEM_Question::instance()->count_deleted($where)
788
-            : EEM_Question::instance()->get_all_deleted($query_params);
789
-    }
790
-
791
-
792
-    /**
793
-     * @param            $per_page
794
-     * @param int        $current_page
795
-     * @param bool|false $count
796
-     * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]
797
-     * @throws EE_Error
798
-     */
799
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
800
-    {
801
-        $questionGroupModel = EEM_Question_Group::instance();
802
-        // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
803
-        return $questionGroupModel->get_all(
804
-            $this->get_query_params($questionGroupModel, $per_page, $current_page)
805
-        );
806
-    }
744
+		return $query_params;
745
+	}
746
+
747
+
748
+	/**
749
+	 * @param int        $per_page
750
+	 * @param int        $current_page
751
+	 * @param bool|false $count
752
+	 * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]|int
753
+	 * @throws EE_Error
754
+	 */
755
+	public function get_questions($per_page = 10, $current_page = 1, $count = false)
756
+	{
757
+		$QST          = EEM_Question::instance();
758
+		$query_params = $this->get_query_params($QST, $per_page, $current_page);
759
+		if ($count) {
760
+			$where   =
761
+				isset($query_params[0])
762
+					? [$query_params[0]]
763
+					: [];
764
+			$results = $QST->count($where);
765
+		} else {
766
+			$results = $QST->get_all($query_params);
767
+		}
768
+		return $results;
769
+	}
770
+
771
+
772
+	/**
773
+	 * @param            $per_page
774
+	 * @param int        $current_page
775
+	 * @param bool|false $count
776
+	 * @return EE_Soft_Delete_Base_Class[]|int
777
+	 * @throws EE_Error
778
+	 */
779
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
780
+	{
781
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
782
+		$where        =
783
+			isset($query_params[0])
784
+				? [$query_params[0]]
785
+				: [];
786
+		return $count
787
+			? EEM_Question::instance()->count_deleted($where)
788
+			: EEM_Question::instance()->get_all_deleted($query_params);
789
+	}
790
+
791
+
792
+	/**
793
+	 * @param            $per_page
794
+	 * @param int        $current_page
795
+	 * @param bool|false $count
796
+	 * @return EE_Base_Class[]|EE_Question_Group[]|EE_Soft_Delete_Base_Class[]
797
+	 * @throws EE_Error
798
+	 */
799
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
800
+	{
801
+		$questionGroupModel = EEM_Question_Group::instance();
802
+		// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
803
+		return $questionGroupModel->get_all(
804
+			$this->get_query_params($questionGroupModel, $per_page, $current_page)
805
+		);
806
+	}
807 807
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -54,8 +54,8 @@  discard block
 block discarded – undo
54 54
      */
55 55
     public function __construct($routing = true)
56 56
     {
57
-        require_once(EE_MODELS . 'EEM_Question.model.php');
58
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
57
+        require_once(EE_MODELS.'EEM_Question.model.php');
58
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
59 59
         $this->_question_model       = EEM_Question::instance();
60 60
         $this->_question_group_model = EEM_Question_Group::instance();
61 61
         parent::__construct($routing);
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
      */
96 96
     protected function _set_page_routes()
97 97
     {
98
-        $qst_id             =
98
+        $qst_id =
99 99
             ! empty($this->_req_data['QST_ID'])
100 100
                 ? $this->_req_data['QST_ID']
101 101
                 : 0;
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
     {
233 233
         wp_register_style(
234 234
             'espresso_registration',
235
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
235
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css',
236 236
             [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
237 237
             EVENT_ESPRESSO_VERSION
238 238
         );
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
         $this->load_scripts_styles_forms();
290 290
         wp_register_script(
291 291
             'espresso_registration_form_single',
292
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
292
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js',
293 293
             ['jquery-ui-sortable'],
294 294
             EVENT_ESPRESSO_VERSION,
295 295
             true
@@ -308,7 +308,7 @@  discard block
 block discarded – undo
308 308
 
309 309
     public function recaptcha_info_help_tab()
310 310
     {
311
-        $template = REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php';
311
+        $template = REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php';
312 312
         EEH_Template::display_template($template, []);
313 313
     }
314 314
 
@@ -357,16 +357,16 @@  discard block
 block discarded – undo
357 357
     {
358 358
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
359 359
         $this->_template_args['preview_img']  =
360
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
360
+            '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'
361 361
             . esc_attr__(
362 362
                 'Preview Question Groups Overview List Table screenshot',
363 363
                 'event_espresso'
364
-            ) . '" />';
364
+            ).'" />';
365 365
         $this->_template_args['preview_text'] = '<strong>'
366 366
                                                 . esc_html__(
367 367
                                                     '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.',
368 368
                                                     'event_espresso'
369
-                                                ) . '</strong>';
369
+                                                ).'</strong>';
370 370
         $this->display_admin_caf_preview_page('question_groups_tab');
371 371
     }
372 372
 
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
 
386 386
         // some initial checks for proper values.
387 387
         // if QST_admin_only, then no matter what QST_required is we disable.
388
-        if (! empty($this->_req_data['QST_admin_only'])) {
388
+        if ( ! empty($this->_req_data['QST_admin_only'])) {
389 389
             $this->_req_data['QST_required'] = 0;
390 390
         }
391 391
         // if the question shouldn't have a max length, don't let them set one
@@ -410,16 +410,16 @@  discard block
 block discarded – undo
410 410
                 && (isset($this->_req_data['QSG_identifier']) && empty($this->_req_data['QSG_identifier']))
411 411
             ) {
412 412
                 $QSG_name                        = $this->_req_data['QSG_name'] ?? '';
413
-                $set_column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
413
+                $set_column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
414 414
             } elseif (
415 415
                 $fieldName === 'QST_admin_label'
416 416
                 && (isset($this->_req_data['QST_admin_label']) && empty($this->_req_data['QST_admin_label']))
417 417
             ) {
418 418
                 // the admin label is blank, use a slug version of the question text
419 419
                 $QST_text                        = $this->_req_data['QST_display_text'] ?? '';
420
-                $set_column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
421
-            } elseif ($fieldName === 'QST_admin_only' && (! isset($this->_req_data['QST_admin_only']))) {
422
-                $set_column_values[ $fieldName ] = 0;
420
+                $set_column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
421
+            } elseif ($fieldName === 'QST_admin_only' && ( ! isset($this->_req_data['QST_admin_only']))) {
422
+                $set_column_values[$fieldName] = 0;
423 423
             } elseif ($fieldName === 'QST_max') {
424 424
                 $qst_system = $question_model->get_var(
425 425
                     [
@@ -429,18 +429,18 @@  discard block
 block discarded – undo
429 429
                     ],
430 430
                     'QST_system'
431 431
                 );
432
-                $max_max    = $question_model->absolute_max_for_system_question((string) $qst_system);
432
+                $max_max = $question_model->absolute_max_for_system_question((string) $qst_system);
433 433
                 if (empty($this->_req_data['QST_max']) || $this->_req_data['QST_max'] > $max_max) {
434
-                    $set_column_values[ $fieldName ] = $max_max;
434
+                    $set_column_values[$fieldName] = $max_max;
435 435
                 }
436 436
             }
437 437
 
438 438
 
439 439
             // only add a property to the array if it's not null (otherwise the model should just use the default value)
440 440
             if (
441
-                ! isset($set_column_values[ $fieldName ]) && isset($this->_req_data[ $fieldName ])
441
+                ! isset($set_column_values[$fieldName]) && isset($this->_req_data[$fieldName])
442 442
             ) {
443
-                $set_column_values[ $fieldName ] = $this->_req_data[ $fieldName ];
443
+                $set_column_values[$fieldName] = $this->_req_data[$fieldName];
444 444
             }
445 445
         }
446 446
         // validation fo this data to be performed by the model before insertion.
@@ -486,7 +486,7 @@  discard block
 block discarded – undo
486 486
         // add PRC_ID to title if editing
487 487
         $this->_admin_page_title =
488 488
             $ID
489
-                ? $this->_admin_page_title . ' # ' . $ID
489
+                ? $this->_admin_page_title.' # '.$ID
490 490
                 : $this->_admin_page_title;
491 491
         if ($ID) {
492 492
             $question                 = $this->_question_model->get_one_by_ID($ID);
@@ -522,7 +522,7 @@  discard block
 block discarded – undo
522 522
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
523 523
         $this->_set_publish_post_box_vars('id', $ID, '', '', true);
524 524
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
525
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
525
+            REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
526 526
             $this->_template_args,
527 527
             true
528 528
         );
@@ -544,7 +544,7 @@  discard block
 block discarded – undo
544 544
         $question_type_descriptions = EEM_Question::instance()->question_descriptions();
545 545
         foreach ($question_type_descriptions as $type => $question_type_description) {
546 546
             if ($type == 'HTML_TEXTAREA') {
547
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
547
+                $html = new EE_Simple_HTML_Validation_Strategy();
548 548
                 $question_type_description .= sprintf(
549 549
                     esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
550 550
                     '<br/>',
@@ -553,7 +553,7 @@  discard block
 block discarded – undo
553 553
             }
554 554
             $descriptions .= EEH_HTML::p(
555 555
                 $question_type_description,
556
-                'question_type_description-' . $type,
556
+                'question_type_description-'.$type,
557 557
                 'question_type_description description',
558 558
                 'display:none;'
559 559
             );
@@ -587,11 +587,11 @@  discard block
 block discarded – undo
587 587
             // trash removed options, save old ones
588 588
             // get list of all options
589 589
             $options = $question->options();
590
-            if (! empty($options)) {
590
+            if ( ! empty($options)) {
591 591
                 foreach ($options as $option_ID => $option) {
592 592
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
593 593
                     if ($option_req_index !== false) {
594
-                        $option->save($this->_req_data['question_options'][ $option_req_index ]);
594
+                        $option->save($this->_req_data['question_options'][$option_req_index]);
595 595
                     } else {
596 596
                         // not found, remove it
597 597
                         $option->delete();
@@ -682,11 +682,11 @@  discard block
 block discarded – undo
682 682
             (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
683 683
                 ? $this->_req_data['order']
684 684
                 : 'ASC';
685
-        $orderby_field            =
685
+        $orderby_field =
686 686
             $model instanceof EEM_Question
687 687
                 ? 'QST_ID'
688 688
                 : 'QSG_order';
689
-        $field_to_order_by        =
689
+        $field_to_order_by =
690 690
             empty($this->_req_data['orderby'])
691 691
                 ? $orderby_field
692 692
                 : $this->_req_data['orderby'];
@@ -695,7 +695,7 @@  discard block
 block discarded – undo
695 695
             array_key_exists('s', $this->_req_data)
696 696
                 ? $this->_req_data['s']
697 697
                 : null;
698
-        if (! empty($search_string)) {
698
+        if ( ! empty($search_string)) {
699 699
             if ($model instanceof EEM_Question_Group) {
700 700
                 $query_params[0] = [
701 701
                     'OR' => [
@@ -757,7 +757,7 @@  discard block
 block discarded – undo
757 757
         $QST          = EEM_Question::instance();
758 758
         $query_params = $this->get_query_params($QST, $per_page, $current_page);
759 759
         if ($count) {
760
-            $where   =
760
+            $where =
761 761
                 isset($query_params[0])
762 762
                     ? [$query_params[0]]
763 763
                     : [];
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_List_Table.class.php 2 patches
Indentation   +576 added lines, -576 removed lines patch added patch discarded remove patch
@@ -14,177 +14,177 @@  discard block
 block discarded – undo
14 14
  */
15 15
 class Events_Admin_List_Table extends EE_Admin_List_Table
16 16
 {
17
-    /**
18
-     * @var Events_Admin_Page
19
-     */
20
-    protected $_admin_page;
21
-
22
-    /**
23
-     * @var EE_Datetime
24
-     */
25
-    private $_dtt;
26
-
27
-
28
-    /**
29
-     * Initial setup of data properties for the list table.
30
-     *
31
-     * @throws Exception
32
-     */
33
-    protected function _setup_data()
34
-    {
35
-        $this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
36
-        $this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
37
-    }
38
-
39
-
40
-    /**
41
-     * Set up of additional properties for the list table.
42
-     *
43
-     * @throws EE_Error
44
-     * @throws ReflectionException
45
-     */
46
-    protected function _set_properties()
47
-    {
48
-        $this->_wp_list_args    = [
49
-            'singular' => esc_html__('event', 'event_espresso'),
50
-            'plural'   => esc_html__('events', 'event_espresso'),
51
-            'ajax'     => true, // for now
52
-            'screen'   => $this->_admin_page->get_current_screen()->id,
53
-        ];
54
-        $approved_registrations = esc_html__('Approved Registrations', 'event_espresso');
55
-        $this->_columns         = [
56
-            'cb'              => '<input type="checkbox" />',
57
-            'id'              => esc_html__('ID', 'event_espresso'),
58
-            'name'            => esc_html__('Name', 'event_espresso'),
59
-            'author'          => esc_html__('Author', 'event_espresso'),
60
-            'venue'           => esc_html__('Venue', 'event_espresso'),
61
-            'start_date_time' => esc_html__('Event Start', 'event_espresso'),
62
-            'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
63
-            'attendees'       => '
17
+	/**
18
+	 * @var Events_Admin_Page
19
+	 */
20
+	protected $_admin_page;
21
+
22
+	/**
23
+	 * @var EE_Datetime
24
+	 */
25
+	private $_dtt;
26
+
27
+
28
+	/**
29
+	 * Initial setup of data properties for the list table.
30
+	 *
31
+	 * @throws Exception
32
+	 */
33
+	protected function _setup_data()
34
+	{
35
+		$this->_data           = $this->_admin_page->get_events($this->_per_page, $this->_current_page);
36
+		$this->_all_data_count = $this->_admin_page->get_events(0, 0, true);
37
+	}
38
+
39
+
40
+	/**
41
+	 * Set up of additional properties for the list table.
42
+	 *
43
+	 * @throws EE_Error
44
+	 * @throws ReflectionException
45
+	 */
46
+	protected function _set_properties()
47
+	{
48
+		$this->_wp_list_args    = [
49
+			'singular' => esc_html__('event', 'event_espresso'),
50
+			'plural'   => esc_html__('events', 'event_espresso'),
51
+			'ajax'     => true, // for now
52
+			'screen'   => $this->_admin_page->get_current_screen()->id,
53
+		];
54
+		$approved_registrations = esc_html__('Approved Registrations', 'event_espresso');
55
+		$this->_columns         = [
56
+			'cb'              => '<input type="checkbox" />',
57
+			'id'              => esc_html__('ID', 'event_espresso'),
58
+			'name'            => esc_html__('Name', 'event_espresso'),
59
+			'author'          => esc_html__('Author', 'event_espresso'),
60
+			'venue'           => esc_html__('Venue', 'event_espresso'),
61
+			'start_date_time' => esc_html__('Event Start', 'event_espresso'),
62
+			'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
63
+			'attendees'       => '
64 64
                 <span class="dashicons dashicons-groups ee-status-color--RAP ee-aria-tooltip"
65 65
                     aria-label="' . $approved_registrations . '"></span>
66 66
                 <span class="screen-reader-text">' . $approved_registrations . '</span>',
67
-            'actions'         => $this->actionsColumnHeader(),
68
-        ];
69
-        $this->addConditionalColumns();
70
-        $this->_sortable_columns = [
71
-            'id'              => ['EVT_ID' => true],
72
-            'name'            => ['EVT_name' => false],
73
-            'author'          => ['EVT_wp_user' => false],
74
-            'venue'           => ['Venue.VNU_name' => false],
75
-            'start_date_time' => ['Datetime.DTT_EVT_start' => false],
76
-            'reg_begins'      => ['Datetime.Ticket.TKT_start_date' => false],
77
-        ];
78
-
79
-        $this->_primary_column = 'id';
80
-        $this->_hidden_columns = ['author', 'event_category'];
81
-    }
82
-
83
-
84
-    /**
85
-     * @return array
86
-     */
87
-    protected function _get_table_filters()
88
-    {
89
-        return []; // no filters with decaf
90
-    }
91
-
92
-
93
-    /**
94
-     * Setup of views properties.
95
-     *
96
-     * @throws InvalidDataTypeException
97
-     * @throws InvalidInterfaceException
98
-     * @throws InvalidArgumentException
99
-     * @throws EE_Error
100
-     * @throws EE_Error
101
-     * @throws EE_Error
102
-     */
103
-    protected function _add_view_counts()
104
-    {
105
-        $this->_views['all']['count']   = $this->_admin_page->total_events();
106
-        $this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
107
-        if (
108
-            EE_Registry::instance()->CAP->current_user_can(
109
-                'ee_delete_events',
110
-                'espresso_events_trash_events'
111
-            )
112
-        ) {
113
-            $this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
114
-        }
115
-    }
116
-
117
-
118
-    /**
119
-     * @param EE_Event $item
120
-     * @return string
121
-     */
122
-    protected function _get_row_class($item): string
123
-    {
124
-        $class = parent::_get_row_class($item);
125
-        if ($this->_has_checkbox_column) {
126
-            $class .= ' has-checkbox-column';
127
-        }
128
-        return $class;
129
-    }
130
-
131
-
132
-    /**
133
-     * @param EE_Event $item
134
-     * @return string
135
-     * @throws EE_Error
136
-     * @throws ReflectionException
137
-     */
138
-    public function column_cb($item): string
139
-    {
140
-        if (! $item instanceof EE_Event) {
141
-            return '';
142
-        }
143
-        $this->_dtt = $item->primary_datetime(); // set this for use in other columns
144
-        $content    = sprintf(
145
-            '<input type="checkbox" name="EVT_IDs[]" value="%s" />',
146
-            $item->ID()
147
-        );
148
-        return $this->columnContent('cb', $content, 'center');
149
-    }
150
-
151
-
152
-    /**
153
-     * @param EE_Event $event
154
-     * @return string
155
-     * @throws EE_Error
156
-     * @throws ReflectionException
157
-     */
158
-    public function column_id(EE_Event $event): string
159
-    {
160
-        $content = '<span class="ee-entity-id">' . $event->ID() . '</span>';
161
-        $content .= '<span class="show-on-mobile-view-only">';
162
-        $content .= $this->column_name($event, false);
163
-        $content .= '</span>';
164
-        return $this->columnContent('id', $content, 'end');
165
-    }
166
-
167
-
168
-    /**
169
-     * @param EE_Event $event
170
-     * @param bool     $prep_content
171
-     * @return string
172
-     * @throws EE_Error
173
-     * @throws ReflectionException
174
-     */
175
-    public function column_name(EE_Event $event, bool $prep_content = true): string
176
-    {
177
-        $edit_query_args = [
178
-            'action' => 'edit',
179
-            'post'   => $event->ID(),
180
-        ];
181
-        $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
182
-        $actions         = $this->_column_name_action_setup($event);
183
-        $status          = esc_attr($event->get_active_status());
184
-        $pretty_status   = EEH_Template::pretty_status($status, false, 'sentence');
185
-        $status_dot      = '<span class="ee-status-dot ee-status-bg--' . $status . '"></span>';
186
-        $visibility      = $event->get_visibility_status();
187
-        $content         = '
67
+			'actions'         => $this->actionsColumnHeader(),
68
+		];
69
+		$this->addConditionalColumns();
70
+		$this->_sortable_columns = [
71
+			'id'              => ['EVT_ID' => true],
72
+			'name'            => ['EVT_name' => false],
73
+			'author'          => ['EVT_wp_user' => false],
74
+			'venue'           => ['Venue.VNU_name' => false],
75
+			'start_date_time' => ['Datetime.DTT_EVT_start' => false],
76
+			'reg_begins'      => ['Datetime.Ticket.TKT_start_date' => false],
77
+		];
78
+
79
+		$this->_primary_column = 'id';
80
+		$this->_hidden_columns = ['author', 'event_category'];
81
+	}
82
+
83
+
84
+	/**
85
+	 * @return array
86
+	 */
87
+	protected function _get_table_filters()
88
+	{
89
+		return []; // no filters with decaf
90
+	}
91
+
92
+
93
+	/**
94
+	 * Setup of views properties.
95
+	 *
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws InvalidInterfaceException
98
+	 * @throws InvalidArgumentException
99
+	 * @throws EE_Error
100
+	 * @throws EE_Error
101
+	 * @throws EE_Error
102
+	 */
103
+	protected function _add_view_counts()
104
+	{
105
+		$this->_views['all']['count']   = $this->_admin_page->total_events();
106
+		$this->_views['draft']['count'] = $this->_admin_page->total_events_draft();
107
+		if (
108
+			EE_Registry::instance()->CAP->current_user_can(
109
+				'ee_delete_events',
110
+				'espresso_events_trash_events'
111
+			)
112
+		) {
113
+			$this->_views['trash']['count'] = $this->_admin_page->total_trashed_events();
114
+		}
115
+	}
116
+
117
+
118
+	/**
119
+	 * @param EE_Event $item
120
+	 * @return string
121
+	 */
122
+	protected function _get_row_class($item): string
123
+	{
124
+		$class = parent::_get_row_class($item);
125
+		if ($this->_has_checkbox_column) {
126
+			$class .= ' has-checkbox-column';
127
+		}
128
+		return $class;
129
+	}
130
+
131
+
132
+	/**
133
+	 * @param EE_Event $item
134
+	 * @return string
135
+	 * @throws EE_Error
136
+	 * @throws ReflectionException
137
+	 */
138
+	public function column_cb($item): string
139
+	{
140
+		if (! $item instanceof EE_Event) {
141
+			return '';
142
+		}
143
+		$this->_dtt = $item->primary_datetime(); // set this for use in other columns
144
+		$content    = sprintf(
145
+			'<input type="checkbox" name="EVT_IDs[]" value="%s" />',
146
+			$item->ID()
147
+		);
148
+		return $this->columnContent('cb', $content, 'center');
149
+	}
150
+
151
+
152
+	/**
153
+	 * @param EE_Event $event
154
+	 * @return string
155
+	 * @throws EE_Error
156
+	 * @throws ReflectionException
157
+	 */
158
+	public function column_id(EE_Event $event): string
159
+	{
160
+		$content = '<span class="ee-entity-id">' . $event->ID() . '</span>';
161
+		$content .= '<span class="show-on-mobile-view-only">';
162
+		$content .= $this->column_name($event, false);
163
+		$content .= '</span>';
164
+		return $this->columnContent('id', $content, 'end');
165
+	}
166
+
167
+
168
+	/**
169
+	 * @param EE_Event $event
170
+	 * @param bool     $prep_content
171
+	 * @return string
172
+	 * @throws EE_Error
173
+	 * @throws ReflectionException
174
+	 */
175
+	public function column_name(EE_Event $event, bool $prep_content = true): string
176
+	{
177
+		$edit_query_args = [
178
+			'action' => 'edit',
179
+			'post'   => $event->ID(),
180
+		];
181
+		$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
182
+		$actions         = $this->_column_name_action_setup($event);
183
+		$status          = esc_attr($event->get_active_status());
184
+		$pretty_status   = EEH_Template::pretty_status($status, false, 'sentence');
185
+		$status_dot      = '<span class="ee-status-dot ee-status-bg--' . $status . '"></span>';
186
+		$visibility      = $event->get_visibility_status();
187
+		$content         = '
188 188
             <div class="ee-layout-row ee-layout-row--fixed">
189 189
                 <a  class="row-title ee-status-color--' . $status . ' ee-aria-tooltip"
190 190
                     aria-label="' . $pretty_status . '"
@@ -193,415 +193,415 @@  discard block
 block discarded – undo
193 193
                     ' . $status_dot . $event->name() . '
194 194
                 </a>
195 195
                 ' . (
196
-                    $visibility
197
-                    ? '<span class="ee-event-visibility-status ee-status-text-small">(' . esc_html($visibility) . ')</span>'
198
-                    : ''
199
-                ) . '
196
+					$visibility
197
+					? '<span class="ee-event-visibility-status ee-status-text-small">(' . esc_html($visibility) . ')</span>'
198
+					: ''
199
+				) . '
200 200
             </div>';
201 201
 
202
-        $content .= $this->row_actions($actions);
203
-
204
-        return $prep_content ? $this->columnContent('name', $content) : $content;
205
-    }
206
-
207
-
208
-    /**
209
-     * Just a method for setting up the actions for the name column
210
-     *
211
-     * @param EE_Event $event
212
-     * @return array array of actions
213
-     * @throws EE_Error
214
-     * @throws InvalidArgumentException
215
-     * @throws InvalidDataTypeException
216
-     * @throws InvalidInterfaceException
217
-     * @throws ReflectionException
218
-     */
219
-    protected function _column_name_action_setup(EE_Event $event): array
220
-    {
221
-        // todo: remove when attendees is active
222
-        if (! defined('REG_ADMIN_URL')) {
223
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
224
-        }
225
-        $actions            = [];
226
-        $restore_event_link = '';
227
-        $delete_event_link  = '';
228
-        $trash_event_link   = '';
229
-        if (
230
-            EE_Registry::instance()->CAP->current_user_can(
231
-                'ee_edit_event',
232
-                'espresso_events_edit',
233
-                $event->ID()
234
-            )
235
-        ) {
236
-            $edit_query_args = [
237
-                'action' => 'edit',
238
-                'post'   => $event->ID(),
239
-            ];
240
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
241
-            $actions['edit'] = '<a href="' . $edit_link . '" class="ee-aria-tooltip" '
242
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
243
-                               . esc_html__('Edit', 'event_espresso')
244
-                               . '</a>';
245
-        }
246
-        if (
247
-            EE_Registry::instance()->CAP->current_user_can(
248
-                'ee_read_registrations',
249
-                'espresso_registrations_view_registration'
250
-            )
251
-            && EE_Registry::instance()->CAP->current_user_can(
252
-                'ee_read_event',
253
-                'espresso_registrations_view_registration',
254
-                $event->ID()
255
-            )
256
-        ) {
257
-            $attendees_query_args = [
258
-                'action'   => 'default',
259
-                'event_id' => $event->ID(),
260
-            ];
261
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
262
-            $actions['attendees'] = '<a href="' . $attendees_link . '" class="ee-aria-tooltip"'
263
-                                    . ' aria-label="' . esc_attr__('View Registrations', 'event_espresso') . '">'
264
-                                    . esc_html__('Registrations', 'event_espresso')
265
-                                    . '</a>';
266
-        }
267
-        if (
268
-            EE_Registry::instance()->CAP->current_user_can(
269
-                'ee_delete_event',
270
-                'espresso_events_trash_event',
271
-                $event->ID()
272
-            )
273
-        ) {
274
-            $trash_event_query_args = [
275
-                'action' => 'trash_event',
276
-                'EVT_ID' => $event->ID(),
277
-            ];
278
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
279
-                $trash_event_query_args,
280
-                EVENTS_ADMIN_URL
281
-            );
282
-        }
283
-        if (
284
-            EE_Registry::instance()->CAP->current_user_can(
285
-                'ee_delete_event',
286
-                'espresso_events_restore_event',
287
-                $event->ID()
288
-            )
289
-        ) {
290
-            $restore_event_query_args = [
291
-                'action' => 'restore_event',
292
-                'EVT_ID' => $event->ID(),
293
-            ];
294
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
295
-                $restore_event_query_args,
296
-                EVENTS_ADMIN_URL
297
-            );
298
-        }
299
-        if (
300
-            EE_Registry::instance()->CAP->current_user_can(
301
-                'ee_delete_event',
302
-                'espresso_events_delete_event',
303
-                $event->ID()
304
-            )
305
-        ) {
306
-            $delete_event_query_args = [
307
-                'action' => 'delete_event',
308
-                'EVT_ID' => $event->ID(),
309
-            ];
310
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
311
-                $delete_event_query_args,
312
-                EVENTS_ADMIN_URL
313
-            );
314
-        }
315
-        $view_link       = get_permalink($event->ID());
316
-        $actions['view'] = '<a href="' . $view_link . '" class="ee-aria-tooltip"'
317
-                           . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '">'
318
-                           . esc_html__('View', 'event_espresso')
319
-                           . '</a>';
320
-        if ($event->get('status') === 'trash') {
321
-            if (
322
-                EE_Registry::instance()->CAP->current_user_can(
323
-                    'ee_delete_event',
324
-                    'espresso_events_restore_event',
325
-                    $event->ID()
326
-                )
327
-            ) {
328
-                $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" class="ee-aria-tooltip"'
329
-                                                 . ' aria-label="' . esc_attr__('Restore from Trash', 'event_espresso')
330
-                                                 . '">'
331
-                                                 . esc_html__('Restore from Trash', 'event_espresso')
332
-                                                 . '</a>';
333
-            }
334
-            if (
335
-                EE_Registry::instance()->CAP->current_user_can(
336
-                    'ee_delete_event',
337
-                    'espresso_events_delete_event',
338
-                    $event->ID()
339
-                )
340
-            ) {
341
-                $actions['delete'] = '<a href="' . $delete_event_link . '" class="ee-aria-tooltip"'
342
-                                     . ' aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
343
-                                     . esc_html__('Delete Permanently', 'event_espresso')
344
-                                     . '</a>';
345
-            }
346
-        } else {
347
-            if (
348
-                EE_Registry::instance()->CAP->current_user_can(
349
-                    'ee_delete_event',
350
-                    'espresso_events_trash_event',
351
-                    $event->ID()
352
-                )
353
-            ) {
354
-                $actions['move to trash'] = '<a href="' . $trash_event_link . '" class="ee-aria-tooltip"'
355
-                                            . ' aria-label="' . esc_attr__('Trash Event', 'event_espresso') . '">'
356
-                                            . esc_html__('Trash', 'event_espresso')
357
-                                            . '</a>';
358
-            }
359
-        }
360
-        return $actions;
361
-    }
362
-
363
-
364
-    /**
365
-     * @param EE_Event $event
366
-     * @return string
367
-     * @throws EE_Error
368
-     * @throws ReflectionException
369
-     */
370
-    public function column_author(EE_Event $event): string
371
-    {
372
-        // user author info
373
-        $event_author = get_userdata($event->wp_user());
374
-        $gravatar     = get_avatar($event->wp_user(), '24');
375
-        // filter link
376
-        $query_args = [
377
-            'action'      => 'default',
378
-            'EVT_wp_user' => $event->wp_user(),
379
-        ];
380
-        $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
381
-        $content    = '<div class="ee-layout-row ee-layout-row--fixed">';
382
-        $content    .= '  <a href="' . $filter_url . '" class="ee-event-author ee-aria-tooltip"'
383
-                       . ' aria-label="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
384
-                       . $gravatar . $event_author->display_name
385
-                       . '</a>';
386
-        $content    .= '</div>';
387
-        return $this->columnContent('author', $content);
388
-    }
389
-
390
-
391
-    /**
392
-     * @param EE_Event $event
393
-     * @return string
394
-     * @throws EE_Error
395
-     * @throws ReflectionException
396
-     */
397
-    public function column_event_category(EE_Event $event): string
398
-    {
399
-        $event_categories = $event->get_all_event_categories();
400
-        $content          = implode(
401
-            ', ',
402
-            array_map(
403
-                function (EE_Term $category) {
404
-                    return $category->name();
405
-                },
406
-                $event_categories
407
-            )
408
-        );
409
-        return $this->columnContent('event_category', $content);
410
-    }
411
-
412
-
413
-    /**
414
-     * @param EE_Event $event
415
-     * @return string
416
-     * @throws EE_Error
417
-     * @throws ReflectionException
418
-     */
419
-    public function column_venue(EE_Event $event): string
420
-    {
421
-        $venue   = $event->get_first_related('Venue');
422
-        $content = ! empty($venue)
423
-            ? $venue->name()
424
-            : '';
425
-        return $this->columnContent('venue', $content);
426
-    }
427
-
428
-
429
-    /**
430
-     * @param EE_Event $event
431
-     * @return string
432
-     * @throws EE_Error
433
-     * @throws ReflectionException
434
-     */
435
-    public function column_start_date_time(EE_Event $event): string
436
-    {
437
-        $content = $this->_dtt instanceof EE_Datetime
438
-            ? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
439
-            : esc_html__('No Date was saved for this Event', 'event_espresso');
440
-        return $this->columnContent('start_date_time', $content);
441
-    }
442
-
443
-
444
-    /**
445
-     * @param EE_Event $event
446
-     * @return string
447
-     * @throws EE_Error
448
-     * @throws ReflectionException
449
-     */
450
-    public function column_reg_begins(EE_Event $event): string
451
-    {
452
-        $reg_start = $event->get_ticket_with_earliest_start_time();
453
-        $content   = $reg_start instanceof EE_Ticket
454
-            ? $reg_start->get_i18n_datetime('TKT_start_date')
455
-            : esc_html__('No Tickets have been setup for this Event', 'event_espresso');
456
-        return $this->columnContent('reg_begins', $content);
457
-    }
458
-
459
-
460
-    /**
461
-     * @param EE_Event $event
462
-     * @return string
463
-     * @throws EE_Error
464
-     * @throws InvalidArgumentException
465
-     * @throws InvalidDataTypeException
466
-     * @throws InvalidInterfaceException
467
-     * @throws ReflectionException
468
-     */
469
-    public function column_attendees(EE_Event $event): string
470
-    {
471
-        $attendees_query_args = [
472
-            'action'   => 'default',
473
-            'event_id' => $event->ID(),
474
-        ];
475
-        $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
476
-        $registered_attendees = EEM_Registration::instance()->get_event_registration_count($event->ID());
477
-
478
-        $content              = EE_Registry::instance()->CAP->current_user_can(
479
-            'ee_read_event',
480
-            'espresso_registrations_view_registration',
481
-            $event->ID()
482
-        ) && EE_Registry::instance()->CAP->current_user_can(
483
-            'ee_read_registrations',
484
-            'espresso_registrations_view_registration'
485
-        )
486
-            ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
487
-            : $registered_attendees;
488
-        return $this->columnContent('attendees', $content, 'center');
489
-    }
490
-
491
-
492
-    /**
493
-     * @param EE_Event $event
494
-     * @return float
495
-     * @throws EE_Error
496
-     * @throws InvalidArgumentException
497
-     * @throws InvalidDataTypeException
498
-     * @throws InvalidInterfaceException
499
-     * @throws ReflectionException
500
-     */
501
-    public function column_tkts_sold(EE_Event $event): float
502
-    {
503
-        $content = EEM_Ticket::instance()->sum([['Datetime.EVT_ID' => $event->ID()]], 'TKT_sold');
504
-        return $this->columnContent('tkts_sold', $content);
505
-    }
506
-
507
-
508
-    /**
509
-     * @param EE_Event $event
510
-     * @return string
511
-     * @throws EE_Error
512
-     * @throws InvalidArgumentException
513
-     * @throws InvalidDataTypeException
514
-     * @throws InvalidInterfaceException
515
-     * @throws ReflectionException
516
-     */
517
-    public function column_actions(EE_Event $event): string
518
-    {
519
-        // todo: remove when attendees is active
520
-        if (! defined('REG_ADMIN_URL')) {
521
-            define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
522
-        }
523
-        $action_links   = [];
524
-        $view_link      = get_permalink($event->ID());
525
-        $action_links[] = '<a href="' . $view_link . '" class="ee-aria-tooltip button button--icon-only"'
526
-                          . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">
202
+		$content .= $this->row_actions($actions);
203
+
204
+		return $prep_content ? $this->columnContent('name', $content) : $content;
205
+	}
206
+
207
+
208
+	/**
209
+	 * Just a method for setting up the actions for the name column
210
+	 *
211
+	 * @param EE_Event $event
212
+	 * @return array array of actions
213
+	 * @throws EE_Error
214
+	 * @throws InvalidArgumentException
215
+	 * @throws InvalidDataTypeException
216
+	 * @throws InvalidInterfaceException
217
+	 * @throws ReflectionException
218
+	 */
219
+	protected function _column_name_action_setup(EE_Event $event): array
220
+	{
221
+		// todo: remove when attendees is active
222
+		if (! defined('REG_ADMIN_URL')) {
223
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
224
+		}
225
+		$actions            = [];
226
+		$restore_event_link = '';
227
+		$delete_event_link  = '';
228
+		$trash_event_link   = '';
229
+		if (
230
+			EE_Registry::instance()->CAP->current_user_can(
231
+				'ee_edit_event',
232
+				'espresso_events_edit',
233
+				$event->ID()
234
+			)
235
+		) {
236
+			$edit_query_args = [
237
+				'action' => 'edit',
238
+				'post'   => $event->ID(),
239
+			];
240
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
241
+			$actions['edit'] = '<a href="' . $edit_link . '" class="ee-aria-tooltip" '
242
+							   . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
243
+							   . esc_html__('Edit', 'event_espresso')
244
+							   . '</a>';
245
+		}
246
+		if (
247
+			EE_Registry::instance()->CAP->current_user_can(
248
+				'ee_read_registrations',
249
+				'espresso_registrations_view_registration'
250
+			)
251
+			&& EE_Registry::instance()->CAP->current_user_can(
252
+				'ee_read_event',
253
+				'espresso_registrations_view_registration',
254
+				$event->ID()
255
+			)
256
+		) {
257
+			$attendees_query_args = [
258
+				'action'   => 'default',
259
+				'event_id' => $event->ID(),
260
+			];
261
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
262
+			$actions['attendees'] = '<a href="' . $attendees_link . '" class="ee-aria-tooltip"'
263
+									. ' aria-label="' . esc_attr__('View Registrations', 'event_espresso') . '">'
264
+									. esc_html__('Registrations', 'event_espresso')
265
+									. '</a>';
266
+		}
267
+		if (
268
+			EE_Registry::instance()->CAP->current_user_can(
269
+				'ee_delete_event',
270
+				'espresso_events_trash_event',
271
+				$event->ID()
272
+			)
273
+		) {
274
+			$trash_event_query_args = [
275
+				'action' => 'trash_event',
276
+				'EVT_ID' => $event->ID(),
277
+			];
278
+			$trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
279
+				$trash_event_query_args,
280
+				EVENTS_ADMIN_URL
281
+			);
282
+		}
283
+		if (
284
+			EE_Registry::instance()->CAP->current_user_can(
285
+				'ee_delete_event',
286
+				'espresso_events_restore_event',
287
+				$event->ID()
288
+			)
289
+		) {
290
+			$restore_event_query_args = [
291
+				'action' => 'restore_event',
292
+				'EVT_ID' => $event->ID(),
293
+			];
294
+			$restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
295
+				$restore_event_query_args,
296
+				EVENTS_ADMIN_URL
297
+			);
298
+		}
299
+		if (
300
+			EE_Registry::instance()->CAP->current_user_can(
301
+				'ee_delete_event',
302
+				'espresso_events_delete_event',
303
+				$event->ID()
304
+			)
305
+		) {
306
+			$delete_event_query_args = [
307
+				'action' => 'delete_event',
308
+				'EVT_ID' => $event->ID(),
309
+			];
310
+			$delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
311
+				$delete_event_query_args,
312
+				EVENTS_ADMIN_URL
313
+			);
314
+		}
315
+		$view_link       = get_permalink($event->ID());
316
+		$actions['view'] = '<a href="' . $view_link . '" class="ee-aria-tooltip"'
317
+						   . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '">'
318
+						   . esc_html__('View', 'event_espresso')
319
+						   . '</a>';
320
+		if ($event->get('status') === 'trash') {
321
+			if (
322
+				EE_Registry::instance()->CAP->current_user_can(
323
+					'ee_delete_event',
324
+					'espresso_events_restore_event',
325
+					$event->ID()
326
+				)
327
+			) {
328
+				$actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" class="ee-aria-tooltip"'
329
+												 . ' aria-label="' . esc_attr__('Restore from Trash', 'event_espresso')
330
+												 . '">'
331
+												 . esc_html__('Restore from Trash', 'event_espresso')
332
+												 . '</a>';
333
+			}
334
+			if (
335
+				EE_Registry::instance()->CAP->current_user_can(
336
+					'ee_delete_event',
337
+					'espresso_events_delete_event',
338
+					$event->ID()
339
+				)
340
+			) {
341
+				$actions['delete'] = '<a href="' . $delete_event_link . '" class="ee-aria-tooltip"'
342
+									 . ' aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
343
+									 . esc_html__('Delete Permanently', 'event_espresso')
344
+									 . '</a>';
345
+			}
346
+		} else {
347
+			if (
348
+				EE_Registry::instance()->CAP->current_user_can(
349
+					'ee_delete_event',
350
+					'espresso_events_trash_event',
351
+					$event->ID()
352
+				)
353
+			) {
354
+				$actions['move to trash'] = '<a href="' . $trash_event_link . '" class="ee-aria-tooltip"'
355
+											. ' aria-label="' . esc_attr__('Trash Event', 'event_espresso') . '">'
356
+											. esc_html__('Trash', 'event_espresso')
357
+											. '</a>';
358
+			}
359
+		}
360
+		return $actions;
361
+	}
362
+
363
+
364
+	/**
365
+	 * @param EE_Event $event
366
+	 * @return string
367
+	 * @throws EE_Error
368
+	 * @throws ReflectionException
369
+	 */
370
+	public function column_author(EE_Event $event): string
371
+	{
372
+		// user author info
373
+		$event_author = get_userdata($event->wp_user());
374
+		$gravatar     = get_avatar($event->wp_user(), '24');
375
+		// filter link
376
+		$query_args = [
377
+			'action'      => 'default',
378
+			'EVT_wp_user' => $event->wp_user(),
379
+		];
380
+		$filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
381
+		$content    = '<div class="ee-layout-row ee-layout-row--fixed">';
382
+		$content    .= '  <a href="' . $filter_url . '" class="ee-event-author ee-aria-tooltip"'
383
+					   . ' aria-label="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
384
+					   . $gravatar . $event_author->display_name
385
+					   . '</a>';
386
+		$content    .= '</div>';
387
+		return $this->columnContent('author', $content);
388
+	}
389
+
390
+
391
+	/**
392
+	 * @param EE_Event $event
393
+	 * @return string
394
+	 * @throws EE_Error
395
+	 * @throws ReflectionException
396
+	 */
397
+	public function column_event_category(EE_Event $event): string
398
+	{
399
+		$event_categories = $event->get_all_event_categories();
400
+		$content          = implode(
401
+			', ',
402
+			array_map(
403
+				function (EE_Term $category) {
404
+					return $category->name();
405
+				},
406
+				$event_categories
407
+			)
408
+		);
409
+		return $this->columnContent('event_category', $content);
410
+	}
411
+
412
+
413
+	/**
414
+	 * @param EE_Event $event
415
+	 * @return string
416
+	 * @throws EE_Error
417
+	 * @throws ReflectionException
418
+	 */
419
+	public function column_venue(EE_Event $event): string
420
+	{
421
+		$venue   = $event->get_first_related('Venue');
422
+		$content = ! empty($venue)
423
+			? $venue->name()
424
+			: '';
425
+		return $this->columnContent('venue', $content);
426
+	}
427
+
428
+
429
+	/**
430
+	 * @param EE_Event $event
431
+	 * @return string
432
+	 * @throws EE_Error
433
+	 * @throws ReflectionException
434
+	 */
435
+	public function column_start_date_time(EE_Event $event): string
436
+	{
437
+		$content = $this->_dtt instanceof EE_Datetime
438
+			? $this->_dtt->get_i18n_datetime('DTT_EVT_start')
439
+			: esc_html__('No Date was saved for this Event', 'event_espresso');
440
+		return $this->columnContent('start_date_time', $content);
441
+	}
442
+
443
+
444
+	/**
445
+	 * @param EE_Event $event
446
+	 * @return string
447
+	 * @throws EE_Error
448
+	 * @throws ReflectionException
449
+	 */
450
+	public function column_reg_begins(EE_Event $event): string
451
+	{
452
+		$reg_start = $event->get_ticket_with_earliest_start_time();
453
+		$content   = $reg_start instanceof EE_Ticket
454
+			? $reg_start->get_i18n_datetime('TKT_start_date')
455
+			: esc_html__('No Tickets have been setup for this Event', 'event_espresso');
456
+		return $this->columnContent('reg_begins', $content);
457
+	}
458
+
459
+
460
+	/**
461
+	 * @param EE_Event $event
462
+	 * @return string
463
+	 * @throws EE_Error
464
+	 * @throws InvalidArgumentException
465
+	 * @throws InvalidDataTypeException
466
+	 * @throws InvalidInterfaceException
467
+	 * @throws ReflectionException
468
+	 */
469
+	public function column_attendees(EE_Event $event): string
470
+	{
471
+		$attendees_query_args = [
472
+			'action'   => 'default',
473
+			'event_id' => $event->ID(),
474
+		];
475
+		$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
476
+		$registered_attendees = EEM_Registration::instance()->get_event_registration_count($event->ID());
477
+
478
+		$content              = EE_Registry::instance()->CAP->current_user_can(
479
+			'ee_read_event',
480
+			'espresso_registrations_view_registration',
481
+			$event->ID()
482
+		) && EE_Registry::instance()->CAP->current_user_can(
483
+			'ee_read_registrations',
484
+			'espresso_registrations_view_registration'
485
+		)
486
+			? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
487
+			: $registered_attendees;
488
+		return $this->columnContent('attendees', $content, 'center');
489
+	}
490
+
491
+
492
+	/**
493
+	 * @param EE_Event $event
494
+	 * @return float
495
+	 * @throws EE_Error
496
+	 * @throws InvalidArgumentException
497
+	 * @throws InvalidDataTypeException
498
+	 * @throws InvalidInterfaceException
499
+	 * @throws ReflectionException
500
+	 */
501
+	public function column_tkts_sold(EE_Event $event): float
502
+	{
503
+		$content = EEM_Ticket::instance()->sum([['Datetime.EVT_ID' => $event->ID()]], 'TKT_sold');
504
+		return $this->columnContent('tkts_sold', $content);
505
+	}
506
+
507
+
508
+	/**
509
+	 * @param EE_Event $event
510
+	 * @return string
511
+	 * @throws EE_Error
512
+	 * @throws InvalidArgumentException
513
+	 * @throws InvalidDataTypeException
514
+	 * @throws InvalidInterfaceException
515
+	 * @throws ReflectionException
516
+	 */
517
+	public function column_actions(EE_Event $event): string
518
+	{
519
+		// todo: remove when attendees is active
520
+		if (! defined('REG_ADMIN_URL')) {
521
+			define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
522
+		}
523
+		$action_links   = [];
524
+		$view_link      = get_permalink($event->ID());
525
+		$action_links[] = '<a href="' . $view_link . '" class="ee-aria-tooltip button button--icon-only"'
526
+						  . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">
527 527
                           <span class="dashicons dashicons-visibility"></span></a>';
528
-        if (
529
-            EE_Registry::instance()->CAP->current_user_can(
530
-                'ee_edit_event',
531
-                'espresso_events_edit',
532
-                $event->ID()
533
-            )
534
-        ) {
535
-            $edit_query_args = [
536
-                'action' => 'edit',
537
-                'post'   => $event->ID(),
538
-            ];
539
-            $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
540
-            $action_links[]  = '<a href="' . $edit_link . '" class="ee-aria-tooltip button button--icon-only"'
541
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
542
-                               . '<span class="dashicons dashicons-calendar-alt"></span>'
543
-                               . '</a>';
544
-        }
545
-        if (
546
-            EE_Registry::instance()->CAP->current_user_can(
547
-                'ee_read_registrations',
548
-                'espresso_registrations_view_registration'
549
-            )
550
-            && EE_Registry::instance()->CAP->current_user_can(
551
-                'ee_read_event',
552
-                'espresso_registrations_view_registration',
553
-                $event->ID()
554
-            )
555
-        ) {
556
-            $attendees_query_args = [
557
-                'action'   => 'default',
558
-                'event_id' => $event->ID(),
559
-            ];
560
-            $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
561
-            $action_links[]       = '<a href="' . $attendees_link . '" class="ee-aria-tooltip button button--icon-only"'
562
-                                    . ' aria-label="' . esc_attr__('View Registrants', 'event_espresso') . '">'
563
-                                    . '<span class="dashicons dashicons-groups"></span>'
564
-                                    . '</a>';
565
-        }
566
-        $action_links = apply_filters(
567
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
568
-            $action_links,
569
-            $event
570
-        );
571
-        $content      = $this->_action_string(
572
-            implode("\n\t", $action_links),
573
-            $event,
574
-            'div',
575
-            'event-overview-actions ee-list-table-actions'
576
-        );
577
-        return $this->columnContent('actions', $this->actionsModalMenu($content));
578
-    }
579
-
580
-
581
-    /**
582
-     * Helper for adding columns conditionally
583
-     *
584
-     * @throws EE_Error
585
-     * @throws InvalidArgumentException
586
-     * @throws InvalidDataTypeException
587
-     * @throws InvalidInterfaceException
588
-     * @throws ReflectionException
589
-     */
590
-    private function addConditionalColumns()
591
-    {
592
-        $event_category_count = EEM_Term::instance()->count(
593
-            [['Term_Taxonomy.taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY]]
594
-        );
595
-        if ($event_category_count === 0) {
596
-            return;
597
-        }
598
-        $column_array = [];
599
-        foreach ($this->_columns as $column => $column_label) {
600
-            $column_array[ $column ] = $column_label;
601
-            if ($column === 'venue') {
602
-                $column_array['event_category'] = esc_html__('Event Category', 'event_espresso');
603
-            }
604
-        }
605
-        $this->_columns = $column_array;
606
-    }
528
+		if (
529
+			EE_Registry::instance()->CAP->current_user_can(
530
+				'ee_edit_event',
531
+				'espresso_events_edit',
532
+				$event->ID()
533
+			)
534
+		) {
535
+			$edit_query_args = [
536
+				'action' => 'edit',
537
+				'post'   => $event->ID(),
538
+			];
539
+			$edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
540
+			$action_links[]  = '<a href="' . $edit_link . '" class="ee-aria-tooltip button button--icon-only"'
541
+							   . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
542
+							   . '<span class="dashicons dashicons-calendar-alt"></span>'
543
+							   . '</a>';
544
+		}
545
+		if (
546
+			EE_Registry::instance()->CAP->current_user_can(
547
+				'ee_read_registrations',
548
+				'espresso_registrations_view_registration'
549
+			)
550
+			&& EE_Registry::instance()->CAP->current_user_can(
551
+				'ee_read_event',
552
+				'espresso_registrations_view_registration',
553
+				$event->ID()
554
+			)
555
+		) {
556
+			$attendees_query_args = [
557
+				'action'   => 'default',
558
+				'event_id' => $event->ID(),
559
+			];
560
+			$attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
561
+			$action_links[]       = '<a href="' . $attendees_link . '" class="ee-aria-tooltip button button--icon-only"'
562
+									. ' aria-label="' . esc_attr__('View Registrants', 'event_espresso') . '">'
563
+									. '<span class="dashicons dashicons-groups"></span>'
564
+									. '</a>';
565
+		}
566
+		$action_links = apply_filters(
567
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
568
+			$action_links,
569
+			$event
570
+		);
571
+		$content      = $this->_action_string(
572
+			implode("\n\t", $action_links),
573
+			$event,
574
+			'div',
575
+			'event-overview-actions ee-list-table-actions'
576
+		);
577
+		return $this->columnContent('actions', $this->actionsModalMenu($content));
578
+	}
579
+
580
+
581
+	/**
582
+	 * Helper for adding columns conditionally
583
+	 *
584
+	 * @throws EE_Error
585
+	 * @throws InvalidArgumentException
586
+	 * @throws InvalidDataTypeException
587
+	 * @throws InvalidInterfaceException
588
+	 * @throws ReflectionException
589
+	 */
590
+	private function addConditionalColumns()
591
+	{
592
+		$event_category_count = EEM_Term::instance()->count(
593
+			[['Term_Taxonomy.taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY]]
594
+		);
595
+		if ($event_category_count === 0) {
596
+			return;
597
+		}
598
+		$column_array = [];
599
+		foreach ($this->_columns as $column => $column_label) {
600
+			$column_array[ $column ] = $column_label;
601
+			if ($column === 'venue') {
602
+				$column_array['event_category'] = esc_html__('Event Category', 'event_espresso');
603
+			}
604
+		}
605
+		$this->_columns = $column_array;
606
+	}
607 607
 }
Please login to merge, or discard this patch.
Spacing   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -45,7 +45,7 @@  discard block
 block discarded – undo
45 45
      */
46 46
     protected function _set_properties()
47 47
     {
48
-        $this->_wp_list_args    = [
48
+        $this->_wp_list_args = [
49 49
             'singular' => esc_html__('event', 'event_espresso'),
50 50
             'plural'   => esc_html__('events', 'event_espresso'),
51 51
             'ajax'     => true, // for now
@@ -62,8 +62,8 @@  discard block
 block discarded – undo
62 62
             'reg_begins'      => esc_html__('On Sale', 'event_espresso'),
63 63
             'attendees'       => '
64 64
                 <span class="dashicons dashicons-groups ee-status-color--RAP ee-aria-tooltip"
65
-                    aria-label="' . $approved_registrations . '"></span>
66
-                <span class="screen-reader-text">' . $approved_registrations . '</span>',
65
+                    aria-label="' . $approved_registrations.'"></span>
66
+                <span class="screen-reader-text">' . $approved_registrations.'</span>',
67 67
             'actions'         => $this->actionsColumnHeader(),
68 68
         ];
69 69
         $this->addConditionalColumns();
@@ -137,7 +137,7 @@  discard block
 block discarded – undo
137 137
      */
138 138
     public function column_cb($item): string
139 139
     {
140
-        if (! $item instanceof EE_Event) {
140
+        if ( ! $item instanceof EE_Event) {
141 141
             return '';
142 142
         }
143 143
         $this->_dtt = $item->primary_datetime(); // set this for use in other columns
@@ -157,7 +157,7 @@  discard block
 block discarded – undo
157 157
      */
158 158
     public function column_id(EE_Event $event): string
159 159
     {
160
-        $content = '<span class="ee-entity-id">' . $event->ID() . '</span>';
160
+        $content = '<span class="ee-entity-id">'.$event->ID().'</span>';
161 161
         $content .= '<span class="show-on-mobile-view-only">';
162 162
         $content .= $this->column_name($event, false);
163 163
         $content .= '</span>';
@@ -182,21 +182,21 @@  discard block
 block discarded – undo
182 182
         $actions         = $this->_column_name_action_setup($event);
183 183
         $status          = esc_attr($event->get_active_status());
184 184
         $pretty_status   = EEH_Template::pretty_status($status, false, 'sentence');
185
-        $status_dot      = '<span class="ee-status-dot ee-status-bg--' . $status . '"></span>';
185
+        $status_dot      = '<span class="ee-status-dot ee-status-bg--'.$status.'"></span>';
186 186
         $visibility      = $event->get_visibility_status();
187 187
         $content         = '
188 188
             <div class="ee-layout-row ee-layout-row--fixed">
189
-                <a  class="row-title ee-status-color--' . $status . ' ee-aria-tooltip"
190
-                    aria-label="' . $pretty_status . '"
191
-                    href="' . $edit_link . '"
189
+                <a  class="row-title ee-status-color--' . $status.' ee-aria-tooltip"
190
+                    aria-label="' . $pretty_status.'"
191
+                    href="' . $edit_link.'"
192 192
                 >
193
-                    ' . $status_dot . $event->name() . '
193
+                    ' . $status_dot.$event->name().'
194 194
                 </a>
195 195
                 ' . (
196 196
                     $visibility
197
-                    ? '<span class="ee-event-visibility-status ee-status-text-small">(' . esc_html($visibility) . ')</span>'
197
+                    ? '<span class="ee-event-visibility-status ee-status-text-small">('.esc_html($visibility).')</span>'
198 198
                     : ''
199
-                ) . '
199
+                ).'
200 200
             </div>';
201 201
 
202 202
         $content .= $this->row_actions($actions);
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
     protected function _column_name_action_setup(EE_Event $event): array
220 220
     {
221 221
         // todo: remove when attendees is active
222
-        if (! defined('REG_ADMIN_URL')) {
222
+        if ( ! defined('REG_ADMIN_URL')) {
223 223
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
224 224
         }
225 225
         $actions            = [];
@@ -238,8 +238,8 @@  discard block
 block discarded – undo
238 238
                 'post'   => $event->ID(),
239 239
             ];
240 240
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
241
-            $actions['edit'] = '<a href="' . $edit_link . '" class="ee-aria-tooltip" '
242
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
241
+            $actions['edit'] = '<a href="'.$edit_link.'" class="ee-aria-tooltip" '
242
+                               . ' aria-label="'.esc_attr__('Edit Event', 'event_espresso').'">'
243 243
                                . esc_html__('Edit', 'event_espresso')
244 244
                                . '</a>';
245 245
         }
@@ -259,8 +259,8 @@  discard block
 block discarded – undo
259 259
                 'event_id' => $event->ID(),
260 260
             ];
261 261
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
262
-            $actions['attendees'] = '<a href="' . $attendees_link . '" class="ee-aria-tooltip"'
263
-                                    . ' aria-label="' . esc_attr__('View Registrations', 'event_espresso') . '">'
262
+            $actions['attendees'] = '<a href="'.$attendees_link.'" class="ee-aria-tooltip"'
263
+                                    . ' aria-label="'.esc_attr__('View Registrations', 'event_espresso').'">'
264 264
                                     . esc_html__('Registrations', 'event_espresso')
265 265
                                     . '</a>';
266 266
         }
@@ -275,7 +275,7 @@  discard block
 block discarded – undo
275 275
                 'action' => 'trash_event',
276 276
                 'EVT_ID' => $event->ID(),
277 277
             ];
278
-            $trash_event_link       = EE_Admin_Page::add_query_args_and_nonce(
278
+            $trash_event_link = EE_Admin_Page::add_query_args_and_nonce(
279 279
                 $trash_event_query_args,
280 280
                 EVENTS_ADMIN_URL
281 281
             );
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
                 'action' => 'restore_event',
292 292
                 'EVT_ID' => $event->ID(),
293 293
             ];
294
-            $restore_event_link       = EE_Admin_Page::add_query_args_and_nonce(
294
+            $restore_event_link = EE_Admin_Page::add_query_args_and_nonce(
295 295
                 $restore_event_query_args,
296 296
                 EVENTS_ADMIN_URL
297 297
             );
@@ -307,14 +307,14 @@  discard block
 block discarded – undo
307 307
                 'action' => 'delete_event',
308 308
                 'EVT_ID' => $event->ID(),
309 309
             ];
310
-            $delete_event_link       = EE_Admin_Page::add_query_args_and_nonce(
310
+            $delete_event_link = EE_Admin_Page::add_query_args_and_nonce(
311 311
                 $delete_event_query_args,
312 312
                 EVENTS_ADMIN_URL
313 313
             );
314 314
         }
315 315
         $view_link       = get_permalink($event->ID());
316
-        $actions['view'] = '<a href="' . $view_link . '" class="ee-aria-tooltip"'
317
-                           . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '">'
316
+        $actions['view'] = '<a href="'.$view_link.'" class="ee-aria-tooltip"'
317
+                           . ' aria-label="'.esc_attr__('View Event', 'event_espresso').'">'
318 318
                            . esc_html__('View', 'event_espresso')
319 319
                            . '</a>';
320 320
         if ($event->get('status') === 'trash') {
@@ -325,8 +325,8 @@  discard block
 block discarded – undo
325 325
                     $event->ID()
326 326
                 )
327 327
             ) {
328
-                $actions['restore_from_trash'] = '<a href="' . $restore_event_link . '" class="ee-aria-tooltip"'
329
-                                                 . ' aria-label="' . esc_attr__('Restore from Trash', 'event_espresso')
328
+                $actions['restore_from_trash'] = '<a href="'.$restore_event_link.'" class="ee-aria-tooltip"'
329
+                                                 . ' aria-label="'.esc_attr__('Restore from Trash', 'event_espresso')
330 330
                                                  . '">'
331 331
                                                  . esc_html__('Restore from Trash', 'event_espresso')
332 332
                                                  . '</a>';
@@ -338,8 +338,8 @@  discard block
 block discarded – undo
338 338
                     $event->ID()
339 339
                 )
340 340
             ) {
341
-                $actions['delete'] = '<a href="' . $delete_event_link . '" class="ee-aria-tooltip"'
342
-                                     . ' aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '">'
341
+                $actions['delete'] = '<a href="'.$delete_event_link.'" class="ee-aria-tooltip"'
342
+                                     . ' aria-label="'.esc_attr__('Delete Permanently', 'event_espresso').'">'
343 343
                                      . esc_html__('Delete Permanently', 'event_espresso')
344 344
                                      . '</a>';
345 345
             }
@@ -351,8 +351,8 @@  discard block
 block discarded – undo
351 351
                     $event->ID()
352 352
                 )
353 353
             ) {
354
-                $actions['move to trash'] = '<a href="' . $trash_event_link . '" class="ee-aria-tooltip"'
355
-                                            . ' aria-label="' . esc_attr__('Trash Event', 'event_espresso') . '">'
354
+                $actions['move to trash'] = '<a href="'.$trash_event_link.'" class="ee-aria-tooltip"'
355
+                                            . ' aria-label="'.esc_attr__('Trash Event', 'event_espresso').'">'
356 356
                                             . esc_html__('Trash', 'event_espresso')
357 357
                                             . '</a>';
358 358
             }
@@ -379,11 +379,11 @@  discard block
 block discarded – undo
379 379
         ];
380 380
         $filter_url = EE_Admin_Page::add_query_args_and_nonce($query_args, EVENTS_ADMIN_URL);
381 381
         $content    = '<div class="ee-layout-row ee-layout-row--fixed">';
382
-        $content    .= '  <a href="' . $filter_url . '" class="ee-event-author ee-aria-tooltip"'
383
-                       . ' aria-label="' . esc_attr__('Click to filter events by this author.', 'event_espresso') . '">'
384
-                       . $gravatar . $event_author->display_name
382
+        $content .= '  <a href="'.$filter_url.'" class="ee-event-author ee-aria-tooltip"'
383
+                       . ' aria-label="'.esc_attr__('Click to filter events by this author.', 'event_espresso').'">'
384
+                       . $gravatar.$event_author->display_name
385 385
                        . '</a>';
386
-        $content    .= '</div>';
386
+        $content .= '</div>';
387 387
         return $this->columnContent('author', $content);
388 388
     }
389 389
 
@@ -400,7 +400,7 @@  discard block
 block discarded – undo
400 400
         $content          = implode(
401 401
             ', ',
402 402
             array_map(
403
-                function (EE_Term $category) {
403
+                function(EE_Term $category) {
404 404
                     return $category->name();
405 405
                 },
406 406
                 $event_categories
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
             'ee_read_registrations',
484 484
             'espresso_registrations_view_registration'
485 485
         )
486
-            ? '<a href="' . $attendees_link . '">' . $registered_attendees . '</a>'
486
+            ? '<a href="'.$attendees_link.'">'.$registered_attendees.'</a>'
487 487
             : $registered_attendees;
488 488
         return $this->columnContent('attendees', $content, 'center');
489 489
     }
@@ -517,13 +517,13 @@  discard block
 block discarded – undo
517 517
     public function column_actions(EE_Event $event): string
518 518
     {
519 519
         // todo: remove when attendees is active
520
-        if (! defined('REG_ADMIN_URL')) {
520
+        if ( ! defined('REG_ADMIN_URL')) {
521 521
             define('REG_ADMIN_URL', EVENTS_ADMIN_URL);
522 522
         }
523 523
         $action_links   = [];
524 524
         $view_link      = get_permalink($event->ID());
525
-        $action_links[] = '<a href="' . $view_link . '" class="ee-aria-tooltip button button--icon-only"'
526
-                          . ' aria-label="' . esc_attr__('View Event', 'event_espresso') . '" target="_blank">
525
+        $action_links[] = '<a href="'.$view_link.'" class="ee-aria-tooltip button button--icon-only"'
526
+                          . ' aria-label="'.esc_attr__('View Event', 'event_espresso').'" target="_blank">
527 527
                           <span class="dashicons dashicons-visibility"></span></a>';
528 528
         if (
529 529
             EE_Registry::instance()->CAP->current_user_can(
@@ -537,8 +537,8 @@  discard block
 block discarded – undo
537 537
                 'post'   => $event->ID(),
538 538
             ];
539 539
             $edit_link       = EE_Admin_Page::add_query_args_and_nonce($edit_query_args, EVENTS_ADMIN_URL);
540
-            $action_links[]  = '<a href="' . $edit_link . '" class="ee-aria-tooltip button button--icon-only"'
541
-                               . ' aria-label="' . esc_attr__('Edit Event', 'event_espresso') . '">'
540
+            $action_links[]  = '<a href="'.$edit_link.'" class="ee-aria-tooltip button button--icon-only"'
541
+                               . ' aria-label="'.esc_attr__('Edit Event', 'event_espresso').'">'
542 542
                                . '<span class="dashicons dashicons-calendar-alt"></span>'
543 543
                                . '</a>';
544 544
         }
@@ -558,8 +558,8 @@  discard block
 block discarded – undo
558 558
                 'event_id' => $event->ID(),
559 559
             ];
560 560
             $attendees_link       = EE_Admin_Page::add_query_args_and_nonce($attendees_query_args, REG_ADMIN_URL);
561
-            $action_links[]       = '<a href="' . $attendees_link . '" class="ee-aria-tooltip button button--icon-only"'
562
-                                    . ' aria-label="' . esc_attr__('View Registrants', 'event_espresso') . '">'
561
+            $action_links[]       = '<a href="'.$attendees_link.'" class="ee-aria-tooltip button button--icon-only"'
562
+                                    . ' aria-label="'.esc_attr__('View Registrants', 'event_espresso').'">'
563 563
                                     . '<span class="dashicons dashicons-groups"></span>'
564 564
                                     . '</a>';
565 565
         }
@@ -568,7 +568,7 @@  discard block
 block discarded – undo
568 568
             $action_links,
569 569
             $event
570 570
         );
571
-        $content      = $this->_action_string(
571
+        $content = $this->_action_string(
572 572
             implode("\n\t", $action_links),
573 573
             $event,
574 574
             'div',
@@ -597,7 +597,7 @@  discard block
 block discarded – undo
597 597
         }
598 598
         $column_array = [];
599 599
         foreach ($this->_columns as $column => $column_label) {
600
-            $column_array[ $column ] = $column_label;
600
+            $column_array[$column] = $column_label;
601 601
             if ($column === 'venue') {
602 602
                 $column_array['event_category'] = esc_html__('Event Category', 'event_espresso');
603 603
             }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2938 added lines, -2938 removed lines patch added patch discarded remove patch
@@ -18,2945 +18,2945 @@
 block discarded – undo
18 18
  */
19 19
 class Events_Admin_Page extends EE_Admin_Page_CPT
20 20
 {
21
-    /**
22
-     * primary key for the event model
23
-     */
24
-    private int $EVT_ID = 0;
25
-
26
-    /**
27
-     * This will hold the event object for event_details screen.
28
-     *
29
-     * @var EE_Event|null $_event
30
-     */
31
-    protected ?EE_Event $_event = null;
32
-
33
-    /**
34
-     * This will hold the category object for category_details screen.
35
-     */
36
-    protected ?stdClass $_category = null;
37
-
38
-    protected ?EEM_Event $_event_model = null;
39
-
40
-    /**
41
-     * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
42
-     */
43
-    protected $_cpt_model_obj;
44
-
45
-    protected ?NodeGroupDao $model_obj_node_group_persister = null;
46
-
47
-    protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
48
-
49
-
50
-    /**
51
-     * Initialize page props for this admin page group.
52
-     */
53
-    protected function _init_page_props()
54
-    {
55
-        // is there a evt_id in the request?
56
-        $this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
57
-        $this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
58
-        $this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
59
-
60
-        $this->page_slug        = EVENTS_PG_SLUG;
61
-        $this->page_label       = EVENTS_LABEL;
62
-        $this->_admin_base_url  = EVENTS_ADMIN_URL;
63
-        $this->_admin_base_path = EVENTS_ADMIN;
64
-        $this->_cpt_model_names = [
65
-            'create_new' => 'EEM_Event',
66
-            'edit'       => 'EEM_Event',
67
-        ];
68
-        $this->_cpt_edit_routes = [
69
-            'espresso_events' => 'edit',
70
-        ];
71
-        add_action(
72
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
-            [$this, 'verify_event_edit'],
74
-            10,
75
-            2
76
-        );
77
-    }
78
-
79
-
80
-    /**
81
-     * Sets the ajax hooks used for this admin page group.
82
-     */
83
-    protected function _ajax_hooks()
84
-    {
85
-        add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
-    }
87
-
88
-
89
-    /**
90
-     * Sets the page properties for this admin page group.
91
-     */
92
-    protected function _define_page_props()
93
-    {
94
-        $this->_admin_page_title = EVENTS_LABEL;
95
-        $this->_labels           = [
96
-            'buttons'      => [
97
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
98
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
-            ],
104
-            'editor_title' => [
105
-                'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
106
-            ],
107
-            'publishbox'   => [
108
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
110
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
-            ],
114
-        ];
115
-    }
116
-
117
-
118
-    /**
119
-     * Sets the page routes property for this admin page group.
120
-     */
121
-    protected function _set_page_routes()
122
-    {
123
-        $this->_page_routes = [
124
-            'default'                       => [
125
-                'func'       => [$this, '_events_overview_list_table'],
126
-                'capability' => 'ee_read_events',
127
-            ],
128
-            'create_new'                    => [
129
-                'func'       => [$this, '_create_new_cpt_item'],
130
-                'capability' => 'ee_edit_events',
131
-            ],
132
-            'edit'                          => [
133
-                'func'       => [$this, '_edit_cpt_item'],
134
-                'capability' => 'ee_edit_event',
135
-                'obj_id'     => $this->EVT_ID,
136
-            ],
137
-            'copy_event'                    => [
138
-                'func'       => [$this, '_copy_events'],
139
-                'capability' => 'ee_edit_event',
140
-                'obj_id'     => $this->EVT_ID,
141
-                'noheader'   => true,
142
-            ],
143
-            'trash_event'                   => [
144
-                'func'       => [$this, '_trash_or_restore_event'],
145
-                'args'       => ['event_status' => 'trash'],
146
-                'capability' => 'ee_delete_event',
147
-                'obj_id'     => $this->EVT_ID,
148
-                'noheader'   => true,
149
-            ],
150
-            'trash_events'                  => [
151
-                'func'       => [$this, '_trash_or_restore_events'],
152
-                'args'       => ['event_status' => 'trash'],
153
-                'capability' => 'ee_delete_events',
154
-                'noheader'   => true,
155
-            ],
156
-            'restore_event'                 => [
157
-                'func'       => [$this, '_trash_or_restore_event'],
158
-                'args'       => ['event_status' => 'draft'],
159
-                'capability' => 'ee_delete_event',
160
-                'obj_id'     => $this->EVT_ID,
161
-                'noheader'   => true,
162
-            ],
163
-            'restore_events'                => [
164
-                'func'       => [$this, '_trash_or_restore_events'],
165
-                'args'       => ['event_status' => 'draft'],
166
-                'capability' => 'ee_delete_events',
167
-                'noheader'   => true,
168
-            ],
169
-            'delete_event'                  => [
170
-                'func'       => [$this, '_delete_event'],
171
-                'capability' => 'ee_delete_event',
172
-                'obj_id'     => $this->EVT_ID,
173
-                'noheader'   => true,
174
-            ],
175
-            'delete_events'                 => [
176
-                'func'       => [$this, '_delete_events'],
177
-                'capability' => 'ee_delete_events',
178
-                'noheader'   => true,
179
-            ],
180
-            'view_report'                   => [
181
-                'func'       => [$this, '_view_report'],
182
-                'capability' => 'ee_edit_events',
183
-            ],
184
-            'default_event_settings'        => [
185
-                'func'       => [$this, '_default_event_settings'],
186
-                'capability' => 'manage_options',
187
-            ],
188
-            'update_default_event_settings' => [
189
-                'func'       => [$this, '_update_default_event_settings'],
190
-                'capability' => 'manage_options',
191
-                'noheader'   => true,
192
-            ],
193
-            'template_settings'             => [
194
-                'func'       => [$this, '_template_settings'],
195
-                'capability' => 'manage_options',
196
-            ],
197
-            // event category tab related
198
-            'add_category'                  => [
199
-                'func'       => [$this, '_category_details'],
200
-                'capability' => 'ee_edit_event_category',
201
-                'args'       => ['view' => 'add'],
202
-            ],
203
-            'edit_category'                 => [
204
-                'func'       => [$this, '_category_details'],
205
-                'capability' => 'ee_edit_event_category',
206
-                'args'       => ['view' => 'edit'],
207
-            ],
208
-            'delete_categories'             => [
209
-                'func'       => [$this, '_delete_categories'],
210
-                'capability' => 'ee_delete_event_category',
211
-                'noheader'   => true,
212
-            ],
213
-            'delete_category'               => [
214
-                'func'       => [$this, '_delete_categories'],
215
-                'capability' => 'ee_delete_event_category',
216
-                'noheader'   => true,
217
-            ],
218
-            'insert_category'               => [
219
-                'func'       => [$this, '_insert_or_update_category'],
220
-                'args'       => ['new_category' => true],
221
-                'capability' => 'ee_edit_event_category',
222
-                'noheader'   => true,
223
-            ],
224
-            'update_category'               => [
225
-                'func'       => [$this, '_insert_or_update_category'],
226
-                'args'       => ['new_category' => false],
227
-                'capability' => 'ee_edit_event_category',
228
-                'noheader'   => true,
229
-            ],
230
-            'category_list'                 => [
231
-                'func'       => [$this, '_category_list_table'],
232
-                'capability' => 'ee_manage_event_categories',
233
-            ],
234
-            'preview_deletion'              => [
235
-                'func'       => [$this, 'previewDeletion'],
236
-                'capability' => 'ee_delete_events',
237
-            ],
238
-            'confirm_deletion'              => [
239
-                'func'       => [$this, 'confirmDeletion'],
240
-                'capability' => 'ee_delete_events',
241
-                'noheader'   => true,
242
-            ],
243
-        ];
244
-    }
245
-
246
-
247
-    /**
248
-     * Set the _page_config property for this admin page group.
249
-     */
250
-    protected function _set_page_config()
251
-    {
252
-        $post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
253
-        $EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
254
-        $this->_page_config = [
255
-            'default'                => [
256
-                'nav'           => [
257
-                    'label' => esc_html__('Overview', 'event_espresso'),
258
-                    'icon'  => 'dashicons-list-view',
259
-                    'order' => 10,
260
-                ],
261
-                'list_table'    => 'Events_Admin_List_Table',
262
-                'help_tabs'     => [
263
-                    'events_overview_help_tab'                       => [
264
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
265
-                        'filename' => 'events_overview',
266
-                    ],
267
-                    'events_overview_table_column_headings_help_tab' => [
268
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
269
-                        'filename' => 'events_overview_table_column_headings',
270
-                    ],
271
-                    'events_overview_filters_help_tab'               => [
272
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
273
-                        'filename' => 'events_overview_filters',
274
-                    ],
275
-                    'events_overview_view_help_tab'                  => [
276
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
277
-                        'filename' => 'events_overview_views',
278
-                    ],
279
-                    'events_overview_other_help_tab'                 => [
280
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
281
-                        'filename' => 'events_overview_other',
282
-                    ],
283
-                ],
284
-                'require_nonce' => false,
285
-            ],
286
-            'create_new'             => [
287
-                'nav'           => [
288
-                    'label'      => esc_html__('Add New Event', 'event_espresso'),
289
-                    'icon'       => 'dashicons-plus-alt',
290
-                    'order'      => 15,
291
-                    'persistent' => false,
292
-                ],
293
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
294
-                'help_tabs'     => [
295
-                    'event_editor_help_tab'                            => [
296
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
297
-                        'filename' => 'event_editor',
298
-                    ],
299
-                    'event_editor_title_richtexteditor_help_tab'       => [
300
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
301
-                        'filename' => 'event_editor_title_richtexteditor',
302
-                    ],
303
-                    'event_editor_venue_details_help_tab'              => [
304
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
305
-                        'filename' => 'event_editor_venue_details',
306
-                    ],
307
-                    'event_editor_event_datetimes_help_tab'            => [
308
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
309
-                        'filename' => 'event_editor_event_datetimes',
310
-                    ],
311
-                    'event_editor_event_tickets_help_tab'              => [
312
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
313
-                        'filename' => 'event_editor_event_tickets',
314
-                    ],
315
-                    'event_editor_event_registration_options_help_tab' => [
316
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
317
-                        'filename' => 'event_editor_event_registration_options',
318
-                    ],
319
-                    'event_editor_tags_categories_help_tab'            => [
320
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
321
-                        'filename' => 'event_editor_tags_categories',
322
-                    ],
323
-                    'event_editor_questions_registrants_help_tab'      => [
324
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
325
-                        'filename' => 'event_editor_questions_registrants',
326
-                    ],
327
-                    'event_editor_save_new_event_help_tab'             => [
328
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
329
-                        'filename' => 'event_editor_save_new_event',
330
-                    ],
331
-                    'event_editor_other_help_tab'                      => [
332
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
333
-                        'filename' => 'event_editor_other',
334
-                    ],
335
-                ],
336
-                'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
337
-                'require_nonce' => false,
338
-            ],
339
-            'edit'                   => [
340
-                'nav'           => [
341
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
342
-                    'icon'       => 'dashicons-edit',
343
-                    'order'      => 15,
344
-                    'persistent' => false,
345
-                    'url'        => $post_id
346
-                        ? EE_Admin_Page::add_query_args_and_nonce(
347
-                            ['post' => $post_id, 'action' => 'edit'],
348
-                            $this->_current_page_view_url
349
-                        )
350
-                        : $this->_admin_base_url,
351
-                ],
352
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
353
-                'help_tabs'     => [
354
-                    'event_editor_help_tab'                            => [
355
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
356
-                        'filename' => 'event_editor',
357
-                    ],
358
-                    'event_editor_title_richtexteditor_help_tab'       => [
359
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
360
-                        'filename' => 'event_editor_title_richtexteditor',
361
-                    ],
362
-                    'event_editor_venue_details_help_tab'              => [
363
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
364
-                        'filename' => 'event_editor_venue_details',
365
-                    ],
366
-                    'event_editor_event_datetimes_help_tab'            => [
367
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
368
-                        'filename' => 'event_editor_event_datetimes',
369
-                    ],
370
-                    'event_editor_event_tickets_help_tab'              => [
371
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
372
-                        'filename' => 'event_editor_event_tickets',
373
-                    ],
374
-                    'event_editor_event_registration_options_help_tab' => [
375
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
376
-                        'filename' => 'event_editor_event_registration_options',
377
-                    ],
378
-                    'event_editor_tags_categories_help_tab'            => [
379
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
380
-                        'filename' => 'event_editor_tags_categories',
381
-                    ],
382
-                    'event_editor_questions_registrants_help_tab'      => [
383
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
384
-                        'filename' => 'event_editor_questions_registrants',
385
-                    ],
386
-                    'event_editor_save_new_event_help_tab'             => [
387
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
388
-                        'filename' => 'event_editor_save_new_event',
389
-                    ],
390
-                    'event_editor_other_help_tab'                      => [
391
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
392
-                        'filename' => 'event_editor_other',
393
-                    ],
394
-                ],
395
-                'require_nonce' => false,
396
-            ],
397
-            'default_event_settings' => [
398
-                'nav'           => [
399
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
400
-                    'icon'  => 'dashicons-admin-generic',
401
-                    'order' => 40,
402
-                ],
403
-                'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
404
-                'labels'        => [
405
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
406
-                ],
407
-                'help_tabs'     => [
408
-                    'default_settings_help_tab'        => [
409
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
410
-                        'filename' => 'events_default_settings',
411
-                    ],
412
-                    'default_settings_status_help_tab' => [
413
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
414
-                        'filename' => 'events_default_settings_status',
415
-                    ],
416
-                    'default_maximum_tickets_help_tab' => [
417
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
418
-                        'filename' => 'events_default_settings_max_tickets',
419
-                    ],
420
-                ],
421
-                'require_nonce' => false,
422
-            ],
423
-            // template settings
424
-            'template_settings'      => [
425
-                'nav'           => [
426
-                    'label' => esc_html__('Templates', 'event_espresso'),
427
-                    'icon'  => 'dashicons-layout',
428
-                    'order' => 30,
429
-                ],
430
-                'metaboxes'     => $this->_default_espresso_metaboxes,
431
-                'help_tabs'     => [
432
-                    'general_settings_templates_help_tab' => [
433
-                        'title'    => esc_html__('Templates', 'event_espresso'),
434
-                        'filename' => 'general_settings_templates',
435
-                    ],
436
-                ],
437
-                'require_nonce' => false,
438
-            ],
439
-            // event category stuff
440
-            'add_category'           => [
441
-                'nav'           => [
442
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
443
-                    'icon'       => 'dashicons-plus-alt',
444
-                    'order'      => 25,
445
-                    'persistent' => false,
446
-                ],
447
-                'help_tabs'     => [
448
-                    'add_category_help_tab' => [
449
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
450
-                        'filename' => 'events_add_category',
451
-                    ],
452
-                ],
453
-                'metaboxes'     => ['_publish_post_box'],
454
-                'require_nonce' => false,
455
-            ],
456
-            'edit_category'          => [
457
-                'nav'           => [
458
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
459
-                    'icon'       => 'dashicons-edit',
460
-                    'order'      => 25,
461
-                    'persistent' => false,
462
-                    'url'        => $EVT_CAT_ID
463
-                        ? add_query_arg(
464
-                            ['EVT_CAT_ID' => $EVT_CAT_ID],
465
-                            $this->_current_page_view_url
466
-                        )
467
-                        : $this->_admin_base_url,
468
-                ],
469
-                'help_tabs'     => [
470
-                    'edit_category_help_tab' => [
471
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
472
-                        'filename' => 'events_edit_category',
473
-                    ],
474
-                ],
475
-                'metaboxes'     => ['_publish_post_box'],
476
-                'require_nonce' => false,
477
-            ],
478
-            'category_list'          => [
479
-                'nav'           => [
480
-                    'label' => esc_html__('Categories', 'event_espresso'),
481
-                    'icon'  => 'dashicons-networking',
482
-                    'order' => 20,
483
-                ],
484
-                'list_table'    => 'Event_Categories_Admin_List_Table',
485
-                'help_tabs'     => [
486
-                    'events_categories_help_tab'                       => [
487
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
488
-                        'filename' => 'events_categories',
489
-                    ],
490
-                    'events_categories_table_column_headings_help_tab' => [
491
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
492
-                        'filename' => 'events_categories_table_column_headings',
493
-                    ],
494
-                    'events_categories_view_help_tab'                  => [
495
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
496
-                        'filename' => 'events_categories_views',
497
-                    ],
498
-                    'events_categories_other_help_tab'                 => [
499
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
500
-                        'filename' => 'events_categories_other',
501
-                    ],
502
-                ],
503
-                'metaboxes'     => $this->_default_espresso_metaboxes,
504
-                'require_nonce' => false,
505
-            ],
506
-            'preview_deletion'       => [
507
-                'nav'           => [
508
-                    'label'      => esc_html__('Preview Deletion', 'event_espresso'),
509
-                    'icon'       => 'dashicons-remove',
510
-                    'order'      => 15,
511
-                    'persistent' => false,
512
-                    'url'        => '',
513
-                ],
514
-                'require_nonce' => false,
515
-            ],
516
-        ];
517
-    }
518
-
519
-
520
-    /**
521
-     * Used to register any global screen options if necessary for every route in this admin page group.
522
-     */
523
-    protected function _add_screen_options()
524
-    {
525
-    }
526
-
527
-
528
-    /**
529
-     * Implementing the screen options for the 'default' route.
530
-     *
531
-     * @throws InvalidArgumentException
532
-     * @throws InvalidDataTypeException
533
-     * @throws InvalidInterfaceException
534
-     */
535
-    protected function _add_screen_options_default()
536
-    {
537
-        $this->_per_page_screen_option();
538
-    }
539
-
540
-
541
-    /**
542
-     * Implementing screen options for the category list route.
543
-     *
544
-     * @throws InvalidArgumentException
545
-     * @throws InvalidDataTypeException
546
-     * @throws InvalidInterfaceException
547
-     */
548
-    protected function _add_screen_options_category_list()
549
-    {
550
-        $page_title              = $this->_admin_page_title;
551
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
552
-        $this->_per_page_screen_option();
553
-        $this->_admin_page_title = $page_title;
554
-    }
555
-
556
-
557
-    /**
558
-     * Used to register any global feature pointers for the admin page group.
559
-     */
560
-    protected function _add_feature_pointers()
561
-    {
562
-    }
563
-
564
-
565
-    /**
566
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
567
-     */
568
-    public function load_scripts_styles()
569
-    {
570
-        wp_register_style(
571
-            'events-admin-css',
572
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
573
-            [],
574
-            EVENT_ESPRESSO_VERSION
575
-        );
576
-        wp_register_style(
577
-            'ee-cat-admin',
578
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
579
-            [],
580
-            EVENT_ESPRESSO_VERSION
581
-        );
582
-        wp_enqueue_style('events-admin-css');
583
-        wp_enqueue_style('ee-cat-admin');
584
-        // scripts
585
-        wp_register_script(
586
-            'event_editor_js',
587
-            EVENTS_ASSETS_URL . 'event_editor.js',
588
-            ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
589
-            EVENT_ESPRESSO_VERSION,
590
-            true
591
-        );
592
-    }
593
-
594
-
595
-    /**
596
-     * Enqueuing scripts and styles specific to this view
597
-     */
598
-    public function load_scripts_styles_create_new()
599
-    {
600
-        $this->load_scripts_styles_edit();
601
-    }
602
-
603
-
604
-    /**
605
-     * Enqueuing scripts and styles specific to this view
606
-     */
607
-    public function load_scripts_styles_edit()
608
-    {
609
-        // styles
610
-        wp_enqueue_style('espresso-ui-theme');
611
-        wp_register_style(
612
-            'event-editor-css',
613
-            EVENTS_ASSETS_URL . 'event-editor.css',
614
-            ['ee-admin-css'],
615
-            EVENT_ESPRESSO_VERSION
616
-        );
617
-        wp_enqueue_style('event-editor-css');
618
-        // scripts
619
-        if (! $this->admin_config->useAdvancedEditor()) {
620
-            wp_register_script(
621
-                'event-datetime-metabox',
622
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
623
-                ['event_editor_js', 'ee-datepicker'],
624
-                EVENT_ESPRESSO_VERSION
625
-            );
626
-            wp_enqueue_script('event-datetime-metabox');
627
-        }
628
-    }
629
-
630
-
631
-    /**
632
-     * Populating the _views property for the category list table view.
633
-     */
634
-    protected function _set_list_table_views_category_list()
635
-    {
636
-        $this->_views = [
637
-            'all' => [
638
-                'slug'        => 'all',
639
-                'label'       => esc_html__('All', 'event_espresso'),
640
-                'count'       => 0,
641
-                'bulk_action' => [
642
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
643
-                ],
644
-            ],
645
-        ];
646
-    }
647
-
648
-
649
-    /**
650
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
651
-     */
652
-    public function admin_init()
653
-    {
654
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
655
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
656
-            'event_espresso'
657
-        );
658
-    }
659
-
660
-
661
-    /**
662
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
663
-     * group.
664
-     */
665
-    public function admin_notices()
666
-    {
667
-    }
668
-
669
-
670
-    /**
671
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
672
-     * this admin page group.
673
-     */
674
-    public function admin_footer_scripts()
675
-    {
676
-    }
677
-
678
-
679
-    /**
680
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
681
-     * warning (via EE_Error::add_error());
682
-     *
683
-     * @param EE_Event|null $event Event object
684
-     * @param string        $req_type
685
-     * @return void
686
-     * @throws EE_Error
687
-     * @throws ReflectionException
688
-     */
689
-    public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
690
-    {
691
-        // don't need to do this when processing
692
-        if (! empty($req_type)) {
693
-            return;
694
-        }
695
-        // no event?
696
-        if (! $event instanceof EE_Event) {
697
-            $event = $this->_cpt_model_obj;
698
-        }
699
-        // STILL no event?
700
-        if (! $event instanceof EE_Event) {
701
-            return;
702
-        }
703
-        // don't need to keep calling this
704
-        remove_action(
705
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
706
-            [$this, 'verify_event_edit']
707
-        );
708
-        $orig_status = $event->status();
709
-        // first check if event is active.
710
-        if (
711
-            $orig_status === EEM_Event::cancelled
712
-            || $orig_status === EEM_Event::postponed
713
-            || $event->is_expired()
714
-            || $event->is_inactive()
715
-        ) {
716
-            return;
717
-        }
718
-        // made it here so it IS active... next check that any of the tickets are sold.
719
-        if ($event->is_sold_out(true)) {
720
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
721
-                EE_Error::add_attention(
722
-                    sprintf(
723
-                        esc_html__(
724
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
725
-                            'event_espresso'
726
-                        ),
727
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
728
-                    )
729
-                );
730
-            }
731
-            return;
732
-        }
733
-        if ($orig_status === EEM_Event::sold_out) {
734
-            EE_Error::add_attention(
735
-                sprintf(
736
-                    esc_html__(
737
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
738
-                        'event_espresso'
739
-                    ),
740
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
741
-                )
742
-            );
743
-        }
744
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
745
-        if (! $event->tickets_on_sale()) {
746
-            return;
747
-        }
748
-        // made it here so show warning
749
-        $this->_edit_event_warning();
750
-    }
751
-
752
-
753
-    /**
754
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
755
-     * When needed, hook this into a EE_Error::add_error() notice.
756
-     *
757
-     * @access protected
758
-     * @return void
759
-     */
760
-    protected function _edit_event_warning()
761
-    {
762
-        // we don't want to add warnings during these requests
763
-        if ($this->request->getRequestParam('action') === 'editpost') {
764
-            return;
765
-        }
766
-        EE_Error::add_attention(
767
-            sprintf(
768
-                esc_html__(
769
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
770
-                    'event_espresso'
771
-                ),
772
-                '<a class="espresso-help-tab-lnk ee-help-tab-link">',
773
-                '</a>'
774
-            )
775
-        );
776
-    }
777
-
778
-
779
-    /**
780
-     * When a user is creating a new event, notify them if they haven't set their timezone.
781
-     * Otherwise, do the normal logic
782
-     *
783
-     * @return void
784
-     * @throws EE_Error
785
-     * @throws InvalidArgumentException
786
-     * @throws InvalidDataTypeException
787
-     * @throws InvalidInterfaceException
788
-     * @throws ReflectionException
789
-     */
790
-    protected function _create_new_cpt_item()
791
-    {
792
-        $has_timezone_string = get_option('timezone_string');
793
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
794
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
795
-            EE_Error::add_attention(
796
-                sprintf(
797
-                    esc_html__(
798
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
799
-                        'event_espresso'
800
-                    ),
801
-                    '<br>',
802
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
803
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
804
-                    . '</select>',
805
-                    '<button class="button button--secondary timezone-submit">',
806
-                    '</button><span class="spinner"></span>'
807
-                ),
808
-                __FILE__,
809
-                __FUNCTION__,
810
-                __LINE__
811
-            );
812
-        }
813
-        parent::_create_new_cpt_item();
814
-    }
815
-
816
-
817
-    /**
818
-     * Sets the _views property for the default route in this admin page group.
819
-     */
820
-    protected function _set_list_table_views_default()
821
-    {
822
-        $this->_views = [
823
-            'all'   => [
824
-                'slug'        => 'all',
825
-                'label'       => esc_html__('View All Events', 'event_espresso'),
826
-                'count'       => 0,
827
-                'bulk_action' => [
828
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
829
-                ],
830
-            ],
831
-            'draft' => [
832
-                'slug'        => 'draft',
833
-                'label'       => esc_html__('Draft', 'event_espresso'),
834
-                'count'       => 0,
835
-                'bulk_action' => [
836
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
837
-                ],
838
-            ],
839
-        ];
840
-        if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
841
-            $this->_views['trash'] = [
842
-                'slug'        => 'trash',
843
-                'label'       => esc_html__('Trash', 'event_espresso'),
844
-                'count'       => 0,
845
-                'bulk_action' => [
846
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
847
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
848
-                ],
849
-            ];
850
-        }
851
-    }
852
-
853
-
854
-    /**
855
-     * Provides the legend item array for the default list table view.
856
-     *
857
-     * @return array
858
-     * @throws EE_Error
859
-     * @throws EE_Error
860
-     */
861
-    protected function _event_legend_items(): array
862
-    {
863
-        $items    = [
864
-            'view_details'   => [
865
-                'class' => 'dashicons dashicons-visibility',
866
-                'desc'  => esc_html__('View Event', 'event_espresso'),
867
-            ],
868
-            'edit_event'     => [
869
-                'class' => 'dashicons dashicons-calendar-alt',
870
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
871
-            ],
872
-            'view_attendees' => [
873
-                'class' => 'dashicons dashicons-groups',
874
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
875
-            ],
876
-        ];
877
-        $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
878
-        $statuses = [
879
-            'sold_out_status'  => [
880
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
881
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
882
-            ],
883
-            'active_status'    => [
884
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
885
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
886
-            ],
887
-            'upcoming_status'  => [
888
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
889
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
890
-            ],
891
-            'postponed_status' => [
892
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
893
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
894
-            ],
895
-            'cancelled_status' => [
896
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
897
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
898
-            ],
899
-            'expired_status'   => [
900
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
901
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
902
-            ],
903
-            'inactive_status'  => [
904
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
905
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
906
-            ],
907
-        ];
908
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
909
-        return array_merge($items, $statuses);
910
-    }
911
-
912
-
913
-    /**
914
-     * @return EEM_Event
915
-     * @throws EE_Error
916
-     * @throws InvalidArgumentException
917
-     * @throws InvalidDataTypeException
918
-     * @throws InvalidInterfaceException
919
-     * @throws ReflectionException
920
-     */
921
-    private function _event_model(): EEM_Event
922
-    {
923
-        if (! $this->_event_model instanceof EEM_Event) {
924
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
925
-        }
926
-        return $this->_event_model;
927
-    }
928
-
929
-
930
-    /**
931
-     * Adds extra buttons to the WP CPT permalink field row.
932
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
933
-     *
934
-     * @param string      $return    the current html
935
-     * @param int         $id        the post id for the page
936
-     * @param string|null $new_title What the title is
937
-     * @param string|null $new_slug  what the slug is
938
-     * @return string            The new html string for the permalink area
939
-     * @deprecated 5.0.0.p
940
-     * @see        TicketSelectorShortcodeButton::addButton
941
-     */
942
-    public function extra_permalink_field_buttons(
943
-        string $return,
944
-        int $id,
945
-        ?string $new_title,
946
-        ?string $new_slug
947
-    ): string {
948
-        return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
949
-    }
950
-
951
-
952
-    /**
953
-     * _events_overview_list_table
954
-     * This contains the logic for showing the events_overview list
955
-     *
956
-     * @access protected
957
-     * @return void
958
-     * @throws DomainException
959
-     * @throws EE_Error
960
-     * @throws InvalidArgumentException
961
-     * @throws InvalidDataTypeException
962
-     * @throws InvalidInterfaceException
963
-     */
964
-    protected function _events_overview_list_table()
965
-    {
966
-        $after_list_table = [];
967
-        $links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
968
-        $links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
969
-        $links_html       .= EEH_HTML::div(
970
-            EEH_Template::get_button_or_link(
971
-                get_post_type_archive_link('espresso_events'),
972
-                esc_html__('View Event Archive Page', 'event_espresso'),
973
-                'button button--small button--secondary'
974
-            ),
975
-            '',
976
-            'ee-admin-button-row ee-admin-button-row--align-start'
977
-        );
978
-        $links_html       .= EEH_HTML::divx();
979
-
980
-        $after_list_table['view_event_list_button'] = $links_html;
981
-
982
-        $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
983
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
984
-                'create_new',
985
-                'add',
986
-                [],
987
-                'add-new-h2'
988
-            );
989
-
990
-        $this->_template_args['after_list_table'] = array_merge(
991
-            (array) $this->_template_args['after_list_table'],
992
-            $after_list_table
993
-        );
994
-        $this->display_admin_list_table_page_with_no_sidebar();
995
-    }
996
-
997
-
998
-    /**
999
-     * this allows for extra misc actions in the default WP publish box
1000
-     *
1001
-     * @return void
1002
-     * @throws DomainException
1003
-     * @throws EE_Error
1004
-     * @throws InvalidArgumentException
1005
-     * @throws InvalidDataTypeException
1006
-     * @throws InvalidInterfaceException
1007
-     * @throws ReflectionException
1008
-     */
1009
-    public function extra_misc_actions_publish_box()
1010
-    {
1011
-        $this->_generate_publish_box_extra_content();
1012
-    }
1013
-
1014
-
1015
-    /**
1016
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1017
-     * saved.
1018
-     * Typically you would use this to save any additional data.
1019
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
1020
-     * ALSO very important.  When a post transitions from scheduled to published,
1021
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1022
-     * other meta saves. So MAKE sure that you handle this accordingly.
1023
-     *
1024
-     * @access protected
1025
-     * @abstract
1026
-     * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1027
-     * @param WP_Post $post    The post object of the cpt that was saved.
1028
-     * @return void
1029
-     * @throws EE_Error
1030
-     * @throws InvalidArgumentException
1031
-     * @throws InvalidDataTypeException
1032
-     * @throws InvalidInterfaceException
1033
-     * @throws ReflectionException
1034
-     */
1035
-    protected function _insert_update_cpt_item($post_id, $post)
1036
-    {
1037
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1038
-            // get out we're not processing an event save.
1039
-            return;
1040
-        }
1041
-        $event_values = [
1042
-            'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1043
-            'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1044
-            'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1045
-        ];
1046
-        // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1047
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1049
-                'display_ticket_selector',
1050
-                false,
1051
-                'bool'
1052
-            );
1053
-            $event_values['EVT_additional_limit']            = min(
1054
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1055
-                $this->request->getRequestParam(
1056
-                    'additional_limit',
1057
-                    EEM_Event::get_default_additional_limit(),
1058
-                    'int'
1059
-                )
1060
-            );
1061
-            $event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1062
-                'EVT_default_registration_status',
1063
-                EE_Registry::instance()->CFG->registration->default_STS_ID
1064
-            );
1065
-
1066
-            $event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1067
-            $event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1068
-            $event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1069
-        } elseif ($post instanceof WP_Post) {
1070
-            $event_values['EVT_name'] = $post->post_title;
1071
-            $event_values['EVT_desc'] = $post->post_content;
1072
-        }
1073
-        // update event
1074
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
-        // get event_object for other metaboxes...
1076
-        // though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
-        // i have to setup where conditions to override the filters in the model
1078
-        // that filter out auto-draft and inherit statuses so we GET the inherit id!
1079
-        /** @var EE_Event $event */
1080
-        $event = $this->_event_model()->get_one(
1081
-            [
1082
-                [
1083
-                    $this->_event_model()->primary_key_name() => $post_id,
1084
-                    'OR'                                      => [
1085
-                        'status'   => $post->post_status,
1086
-                        // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1087
-                        // but the returned object here has a status of "publish", so use the original post status as well
1088
-                        'status*1' => $this->request->getRequestParam('original_post_status'),
1089
-                    ],
1090
-                ],
1091
-            ]
1092
-        );
1093
-
1094
-        // the following are default callbacks for event attachment updates
1095
-        // that can be overridden by caffeinated functionality and/or addons.
1096
-        $event_update_callbacks = [];
1097
-        if (! $this->admin_config->useAdvancedEditor()) {
1098
-            $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1099
-            $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1100
-        }
1101
-        $event_update_callbacks = apply_filters(
1102
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1103
-            $event_update_callbacks
1104
-        );
1105
-
1106
-        $att_success = true;
1107
-        foreach ($event_update_callbacks as $e_callback) {
1108
-            $_success = is_callable($e_callback)
1109
-                ? $e_callback($event, $this->request->requestParams())
1110
-                : false;
1111
-            // if ANY of these updates fail then we want the appropriate global error message
1112
-            $att_success = $_success !== false ? $att_success : false;
1113
-        }
1114
-        // any errors?
1115
-        if ($success && $att_success === false) {
1116
-            EE_Error::add_error(
1117
-                esc_html__(
1118
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1119
-                    'event_espresso'
1120
-                ),
1121
-                __FILE__,
1122
-                __FUNCTION__,
1123
-                __LINE__
1124
-            );
1125
-        } elseif ($success === false) {
1126
-            EE_Error::add_error(
1127
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1128
-                __FILE__,
1129
-                __FUNCTION__,
1130
-                __LINE__
1131
-            );
1132
-        }
1133
-    }
1134
-
1135
-
1136
-    /**
1137
-     * @param int $post_id
1138
-     * @param int $revision_id
1139
-     * @throws EE_Error
1140
-     * @throws EE_Error
1141
-     * @throws ReflectionException
1142
-     * @see parent::restore_item()
1143
-     */
1144
-    protected function _restore_cpt_item(int $post_id, int $revision_id)
1145
-    {
1146
-        // copy existing event meta to new post
1147
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1148
-        if ($post_evt instanceof EE_Event) {
1149
-            // meta revision restore
1150
-            $post_evt->restore_revision($revision_id);
1151
-            // related objs restore
1152
-            $post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1153
-        }
1154
-    }
1155
-
1156
-
1157
-    /**
1158
-     * Attach the venue to the Event
1159
-     *
1160
-     * @param EE_Event $event Event Object to add the venue to
1161
-     * @param array    $data  The request data from the form
1162
-     * @return bool           Success or fail.
1163
-     * @throws EE_Error
1164
-     * @throws ReflectionException
1165
-     */
1166
-    protected function _default_venue_update(EE_Event $event, array $data): bool
1167
-    {
1168
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1169
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1170
-        $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1171
-        // very important.  If we don't have a venue name...
1172
-        // then we'll get out because not necessary to create empty venue
1173
-        if (empty($data['venue_title'])) {
1174
-            return false;
1175
-        }
1176
-        $venue_array = [
1177
-            'VNU_wp_user'         => $event->get('EVT_wp_user'),
1178
-            'VNU_name'            => $data['venue_title'],
1179
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1180
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1181
-            'VNU_short_desc'      => ! empty($data['venue_short_description'])
1182
-                ? $data['venue_short_description']
1183
-                : null,
1184
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1185
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1186
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1187
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1188
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1189
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1190
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1191
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1192
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1193
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1194
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1195
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1196
-            'status'              => 'publish',
1197
-        ];
1198
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1199
-        if (! empty($venue_id)) {
1200
-            $update_where  = [$venue_model->primary_key_name() => $venue_id];
1201
-            $rows_affected = $venue_model->update($venue_array, [$update_where]);
1202
-            // we've gotta make sure that the venue is always attached to a revision..
1203
-            // add_relation_to should take care of making sure that the relation is already present.
1204
-            $event->_add_relation_to($venue_id, 'Venue');
1205
-            return $rows_affected > 0;
1206
-        }
1207
-        // we insert the venue
1208
-        $venue_id = $venue_model->insert($venue_array);
1209
-        $event->_add_relation_to($venue_id, 'Venue');
1210
-        return ! empty($venue_id);
1211
-        // when we have the ancestor come in it's already been handled by the revision save.
1212
-    }
1213
-
1214
-
1215
-    /**
1216
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1217
-     *
1218
-     * @param EE_Event $event The Event object we're attaching data to
1219
-     * @param array    $data  The request data from the form
1220
-     * @return array
1221
-     * @throws EE_Error
1222
-     * @throws ReflectionException
1223
-     * @throws Exception
1224
-     */
1225
-    protected function _default_tickets_update(EE_Event $event, array $data): array
1226
-    {
1227
-        if ($this->admin_config->useAdvancedEditor()) {
1228
-            return [];
1229
-        }
1230
-        $datetime       = null;
1231
-        $saved_tickets  = [];
1232
-        $event_timezone = $event->get_timezone();
1233
-        $date_formats   = ['Y-m-d', 'h:i a'];
1234
-        foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1235
-            // trim all values to ensure any excess whitespace is removed.
1236
-            $datetime_data                = array_map('trim', $datetime_data);
1237
-            $datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1238
-                    ? $datetime_data['DTT_EVT_end']
1239
-                    : $datetime_data['DTT_EVT_start'];
1240
-            $datetime_values              = [
1241
-                'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1242
-                'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1243
-                'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1244
-                'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1245
-                'DTT_order'     => $row,
1246
-            ];
1247
-            // if we have an id then let's get existing object first and then set the new values.
1248
-            //  Otherwise we instantiate a new object for save.
1249
-            if (! empty($datetime_data['DTT_ID'])) {
1250
-                $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
-                if (! $datetime instanceof EE_Datetime) {
1252
-                    throw new RuntimeException(
1253
-                        sprintf(
1254
-                            esc_html__(
1255
-                                'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1256
-                                'event_espresso'
1257
-                            ),
1258
-                            $datetime_data['DTT_ID']
1259
-                        )
1260
-                    );
1261
-                }
1262
-                $datetime->set_date_format($date_formats[0]);
1263
-                $datetime->set_time_format($date_formats[1]);
1264
-                foreach ($datetime_values as $field => $value) {
1265
-                    $datetime->set($field, $value);
1266
-                }
1267
-            } else {
1268
-                $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269
-            }
1270
-            if (! $datetime instanceof EE_Datetime) {
1271
-                throw new RuntimeException(
1272
-                    sprintf(
1273
-                        esc_html__(
1274
-                            'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1275
-                            'event_espresso'
1276
-                        ),
1277
-                        print_r($datetime_values, true)
1278
-                    )
1279
-                );
1280
-            }
1281
-            // before going any further make sure our dates are setup correctly
1282
-            // so that the end date is always equal or greater than the start date.
1283
-            if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1284
-                $datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1285
-                $datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1286
-            }
1287
-            $datetime->save();
1288
-            $event->_add_relation_to($datetime, 'Datetime');
1289
-        }
1290
-        // no datetimes get deleted so we don't do any of that logic here.
1291
-        // update tickets next
1292
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1293
-
1294
-        // set up some default start and end dates in case those are not present in the incoming data
1295
-        $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1297
-        // use the start date of the first datetime for the end date
1298
-        $first_datetime   = $event->first_datetime();
1299
-        $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1300
-
1301
-        // now process the incoming data
1302
-        foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303
-            $update_prices = false;
1304
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1305
-            // trim inputs to ensure any excess whitespace is removed.
1306
-            $ticket_data   = array_map('trim', $ticket_data);
1307
-            $ticket_values = [
1308
-                'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1309
-                'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1310
-                'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1311
-                'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1312
-                'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1313
-                    ? $ticket_data['TKT_start_date']
1314
-                    : $default_start_date,
1315
-                'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1316
-                    ? $ticket_data['TKT_end_date']
1317
-                    : $default_end_date,
1318
-                'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1319
-                                     || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1320
-                    ? $ticket_data['TKT_qty']
1321
-                    : EE_INF,
1322
-                'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1323
-                                     || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1324
-                    ? $ticket_data['TKT_uses']
1325
-                    : EE_INF,
1326
-                'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1327
-                'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1328
-                'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1329
-                'TKT_price'       => $ticket_price,
1330
-                'TKT_row'         => $row,
1331
-            ];
1332
-            // if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1333
-            // which means in turn that the prices will become new prices as well.
1334
-            if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1335
-                $ticket_values['TKT_ID']         = 0;
1336
-                $ticket_values['TKT_is_default'] = 0;
1337
-                $update_prices                   = true;
1338
-            }
1339
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1340
-            // we actually do our saves ahead of adding any relations because its entirely possible that this
1341
-            // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1342
-            // keep in mind that if the ticket has been sold (and we have changed pricing information),
1343
-            // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1344
-            if (! empty($ticket_data['TKT_ID'])) {
1345
-                $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1346
-                if (! $existing_ticket instanceof EE_Ticket) {
1347
-                    throw new RuntimeException(
1348
-                        sprintf(
1349
-                            esc_html__(
1350
-                                'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1351
-                                'event_espresso'
1352
-                            ),
1353
-                            $ticket_data['TKT_ID']
1354
-                        )
1355
-                    );
1356
-                }
1357
-                $ticket_sold = $existing_ticket->count_related(
1358
-                        'Registration',
1359
-                        [
1360
-                            [
1361
-                                'STS_ID' => [
1362
-                                    'NOT IN',
1363
-                                    [EEM_Registration::status_id_incomplete],
1364
-                                ],
1365
-                            ],
1366
-                        ]
1367
-                    ) > 0;
1368
-                // let's just check the total price for the existing ticket and determine if it matches the new total price.
1369
-                // if they are different then we create a new ticket (if $ticket_sold)
1370
-                // if they aren't different then we go ahead and modify existing ticket.
1371
-                $create_new_ticket = $ticket_sold
1372
-                                     && $ticket_price !== $existing_ticket->price()
1373
-                                     && ! $existing_ticket->deleted();
1374
-                $existing_ticket->set_date_format($date_formats[0]);
1375
-                $existing_ticket->set_time_format($date_formats[1]);
1376
-                // set new values
1377
-                foreach ($ticket_values as $field => $value) {
1378
-                    if ($field == 'TKT_qty') {
1379
-                        $existing_ticket->set_qty($value);
1380
-                    } elseif ($field == 'TKT_price') {
1381
-                        $existing_ticket->set('TKT_price', $ticket_price);
1382
-                    } else {
1383
-                        $existing_ticket->set($field, $value);
1384
-                    }
1385
-                }
1386
-                $ticket = $existing_ticket;
1387
-                // if $create_new_ticket is false then we can safely update the existing ticket.
1388
-                //  Otherwise we have to create a new ticket.
1389
-                if ($create_new_ticket) {
1390
-                    // archive the old ticket first
1391
-                    $existing_ticket->set('TKT_deleted', 1);
1392
-                    $existing_ticket->save();
1393
-                    // make sure this ticket is still recorded in our $saved_tickets
1394
-                    // so we don't run it through the regular trash routine.
1395
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1396
-                    // create new ticket that's a copy of the existing except,
1397
-                    // (a new id of course and not archived) AND has the new TKT_price associated with it.
1398
-                    $new_ticket = clone $existing_ticket;
1399
-                    $new_ticket->set('TKT_ID', 0);
1400
-                    $new_ticket->set('TKT_deleted', 0);
1401
-                    $new_ticket->set('TKT_sold', 0);
1402
-                    // now we need to make sure that $new prices are created as well and attached to new ticket.
1403
-                    $update_prices = true;
1404
-                    $ticket        = $new_ticket;
1405
-                }
1406
-            } else {
1407
-                // no TKT_id so a new ticket
1408
-                $ticket_values['TKT_price'] = $ticket_price;
1409
-                $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1410
-                $update_prices              = true;
1411
-            }
1412
-            if (! $ticket instanceof EE_Ticket) {
1413
-                throw new RuntimeException(
1414
-                    sprintf(
1415
-                        esc_html__(
1416
-                            'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1417
-                            'event_espresso'
1418
-                        ),
1419
-                        print_r($ticket_values, true)
1420
-                    )
1421
-                );
1422
-            }
1423
-            // cap ticket qty by datetime reg limits
1424
-            $ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1425
-            // update ticket.
1426
-            $ticket->save();
1427
-            // before going any further make sure our dates are setup correctly
1428
-            // so that the end date is always equal or greater than the start date.
1429
-            if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1430
-                $ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1431
-                $ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1432
-                $ticket->save();
1433
-            }
1434
-            // initially let's add the ticket to the datetime
1435
-            $datetime->_add_relation_to($ticket, 'Ticket');
1436
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1437
-            // add prices to ticket
1438
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1439
-                ? $data['edit_prices'][ $row ]
1440
-                : [];
1441
-            $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1442
-        }
1443
-        // however now we need to handle permanently deleting tickets via the ui.
1444
-        // Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1445
-        // However, it does allow for deleting tickets that have no tickets sold,
1446
-        // in which case we want to get rid of permanently because there is no need to save in db.
1447
-        $old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1448
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1449
-        foreach ($tickets_removed as $id) {
1450
-            $id = absint($id);
1451
-            // get the ticket for this id
1452
-            $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1453
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1454
-                continue;
1455
-            }
1456
-            // need to get all the related datetimes on this ticket and remove from every single one of them
1457
-            // (remember this process can ONLY kick off if there are NO tickets sold)
1458
-            $related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1459
-            foreach ($related_datetimes as $related_datetime) {
1460
-                $ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1461
-            }
1462
-            // need to do the same for prices (except these prices can also be deleted because again,
1463
-            // tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1464
-            $ticket_to_remove->delete_related_permanently('Price');
1465
-            // finally let's delete this ticket
1466
-            // (which should not be blocked at this point b/c we've removed all our relationships)
1467
-            $ticket_to_remove->delete_permanently();
1468
-        }
1469
-        return [$datetime, $saved_tickets];
1470
-    }
1471
-
1472
-
1473
-    /**
1474
-     * This attaches a list of given prices to a ticket.
1475
-     * Note we dont' have to worry about ever removing relationships (or archiving prices)
1476
-     * because if there is a change in price information on a ticket, a new ticket is created anyways
1477
-     * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1478
-     *
1479
-     * @access  private
1480
-     * @param array     $prices_data Array of prices from the form.
1481
-     * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1482
-     * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1483
-     * @return  void
1484
-     * @throws EE_Error
1485
-     * @throws ReflectionException
1486
-     */
1487
-    private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1488
-    {
1489
-        $timezone = $ticket->get_timezone();
1490
-        foreach ($prices_data as $row => $price_data) {
1491
-            $price_values = [
1492
-                'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1493
-                'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1494
-                'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1495
-                'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1496
-                'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1497
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1498
-                'PRC_order'      => $row,
1499
-            ];
1500
-            if ($new_prices || empty($price_values['PRC_ID'])) {
1501
-                $price_values['PRC_ID'] = 0;
1502
-                $price                  = EE_Price::new_instance($price_values, $timezone);
1503
-            } else {
1504
-                $price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1505
-                // update this price with new values
1506
-                foreach ($price_values as $field => $new_price) {
1507
-                    $price->set($field, $new_price);
1508
-                }
1509
-            }
1510
-            if (! $price instanceof EE_Price) {
1511
-                throw new RuntimeException(
1512
-                    sprintf(
1513
-                        esc_html__(
1514
-                            'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1515
-                            'event_espresso'
1516
-                        ),
1517
-                        print_r($price_values, true)
1518
-                    )
1519
-                );
1520
-            }
1521
-            $price->save();
1522
-            $ticket->_add_relation_to($price, 'Price');
1523
-        }
1524
-    }
1525
-
1526
-
1527
-    /**
1528
-     * Add in our autosave ajax handlers
1529
-     */
1530
-    protected function _ee_autosave_create_new()
1531
-    {
1532
-    }
1533
-
1534
-
1535
-    /**
1536
-     * More autosave handlers.
1537
-     */
1538
-    protected function _ee_autosave_edit()
1539
-    {
1540
-    }
1541
-
1542
-
1543
-    /**
1544
-     * @throws EE_Error
1545
-     * @throws ReflectionException
1546
-     */
1547
-    private function _generate_publish_box_extra_content()
1548
-    {
1549
-        // load formatter helper
1550
-        // args for getting related registrations
1551
-        $approved_query_args        = [
1552
-            [
1553
-                'REG_deleted' => 0,
1554
-                'STS_ID'      => EEM_Registration::status_id_approved,
1555
-            ],
1556
-        ];
1557
-        $not_approved_query_args    = [
1558
-            [
1559
-                'REG_deleted' => 0,
1560
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
-            ],
1562
-        ];
1563
-        $pending_payment_query_args = [
1564
-            [
1565
-                'REG_deleted' => 0,
1566
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
-            ],
1568
-        ];
1569
-        // publish box
1570
-        $publish_box_extra_args = [
1571
-            'view_approved_reg_url'        => add_query_arg(
1572
-                [
1573
-                    'action'      => 'default',
1574
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1575
-                    '_reg_status' => EEM_Registration::status_id_approved,
1576
-                    'use_filters' => true,
1577
-                ],
1578
-                REG_ADMIN_URL
1579
-            ),
1580
-            'view_not_approved_reg_url'    => add_query_arg(
1581
-                [
1582
-                    'action'      => 'default',
1583
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1584
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1585
-                    'use_filters' => true,
1586
-                ],
1587
-                REG_ADMIN_URL
1588
-            ),
1589
-            'view_pending_payment_reg_url' => add_query_arg(
1590
-                [
1591
-                    'action'      => 'default',
1592
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1593
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1594
-                    'use_filters' => true,
1595
-                ],
1596
-                REG_ADMIN_URL
1597
-            ),
1598
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1599
-                'Registration',
1600
-                $approved_query_args
1601
-            ),
1602
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1603
-                'Registration',
1604
-                $not_approved_query_args
1605
-            ),
1606
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1607
-                'Registration',
1608
-                $pending_payment_query_args
1609
-            ),
1610
-            'misc_pub_section_class'       => apply_filters(
1611
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1612
-                'misc-pub-section'
1613
-            ),
1614
-        ];
1615
-        ob_start();
1616
-        do_action(
1617
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1618
-            $this->_cpt_model_obj
1619
-        );
1620
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1621
-        // load template
1622
-        EEH_Template::display_template(
1623
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1624
-            $publish_box_extra_args
1625
-        );
1626
-    }
1627
-
1628
-
1629
-    /**
1630
-     * @return EE_Event
1631
-     */
1632
-    public function get_event_object()
1633
-    {
1634
-        return $this->_cpt_model_obj;
1635
-    }
1636
-
1637
-
1638
-
1639
-
1640
-    /** METABOXES * */
1641
-    /**
1642
-     * _register_event_editor_meta_boxes
1643
-     * add all metaboxes related to the event_editor
1644
-     *
1645
-     * @return void
1646
-     * @throws EE_Error
1647
-     * @throws ReflectionException
1648
-     */
1649
-    protected function _register_event_editor_meta_boxes()
1650
-    {
1651
-        $this->verify_cpt_object();
1652
-        $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1653
-        // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1654
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1655
-            $this->addMetaBox(
1656
-                'espresso_event_editor_event_options',
1657
-                esc_html__('Event Registration Options', 'event_espresso'),
1658
-                [$this, 'registration_options_meta_box'],
1659
-                $this->page_slug,
1660
-                'side'
1661
-            );
1662
-        }
1663
-        if (! $use_advanced_editor) {
1664
-            $this->addMetaBox(
1665
-                'espresso_event_editor_tickets',
1666
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1667
-                [$this, 'ticket_metabox'],
1668
-                $this->page_slug,
1669
-                'normal',
1670
-                'high'
1671
-            );
1672
-        } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1673
-            add_action(
1674
-                'add_meta_boxes_espresso_events',
1675
-                function () {
1676
-                    global $current_screen;
1677
-                    remove_meta_box('authordiv', $current_screen, 'normal');
1678
-                },
1679
-                99
1680
-            );
1681
-        }
1682
-        // NOTE: if you're looking for other metaboxes in here,
1683
-        // where a metabox has a related management page in the admin
1684
-        // you will find it setup in the related management page's "_Hooks" file.
1685
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1686
-    }
1687
-
1688
-
1689
-    /**
1690
-     * @throws DomainException
1691
-     * @throws EE_Error
1692
-     * @throws ReflectionException
1693
-     */
1694
-    public function ticket_metabox()
1695
-    {
1696
-        $existing_datetime_ids = $existing_ticket_ids = [];
1697
-        // defaults for template args
1698
-        $template_args = [
1699
-            'ticket_rows'       => '',
1700
-            'total_ticket_rows' => 1,
1701
-            'trash_icon'        => 'dashicons dashicons-lock',
1702
-            'disabled'          => '',
1703
-        ];
1704
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1705
-        /**
1706
-         * 1. Start with retrieving Datetimes
1707
-         * 2. Fore each datetime get related tickets
1708
-         * 3. For each ticket get related prices
1709
-         */
1710
-        /** @var EEM_Datetime $datetime_model */
1711
-        $datetime_model = EE_Registry::instance()->load_model('Datetime');
1712
-        /** @var EEM_Ticket $datetime_model */
1713
-        $ticket_model = EE_Registry::instance()->load_model('Ticket');
1714
-        $times        = $datetime_model->get_all_event_dates($event_id);
1715
-        /** @type EE_Datetime $first_datetime */
1716
-        $first_datetime = reset($times);
1717
-        // do we get related tickets?
1718
-        if (
1719
-            $first_datetime instanceof EE_Datetime
1720
-            && $first_datetime->ID() !== 0
1721
-        ) {
1722
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1723
-            $template_args['time']   = $first_datetime;
1724
-            $related_tickets         = $first_datetime->tickets(
1725
-                [
1726
-                    ['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1727
-                    'default_where_conditions' => 'none',
1728
-                ]
1729
-            );
1730
-            if (! empty($related_tickets)) {
1731
-                $template_args['total_ticket_rows'] = count($related_tickets);
1732
-                $row                                = 0;
1733
-                foreach ($related_tickets as $ticket) {
1734
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1735
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1736
-                    $row++;
1737
-                }
1738
-            } else {
1739
-                $template_args['total_ticket_rows'] = 1;
1740
-                /** @type EE_Ticket $ticket */
1741
-                $ticket                       = $ticket_model->create_default_object();
1742
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1743
-            }
1744
-        } else {
1745
-            $template_args['time'] = $times[0];
1746
-            /** @type EE_Ticket[] $tickets */
1747
-            $tickets                      = $ticket_model->get_all_default_tickets();
1748
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1749
-            // NOTE: we're just sending the first default row
1750
-            // (decaf can't manage default tickets so this should be sufficient);
1751
-        }
1752
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1753
-            'event_editor_event_datetimes_help_tab'
1754
-        );
1755
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1756
-        $template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1757
-        $template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1758
-        $template_args['ticket_js_structure']      = $this->_get_ticket_row(
1759
-            $ticket_model->create_default_object(),
1760
-            true
1761
-        );
1762
-        $template                                  = apply_filters(
1763
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1764
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1765
-        );
1766
-        EEH_Template::display_template($template, $template_args);
1767
-    }
1768
-
1769
-
1770
-    /**
1771
-     * Setup an individual ticket form for the decaf event editor page
21
+	/**
22
+	 * primary key for the event model
23
+	 */
24
+	private int $EVT_ID = 0;
25
+
26
+	/**
27
+	 * This will hold the event object for event_details screen.
28
+	 *
29
+	 * @var EE_Event|null $_event
30
+	 */
31
+	protected ?EE_Event $_event = null;
32
+
33
+	/**
34
+	 * This will hold the category object for category_details screen.
35
+	 */
36
+	protected ?stdClass $_category = null;
37
+
38
+	protected ?EEM_Event $_event_model = null;
39
+
40
+	/**
41
+	 * @var EE_Event|EE_CPT_Base|null $_cpt_model_obj
42
+	 */
43
+	protected $_cpt_model_obj;
44
+
45
+	protected ?NodeGroupDao $model_obj_node_group_persister = null;
46
+
47
+	protected ?AdvancedEditorAdminFormSection $advanced_editor_admin_form = null;
48
+
49
+
50
+	/**
51
+	 * Initialize page props for this admin page group.
52
+	 */
53
+	protected function _init_page_props()
54
+	{
55
+		// is there a evt_id in the request?
56
+		$this->EVT_ID = $this->request->getRequestParam('EVT_ID', 0, DataType::INT);
57
+		$this->EVT_ID = $this->request->getRequestParam('post', $this->EVT_ID, DataType::INT);
58
+		$this->EVT_ID = $this->request->getRequestParam('post_ID', $this->EVT_ID, DataType::INT);
59
+
60
+		$this->page_slug        = EVENTS_PG_SLUG;
61
+		$this->page_label       = EVENTS_LABEL;
62
+		$this->_admin_base_url  = EVENTS_ADMIN_URL;
63
+		$this->_admin_base_path = EVENTS_ADMIN;
64
+		$this->_cpt_model_names = [
65
+			'create_new' => 'EEM_Event',
66
+			'edit'       => 'EEM_Event',
67
+		];
68
+		$this->_cpt_edit_routes = [
69
+			'espresso_events' => 'edit',
70
+		];
71
+		add_action(
72
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
73
+			[$this, 'verify_event_edit'],
74
+			10,
75
+			2
76
+		);
77
+	}
78
+
79
+
80
+	/**
81
+	 * Sets the ajax hooks used for this admin page group.
82
+	 */
83
+	protected function _ajax_hooks()
84
+	{
85
+		add_action('wp_ajax_ee_save_timezone_setting', [$this, 'saveTimezoneString']);
86
+	}
87
+
88
+
89
+	/**
90
+	 * Sets the page properties for this admin page group.
91
+	 */
92
+	protected function _define_page_props()
93
+	{
94
+		$this->_admin_page_title = EVENTS_LABEL;
95
+		$this->_labels           = [
96
+			'buttons'      => [
97
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
98
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
99
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
100
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
101
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
102
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
103
+			],
104
+			'editor_title' => [
105
+				'espresso_events' => esc_html__('Edit Event', 'event_espresso'),
106
+			],
107
+			'publishbox'   => [
108
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
109
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
110
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
111
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
112
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
113
+			],
114
+		];
115
+	}
116
+
117
+
118
+	/**
119
+	 * Sets the page routes property for this admin page group.
120
+	 */
121
+	protected function _set_page_routes()
122
+	{
123
+		$this->_page_routes = [
124
+			'default'                       => [
125
+				'func'       => [$this, '_events_overview_list_table'],
126
+				'capability' => 'ee_read_events',
127
+			],
128
+			'create_new'                    => [
129
+				'func'       => [$this, '_create_new_cpt_item'],
130
+				'capability' => 'ee_edit_events',
131
+			],
132
+			'edit'                          => [
133
+				'func'       => [$this, '_edit_cpt_item'],
134
+				'capability' => 'ee_edit_event',
135
+				'obj_id'     => $this->EVT_ID,
136
+			],
137
+			'copy_event'                    => [
138
+				'func'       => [$this, '_copy_events'],
139
+				'capability' => 'ee_edit_event',
140
+				'obj_id'     => $this->EVT_ID,
141
+				'noheader'   => true,
142
+			],
143
+			'trash_event'                   => [
144
+				'func'       => [$this, '_trash_or_restore_event'],
145
+				'args'       => ['event_status' => 'trash'],
146
+				'capability' => 'ee_delete_event',
147
+				'obj_id'     => $this->EVT_ID,
148
+				'noheader'   => true,
149
+			],
150
+			'trash_events'                  => [
151
+				'func'       => [$this, '_trash_or_restore_events'],
152
+				'args'       => ['event_status' => 'trash'],
153
+				'capability' => 'ee_delete_events',
154
+				'noheader'   => true,
155
+			],
156
+			'restore_event'                 => [
157
+				'func'       => [$this, '_trash_or_restore_event'],
158
+				'args'       => ['event_status' => 'draft'],
159
+				'capability' => 'ee_delete_event',
160
+				'obj_id'     => $this->EVT_ID,
161
+				'noheader'   => true,
162
+			],
163
+			'restore_events'                => [
164
+				'func'       => [$this, '_trash_or_restore_events'],
165
+				'args'       => ['event_status' => 'draft'],
166
+				'capability' => 'ee_delete_events',
167
+				'noheader'   => true,
168
+			],
169
+			'delete_event'                  => [
170
+				'func'       => [$this, '_delete_event'],
171
+				'capability' => 'ee_delete_event',
172
+				'obj_id'     => $this->EVT_ID,
173
+				'noheader'   => true,
174
+			],
175
+			'delete_events'                 => [
176
+				'func'       => [$this, '_delete_events'],
177
+				'capability' => 'ee_delete_events',
178
+				'noheader'   => true,
179
+			],
180
+			'view_report'                   => [
181
+				'func'       => [$this, '_view_report'],
182
+				'capability' => 'ee_edit_events',
183
+			],
184
+			'default_event_settings'        => [
185
+				'func'       => [$this, '_default_event_settings'],
186
+				'capability' => 'manage_options',
187
+			],
188
+			'update_default_event_settings' => [
189
+				'func'       => [$this, '_update_default_event_settings'],
190
+				'capability' => 'manage_options',
191
+				'noheader'   => true,
192
+			],
193
+			'template_settings'             => [
194
+				'func'       => [$this, '_template_settings'],
195
+				'capability' => 'manage_options',
196
+			],
197
+			// event category tab related
198
+			'add_category'                  => [
199
+				'func'       => [$this, '_category_details'],
200
+				'capability' => 'ee_edit_event_category',
201
+				'args'       => ['view' => 'add'],
202
+			],
203
+			'edit_category'                 => [
204
+				'func'       => [$this, '_category_details'],
205
+				'capability' => 'ee_edit_event_category',
206
+				'args'       => ['view' => 'edit'],
207
+			],
208
+			'delete_categories'             => [
209
+				'func'       => [$this, '_delete_categories'],
210
+				'capability' => 'ee_delete_event_category',
211
+				'noheader'   => true,
212
+			],
213
+			'delete_category'               => [
214
+				'func'       => [$this, '_delete_categories'],
215
+				'capability' => 'ee_delete_event_category',
216
+				'noheader'   => true,
217
+			],
218
+			'insert_category'               => [
219
+				'func'       => [$this, '_insert_or_update_category'],
220
+				'args'       => ['new_category' => true],
221
+				'capability' => 'ee_edit_event_category',
222
+				'noheader'   => true,
223
+			],
224
+			'update_category'               => [
225
+				'func'       => [$this, '_insert_or_update_category'],
226
+				'args'       => ['new_category' => false],
227
+				'capability' => 'ee_edit_event_category',
228
+				'noheader'   => true,
229
+			],
230
+			'category_list'                 => [
231
+				'func'       => [$this, '_category_list_table'],
232
+				'capability' => 'ee_manage_event_categories',
233
+			],
234
+			'preview_deletion'              => [
235
+				'func'       => [$this, 'previewDeletion'],
236
+				'capability' => 'ee_delete_events',
237
+			],
238
+			'confirm_deletion'              => [
239
+				'func'       => [$this, 'confirmDeletion'],
240
+				'capability' => 'ee_delete_events',
241
+				'noheader'   => true,
242
+			],
243
+		];
244
+	}
245
+
246
+
247
+	/**
248
+	 * Set the _page_config property for this admin page group.
249
+	 */
250
+	protected function _set_page_config()
251
+	{
252
+		$post_id            = $this->request->getRequestParam('post', 0, DataType::INT);
253
+		$EVT_CAT_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
254
+		$this->_page_config = [
255
+			'default'                => [
256
+				'nav'           => [
257
+					'label' => esc_html__('Overview', 'event_espresso'),
258
+					'icon'  => 'dashicons-list-view',
259
+					'order' => 10,
260
+				],
261
+				'list_table'    => 'Events_Admin_List_Table',
262
+				'help_tabs'     => [
263
+					'events_overview_help_tab'                       => [
264
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
265
+						'filename' => 'events_overview',
266
+					],
267
+					'events_overview_table_column_headings_help_tab' => [
268
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
269
+						'filename' => 'events_overview_table_column_headings',
270
+					],
271
+					'events_overview_filters_help_tab'               => [
272
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
273
+						'filename' => 'events_overview_filters',
274
+					],
275
+					'events_overview_view_help_tab'                  => [
276
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
277
+						'filename' => 'events_overview_views',
278
+					],
279
+					'events_overview_other_help_tab'                 => [
280
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
281
+						'filename' => 'events_overview_other',
282
+					],
283
+				],
284
+				'require_nonce' => false,
285
+			],
286
+			'create_new'             => [
287
+				'nav'           => [
288
+					'label'      => esc_html__('Add New Event', 'event_espresso'),
289
+					'icon'       => 'dashicons-plus-alt',
290
+					'order'      => 15,
291
+					'persistent' => false,
292
+				],
293
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
294
+				'help_tabs'     => [
295
+					'event_editor_help_tab'                            => [
296
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
297
+						'filename' => 'event_editor',
298
+					],
299
+					'event_editor_title_richtexteditor_help_tab'       => [
300
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
301
+						'filename' => 'event_editor_title_richtexteditor',
302
+					],
303
+					'event_editor_venue_details_help_tab'              => [
304
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
305
+						'filename' => 'event_editor_venue_details',
306
+					],
307
+					'event_editor_event_datetimes_help_tab'            => [
308
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
309
+						'filename' => 'event_editor_event_datetimes',
310
+					],
311
+					'event_editor_event_tickets_help_tab'              => [
312
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
313
+						'filename' => 'event_editor_event_tickets',
314
+					],
315
+					'event_editor_event_registration_options_help_tab' => [
316
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
317
+						'filename' => 'event_editor_event_registration_options',
318
+					],
319
+					'event_editor_tags_categories_help_tab'            => [
320
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
321
+						'filename' => 'event_editor_tags_categories',
322
+					],
323
+					'event_editor_questions_registrants_help_tab'      => [
324
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
325
+						'filename' => 'event_editor_questions_registrants',
326
+					],
327
+					'event_editor_save_new_event_help_tab'             => [
328
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
329
+						'filename' => 'event_editor_save_new_event',
330
+					],
331
+					'event_editor_other_help_tab'                      => [
332
+						'title'    => esc_html__('Event Other', 'event_espresso'),
333
+						'filename' => 'event_editor_other',
334
+					],
335
+				],
336
+				'qtips'         => ['EE_Event_Editor_Decaf_Tips'],
337
+				'require_nonce' => false,
338
+			],
339
+			'edit'                   => [
340
+				'nav'           => [
341
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
342
+					'icon'       => 'dashicons-edit',
343
+					'order'      => 15,
344
+					'persistent' => false,
345
+					'url'        => $post_id
346
+						? EE_Admin_Page::add_query_args_and_nonce(
347
+							['post' => $post_id, 'action' => 'edit'],
348
+							$this->_current_page_view_url
349
+						)
350
+						: $this->_admin_base_url,
351
+				],
352
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
353
+				'help_tabs'     => [
354
+					'event_editor_help_tab'                            => [
355
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
356
+						'filename' => 'event_editor',
357
+					],
358
+					'event_editor_title_richtexteditor_help_tab'       => [
359
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
360
+						'filename' => 'event_editor_title_richtexteditor',
361
+					],
362
+					'event_editor_venue_details_help_tab'              => [
363
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
364
+						'filename' => 'event_editor_venue_details',
365
+					],
366
+					'event_editor_event_datetimes_help_tab'            => [
367
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
368
+						'filename' => 'event_editor_event_datetimes',
369
+					],
370
+					'event_editor_event_tickets_help_tab'              => [
371
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
372
+						'filename' => 'event_editor_event_tickets',
373
+					],
374
+					'event_editor_event_registration_options_help_tab' => [
375
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
376
+						'filename' => 'event_editor_event_registration_options',
377
+					],
378
+					'event_editor_tags_categories_help_tab'            => [
379
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
380
+						'filename' => 'event_editor_tags_categories',
381
+					],
382
+					'event_editor_questions_registrants_help_tab'      => [
383
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
384
+						'filename' => 'event_editor_questions_registrants',
385
+					],
386
+					'event_editor_save_new_event_help_tab'             => [
387
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
388
+						'filename' => 'event_editor_save_new_event',
389
+					],
390
+					'event_editor_other_help_tab'                      => [
391
+						'title'    => esc_html__('Event Other', 'event_espresso'),
392
+						'filename' => 'event_editor_other',
393
+					],
394
+				],
395
+				'require_nonce' => false,
396
+			],
397
+			'default_event_settings' => [
398
+				'nav'           => [
399
+					'label' => esc_html__('Default Settings', 'event_espresso'),
400
+					'icon'  => 'dashicons-admin-generic',
401
+					'order' => 40,
402
+				],
403
+				'metaboxes'     => array_merge(['_publish_post_box'], $this->_default_espresso_metaboxes),
404
+				'labels'        => [
405
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
406
+				],
407
+				'help_tabs'     => [
408
+					'default_settings_help_tab'        => [
409
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
410
+						'filename' => 'events_default_settings',
411
+					],
412
+					'default_settings_status_help_tab' => [
413
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
414
+						'filename' => 'events_default_settings_status',
415
+					],
416
+					'default_maximum_tickets_help_tab' => [
417
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
418
+						'filename' => 'events_default_settings_max_tickets',
419
+					],
420
+				],
421
+				'require_nonce' => false,
422
+			],
423
+			// template settings
424
+			'template_settings'      => [
425
+				'nav'           => [
426
+					'label' => esc_html__('Templates', 'event_espresso'),
427
+					'icon'  => 'dashicons-layout',
428
+					'order' => 30,
429
+				],
430
+				'metaboxes'     => $this->_default_espresso_metaboxes,
431
+				'help_tabs'     => [
432
+					'general_settings_templates_help_tab' => [
433
+						'title'    => esc_html__('Templates', 'event_espresso'),
434
+						'filename' => 'general_settings_templates',
435
+					],
436
+				],
437
+				'require_nonce' => false,
438
+			],
439
+			// event category stuff
440
+			'add_category'           => [
441
+				'nav'           => [
442
+					'label'      => esc_html__('Add Category', 'event_espresso'),
443
+					'icon'       => 'dashicons-plus-alt',
444
+					'order'      => 25,
445
+					'persistent' => false,
446
+				],
447
+				'help_tabs'     => [
448
+					'add_category_help_tab' => [
449
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
450
+						'filename' => 'events_add_category',
451
+					],
452
+				],
453
+				'metaboxes'     => ['_publish_post_box'],
454
+				'require_nonce' => false,
455
+			],
456
+			'edit_category'          => [
457
+				'nav'           => [
458
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
459
+					'icon'       => 'dashicons-edit',
460
+					'order'      => 25,
461
+					'persistent' => false,
462
+					'url'        => $EVT_CAT_ID
463
+						? add_query_arg(
464
+							['EVT_CAT_ID' => $EVT_CAT_ID],
465
+							$this->_current_page_view_url
466
+						)
467
+						: $this->_admin_base_url,
468
+				],
469
+				'help_tabs'     => [
470
+					'edit_category_help_tab' => [
471
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
472
+						'filename' => 'events_edit_category',
473
+					],
474
+				],
475
+				'metaboxes'     => ['_publish_post_box'],
476
+				'require_nonce' => false,
477
+			],
478
+			'category_list'          => [
479
+				'nav'           => [
480
+					'label' => esc_html__('Categories', 'event_espresso'),
481
+					'icon'  => 'dashicons-networking',
482
+					'order' => 20,
483
+				],
484
+				'list_table'    => 'Event_Categories_Admin_List_Table',
485
+				'help_tabs'     => [
486
+					'events_categories_help_tab'                       => [
487
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
488
+						'filename' => 'events_categories',
489
+					],
490
+					'events_categories_table_column_headings_help_tab' => [
491
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
492
+						'filename' => 'events_categories_table_column_headings',
493
+					],
494
+					'events_categories_view_help_tab'                  => [
495
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
496
+						'filename' => 'events_categories_views',
497
+					],
498
+					'events_categories_other_help_tab'                 => [
499
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
500
+						'filename' => 'events_categories_other',
501
+					],
502
+				],
503
+				'metaboxes'     => $this->_default_espresso_metaboxes,
504
+				'require_nonce' => false,
505
+			],
506
+			'preview_deletion'       => [
507
+				'nav'           => [
508
+					'label'      => esc_html__('Preview Deletion', 'event_espresso'),
509
+					'icon'       => 'dashicons-remove',
510
+					'order'      => 15,
511
+					'persistent' => false,
512
+					'url'        => '',
513
+				],
514
+				'require_nonce' => false,
515
+			],
516
+		];
517
+	}
518
+
519
+
520
+	/**
521
+	 * Used to register any global screen options if necessary for every route in this admin page group.
522
+	 */
523
+	protected function _add_screen_options()
524
+	{
525
+	}
526
+
527
+
528
+	/**
529
+	 * Implementing the screen options for the 'default' route.
530
+	 *
531
+	 * @throws InvalidArgumentException
532
+	 * @throws InvalidDataTypeException
533
+	 * @throws InvalidInterfaceException
534
+	 */
535
+	protected function _add_screen_options_default()
536
+	{
537
+		$this->_per_page_screen_option();
538
+	}
539
+
540
+
541
+	/**
542
+	 * Implementing screen options for the category list route.
543
+	 *
544
+	 * @throws InvalidArgumentException
545
+	 * @throws InvalidDataTypeException
546
+	 * @throws InvalidInterfaceException
547
+	 */
548
+	protected function _add_screen_options_category_list()
549
+	{
550
+		$page_title              = $this->_admin_page_title;
551
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
552
+		$this->_per_page_screen_option();
553
+		$this->_admin_page_title = $page_title;
554
+	}
555
+
556
+
557
+	/**
558
+	 * Used to register any global feature pointers for the admin page group.
559
+	 */
560
+	protected function _add_feature_pointers()
561
+	{
562
+	}
563
+
564
+
565
+	/**
566
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
567
+	 */
568
+	public function load_scripts_styles()
569
+	{
570
+		wp_register_style(
571
+			'events-admin-css',
572
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
573
+			[],
574
+			EVENT_ESPRESSO_VERSION
575
+		);
576
+		wp_register_style(
577
+			'ee-cat-admin',
578
+			EVENTS_ASSETS_URL . 'ee-cat-admin.css',
579
+			[],
580
+			EVENT_ESPRESSO_VERSION
581
+		);
582
+		wp_enqueue_style('events-admin-css');
583
+		wp_enqueue_style('ee-cat-admin');
584
+		// scripts
585
+		wp_register_script(
586
+			'event_editor_js',
587
+			EVENTS_ASSETS_URL . 'event_editor.js',
588
+			['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
589
+			EVENT_ESPRESSO_VERSION,
590
+			true
591
+		);
592
+	}
593
+
594
+
595
+	/**
596
+	 * Enqueuing scripts and styles specific to this view
597
+	 */
598
+	public function load_scripts_styles_create_new()
599
+	{
600
+		$this->load_scripts_styles_edit();
601
+	}
602
+
603
+
604
+	/**
605
+	 * Enqueuing scripts and styles specific to this view
606
+	 */
607
+	public function load_scripts_styles_edit()
608
+	{
609
+		// styles
610
+		wp_enqueue_style('espresso-ui-theme');
611
+		wp_register_style(
612
+			'event-editor-css',
613
+			EVENTS_ASSETS_URL . 'event-editor.css',
614
+			['ee-admin-css'],
615
+			EVENT_ESPRESSO_VERSION
616
+		);
617
+		wp_enqueue_style('event-editor-css');
618
+		// scripts
619
+		if (! $this->admin_config->useAdvancedEditor()) {
620
+			wp_register_script(
621
+				'event-datetime-metabox',
622
+				EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
623
+				['event_editor_js', 'ee-datepicker'],
624
+				EVENT_ESPRESSO_VERSION
625
+			);
626
+			wp_enqueue_script('event-datetime-metabox');
627
+		}
628
+	}
629
+
630
+
631
+	/**
632
+	 * Populating the _views property for the category list table view.
633
+	 */
634
+	protected function _set_list_table_views_category_list()
635
+	{
636
+		$this->_views = [
637
+			'all' => [
638
+				'slug'        => 'all',
639
+				'label'       => esc_html__('All', 'event_espresso'),
640
+				'count'       => 0,
641
+				'bulk_action' => [
642
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
643
+				],
644
+			],
645
+		];
646
+	}
647
+
648
+
649
+	/**
650
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
651
+	 */
652
+	public function admin_init()
653
+	{
654
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
655
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
656
+			'event_espresso'
657
+		);
658
+	}
659
+
660
+
661
+	/**
662
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
663
+	 * group.
664
+	 */
665
+	public function admin_notices()
666
+	{
667
+	}
668
+
669
+
670
+	/**
671
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
672
+	 * this admin page group.
673
+	 */
674
+	public function admin_footer_scripts()
675
+	{
676
+	}
677
+
678
+
679
+	/**
680
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
681
+	 * warning (via EE_Error::add_error());
682
+	 *
683
+	 * @param EE_Event|null $event Event object
684
+	 * @param string        $req_type
685
+	 * @return void
686
+	 * @throws EE_Error
687
+	 * @throws ReflectionException
688
+	 */
689
+	public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
690
+	{
691
+		// don't need to do this when processing
692
+		if (! empty($req_type)) {
693
+			return;
694
+		}
695
+		// no event?
696
+		if (! $event instanceof EE_Event) {
697
+			$event = $this->_cpt_model_obj;
698
+		}
699
+		// STILL no event?
700
+		if (! $event instanceof EE_Event) {
701
+			return;
702
+		}
703
+		// don't need to keep calling this
704
+		remove_action(
705
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
706
+			[$this, 'verify_event_edit']
707
+		);
708
+		$orig_status = $event->status();
709
+		// first check if event is active.
710
+		if (
711
+			$orig_status === EEM_Event::cancelled
712
+			|| $orig_status === EEM_Event::postponed
713
+			|| $event->is_expired()
714
+			|| $event->is_inactive()
715
+		) {
716
+			return;
717
+		}
718
+		// made it here so it IS active... next check that any of the tickets are sold.
719
+		if ($event->is_sold_out(true)) {
720
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
721
+				EE_Error::add_attention(
722
+					sprintf(
723
+						esc_html__(
724
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
725
+							'event_espresso'
726
+						),
727
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
728
+					)
729
+				);
730
+			}
731
+			return;
732
+		}
733
+		if ($orig_status === EEM_Event::sold_out) {
734
+			EE_Error::add_attention(
735
+				sprintf(
736
+					esc_html__(
737
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
738
+						'event_espresso'
739
+					),
740
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
741
+				)
742
+			);
743
+		}
744
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
745
+		if (! $event->tickets_on_sale()) {
746
+			return;
747
+		}
748
+		// made it here so show warning
749
+		$this->_edit_event_warning();
750
+	}
751
+
752
+
753
+	/**
754
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
755
+	 * When needed, hook this into a EE_Error::add_error() notice.
756
+	 *
757
+	 * @access protected
758
+	 * @return void
759
+	 */
760
+	protected function _edit_event_warning()
761
+	{
762
+		// we don't want to add warnings during these requests
763
+		if ($this->request->getRequestParam('action') === 'editpost') {
764
+			return;
765
+		}
766
+		EE_Error::add_attention(
767
+			sprintf(
768
+				esc_html__(
769
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
770
+					'event_espresso'
771
+				),
772
+				'<a class="espresso-help-tab-lnk ee-help-tab-link">',
773
+				'</a>'
774
+			)
775
+		);
776
+	}
777
+
778
+
779
+	/**
780
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
781
+	 * Otherwise, do the normal logic
782
+	 *
783
+	 * @return void
784
+	 * @throws EE_Error
785
+	 * @throws InvalidArgumentException
786
+	 * @throws InvalidDataTypeException
787
+	 * @throws InvalidInterfaceException
788
+	 * @throws ReflectionException
789
+	 */
790
+	protected function _create_new_cpt_item()
791
+	{
792
+		$has_timezone_string = get_option('timezone_string');
793
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
794
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
795
+			EE_Error::add_attention(
796
+				sprintf(
797
+					esc_html__(
798
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
799
+						'event_espresso'
800
+					),
801
+					'<br>',
802
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
803
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
804
+					. '</select>',
805
+					'<button class="button button--secondary timezone-submit">',
806
+					'</button><span class="spinner"></span>'
807
+				),
808
+				__FILE__,
809
+				__FUNCTION__,
810
+				__LINE__
811
+			);
812
+		}
813
+		parent::_create_new_cpt_item();
814
+	}
815
+
816
+
817
+	/**
818
+	 * Sets the _views property for the default route in this admin page group.
819
+	 */
820
+	protected function _set_list_table_views_default()
821
+	{
822
+		$this->_views = [
823
+			'all'   => [
824
+				'slug'        => 'all',
825
+				'label'       => esc_html__('View All Events', 'event_espresso'),
826
+				'count'       => 0,
827
+				'bulk_action' => [
828
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
829
+				],
830
+			],
831
+			'draft' => [
832
+				'slug'        => 'draft',
833
+				'label'       => esc_html__('Draft', 'event_espresso'),
834
+				'count'       => 0,
835
+				'bulk_action' => [
836
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
837
+				],
838
+			],
839
+		];
840
+		if ($this->capabilities->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
841
+			$this->_views['trash'] = [
842
+				'slug'        => 'trash',
843
+				'label'       => esc_html__('Trash', 'event_espresso'),
844
+				'count'       => 0,
845
+				'bulk_action' => [
846
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
847
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
848
+				],
849
+			];
850
+		}
851
+	}
852
+
853
+
854
+	/**
855
+	 * Provides the legend item array for the default list table view.
856
+	 *
857
+	 * @return array
858
+	 * @throws EE_Error
859
+	 * @throws EE_Error
860
+	 */
861
+	protected function _event_legend_items(): array
862
+	{
863
+		$items    = [
864
+			'view_details'   => [
865
+				'class' => 'dashicons dashicons-visibility',
866
+				'desc'  => esc_html__('View Event', 'event_espresso'),
867
+			],
868
+			'edit_event'     => [
869
+				'class' => 'dashicons dashicons-calendar-alt',
870
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
871
+			],
872
+			'view_attendees' => [
873
+				'class' => 'dashicons dashicons-groups',
874
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
875
+			],
876
+		];
877
+		$items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
878
+		$statuses = [
879
+			'sold_out_status'  => [
880
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
881
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
882
+			],
883
+			'active_status'    => [
884
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
885
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
886
+			],
887
+			'upcoming_status'  => [
888
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
889
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
890
+			],
891
+			'postponed_status' => [
892
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
893
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
894
+			],
895
+			'cancelled_status' => [
896
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
897
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
898
+			],
899
+			'expired_status'   => [
900
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
901
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
902
+			],
903
+			'inactive_status'  => [
904
+				'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
905
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
906
+			],
907
+		];
908
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
909
+		return array_merge($items, $statuses);
910
+	}
911
+
912
+
913
+	/**
914
+	 * @return EEM_Event
915
+	 * @throws EE_Error
916
+	 * @throws InvalidArgumentException
917
+	 * @throws InvalidDataTypeException
918
+	 * @throws InvalidInterfaceException
919
+	 * @throws ReflectionException
920
+	 */
921
+	private function _event_model(): EEM_Event
922
+	{
923
+		if (! $this->_event_model instanceof EEM_Event) {
924
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
925
+		}
926
+		return $this->_event_model;
927
+	}
928
+
929
+
930
+	/**
931
+	 * Adds extra buttons to the WP CPT permalink field row.
932
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
933
+	 *
934
+	 * @param string      $return    the current html
935
+	 * @param int         $id        the post id for the page
936
+	 * @param string|null $new_title What the title is
937
+	 * @param string|null $new_slug  what the slug is
938
+	 * @return string            The new html string for the permalink area
939
+	 * @deprecated 5.0.0.p
940
+	 * @see        TicketSelectorShortcodeButton::addButton
941
+	 */
942
+	public function extra_permalink_field_buttons(
943
+		string $return,
944
+		int $id,
945
+		?string $new_title,
946
+		?string $new_slug
947
+	): string {
948
+		return TicketSelectorShortcodeButton::addButton($return, $id, $new_title, $new_slug);
949
+	}
950
+
951
+
952
+	/**
953
+	 * _events_overview_list_table
954
+	 * This contains the logic for showing the events_overview list
955
+	 *
956
+	 * @access protected
957
+	 * @return void
958
+	 * @throws DomainException
959
+	 * @throws EE_Error
960
+	 * @throws InvalidArgumentException
961
+	 * @throws InvalidDataTypeException
962
+	 * @throws InvalidInterfaceException
963
+	 */
964
+	protected function _events_overview_list_table()
965
+	{
966
+		$after_list_table = [];
967
+		$links_html       = EEH_HTML::div('', '', 'ee-admin-section ee-layout-stack');
968
+		$links_html       .= EEH_HTML::h3(esc_html__('Links', 'event_espresso'));
969
+		$links_html       .= EEH_HTML::div(
970
+			EEH_Template::get_button_or_link(
971
+				get_post_type_archive_link('espresso_events'),
972
+				esc_html__('View Event Archive Page', 'event_espresso'),
973
+				'button button--small button--secondary'
974
+			),
975
+			'',
976
+			'ee-admin-button-row ee-admin-button-row--align-start'
977
+		);
978
+		$links_html       .= EEH_HTML::divx();
979
+
980
+		$after_list_table['view_event_list_button'] = $links_html;
981
+
982
+		$after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
983
+		$this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
984
+				'create_new',
985
+				'add',
986
+				[],
987
+				'add-new-h2'
988
+			);
989
+
990
+		$this->_template_args['after_list_table'] = array_merge(
991
+			(array) $this->_template_args['after_list_table'],
992
+			$after_list_table
993
+		);
994
+		$this->display_admin_list_table_page_with_no_sidebar();
995
+	}
996
+
997
+
998
+	/**
999
+	 * this allows for extra misc actions in the default WP publish box
1000
+	 *
1001
+	 * @return void
1002
+	 * @throws DomainException
1003
+	 * @throws EE_Error
1004
+	 * @throws InvalidArgumentException
1005
+	 * @throws InvalidDataTypeException
1006
+	 * @throws InvalidInterfaceException
1007
+	 * @throws ReflectionException
1008
+	 */
1009
+	public function extra_misc_actions_publish_box()
1010
+	{
1011
+		$this->_generate_publish_box_extra_content();
1012
+	}
1013
+
1014
+
1015
+	/**
1016
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
1017
+	 * saved.
1018
+	 * Typically you would use this to save any additional data.
1019
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
1020
+	 * ALSO very important.  When a post transitions from scheduled to published,
1021
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
1022
+	 * other meta saves. So MAKE sure that you handle this accordingly.
1023
+	 *
1024
+	 * @access protected
1025
+	 * @abstract
1026
+	 * @param string  $post_id The ID of the cpt that was saved (so you can link relationally)
1027
+	 * @param WP_Post $post    The post object of the cpt that was saved.
1028
+	 * @return void
1029
+	 * @throws EE_Error
1030
+	 * @throws InvalidArgumentException
1031
+	 * @throws InvalidDataTypeException
1032
+	 * @throws InvalidInterfaceException
1033
+	 * @throws ReflectionException
1034
+	 */
1035
+	protected function _insert_update_cpt_item($post_id, $post)
1036
+	{
1037
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1038
+			// get out we're not processing an event save.
1039
+			return;
1040
+		}
1041
+		$event_values = [
1042
+			'EVT_member_only'     => $this->request->getRequestParam('member_only', false, DataType::BOOL),
1043
+			'EVT_allow_overflow'  => $this->request->getRequestParam('EVT_allow_overflow', false, DataType::BOOL),
1044
+			'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1045
+		];
1046
+		// check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1047
+		if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
+			$event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1049
+				'display_ticket_selector',
1050
+				false,
1051
+				'bool'
1052
+			);
1053
+			$event_values['EVT_additional_limit']            = min(
1054
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1055
+				$this->request->getRequestParam(
1056
+					'additional_limit',
1057
+					EEM_Event::get_default_additional_limit(),
1058
+					'int'
1059
+				)
1060
+			);
1061
+			$event_values['EVT_default_registration_status'] = $this->request->getRequestParam(
1062
+				'EVT_default_registration_status',
1063
+				EE_Registry::instance()->CFG->registration->default_STS_ID
1064
+			);
1065
+
1066
+			$event_values['EVT_external_URL'] = $this->request->getRequestParam('externalURL');
1067
+			$event_values['EVT_phone']        = $this->request->getRequestParam('event_phone');
1068
+			$event_values['EVT_display_desc'] = $this->request->getRequestParam('display_desc', false, DataType::BOOL);
1069
+		} elseif ($post instanceof WP_Post) {
1070
+			$event_values['EVT_name'] = $post->post_title;
1071
+			$event_values['EVT_desc'] = $post->post_content;
1072
+		}
1073
+		// update event
1074
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1075
+		// get event_object for other metaboxes...
1076
+		// though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id )..
1077
+		// i have to setup where conditions to override the filters in the model
1078
+		// that filter out auto-draft and inherit statuses so we GET the inherit id!
1079
+		/** @var EE_Event $event */
1080
+		$event = $this->_event_model()->get_one(
1081
+			[
1082
+				[
1083
+					$this->_event_model()->primary_key_name() => $post_id,
1084
+					'OR'                                      => [
1085
+						'status'   => $post->post_status,
1086
+						// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1087
+						// but the returned object here has a status of "publish", so use the original post status as well
1088
+						'status*1' => $this->request->getRequestParam('original_post_status'),
1089
+					],
1090
+				],
1091
+			]
1092
+		);
1093
+
1094
+		// the following are default callbacks for event attachment updates
1095
+		// that can be overridden by caffeinated functionality and/or addons.
1096
+		$event_update_callbacks = [];
1097
+		if (! $this->admin_config->useAdvancedEditor()) {
1098
+			$event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1099
+			$event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1100
+		}
1101
+		$event_update_callbacks = apply_filters(
1102
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1103
+			$event_update_callbacks
1104
+		);
1105
+
1106
+		$att_success = true;
1107
+		foreach ($event_update_callbacks as $e_callback) {
1108
+			$_success = is_callable($e_callback)
1109
+				? $e_callback($event, $this->request->requestParams())
1110
+				: false;
1111
+			// if ANY of these updates fail then we want the appropriate global error message
1112
+			$att_success = $_success !== false ? $att_success : false;
1113
+		}
1114
+		// any errors?
1115
+		if ($success && $att_success === false) {
1116
+			EE_Error::add_error(
1117
+				esc_html__(
1118
+					'Event Details saved successfully but something went wrong with saving attachments.',
1119
+					'event_espresso'
1120
+				),
1121
+				__FILE__,
1122
+				__FUNCTION__,
1123
+				__LINE__
1124
+			);
1125
+		} elseif ($success === false) {
1126
+			EE_Error::add_error(
1127
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1128
+				__FILE__,
1129
+				__FUNCTION__,
1130
+				__LINE__
1131
+			);
1132
+		}
1133
+	}
1134
+
1135
+
1136
+	/**
1137
+	 * @param int $post_id
1138
+	 * @param int $revision_id
1139
+	 * @throws EE_Error
1140
+	 * @throws EE_Error
1141
+	 * @throws ReflectionException
1142
+	 * @see parent::restore_item()
1143
+	 */
1144
+	protected function _restore_cpt_item(int $post_id, int $revision_id)
1145
+	{
1146
+		// copy existing event meta to new post
1147
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1148
+		if ($post_evt instanceof EE_Event) {
1149
+			// meta revision restore
1150
+			$post_evt->restore_revision($revision_id);
1151
+			// related objs restore
1152
+			$post_evt->restore_revision($revision_id, ['Venue', 'Datetime', 'Price']);
1153
+		}
1154
+	}
1155
+
1156
+
1157
+	/**
1158
+	 * Attach the venue to the Event
1159
+	 *
1160
+	 * @param EE_Event $event Event Object to add the venue to
1161
+	 * @param array    $data  The request data from the form
1162
+	 * @return bool           Success or fail.
1163
+	 * @throws EE_Error
1164
+	 * @throws ReflectionException
1165
+	 */
1166
+	protected function _default_venue_update(EE_Event $event, array $data): bool
1167
+	{
1168
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1169
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1170
+		$venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1171
+		// very important.  If we don't have a venue name...
1172
+		// then we'll get out because not necessary to create empty venue
1173
+		if (empty($data['venue_title'])) {
1174
+			return false;
1175
+		}
1176
+		$venue_array = [
1177
+			'VNU_wp_user'         => $event->get('EVT_wp_user'),
1178
+			'VNU_name'            => $data['venue_title'],
1179
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1180
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1181
+			'VNU_short_desc'      => ! empty($data['venue_short_description'])
1182
+				? $data['venue_short_description']
1183
+				: null,
1184
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1185
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1186
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1187
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1188
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1189
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1190
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1191
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1192
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1193
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1194
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1195
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1196
+			'status'              => 'publish',
1197
+		];
1198
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1199
+		if (! empty($venue_id)) {
1200
+			$update_where  = [$venue_model->primary_key_name() => $venue_id];
1201
+			$rows_affected = $venue_model->update($venue_array, [$update_where]);
1202
+			// we've gotta make sure that the venue is always attached to a revision..
1203
+			// add_relation_to should take care of making sure that the relation is already present.
1204
+			$event->_add_relation_to($venue_id, 'Venue');
1205
+			return $rows_affected > 0;
1206
+		}
1207
+		// we insert the venue
1208
+		$venue_id = $venue_model->insert($venue_array);
1209
+		$event->_add_relation_to($venue_id, 'Venue');
1210
+		return ! empty($venue_id);
1211
+		// when we have the ancestor come in it's already been handled by the revision save.
1212
+	}
1213
+
1214
+
1215
+	/**
1216
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1217
+	 *
1218
+	 * @param EE_Event $event The Event object we're attaching data to
1219
+	 * @param array    $data  The request data from the form
1220
+	 * @return array
1221
+	 * @throws EE_Error
1222
+	 * @throws ReflectionException
1223
+	 * @throws Exception
1224
+	 */
1225
+	protected function _default_tickets_update(EE_Event $event, array $data): array
1226
+	{
1227
+		if ($this->admin_config->useAdvancedEditor()) {
1228
+			return [];
1229
+		}
1230
+		$datetime       = null;
1231
+		$saved_tickets  = [];
1232
+		$event_timezone = $event->get_timezone();
1233
+		$date_formats   = ['Y-m-d', 'h:i a'];
1234
+		foreach ($data['edit_event_datetimes'] as $row => $datetime_data) {
1235
+			// trim all values to ensure any excess whitespace is removed.
1236
+			$datetime_data                = array_map('trim', $datetime_data);
1237
+			$datetime_data['DTT_EVT_end'] = ! empty($datetime_data['DTT_EVT_end'])
1238
+					? $datetime_data['DTT_EVT_end']
1239
+					: $datetime_data['DTT_EVT_start'];
1240
+			$datetime_values              = [
1241
+				'DTT_ID'        => ! empty($datetime_data['DTT_ID']) ? $datetime_data['DTT_ID'] : null,
1242
+				'DTT_EVT_start' => $datetime_data['DTT_EVT_start'],
1243
+				'DTT_EVT_end'   => $datetime_data['DTT_EVT_end'],
1244
+				'DTT_reg_limit' => empty($datetime_data['DTT_reg_limit']) ? EE_INF : $datetime_data['DTT_reg_limit'],
1245
+				'DTT_order'     => $row,
1246
+			];
1247
+			// if we have an id then let's get existing object first and then set the new values.
1248
+			//  Otherwise we instantiate a new object for save.
1249
+			if (! empty($datetime_data['DTT_ID'])) {
1250
+				$datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
+				if (! $datetime instanceof EE_Datetime) {
1252
+					throw new RuntimeException(
1253
+						sprintf(
1254
+							esc_html__(
1255
+								'Something went wrong! A valid Datetime could not be retrieved from the database using the supplied ID: %1$d',
1256
+								'event_espresso'
1257
+							),
1258
+							$datetime_data['DTT_ID']
1259
+						)
1260
+					);
1261
+				}
1262
+				$datetime->set_date_format($date_formats[0]);
1263
+				$datetime->set_time_format($date_formats[1]);
1264
+				foreach ($datetime_values as $field => $value) {
1265
+					$datetime->set($field, $value);
1266
+				}
1267
+			} else {
1268
+				$datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269
+			}
1270
+			if (! $datetime instanceof EE_Datetime) {
1271
+				throw new RuntimeException(
1272
+					sprintf(
1273
+						esc_html__(
1274
+							'Something went wrong! A valid Datetime could not be generated or retrieved using the supplied data: %1$s',
1275
+							'event_espresso'
1276
+						),
1277
+						print_r($datetime_values, true)
1278
+					)
1279
+				);
1280
+			}
1281
+			// before going any further make sure our dates are setup correctly
1282
+			// so that the end date is always equal or greater than the start date.
1283
+			if ($datetime->get_raw('DTT_EVT_start') > $datetime->get_raw('DTT_EVT_end')) {
1284
+				$datetime->set('DTT_EVT_end', $datetime->get('DTT_EVT_start'));
1285
+				$datetime = EEH_DTT_Helper::date_time_add($datetime, 'DTT_EVT_end', 'days');
1286
+			}
1287
+			$datetime->save();
1288
+			$event->_add_relation_to($datetime, 'Datetime');
1289
+		}
1290
+		// no datetimes get deleted so we don't do any of that logic here.
1291
+		// update tickets next
1292
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : [];
1293
+
1294
+		// set up some default start and end dates in case those are not present in the incoming data
1295
+		$default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
+		$default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1297
+		// use the start date of the first datetime for the end date
1298
+		$first_datetime   = $event->first_datetime();
1299
+		$default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
1300
+
1301
+		// now process the incoming data
1302
+		foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303
+			$update_prices = false;
1304
+			$ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1305
+			// trim inputs to ensure any excess whitespace is removed.
1306
+			$ticket_data   = array_map('trim', $ticket_data);
1307
+			$ticket_values = [
1308
+				'TKT_ID'          => ! empty($ticket_data['TKT_ID']) ? $ticket_data['TKT_ID'] : null,
1309
+				'TTM_ID'          => ! empty($ticket_data['TTM_ID']) ? $ticket_data['TTM_ID'] : 0,
1310
+				'TKT_name'        => ! empty($ticket_data['TKT_name']) ? $ticket_data['TKT_name'] : '',
1311
+				'TKT_description' => ! empty($ticket_data['TKT_description']) ? $ticket_data['TKT_description'] : '',
1312
+				'TKT_start_date'  => ! empty($ticket_data['TKT_start_date'])
1313
+					? $ticket_data['TKT_start_date']
1314
+					: $default_start_date,
1315
+				'TKT_end_date'    => ! empty($ticket_data['TKT_end_date'])
1316
+					? $ticket_data['TKT_end_date']
1317
+					: $default_end_date,
1318
+				'TKT_qty'         => ! empty($ticket_data['TKT_qty'])
1319
+									 || (isset($ticket_data['TKT_qty']) && (int) $ticket_data['TKT_qty'] === 0)
1320
+					? $ticket_data['TKT_qty']
1321
+					: EE_INF,
1322
+				'TKT_uses'        => ! empty($ticket_data['TKT_uses'])
1323
+									 || (isset($ticket_data['TKT_uses']) && (int) $ticket_data['TKT_uses'] === 0)
1324
+					? $ticket_data['TKT_uses']
1325
+					: EE_INF,
1326
+				'TKT_min'         => ! empty($ticket_data['TKT_min']) ? $ticket_data['TKT_min'] : 0,
1327
+				'TKT_max'         => ! empty($ticket_data['TKT_max']) ? $ticket_data['TKT_max'] : EE_INF,
1328
+				'TKT_order'       => $ticket_data['TKT_order'] ?? $row,
1329
+				'TKT_price'       => $ticket_price,
1330
+				'TKT_row'         => $row,
1331
+			];
1332
+			// if this is a default ticket, then we need to set the TKT_ID to 0 and update accordingly,
1333
+			// which means in turn that the prices will become new prices as well.
1334
+			if (isset($ticket_data['TKT_is_default']) && $ticket_data['TKT_is_default']) {
1335
+				$ticket_values['TKT_ID']         = 0;
1336
+				$ticket_values['TKT_is_default'] = 0;
1337
+				$update_prices                   = true;
1338
+			}
1339
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1340
+			// we actually do our saves ahead of adding any relations because its entirely possible that this
1341
+			// ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1342
+			// keep in mind that if the ticket has been sold (and we have changed pricing information),
1343
+			// then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1344
+			if (! empty($ticket_data['TKT_ID'])) {
1345
+				$existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1346
+				if (! $existing_ticket instanceof EE_Ticket) {
1347
+					throw new RuntimeException(
1348
+						sprintf(
1349
+							esc_html__(
1350
+								'Something went wrong! A valid Ticket could not be retrieved from the database using the supplied ID: %1$d',
1351
+								'event_espresso'
1352
+							),
1353
+							$ticket_data['TKT_ID']
1354
+						)
1355
+					);
1356
+				}
1357
+				$ticket_sold = $existing_ticket->count_related(
1358
+						'Registration',
1359
+						[
1360
+							[
1361
+								'STS_ID' => [
1362
+									'NOT IN',
1363
+									[EEM_Registration::status_id_incomplete],
1364
+								],
1365
+							],
1366
+						]
1367
+					) > 0;
1368
+				// let's just check the total price for the existing ticket and determine if it matches the new total price.
1369
+				// if they are different then we create a new ticket (if $ticket_sold)
1370
+				// if they aren't different then we go ahead and modify existing ticket.
1371
+				$create_new_ticket = $ticket_sold
1372
+									 && $ticket_price !== $existing_ticket->price()
1373
+									 && ! $existing_ticket->deleted();
1374
+				$existing_ticket->set_date_format($date_formats[0]);
1375
+				$existing_ticket->set_time_format($date_formats[1]);
1376
+				// set new values
1377
+				foreach ($ticket_values as $field => $value) {
1378
+					if ($field == 'TKT_qty') {
1379
+						$existing_ticket->set_qty($value);
1380
+					} elseif ($field == 'TKT_price') {
1381
+						$existing_ticket->set('TKT_price', $ticket_price);
1382
+					} else {
1383
+						$existing_ticket->set($field, $value);
1384
+					}
1385
+				}
1386
+				$ticket = $existing_ticket;
1387
+				// if $create_new_ticket is false then we can safely update the existing ticket.
1388
+				//  Otherwise we have to create a new ticket.
1389
+				if ($create_new_ticket) {
1390
+					// archive the old ticket first
1391
+					$existing_ticket->set('TKT_deleted', 1);
1392
+					$existing_ticket->save();
1393
+					// make sure this ticket is still recorded in our $saved_tickets
1394
+					// so we don't run it through the regular trash routine.
1395
+					$saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1396
+					// create new ticket that's a copy of the existing except,
1397
+					// (a new id of course and not archived) AND has the new TKT_price associated with it.
1398
+					$new_ticket = clone $existing_ticket;
1399
+					$new_ticket->set('TKT_ID', 0);
1400
+					$new_ticket->set('TKT_deleted', 0);
1401
+					$new_ticket->set('TKT_sold', 0);
1402
+					// now we need to make sure that $new prices are created as well and attached to new ticket.
1403
+					$update_prices = true;
1404
+					$ticket        = $new_ticket;
1405
+				}
1406
+			} else {
1407
+				// no TKT_id so a new ticket
1408
+				$ticket_values['TKT_price'] = $ticket_price;
1409
+				$ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1410
+				$update_prices              = true;
1411
+			}
1412
+			if (! $ticket instanceof EE_Ticket) {
1413
+				throw new RuntimeException(
1414
+					sprintf(
1415
+						esc_html__(
1416
+							'Something went wrong! A valid Ticket could not be generated or retrieved using the supplied data: %1$s',
1417
+							'event_espresso'
1418
+						),
1419
+						print_r($ticket_values, true)
1420
+					)
1421
+				);
1422
+			}
1423
+			// cap ticket qty by datetime reg limits
1424
+			$ticket->set_qty(min($ticket->qty(), $ticket->qty('reg_limit')));
1425
+			// update ticket.
1426
+			$ticket->save();
1427
+			// before going any further make sure our dates are setup correctly
1428
+			// so that the end date is always equal or greater than the start date.
1429
+			if ($ticket->get_raw('TKT_start_date') > $ticket->get_raw('TKT_end_date')) {
1430
+				$ticket->set('TKT_end_date', $ticket->get('TKT_start_date'));
1431
+				$ticket = EEH_DTT_Helper::date_time_add($ticket, 'TKT_end_date', 'days');
1432
+				$ticket->save();
1433
+			}
1434
+			// initially let's add the ticket to the datetime
1435
+			$datetime->_add_relation_to($ticket, 'Ticket');
1436
+			$saved_tickets[ $ticket->ID() ] = $ticket;
1437
+			// add prices to ticket
1438
+			$prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1439
+				? $data['edit_prices'][ $row ]
1440
+				: [];
1441
+			$this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1442
+		}
1443
+		// however now we need to handle permanently deleting tickets via the ui.
1444
+		// Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.
1445
+		// However, it does allow for deleting tickets that have no tickets sold,
1446
+		// in which case we want to get rid of permanently because there is no need to save in db.
1447
+		$old_tickets     = isset($old_tickets[0]) && $old_tickets[0] === '' ? [] : $old_tickets;
1448
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1449
+		foreach ($tickets_removed as $id) {
1450
+			$id = absint($id);
1451
+			// get the ticket for this id
1452
+			$ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1453
+			if (! $ticket_to_remove instanceof EE_Ticket) {
1454
+				continue;
1455
+			}
1456
+			// need to get all the related datetimes on this ticket and remove from every single one of them
1457
+			// (remember this process can ONLY kick off if there are NO tickets sold)
1458
+			$related_datetimes = $ticket_to_remove->get_many_related('Datetime');
1459
+			foreach ($related_datetimes as $related_datetime) {
1460
+				$ticket_to_remove->_remove_relation_to($related_datetime, 'Datetime');
1461
+			}
1462
+			// need to do the same for prices (except these prices can also be deleted because again,
1463
+			// tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1464
+			$ticket_to_remove->delete_related_permanently('Price');
1465
+			// finally let's delete this ticket
1466
+			// (which should not be blocked at this point b/c we've removed all our relationships)
1467
+			$ticket_to_remove->delete_permanently();
1468
+		}
1469
+		return [$datetime, $saved_tickets];
1470
+	}
1471
+
1472
+
1473
+	/**
1474
+	 * This attaches a list of given prices to a ticket.
1475
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices)
1476
+	 * because if there is a change in price information on a ticket, a new ticket is created anyways
1477
+	 * so the archived ticket will retain the old price info and prices are automatically "archived" via the ticket.
1478
+	 *
1479
+	 * @access  private
1480
+	 * @param array     $prices_data Array of prices from the form.
1481
+	 * @param EE_Ticket $ticket      EE_Ticket object that prices are being attached to.
1482
+	 * @param bool      $new_prices  Whether attach existing incoming prices or create new ones.
1483
+	 * @return  void
1484
+	 * @throws EE_Error
1485
+	 * @throws ReflectionException
1486
+	 */
1487
+	private function _add_prices_to_ticket(array $prices_data, EE_Ticket $ticket, bool $new_prices = false)
1488
+	{
1489
+		$timezone = $ticket->get_timezone();
1490
+		foreach ($prices_data as $row => $price_data) {
1491
+			$price_values = [
1492
+				'PRC_ID'         => ! empty($price_data['PRC_ID']) ? $price_data['PRC_ID'] : null,
1493
+				'PRT_ID'         => ! empty($price_data['PRT_ID']) ? $price_data['PRT_ID'] : null,
1494
+				'PRC_amount'     => ! empty($price_data['PRC_amount']) ? $price_data['PRC_amount'] : 0,
1495
+				'PRC_name'       => ! empty($price_data['PRC_name']) ? $price_data['PRC_name'] : '',
1496
+				'PRC_desc'       => ! empty($price_data['PRC_desc']) ? $price_data['PRC_desc'] : '',
1497
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1498
+				'PRC_order'      => $row,
1499
+			];
1500
+			if ($new_prices || empty($price_values['PRC_ID'])) {
1501
+				$price_values['PRC_ID'] = 0;
1502
+				$price                  = EE_Price::new_instance($price_values, $timezone);
1503
+			} else {
1504
+				$price = EEM_Price::instance($timezone)->get_one_by_ID($price_data['PRC_ID']);
1505
+				// update this price with new values
1506
+				foreach ($price_values as $field => $new_price) {
1507
+					$price->set($field, $new_price);
1508
+				}
1509
+			}
1510
+			if (! $price instanceof EE_Price) {
1511
+				throw new RuntimeException(
1512
+					sprintf(
1513
+						esc_html__(
1514
+							'Something went wrong! A valid Price could not be generated or retrieved using the supplied data: %1$s',
1515
+							'event_espresso'
1516
+						),
1517
+						print_r($price_values, true)
1518
+					)
1519
+				);
1520
+			}
1521
+			$price->save();
1522
+			$ticket->_add_relation_to($price, 'Price');
1523
+		}
1524
+	}
1525
+
1526
+
1527
+	/**
1528
+	 * Add in our autosave ajax handlers
1529
+	 */
1530
+	protected function _ee_autosave_create_new()
1531
+	{
1532
+	}
1533
+
1534
+
1535
+	/**
1536
+	 * More autosave handlers.
1537
+	 */
1538
+	protected function _ee_autosave_edit()
1539
+	{
1540
+	}
1541
+
1542
+
1543
+	/**
1544
+	 * @throws EE_Error
1545
+	 * @throws ReflectionException
1546
+	 */
1547
+	private function _generate_publish_box_extra_content()
1548
+	{
1549
+		// load formatter helper
1550
+		// args for getting related registrations
1551
+		$approved_query_args        = [
1552
+			[
1553
+				'REG_deleted' => 0,
1554
+				'STS_ID'      => EEM_Registration::status_id_approved,
1555
+			],
1556
+		];
1557
+		$not_approved_query_args    = [
1558
+			[
1559
+				'REG_deleted' => 0,
1560
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1561
+			],
1562
+		];
1563
+		$pending_payment_query_args = [
1564
+			[
1565
+				'REG_deleted' => 0,
1566
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1567
+			],
1568
+		];
1569
+		// publish box
1570
+		$publish_box_extra_args = [
1571
+			'view_approved_reg_url'        => add_query_arg(
1572
+				[
1573
+					'action'      => 'default',
1574
+					'event_id'    => $this->_cpt_model_obj->ID(),
1575
+					'_reg_status' => EEM_Registration::status_id_approved,
1576
+					'use_filters' => true,
1577
+				],
1578
+				REG_ADMIN_URL
1579
+			),
1580
+			'view_not_approved_reg_url'    => add_query_arg(
1581
+				[
1582
+					'action'      => 'default',
1583
+					'event_id'    => $this->_cpt_model_obj->ID(),
1584
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1585
+					'use_filters' => true,
1586
+				],
1587
+				REG_ADMIN_URL
1588
+			),
1589
+			'view_pending_payment_reg_url' => add_query_arg(
1590
+				[
1591
+					'action'      => 'default',
1592
+					'event_id'    => $this->_cpt_model_obj->ID(),
1593
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1594
+					'use_filters' => true,
1595
+				],
1596
+				REG_ADMIN_URL
1597
+			),
1598
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1599
+				'Registration',
1600
+				$approved_query_args
1601
+			),
1602
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1603
+				'Registration',
1604
+				$not_approved_query_args
1605
+			),
1606
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1607
+				'Registration',
1608
+				$pending_payment_query_args
1609
+			),
1610
+			'misc_pub_section_class'       => apply_filters(
1611
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1612
+				'misc-pub-section'
1613
+			),
1614
+		];
1615
+		ob_start();
1616
+		do_action(
1617
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1618
+			$this->_cpt_model_obj
1619
+		);
1620
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1621
+		// load template
1622
+		EEH_Template::display_template(
1623
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1624
+			$publish_box_extra_args
1625
+		);
1626
+	}
1627
+
1628
+
1629
+	/**
1630
+	 * @return EE_Event
1631
+	 */
1632
+	public function get_event_object()
1633
+	{
1634
+		return $this->_cpt_model_obj;
1635
+	}
1636
+
1637
+
1638
+
1639
+
1640
+	/** METABOXES * */
1641
+	/**
1642
+	 * _register_event_editor_meta_boxes
1643
+	 * add all metaboxes related to the event_editor
1644
+	 *
1645
+	 * @return void
1646
+	 * @throws EE_Error
1647
+	 * @throws ReflectionException
1648
+	 */
1649
+	protected function _register_event_editor_meta_boxes()
1650
+	{
1651
+		$this->verify_cpt_object();
1652
+		$use_advanced_editor = $this->admin_config->useAdvancedEditor();
1653
+		// check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1654
+		if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1655
+			$this->addMetaBox(
1656
+				'espresso_event_editor_event_options',
1657
+				esc_html__('Event Registration Options', 'event_espresso'),
1658
+				[$this, 'registration_options_meta_box'],
1659
+				$this->page_slug,
1660
+				'side'
1661
+			);
1662
+		}
1663
+		if (! $use_advanced_editor) {
1664
+			$this->addMetaBox(
1665
+				'espresso_event_editor_tickets',
1666
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1667
+				[$this, 'ticket_metabox'],
1668
+				$this->page_slug,
1669
+				'normal',
1670
+				'high'
1671
+			);
1672
+		} elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1673
+			add_action(
1674
+				'add_meta_boxes_espresso_events',
1675
+				function () {
1676
+					global $current_screen;
1677
+					remove_meta_box('authordiv', $current_screen, 'normal');
1678
+				},
1679
+				99
1680
+			);
1681
+		}
1682
+		// NOTE: if you're looking for other metaboxes in here,
1683
+		// where a metabox has a related management page in the admin
1684
+		// you will find it setup in the related management page's "_Hooks" file.
1685
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1686
+	}
1687
+
1688
+
1689
+	/**
1690
+	 * @throws DomainException
1691
+	 * @throws EE_Error
1692
+	 * @throws ReflectionException
1693
+	 */
1694
+	public function ticket_metabox()
1695
+	{
1696
+		$existing_datetime_ids = $existing_ticket_ids = [];
1697
+		// defaults for template args
1698
+		$template_args = [
1699
+			'ticket_rows'       => '',
1700
+			'total_ticket_rows' => 1,
1701
+			'trash_icon'        => 'dashicons dashicons-lock',
1702
+			'disabled'          => '',
1703
+		];
1704
+		$event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1705
+		/**
1706
+		 * 1. Start with retrieving Datetimes
1707
+		 * 2. Fore each datetime get related tickets
1708
+		 * 3. For each ticket get related prices
1709
+		 */
1710
+		/** @var EEM_Datetime $datetime_model */
1711
+		$datetime_model = EE_Registry::instance()->load_model('Datetime');
1712
+		/** @var EEM_Ticket $datetime_model */
1713
+		$ticket_model = EE_Registry::instance()->load_model('Ticket');
1714
+		$times        = $datetime_model->get_all_event_dates($event_id);
1715
+		/** @type EE_Datetime $first_datetime */
1716
+		$first_datetime = reset($times);
1717
+		// do we get related tickets?
1718
+		if (
1719
+			$first_datetime instanceof EE_Datetime
1720
+			&& $first_datetime->ID() !== 0
1721
+		) {
1722
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1723
+			$template_args['time']   = $first_datetime;
1724
+			$related_tickets         = $first_datetime->tickets(
1725
+				[
1726
+					['OR' => ['TKT_deleted' => 1, 'TKT_deleted*' => 0]],
1727
+					'default_where_conditions' => 'none',
1728
+				]
1729
+			);
1730
+			if (! empty($related_tickets)) {
1731
+				$template_args['total_ticket_rows'] = count($related_tickets);
1732
+				$row                                = 0;
1733
+				foreach ($related_tickets as $ticket) {
1734
+					$existing_ticket_ids[]        = $ticket->get('TKT_ID');
1735
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1736
+					$row++;
1737
+				}
1738
+			} else {
1739
+				$template_args['total_ticket_rows'] = 1;
1740
+				/** @type EE_Ticket $ticket */
1741
+				$ticket                       = $ticket_model->create_default_object();
1742
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1743
+			}
1744
+		} else {
1745
+			$template_args['time'] = $times[0];
1746
+			/** @type EE_Ticket[] $tickets */
1747
+			$tickets                      = $ticket_model->get_all_default_tickets();
1748
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1749
+			// NOTE: we're just sending the first default row
1750
+			// (decaf can't manage default tickets so this should be sufficient);
1751
+		}
1752
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1753
+			'event_editor_event_datetimes_help_tab'
1754
+		);
1755
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1756
+		$template_args['existing_datetime_ids']    = implode(',', $existing_datetime_ids);
1757
+		$template_args['existing_ticket_ids']      = implode(',', $existing_ticket_ids);
1758
+		$template_args['ticket_js_structure']      = $this->_get_ticket_row(
1759
+			$ticket_model->create_default_object(),
1760
+			true
1761
+		);
1762
+		$template                                  = apply_filters(
1763
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1764
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1765
+		);
1766
+		EEH_Template::display_template($template, $template_args);
1767
+	}
1768
+
1769
+
1770
+	/**
1771
+	 * Setup an individual ticket form for the decaf event editor page
1772
+	 *
1773
+	 * @access private
1774
+	 * @param EE_Ticket $ticket   the ticket object
1775
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1776
+	 * @param int       $row
1777
+	 * @return string generated html for the ticket row.
1778
+	 * @throws EE_Error
1779
+	 * @throws ReflectionException
1780
+	 */
1781
+	private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1782
+	{
1783
+		$template_args = [
1784
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1785
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1786
+				: '',
1787
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1788
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1789
+			'TKT_name'            => $ticket->get('TKT_name'),
1790
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1791
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1792
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1793
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1794
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1795
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1796
+			'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1797
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1798
+				? 'dashicons dashicons-post-trash clickable'
1799
+				: 'dashicons dashicons-lock',
1800
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1801
+				: ' disabled=disabled',
1802
+		];
1803
+		$price         = $ticket->ID() !== 0
1804
+			? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1805
+			: null;
1806
+		$price         = $price instanceof EE_Price
1807
+			? $price
1808
+			: EEM_Price::instance()->create_default_object();
1809
+		$price_args    = [
1810
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1811
+			'PRC_amount'            => $price->get('PRC_amount'),
1812
+			'PRT_ID'                => $price->get('PRT_ID'),
1813
+			'PRC_ID'                => $price->get('PRC_ID'),
1814
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1815
+		];
1816
+		// make sure we have default start and end dates if skeleton
1817
+		// handle rows that should NOT be empty
1818
+		if (empty($template_args['TKT_start_date'])) {
1819
+			// if empty then the start date will be now.
1820
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1821
+		}
1822
+		if (empty($template_args['TKT_end_date'])) {
1823
+			// get the earliest datetime (if present);
1824
+			$earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1825
+				? $this->_cpt_model_obj->get_first_related(
1826
+					'Datetime',
1827
+					['order_by' => ['DTT_EVT_start' => 'ASC']]
1828
+				)
1829
+				: null;
1830
+			$template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1831
+				? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1832
+				: date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1833
+		}
1834
+		$template_args = array_merge($template_args, $price_args);
1835
+		$template      = apply_filters(
1836
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1837
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1838
+			$ticket
1839
+		);
1840
+		return EEH_Template::display_template($template, $template_args, true);
1841
+	}
1842
+
1843
+
1844
+	/**
1845
+	 * @throws EE_Error
1846
+	 * @throws ReflectionException
1847
+	 */
1848
+	public function registration_options_meta_box()
1849
+	{
1850
+		$yes_no_values             = [
1851
+			['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1852
+			['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1853
+		];
1854
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1855
+			[
1856
+				EEM_Registration::status_id_cancelled,
1857
+				EEM_Registration::status_id_declined,
1858
+				EEM_Registration::status_id_incomplete,
1859
+			],
1860
+			true
1861
+		);
1862
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1863
+		$template_args['_event']                          = $this->_cpt_model_obj;
1864
+		$template_args['event']                           = $this->_cpt_model_obj;
1865
+		$template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1866
+		$template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1867
+		$template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1868
+			'default_reg_status',
1869
+			$default_reg_status_values,
1870
+			$this->_cpt_model_obj->default_registration_status(),
1871
+			'',
1872
+			'ee-input-width--reg',
1873
+			false
1874
+		);
1875
+		$template_args['display_description']             = EEH_Form_Fields::select_input(
1876
+			'display_desc',
1877
+			$yes_no_values,
1878
+			$this->_cpt_model_obj->display_description()
1879
+		);
1880
+		$template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1881
+			'display_ticket_selector',
1882
+			$yes_no_values,
1883
+			$this->_cpt_model_obj->display_ticket_selector(),
1884
+			'',
1885
+			'ee-input-width--small',
1886
+			false
1887
+		);
1888
+		$template_args['additional_registration_options'] = apply_filters(
1889
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1890
+			'',
1891
+			$template_args,
1892
+			$yes_no_values,
1893
+			$default_reg_status_values
1894
+		);
1895
+		EEH_Template::display_template(
1896
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1897
+			$template_args
1898
+		);
1899
+	}
1900
+
1901
+
1902
+	/**
1903
+	 * _get_events()
1904
+	 * This method simply returns all the events (for the given _view and paging)
1905
+	 *
1906
+	 * @access public
1907
+	 * @param int  $per_page     count of items per page (20 default);
1908
+	 * @param int  $current_page what is the current page being viewed.
1909
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1910
+	 *                           If FALSE then we return an array of event objects
1911
+	 *                           that match the given _view and paging parameters.
1912
+	 * @return array|int         an array of event objects or a count of them.
1913
+	 * @throws Exception
1914
+	 */
1915
+	public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1916
+	{
1917
+		$EEM_Event   = $this->_event_model();
1918
+		$offset      = ($current_page - 1) * $per_page;
1919
+		$limit       = $count ? null : $offset . ',' . $per_page;
1920
+		$orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1921
+		$order       = $this->request->getRequestParam('order', 'DESC');
1922
+		$month_range = $this->request->getRequestParam('month_range');
1923
+		if ($month_range) {
1924
+			$pieces = explode(' ', $month_range, 3);
1925
+			// simulate the FIRST day of the month, that fixes issues for months like February
1926
+			// where PHP doesn't know what to assume for date.
1927
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1928
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1929
+			$year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1930
+		}
1931
+		$where  = [];
1932
+		$status = $this->request->getRequestParam('status');
1933
+		// determine what post_status our condition will have for the query.
1934
+		switch ($status) {
1935
+			case 'month':
1936
+			case 'today':
1937
+			case null:
1938
+			case 'all':
1939
+				break;
1940
+			case 'draft':
1941
+				$where['status'] = ['IN', ['draft', 'auto-draft']];
1942
+				break;
1943
+			default:
1944
+				$where['status'] = $status;
1945
+		}
1946
+		// categories? The default for all categories is -1
1947
+		$category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1948
+		if ($category !== -1) {
1949
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1950
+			$where['Term_Taxonomy.term_id']  = $category;
1951
+		}
1952
+		// date where conditions
1953
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1954
+		if ($month_range) {
1955
+			$DateTime = new DateTime(
1956
+				$year_r . '-' . $month_r . '-01 00:00:00',
1957
+				new DateTimeZone('UTC')
1958
+			);
1959
+			$start    = $DateTime->getTimestamp();
1960
+			// set the datetime to be the end of the month
1961
+			$DateTime->setDate(
1962
+				$year_r,
1963
+				$month_r,
1964
+				$DateTime->format('t')
1965
+			)->setTime(23, 59, 59);
1966
+			$end                             = $DateTime->getTimestamp();
1967
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1968
+		} elseif ($status === 'today') {
1969
+			$DateTime                        =
1970
+				new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1971
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1972
+			$end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1973
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1974
+		} elseif ($status === 'month') {
1975
+			$now                             = date('Y-m-01');
1976
+			$DateTime                        =
1977
+				new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1978
+			$start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1979
+			$end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1980
+														->setTime(23, 59, 59)
1981
+														->format(implode(' ', $start_formats));
1982
+			$where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1983
+		}
1984
+		if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1985
+			$where['EVT_wp_user'] = get_current_user_id();
1986
+		} else {
1987
+			if (! isset($where['status'])) {
1988
+				if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1989
+					$where['OR'] = [
1990
+						'status*restrict_private' => ['!=', 'private'],
1991
+						'AND'                     => [
1992
+							'status*inclusive' => ['=', 'private'],
1993
+							'EVT_wp_user'      => get_current_user_id(),
1994
+						],
1995
+					];
1996
+				}
1997
+			}
1998
+		}
1999
+		$wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2000
+		if (
2001
+			$wp_user
2002
+			&& $wp_user !== get_current_user_id()
2003
+			&& $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2004
+		) {
2005
+			$where['EVT_wp_user'] = $wp_user;
2006
+		}
2007
+		// search query handling
2008
+		$search_term = $this->request->getRequestParam('s');
2009
+		if ($search_term) {
2010
+			$search_term = '%' . $search_term . '%';
2011
+			$where['OR'] = [
2012
+				'EVT_name'       => ['LIKE', $search_term],
2013
+				'EVT_desc'       => ['LIKE', $search_term],
2014
+				'EVT_short_desc' => ['LIKE', $search_term],
2015
+			];
2016
+		}
2017
+		// filter events by venue.
2018
+		$venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2019
+		if ($venue) {
2020
+			$where['Venue.VNU_ID'] = $venue;
2021
+		}
2022
+		$request_params = $this->request->requestParams();
2023
+		$where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2024
+		$query_params   = apply_filters(
2025
+			'FHEE__Events_Admin_Page__get_events__query_params',
2026
+			[
2027
+				$where,
2028
+				'limit'    => $limit,
2029
+				'order_by' => $orderby,
2030
+				'order'    => $order,
2031
+				'group_by' => 'EVT_ID',
2032
+			],
2033
+			$request_params
2034
+		);
2035
+
2036
+		// let's first check if we have special requests coming in.
2037
+		$active_status = $this->request->getRequestParam('active_status');
2038
+		if ($active_status) {
2039
+			switch ($active_status) {
2040
+				case 'upcoming':
2041
+					return $EEM_Event->get_upcoming_events($query_params, $count);
2042
+				case 'expired':
2043
+					return $EEM_Event->get_expired_events($query_params, $count);
2044
+				case 'active':
2045
+					return $EEM_Event->get_active_events($query_params, $count);
2046
+				case 'inactive':
2047
+					return $EEM_Event->get_inactive_events($query_params, $count);
2048
+			}
2049
+		}
2050
+
2051
+		return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2052
+	}
2053
+
2054
+
2055
+	/**
2056
+	 * handling for WordPress CPT actions (trash, restore, delete)
2057
+	 *
2058
+	 * @param string $post_id
2059
+	 * @throws EE_Error
2060
+	 * @throws ReflectionException
2061
+	 */
2062
+	public function trash_cpt_item($post_id)
2063
+	{
2064
+		$this->request->setRequestParam('EVT_ID', $post_id);
2065
+		$this->_trash_or_restore_event('trash', false);
2066
+	}
2067
+
2068
+
2069
+	/**
2070
+	 * @param string $post_id
2071
+	 * @throws EE_Error
2072
+	 * @throws ReflectionException
2073
+	 */
2074
+	public function restore_cpt_item($post_id)
2075
+	{
2076
+		$this->request->setRequestParam('EVT_ID', $post_id);
2077
+		$this->_trash_or_restore_event('draft', false);
2078
+	}
2079
+
2080
+
2081
+	/**
2082
+	 * @param string $post_id
2083
+	 * @throws EE_Error
2084
+	 * @throws EE_Error
2085
+	 */
2086
+	public function delete_cpt_item($post_id)
2087
+	{
2088
+		throw new EE_Error(
2089
+			esc_html__(
2090
+				'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2091
+				'event_espresso'
2092
+			)
2093
+		);
2094
+		// $this->request->setRequestParam('EVT_ID', $post_id);
2095
+		// $this->_delete_event();
2096
+	}
2097
+
2098
+
2099
+	/**
2100
+	 * _trash_or_restore_event
2101
+	 *
2102
+	 * @access protected
2103
+	 * @param string $event_status
2104
+	 * @param bool   $redirect_after
2105
+	 * @throws EE_Error
2106
+	 * @throws EE_Error
2107
+	 * @throws ReflectionException
2108
+	 */
2109
+	protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2110
+	{
2111
+		// loop thru events
2112
+		if ($this->EVT_ID) {
2113
+			// clean status
2114
+			$event_status = sanitize_key($event_status);
2115
+			// grab status
2116
+			if (! empty($event_status)) {
2117
+				$success = $this->_change_event_status($this->EVT_ID, $event_status);
2118
+			} else {
2119
+				$success = false;
2120
+				$msg     = esc_html__(
2121
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2122
+					'event_espresso'
2123
+				);
2124
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2125
+			}
2126
+		} else {
2127
+			$success = false;
2128
+			$msg     = esc_html__(
2129
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2130
+				'event_espresso'
2131
+			);
2132
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2133
+		}
2134
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2135
+		if ($redirect_after) {
2136
+			$this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2137
+		}
2138
+	}
2139
+
2140
+
2141
+	/**
2142
+	 * _trash_or_restore_events
2143
+	 *
2144
+	 * @access protected
2145
+	 * @param string $event_status
2146
+	 * @return void
2147
+	 * @throws EE_Error
2148
+	 * @throws EE_Error
2149
+	 * @throws ReflectionException
2150
+	 */
2151
+	protected function _trash_or_restore_events(string $event_status = 'trash')
2152
+	{
2153
+		// clean status
2154
+		$event_status = sanitize_key($event_status);
2155
+		// grab status
2156
+		if (! empty($event_status)) {
2157
+			$success = true;
2158
+			// determine the event id and set to array.
2159
+			$EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2160
+			// loop thru events
2161
+			foreach ($EVT_IDs as $EVT_ID) {
2162
+				if ($EVT_ID = absint($EVT_ID)) {
2163
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2164
+					$success = $results !== false ? $success : false;
2165
+				} else {
2166
+					$msg = sprintf(
2167
+						esc_html__(
2168
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2169
+							'event_espresso'
2170
+						),
2171
+						$EVT_ID
2172
+					);
2173
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2174
+					$success = false;
2175
+				}
2176
+			}
2177
+		} else {
2178
+			$success = false;
2179
+			$msg     = esc_html__(
2180
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2181
+				'event_espresso'
2182
+			);
2183
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2184
+		}
2185
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2186
+		$success = $success ? 2 : false;
2187
+		$action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2188
+		$this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2189
+	}
2190
+
2191
+
2192
+	/**
2193
+	 * @param int    $EVT_ID
2194
+	 * @param string $event_status
2195
+	 * @return bool
2196
+	 * @throws EE_Error
2197
+	 * @throws ReflectionException
2198
+	 */
2199
+	private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2200
+	{
2201
+		// grab event id
2202
+		if (! $EVT_ID) {
2203
+			$msg = esc_html__(
2204
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2205
+				'event_espresso'
2206
+			);
2207
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2208
+			return false;
2209
+		}
2210
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2211
+		// clean status
2212
+		$event_status = sanitize_key($event_status);
2213
+		// grab status
2214
+		if (empty($event_status)) {
2215
+			$msg = esc_html__(
2216
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2217
+				'event_espresso'
2218
+			);
2219
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
+			return false;
2221
+		}
2222
+		// was event trashed or restored ?
2223
+		switch ($event_status) {
2224
+			case 'draft':
2225
+				$action = 'restored from the trash';
2226
+				$hook   = 'AHEE_event_restored_from_trash';
2227
+				break;
2228
+			case 'trash':
2229
+				$action = 'moved to the trash';
2230
+				$hook   = 'AHEE_event_moved_to_trash';
2231
+				break;
2232
+			default:
2233
+				$action = 'updated';
2234
+				$hook   = false;
2235
+		}
2236
+		// use class to change status
2237
+		$this->_cpt_model_obj->set_status($event_status);
2238
+		$success = $this->_cpt_model_obj->save();
2239
+		if (! $success) {
2240
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2241
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2242
+			return false;
2243
+		}
2244
+		if ($hook) {
2245
+			do_action($hook);
2246
+			// fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2247
+			// because events side step that and it otherwise won't get called
2248
+			do_action(
2249
+				'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2250
+				$this->_cpt_model_obj,
2251
+				$hook === 'AHEE_event_moved_to_trash',
2252
+				$success
2253
+			);
2254
+		}
2255
+		return true;
2256
+	}
2257
+
2258
+
2259
+	/**
2260
+	 * @param array $event_ids
2261
+	 * @return array
2262
+	 * @since   4.10.23.p
2263
+	 */
2264
+	private function cleanEventIds(array $event_ids): array
2265
+	{
2266
+		return array_map('absint', $event_ids);
2267
+	}
2268
+
2269
+
2270
+	/**
2271
+	 * @return array
2272
+	 * @since   4.10.23.p
2273
+	 */
2274
+	private function getEventIdsFromRequest(): array
2275
+	{
2276
+		if ($this->request->requestParamIsSet('EVT_IDs')) {
2277
+			return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2278
+		} else {
2279
+			return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2280
+		}
2281
+	}
2282
+
2283
+
2284
+	/**
2285
+	 * @param bool $preview_delete
2286
+	 * @throws EE_Error
2287
+	 * @throws ReflectionException
2288
+	 */
2289
+	protected function _delete_event(bool $preview_delete = true)
2290
+	{
2291
+		$this->_delete_events($preview_delete);
2292
+	}
2293
+
2294
+
2295
+	/**
2296
+	 * Gets the tree traversal batch persister.
2297
+	 *
2298
+	 * @return NodeGroupDao
2299
+	 * @throws InvalidArgumentException
2300
+	 * @throws InvalidDataTypeException
2301
+	 * @throws InvalidInterfaceException
2302
+	 * @since 4.10.12.p
2303
+	 */
2304
+	protected function getModelObjNodeGroupPersister(): NodeGroupDao
2305
+	{
2306
+		if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2307
+			$this->model_obj_node_group_persister =
2308
+				$this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2309
+		}
2310
+		return $this->model_obj_node_group_persister;
2311
+	}
2312
+
2313
+
2314
+	/**
2315
+	 * @param bool $preview_delete
2316
+	 * @return void
2317
+	 * @throws EE_Error
2318
+	 * @throws ReflectionException
2319
+	 */
2320
+	protected function _delete_events(bool $preview_delete = true)
2321
+	{
2322
+		$event_ids = $this->getEventIdsFromRequest();
2323
+		if ($preview_delete) {
2324
+			$this->generateDeletionPreview($event_ids);
2325
+		} else {
2326
+			foreach ($event_ids as $event_id) {
2327
+				$event = EEM_Event::instance()->get_one_by_ID($event_id);
2328
+				if ($event instanceof EE_Event) {
2329
+					$event->delete_permanently();
2330
+				}
2331
+			}
2332
+		}
2333
+	}
2334
+
2335
+
2336
+	/**
2337
+	 * @param array $event_ids
2338
+	 */
2339
+	protected function generateDeletionPreview(array $event_ids)
2340
+	{
2341
+		$event_ids = $this->cleanEventIds($event_ids);
2342
+		// Set a code we can use to reference this deletion task in the batch jobs and preview page.
2343
+		$deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2344
+		$return_url        = EE_Admin_Page::add_query_args_and_nonce(
2345
+			[
2346
+				'action'            => 'preview_deletion',
2347
+				'deletion_job_code' => $deletion_job_code,
2348
+			],
2349
+			$this->_admin_base_url
2350
+		);
2351
+		EEH_URL::safeRedirectAndExit(
2352
+			EE_Admin_Page::add_query_args_and_nonce(
2353
+				[
2354
+					'page'              => EED_Batch::PAGE_SLUG,
2355
+					'batch'             => EED_Batch::batch_job,
2356
+					'EVT_IDs'           => $event_ids,
2357
+					'deletion_job_code' => $deletion_job_code,
2358
+					'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2359
+					'return_url'        => urlencode($return_url),
2360
+				],
2361
+				admin_url()
2362
+			)
2363
+		);
2364
+	}
2365
+
2366
+
2367
+	/**
2368
+	 * Checks for a POST submission
2369
+	 *
2370
+	 * @since 4.10.12.p
2371
+	 */
2372
+	protected function confirmDeletion()
2373
+	{
2374
+		$deletion_redirect_logic = $this->getLoader()->getShared(
2375
+			'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2376
+		);
2377
+		$deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2378
+	}
2379
+
2380
+
2381
+	/**
2382
+	 * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2383
+	 *
2384
+	 * @throws EE_Error
2385
+	 * @since 4.10.12.p
2386
+	 */
2387
+	protected function previewDeletion()
2388
+	{
2389
+		$preview_deletion_logic = $this->getLoader()->getShared(
2390
+			'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2391
+		);
2392
+		$this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2393
+		$this->display_admin_page_with_no_sidebar();
2394
+	}
2395
+
2396
+
2397
+	/**
2398
+	 * get total number of events
2399
+	 *
2400
+	 * @access public
2401
+	 * @return int
2402
+	 * @throws EE_Error
2403
+	 * @throws EE_Error
2404
+	 * @throws ReflectionException
2405
+	 */
2406
+	public function total_events(): int
2407
+	{
2408
+		return EEM_Event::instance()->count(
2409
+			['caps' => 'read_admin'],
2410
+			'EVT_ID',
2411
+			true
2412
+		);
2413
+	}
2414
+
2415
+
2416
+	/**
2417
+	 * get total number of draft events
2418
+	 *
2419
+	 * @access public
2420
+	 * @return int
2421
+	 * @throws EE_Error
2422
+	 * @throws EE_Error
2423
+	 * @throws ReflectionException
2424
+	 */
2425
+	public function total_events_draft(): int
2426
+	{
2427
+		return EEM_Event::instance()->count(
2428
+			[
2429
+				['status' => ['IN', ['draft', 'auto-draft']]],
2430
+				'caps' => 'read_admin',
2431
+			],
2432
+			'EVT_ID',
2433
+			true
2434
+		);
2435
+	}
2436
+
2437
+
2438
+	/**
2439
+	 * get total number of trashed events
2440
+	 *
2441
+	 * @access public
2442
+	 * @return int
2443
+	 * @throws EE_Error
2444
+	 * @throws EE_Error
2445
+	 * @throws ReflectionException
2446
+	 */
2447
+	public function total_trashed_events(): int
2448
+	{
2449
+		return EEM_Event::instance()->count(
2450
+			[
2451
+				['status' => 'trash'],
2452
+				'caps' => 'read_admin',
2453
+			],
2454
+			'EVT_ID',
2455
+			true
2456
+		);
2457
+	}
2458
+
2459
+
2460
+	/**
2461
+	 *    _default_event_settings
2462
+	 *    This generates the Default Settings Tab
2463
+	 *
2464
+	 * @return void
2465
+	 * @throws DomainException
2466
+	 * @throws EE_Error
2467
+	 * @throws InvalidArgumentException
2468
+	 * @throws InvalidDataTypeException
2469
+	 * @throws InvalidInterfaceException
2470
+	 * @throws ReflectionException
2471
+	 */
2472
+	protected function _default_event_settings()
2473
+	{
2474
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2475
+		$this->_set_publish_post_box_vars();
2476
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
2477
+			$this->_default_event_settings_form()->get_html(),
2478
+			'',
2479
+			'padding'
2480
+		);
2481
+		$this->display_admin_page_with_sidebar();
2482
+	}
2483
+
2484
+
2485
+	/**
2486
+	 * Return the form for event settings.
2487
+	 *
2488
+	 * @return EE_Form_Section_Proper
2489
+	 * @throws EE_Error
2490
+	 * @throws ReflectionException
2491
+	 */
2492
+	protected function _default_event_settings_form(): EE_Form_Section_Proper
2493
+	{
2494
+		$registration_config              = EE_Registry::instance()->CFG->registration;
2495
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2496
+		// exclude
2497
+			[
2498
+				EEM_Registration::status_id_cancelled,
2499
+				EEM_Registration::status_id_declined,
2500
+				EEM_Registration::status_id_incomplete,
2501
+				EEM_Registration::status_id_wait_list,
2502
+			],
2503
+			true
2504
+		);
2505
+		// setup Advanced Editor ???
2506
+		if (
2507
+			$this->raw_req_action === 'default_event_settings'
2508
+			|| $this->raw_req_action === 'update_default_event_settings'
2509
+		) {
2510
+			$this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2511
+		}
2512
+		return new EE_Form_Section_Proper(
2513
+			[
2514
+				'name'            => 'update_default_event_settings',
2515
+				'html_id'         => 'update_default_event_settings',
2516
+				'html_class'      => 'form-table',
2517
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2518
+				'subsections'     => apply_filters(
2519
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2520
+					[
2521
+						'defaults_section_header' => new EE_Form_Section_HTML(
2522
+							EEH_HTML::h2(
2523
+								esc_html__('Default Settings', 'event_espresso'),
2524
+								'',
2525
+								'ee-admin-settings-hdr'
2526
+							)
2527
+						),
2528
+						'default_reg_status'      => new EE_Select_Input(
2529
+							$registration_stati_for_selection,
2530
+							[
2531
+								'default'         => isset($registration_config->default_STS_ID)
2532
+													 && array_key_exists(
2533
+														 $registration_config->default_STS_ID,
2534
+														 $registration_stati_for_selection
2535
+													 )
2536
+									? sanitize_text_field($registration_config->default_STS_ID)
2537
+									: EEM_Registration::status_id_pending_payment,
2538
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2539
+													 . EEH_Template::get_help_tab_link(
2540
+										'default_settings_status_help_tab'
2541
+									),
2542
+								'html_help_text'  => esc_html__(
2543
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2544
+									'event_espresso'
2545
+								),
2546
+							]
2547
+						),
2548
+						'default_max_tickets'     => new EE_Integer_Input(
2549
+							[
2550
+								'default'         => $registration_config->default_maximum_number_of_tickets
2551
+													 ?? EEM_Event::get_default_additional_limit(),
2552
+								'html_label_text' => esc_html__(
2553
+														 'Default Maximum Tickets Allowed Per Order:',
2554
+														 'event_espresso'
2555
+													 )
2556
+													 . EEH_Template::get_help_tab_link(
2557
+										'default_maximum_tickets_help_tab"'
2558
+									),
2559
+								'html_help_text'  => esc_html__(
2560
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2561
+									'event_espresso'
2562
+								),
2563
+							]
2564
+						),
2565
+					]
2566
+				),
2567
+			]
2568
+		);
2569
+	}
2570
+
2571
+
2572
+	/**
2573
+	 * @return void
2574
+	 * @throws EE_Error
2575
+	 * @throws InvalidArgumentException
2576
+	 * @throws InvalidDataTypeException
2577
+	 * @throws InvalidInterfaceException
2578
+	 * @throws ReflectionException
2579
+	 */
2580
+	protected function _update_default_event_settings()
2581
+	{
2582
+		$form = $this->_default_event_settings_form();
2583
+		if ($form->was_submitted()) {
2584
+			$form->receive_form_submission();
2585
+			if ($form->is_valid()) {
2586
+				$registration_config = EE_Registry::instance()->CFG->registration;
2587
+				$valid_data          = $form->valid_data();
2588
+				if (isset($valid_data['default_reg_status'])) {
2589
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2590
+				}
2591
+				if (isset($valid_data['default_max_tickets'])) {
2592
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2593
+				}
2594
+				do_action(
2595
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2596
+					$valid_data,
2597
+					EE_Registry::instance()->CFG,
2598
+					$this
2599
+				);
2600
+				// update because data was valid!
2601
+				EE_Registry::instance()->CFG->update_espresso_config();
2602
+				EE_Error::overwrite_success();
2603
+				EE_Error::add_success(
2604
+					esc_html__('Default Event Settings were updated', 'event_espresso')
2605
+				);
2606
+			}
2607
+		}
2608
+		$this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2609
+	}
2610
+
2611
+
2612
+	/*************        Templates        *************
1772 2613
      *
1773
-     * @access private
1774
-     * @param EE_Ticket $ticket   the ticket object
1775
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1776
-     * @param int       $row
1777
-     * @return string generated html for the ticket row.
1778
-     * @throws EE_Error
1779
-     * @throws ReflectionException
1780
-     */
1781
-    private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1782
-    {
1783
-        $template_args = [
1784
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1785
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1786
-                : '',
1787
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1788
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1789
-            'TKT_name'            => $ticket->get('TKT_name'),
1790
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1791
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1792
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1793
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1794
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1795
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1796
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1797
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1798
-                ? 'dashicons dashicons-post-trash clickable'
1799
-                : 'dashicons dashicons-lock',
1800
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1801
-                : ' disabled=disabled',
1802
-        ];
1803
-        $price         = $ticket->ID() !== 0
1804
-            ? $ticket->get_first_related('Price', ['default_where_conditions' => 'none'])
1805
-            : null;
1806
-        $price         = $price instanceof EE_Price
1807
-            ? $price
1808
-            : EEM_Price::instance()->create_default_object();
1809
-        $price_args    = [
1810
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1811
-            'PRC_amount'            => $price->get('PRC_amount'),
1812
-            'PRT_ID'                => $price->get('PRT_ID'),
1813
-            'PRC_ID'                => $price->get('PRC_ID'),
1814
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1815
-        ];
1816
-        // make sure we have default start and end dates if skeleton
1817
-        // handle rows that should NOT be empty
1818
-        if (empty($template_args['TKT_start_date'])) {
1819
-            // if empty then the start date will be now.
1820
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1821
-        }
1822
-        if (empty($template_args['TKT_end_date'])) {
1823
-            // get the earliest datetime (if present);
1824
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1825
-                ? $this->_cpt_model_obj->get_first_related(
1826
-                    'Datetime',
1827
-                    ['order_by' => ['DTT_EVT_start' => 'ASC']]
1828
-                )
1829
-                : null;
1830
-            $template_args['TKT_end_date'] = $earliest_datetime instanceof EE_Datetime
1831
-                ? $earliest_datetime->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a')
1832
-                : date('Y-m-d h:i a', mktime(0, 0, 0, date('m'), date('d') + 7, date('Y')));
1833
-        }
1834
-        $template_args = array_merge($template_args, $price_args);
1835
-        $template      = apply_filters(
1836
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1837
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1838
-            $ticket
1839
-        );
1840
-        return EEH_Template::display_template($template, $template_args, true);
1841
-    }
1842
-
1843
-
1844
-    /**
1845
-     * @throws EE_Error
1846
-     * @throws ReflectionException
1847
-     */
1848
-    public function registration_options_meta_box()
1849
-    {
1850
-        $yes_no_values             = [
1851
-            ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1852
-            ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1853
-        ];
1854
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1855
-            [
1856
-                EEM_Registration::status_id_cancelled,
1857
-                EEM_Registration::status_id_declined,
1858
-                EEM_Registration::status_id_incomplete,
1859
-            ],
1860
-            true
1861
-        );
1862
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1863
-        $template_args['_event']                          = $this->_cpt_model_obj;
1864
-        $template_args['event']                           = $this->_cpt_model_obj;
1865
-        $template_args['active_status']                   = $this->_cpt_model_obj->pretty_active_status(false);
1866
-        $template_args['additional_limit']                = $this->_cpt_model_obj->additional_limit();
1867
-        $template_args['default_registration_status']     = EEH_Form_Fields::select_input(
1868
-            'default_reg_status',
1869
-            $default_reg_status_values,
1870
-            $this->_cpt_model_obj->default_registration_status(),
1871
-            '',
1872
-            'ee-input-width--reg',
1873
-            false
1874
-        );
1875
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1876
-            'display_desc',
1877
-            $yes_no_values,
1878
-            $this->_cpt_model_obj->display_description()
1879
-        );
1880
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1881
-            'display_ticket_selector',
1882
-            $yes_no_values,
1883
-            $this->_cpt_model_obj->display_ticket_selector(),
1884
-            '',
1885
-            'ee-input-width--small',
1886
-            false
1887
-        );
1888
-        $template_args['additional_registration_options'] = apply_filters(
1889
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1890
-            '',
1891
-            $template_args,
1892
-            $yes_no_values,
1893
-            $default_reg_status_values
1894
-        );
1895
-        EEH_Template::display_template(
1896
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1897
-            $template_args
1898
-        );
1899
-    }
1900
-
1901
-
1902
-    /**
1903
-     * _get_events()
1904
-     * This method simply returns all the events (for the given _view and paging)
1905
-     *
1906
-     * @access public
1907
-     * @param int  $per_page     count of items per page (20 default);
1908
-     * @param int  $current_page what is the current page being viewed.
1909
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1910
-     *                           If FALSE then we return an array of event objects
1911
-     *                           that match the given _view and paging parameters.
1912
-     * @return array|int         an array of event objects or a count of them.
1913
-     * @throws Exception
1914
-     */
1915
-    public function get_events(int $per_page = 10, int $current_page = 1, bool $count = false)
1916
-    {
1917
-        $EEM_Event   = $this->_event_model();
1918
-        $offset      = ($current_page - 1) * $per_page;
1919
-        $limit       = $count ? null : $offset . ',' . $per_page;
1920
-        $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1921
-        $order       = $this->request->getRequestParam('order', 'DESC');
1922
-        $month_range = $this->request->getRequestParam('month_range');
1923
-        if ($month_range) {
1924
-            $pieces = explode(' ', $month_range, 3);
1925
-            // simulate the FIRST day of the month, that fixes issues for months like February
1926
-            // where PHP doesn't know what to assume for date.
1927
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1928
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1929
-            $year_r  = ! empty($pieces[1]) ? $pieces[1] : '';
1930
-        }
1931
-        $where  = [];
1932
-        $status = $this->request->getRequestParam('status');
1933
-        // determine what post_status our condition will have for the query.
1934
-        switch ($status) {
1935
-            case 'month':
1936
-            case 'today':
1937
-            case null:
1938
-            case 'all':
1939
-                break;
1940
-            case 'draft':
1941
-                $where['status'] = ['IN', ['draft', 'auto-draft']];
1942
-                break;
1943
-            default:
1944
-                $where['status'] = $status;
1945
-        }
1946
-        // categories? The default for all categories is -1
1947
-        $category = $this->request->getRequestParam('EVT_CAT', -1, DataType::INT);
1948
-        if ($category !== -1) {
1949
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1950
-            $where['Term_Taxonomy.term_id']  = $category;
1951
-        }
1952
-        // date where conditions
1953
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1954
-        if ($month_range) {
1955
-            $DateTime = new DateTime(
1956
-                $year_r . '-' . $month_r . '-01 00:00:00',
1957
-                new DateTimeZone('UTC')
1958
-            );
1959
-            $start    = $DateTime->getTimestamp();
1960
-            // set the datetime to be the end of the month
1961
-            $DateTime->setDate(
1962
-                $year_r,
1963
-                $month_r,
1964
-                $DateTime->format('t')
1965
-            )->setTime(23, 59, 59);
1966
-            $end                             = $DateTime->getTimestamp();
1967
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1968
-        } elseif ($status === 'today') {
1969
-            $DateTime                        =
1970
-                new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1971
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1972
-            $end                             = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1973
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1974
-        } elseif ($status === 'month') {
1975
-            $now                             = date('Y-m-01');
1976
-            $DateTime                        =
1977
-                new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1978
-            $start                           = $DateTime->setTime(0, 0)->format(implode(' ', $start_formats));
1979
-            $end                             = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1980
-                                                        ->setTime(23, 59, 59)
1981
-                                                        ->format(implode(' ', $start_formats));
1982
-            $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1983
-        }
1984
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1985
-            $where['EVT_wp_user'] = get_current_user_id();
1986
-        } else {
1987
-            if (! isset($where['status'])) {
1988
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1989
-                    $where['OR'] = [
1990
-                        'status*restrict_private' => ['!=', 'private'],
1991
-                        'AND'                     => [
1992
-                            'status*inclusive' => ['=', 'private'],
1993
-                            'EVT_wp_user'      => get_current_user_id(),
1994
-                        ],
1995
-                    ];
1996
-                }
1997
-            }
1998
-        }
1999
-        $wp_user = $this->request->getRequestParam('EVT_wp_user', 0, DataType::INT);
2000
-        if (
2001
-            $wp_user
2002
-            && $wp_user !== get_current_user_id()
2003
-            && $this->capabilities->current_user_can('ee_read_others_events', 'get_events')
2004
-        ) {
2005
-            $where['EVT_wp_user'] = $wp_user;
2006
-        }
2007
-        // search query handling
2008
-        $search_term = $this->request->getRequestParam('s');
2009
-        if ($search_term) {
2010
-            $search_term = '%' . $search_term . '%';
2011
-            $where['OR'] = [
2012
-                'EVT_name'       => ['LIKE', $search_term],
2013
-                'EVT_desc'       => ['LIKE', $search_term],
2014
-                'EVT_short_desc' => ['LIKE', $search_term],
2015
-            ];
2016
-        }
2017
-        // filter events by venue.
2018
-        $venue = $this->request->getRequestParam('venue', 0, DataType::INT);
2019
-        if ($venue) {
2020
-            $where['Venue.VNU_ID'] = $venue;
2021
-        }
2022
-        $request_params = $this->request->requestParams();
2023
-        $where          = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $request_params);
2024
-        $query_params   = apply_filters(
2025
-            'FHEE__Events_Admin_Page__get_events__query_params',
2026
-            [
2027
-                $where,
2028
-                'limit'    => $limit,
2029
-                'order_by' => $orderby,
2030
-                'order'    => $order,
2031
-                'group_by' => 'EVT_ID',
2032
-            ],
2033
-            $request_params
2034
-        );
2035
-
2036
-        // let's first check if we have special requests coming in.
2037
-        $active_status = $this->request->getRequestParam('active_status');
2038
-        if ($active_status) {
2039
-            switch ($active_status) {
2040
-                case 'upcoming':
2041
-                    return $EEM_Event->get_upcoming_events($query_params, $count);
2042
-                case 'expired':
2043
-                    return $EEM_Event->get_expired_events($query_params, $count);
2044
-                case 'active':
2045
-                    return $EEM_Event->get_active_events($query_params, $count);
2046
-                case 'inactive':
2047
-                    return $EEM_Event->get_inactive_events($query_params, $count);
2048
-            }
2049
-        }
2050
-
2051
-        return $count ? $EEM_Event->count([$where], 'EVT_ID', true) : $EEM_Event->get_all($query_params);
2052
-    }
2053
-
2054
-
2055
-    /**
2056
-     * handling for WordPress CPT actions (trash, restore, delete)
2057
-     *
2058
-     * @param string $post_id
2059
-     * @throws EE_Error
2060
-     * @throws ReflectionException
2061
-     */
2062
-    public function trash_cpt_item($post_id)
2063
-    {
2064
-        $this->request->setRequestParam('EVT_ID', $post_id);
2065
-        $this->_trash_or_restore_event('trash', false);
2066
-    }
2067
-
2068
-
2069
-    /**
2070
-     * @param string $post_id
2071
-     * @throws EE_Error
2072
-     * @throws ReflectionException
2073
-     */
2074
-    public function restore_cpt_item($post_id)
2075
-    {
2076
-        $this->request->setRequestParam('EVT_ID', $post_id);
2077
-        $this->_trash_or_restore_event('draft', false);
2078
-    }
2079
-
2080
-
2081
-    /**
2082
-     * @param string $post_id
2083
-     * @throws EE_Error
2084
-     * @throws EE_Error
2085
-     */
2086
-    public function delete_cpt_item($post_id)
2087
-    {
2088
-        throw new EE_Error(
2089
-            esc_html__(
2090
-                'Please contact Event Espresso support with the details of the steps taken to produce this error.',
2091
-                'event_espresso'
2092
-            )
2093
-        );
2094
-        // $this->request->setRequestParam('EVT_ID', $post_id);
2095
-        // $this->_delete_event();
2096
-    }
2097
-
2098
-
2099
-    /**
2100
-     * _trash_or_restore_event
2101
-     *
2102
-     * @access protected
2103
-     * @param string $event_status
2104
-     * @param bool   $redirect_after
2105
-     * @throws EE_Error
2106
-     * @throws EE_Error
2107
-     * @throws ReflectionException
2108
-     */
2109
-    protected function _trash_or_restore_event(string $event_status = 'trash', bool $redirect_after = true)
2110
-    {
2111
-        // loop thru events
2112
-        if ($this->EVT_ID) {
2113
-            // clean status
2114
-            $event_status = sanitize_key($event_status);
2115
-            // grab status
2116
-            if (! empty($event_status)) {
2117
-                $success = $this->_change_event_status($this->EVT_ID, $event_status);
2118
-            } else {
2119
-                $success = false;
2120
-                $msg     = esc_html__(
2121
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2122
-                    'event_espresso'
2123
-                );
2124
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2125
-            }
2126
-        } else {
2127
-            $success = false;
2128
-            $msg     = esc_html__(
2129
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2130
-                'event_espresso'
2131
-            );
2132
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2133
-        }
2134
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2135
-        if ($redirect_after) {
2136
-            $this->_redirect_after_action($success, 'Event', $action, ['action' => 'default']);
2137
-        }
2138
-    }
2139
-
2140
-
2141
-    /**
2142
-     * _trash_or_restore_events
2143
-     *
2144
-     * @access protected
2145
-     * @param string $event_status
2146
-     * @return void
2147
-     * @throws EE_Error
2148
-     * @throws EE_Error
2149
-     * @throws ReflectionException
2150
-     */
2151
-    protected function _trash_or_restore_events(string $event_status = 'trash')
2152
-    {
2153
-        // clean status
2154
-        $event_status = sanitize_key($event_status);
2155
-        // grab status
2156
-        if (! empty($event_status)) {
2157
-            $success = true;
2158
-            // determine the event id and set to array.
2159
-            $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2160
-            // loop thru events
2161
-            foreach ($EVT_IDs as $EVT_ID) {
2162
-                if ($EVT_ID = absint($EVT_ID)) {
2163
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2164
-                    $success = $results !== false ? $success : false;
2165
-                } else {
2166
-                    $msg = sprintf(
2167
-                        esc_html__(
2168
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2169
-                            'event_espresso'
2170
-                        ),
2171
-                        $EVT_ID
2172
-                    );
2173
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2174
-                    $success = false;
2175
-                }
2176
-            }
2177
-        } else {
2178
-            $success = false;
2179
-            $msg     = esc_html__(
2180
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2181
-                'event_espresso'
2182
-            );
2183
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2184
-        }
2185
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2186
-        $success = $success ? 2 : false;
2187
-        $action  = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2188
-        $this->_redirect_after_action($success, 'Events', $action, ['action' => 'default']);
2189
-    }
2190
-
2191
-
2192
-    /**
2193
-     * @param int    $EVT_ID
2194
-     * @param string $event_status
2195
-     * @return bool
2196
-     * @throws EE_Error
2197
-     * @throws ReflectionException
2198
-     */
2199
-    private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2200
-    {
2201
-        // grab event id
2202
-        if (! $EVT_ID) {
2203
-            $msg = esc_html__(
2204
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2205
-                'event_espresso'
2206
-            );
2207
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2208
-            return false;
2209
-        }
2210
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2211
-        // clean status
2212
-        $event_status = sanitize_key($event_status);
2213
-        // grab status
2214
-        if (empty($event_status)) {
2215
-            $msg = esc_html__(
2216
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2217
-                'event_espresso'
2218
-            );
2219
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2220
-            return false;
2221
-        }
2222
-        // was event trashed or restored ?
2223
-        switch ($event_status) {
2224
-            case 'draft':
2225
-                $action = 'restored from the trash';
2226
-                $hook   = 'AHEE_event_restored_from_trash';
2227
-                break;
2228
-            case 'trash':
2229
-                $action = 'moved to the trash';
2230
-                $hook   = 'AHEE_event_moved_to_trash';
2231
-                break;
2232
-            default:
2233
-                $action = 'updated';
2234
-                $hook   = false;
2235
-        }
2236
-        // use class to change status
2237
-        $this->_cpt_model_obj->set_status($event_status);
2238
-        $success = $this->_cpt_model_obj->save();
2239
-        if (! $success) {
2240
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2241
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2242
-            return false;
2243
-        }
2244
-        if ($hook) {
2245
-            do_action($hook);
2246
-            // fake the action hook in EE_Soft_Delete_Base_Class::delete_or_restore()
2247
-            // because events side step that and it otherwise won't get called
2248
-            do_action(
2249
-                'AHEE__EE_Soft_Delete_Base_Class__delete_or_restore__after',
2250
-                $this->_cpt_model_obj,
2251
-                $hook === 'AHEE_event_moved_to_trash',
2252
-                $success
2253
-            );
2254
-        }
2255
-        return true;
2256
-    }
2257
-
2258
-
2259
-    /**
2260
-     * @param array $event_ids
2261
-     * @return array
2262
-     * @since   4.10.23.p
2263
-     */
2264
-    private function cleanEventIds(array $event_ids): array
2265
-    {
2266
-        return array_map('absint', $event_ids);
2267
-    }
2268
-
2269
-
2270
-    /**
2271
-     * @return array
2272
-     * @since   4.10.23.p
2273
-     */
2274
-    private function getEventIdsFromRequest(): array
2275
-    {
2276
-        if ($this->request->requestParamIsSet('EVT_IDs')) {
2277
-            return $this->request->getRequestParam('EVT_IDs', [], 'int', true);
2278
-        } else {
2279
-            return $this->request->getRequestParam('EVT_ID', [], 'int', true);
2280
-        }
2281
-    }
2282
-
2283
-
2284
-    /**
2285
-     * @param bool $preview_delete
2286
-     * @throws EE_Error
2287
-     * @throws ReflectionException
2288
-     */
2289
-    protected function _delete_event(bool $preview_delete = true)
2290
-    {
2291
-        $this->_delete_events($preview_delete);
2292
-    }
2293
-
2294
-
2295
-    /**
2296
-     * Gets the tree traversal batch persister.
2297
-     *
2298
-     * @return NodeGroupDao
2299
-     * @throws InvalidArgumentException
2300
-     * @throws InvalidDataTypeException
2301
-     * @throws InvalidInterfaceException
2302
-     * @since 4.10.12.p
2303
-     */
2304
-    protected function getModelObjNodeGroupPersister(): NodeGroupDao
2305
-    {
2306
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2307
-            $this->model_obj_node_group_persister =
2308
-                $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2309
-        }
2310
-        return $this->model_obj_node_group_persister;
2311
-    }
2312
-
2313
-
2314
-    /**
2315
-     * @param bool $preview_delete
2316
-     * @return void
2317
-     * @throws EE_Error
2318
-     * @throws ReflectionException
2319
-     */
2320
-    protected function _delete_events(bool $preview_delete = true)
2321
-    {
2322
-        $event_ids = $this->getEventIdsFromRequest();
2323
-        if ($preview_delete) {
2324
-            $this->generateDeletionPreview($event_ids);
2325
-        } else {
2326
-            foreach ($event_ids as $event_id) {
2327
-                $event = EEM_Event::instance()->get_one_by_ID($event_id);
2328
-                if ($event instanceof EE_Event) {
2329
-                    $event->delete_permanently();
2330
-                }
2331
-            }
2332
-        }
2333
-    }
2334
-
2335
-
2336
-    /**
2337
-     * @param array $event_ids
2338
-     */
2339
-    protected function generateDeletionPreview(array $event_ids)
2340
-    {
2341
-        $event_ids = $this->cleanEventIds($event_ids);
2342
-        // Set a code we can use to reference this deletion task in the batch jobs and preview page.
2343
-        $deletion_job_code = $this->getModelObjNodeGroupPersister()->generateGroupCode();
2344
-        $return_url        = EE_Admin_Page::add_query_args_and_nonce(
2345
-            [
2346
-                'action'            => 'preview_deletion',
2347
-                'deletion_job_code' => $deletion_job_code,
2348
-            ],
2349
-            $this->_admin_base_url
2350
-        );
2351
-        EEH_URL::safeRedirectAndExit(
2352
-            EE_Admin_Page::add_query_args_and_nonce(
2353
-                [
2354
-                    'page'              => EED_Batch::PAGE_SLUG,
2355
-                    'batch'             => EED_Batch::batch_job,
2356
-                    'EVT_IDs'           => $event_ids,
2357
-                    'deletion_job_code' => $deletion_job_code,
2358
-                    'job_handler'       => urlencode('EventEspressoBatchRequest\JobHandlers\PreviewEventDeletion'),
2359
-                    'return_url'        => urlencode($return_url),
2360
-                ],
2361
-                admin_url()
2362
-            )
2363
-        );
2364
-    }
2365
-
2366
-
2367
-    /**
2368
-     * Checks for a POST submission
2369
-     *
2370
-     * @since 4.10.12.p
2371
-     */
2372
-    protected function confirmDeletion()
2373
-    {
2374
-        $deletion_redirect_logic = $this->getLoader()->getShared(
2375
-            'EventEspresso\core\domain\services\admin\events\data\ConfirmDeletion'
2376
-        );
2377
-        $deletion_redirect_logic->handle($this->get_request_data(), $this->admin_base_url());
2378
-    }
2379
-
2380
-
2381
-    /**
2382
-     * A page for users to preview what exactly will be deleted, and confirm they want to delete it.
2383
-     *
2384
-     * @throws EE_Error
2385
-     * @since 4.10.12.p
2386
-     */
2387
-    protected function previewDeletion()
2388
-    {
2389
-        $preview_deletion_logic = $this->getLoader()->getShared(
2390
-            'EventEspresso\core\domain\services\admin\events\data\PreviewDeletion'
2391
-        );
2392
-        $this->set_template_args($preview_deletion_logic->handle($this->get_request_data(), $this->admin_base_url()));
2393
-        $this->display_admin_page_with_no_sidebar();
2394
-    }
2395
-
2396
-
2397
-    /**
2398
-     * get total number of events
2399
-     *
2400
-     * @access public
2401
-     * @return int
2402
-     * @throws EE_Error
2403
-     * @throws EE_Error
2404
-     * @throws ReflectionException
2405
-     */
2406
-    public function total_events(): int
2407
-    {
2408
-        return EEM_Event::instance()->count(
2409
-            ['caps' => 'read_admin'],
2410
-            'EVT_ID',
2411
-            true
2412
-        );
2413
-    }
2414
-
2415
-
2416
-    /**
2417
-     * get total number of draft events
2418
-     *
2419
-     * @access public
2420
-     * @return int
2421
-     * @throws EE_Error
2422
-     * @throws EE_Error
2423
-     * @throws ReflectionException
2424
-     */
2425
-    public function total_events_draft(): int
2426
-    {
2427
-        return EEM_Event::instance()->count(
2428
-            [
2429
-                ['status' => ['IN', ['draft', 'auto-draft']]],
2430
-                'caps' => 'read_admin',
2431
-            ],
2432
-            'EVT_ID',
2433
-            true
2434
-        );
2435
-    }
2436
-
2437
-
2438
-    /**
2439
-     * get total number of trashed events
2440
-     *
2441
-     * @access public
2442
-     * @return int
2443
-     * @throws EE_Error
2444
-     * @throws EE_Error
2445
-     * @throws ReflectionException
2446
-     */
2447
-    public function total_trashed_events(): int
2448
-    {
2449
-        return EEM_Event::instance()->count(
2450
-            [
2451
-                ['status' => 'trash'],
2452
-                'caps' => 'read_admin',
2453
-            ],
2454
-            'EVT_ID',
2455
-            true
2456
-        );
2457
-    }
2458
-
2459
-
2460
-    /**
2461
-     *    _default_event_settings
2462
-     *    This generates the Default Settings Tab
2463
-     *
2464
-     * @return void
2465
-     * @throws DomainException
2466
-     * @throws EE_Error
2467
-     * @throws InvalidArgumentException
2468
-     * @throws InvalidDataTypeException
2469
-     * @throws InvalidInterfaceException
2470
-     * @throws ReflectionException
2471
-     */
2472
-    protected function _default_event_settings()
2473
-    {
2474
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2475
-        $this->_set_publish_post_box_vars();
2476
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
2477
-            $this->_default_event_settings_form()->get_html(),
2478
-            '',
2479
-            'padding'
2480
-        );
2481
-        $this->display_admin_page_with_sidebar();
2482
-    }
2483
-
2484
-
2485
-    /**
2486
-     * Return the form for event settings.
2487
-     *
2488
-     * @return EE_Form_Section_Proper
2489
-     * @throws EE_Error
2490
-     * @throws ReflectionException
2491
-     */
2492
-    protected function _default_event_settings_form(): EE_Form_Section_Proper
2493
-    {
2494
-        $registration_config              = EE_Registry::instance()->CFG->registration;
2495
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2496
-        // exclude
2497
-            [
2498
-                EEM_Registration::status_id_cancelled,
2499
-                EEM_Registration::status_id_declined,
2500
-                EEM_Registration::status_id_incomplete,
2501
-                EEM_Registration::status_id_wait_list,
2502
-            ],
2503
-            true
2504
-        );
2505
-        // setup Advanced Editor ???
2506
-        if (
2507
-            $this->raw_req_action === 'default_event_settings'
2508
-            || $this->raw_req_action === 'update_default_event_settings'
2509
-        ) {
2510
-            $this->advanced_editor_admin_form = $this->loader->getShared(AdvancedEditorAdminFormSection::class);
2511
-        }
2512
-        return new EE_Form_Section_Proper(
2513
-            [
2514
-                'name'            => 'update_default_event_settings',
2515
-                'html_id'         => 'update_default_event_settings',
2516
-                'html_class'      => 'form-table',
2517
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2518
-                'subsections'     => apply_filters(
2519
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2520
-                    [
2521
-                        'defaults_section_header' => new EE_Form_Section_HTML(
2522
-                            EEH_HTML::h2(
2523
-                                esc_html__('Default Settings', 'event_espresso'),
2524
-                                '',
2525
-                                'ee-admin-settings-hdr'
2526
-                            )
2527
-                        ),
2528
-                        'default_reg_status'      => new EE_Select_Input(
2529
-                            $registration_stati_for_selection,
2530
-                            [
2531
-                                'default'         => isset($registration_config->default_STS_ID)
2532
-                                                     && array_key_exists(
2533
-                                                         $registration_config->default_STS_ID,
2534
-                                                         $registration_stati_for_selection
2535
-                                                     )
2536
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2537
-                                    : EEM_Registration::status_id_pending_payment,
2538
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2539
-                                                     . EEH_Template::get_help_tab_link(
2540
-                                        'default_settings_status_help_tab'
2541
-                                    ),
2542
-                                'html_help_text'  => esc_html__(
2543
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2544
-                                    'event_espresso'
2545
-                                ),
2546
-                            ]
2547
-                        ),
2548
-                        'default_max_tickets'     => new EE_Integer_Input(
2549
-                            [
2550
-                                'default'         => $registration_config->default_maximum_number_of_tickets
2551
-                                                     ?? EEM_Event::get_default_additional_limit(),
2552
-                                'html_label_text' => esc_html__(
2553
-                                                         'Default Maximum Tickets Allowed Per Order:',
2554
-                                                         'event_espresso'
2555
-                                                     )
2556
-                                                     . EEH_Template::get_help_tab_link(
2557
-                                        'default_maximum_tickets_help_tab"'
2558
-                                    ),
2559
-                                'html_help_text'  => esc_html__(
2560
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2561
-                                    'event_espresso'
2562
-                                ),
2563
-                            ]
2564
-                        ),
2565
-                    ]
2566
-                ),
2567
-            ]
2568
-        );
2569
-    }
2570
-
2571
-
2572
-    /**
2573
-     * @return void
2574
-     * @throws EE_Error
2575
-     * @throws InvalidArgumentException
2576
-     * @throws InvalidDataTypeException
2577
-     * @throws InvalidInterfaceException
2578
-     * @throws ReflectionException
2579
-     */
2580
-    protected function _update_default_event_settings()
2581
-    {
2582
-        $form = $this->_default_event_settings_form();
2583
-        if ($form->was_submitted()) {
2584
-            $form->receive_form_submission();
2585
-            if ($form->is_valid()) {
2586
-                $registration_config = EE_Registry::instance()->CFG->registration;
2587
-                $valid_data          = $form->valid_data();
2588
-                if (isset($valid_data['default_reg_status'])) {
2589
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2590
-                }
2591
-                if (isset($valid_data['default_max_tickets'])) {
2592
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2593
-                }
2594
-                do_action(
2595
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2596
-                    $valid_data,
2597
-                    EE_Registry::instance()->CFG,
2598
-                    $this
2599
-                );
2600
-                // update because data was valid!
2601
-                EE_Registry::instance()->CFG->update_espresso_config();
2602
-                EE_Error::overwrite_success();
2603
-                EE_Error::add_success(
2604
-                    esc_html__('Default Event Settings were updated', 'event_espresso')
2605
-                );
2606
-            }
2607
-        }
2608
-        $this->_redirect_after_action(0, '', '', ['action' => 'default_event_settings'], true);
2609
-    }
2610
-
2611
-
2612
-    /*************        Templates        *************
2613
-     *
2614
-     * @throws EE_Error
2615
-     */
2616
-    protected function _template_settings()
2617
-    {
2618
-        $this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2619
-        $this->_template_args['preview_img']  = '<img src="'
2620
-                                                . EVENTS_ASSETS_URL
2621
-                                                . '/images/'
2622
-                                                . 'caffeinated_template_features.jpg" alt="'
2623
-                                                . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2624
-                                                . '" />';
2625
-        $this->_template_args['preview_text'] = '<strong>'
2626
-                                                . esc_html__(
2627
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2628
-                                                    'event_espresso'
2629
-                                                ) . '</strong>';
2630
-        $this->display_admin_caf_preview_page('template_settings_tab');
2631
-    }
2632
-
2633
-
2634
-    /** Event Category Stuff **/
2635
-    /**
2636
-     * set the _category property with the category object for the loaded page.
2637
-     *
2638
-     * @access private
2639
-     * @return void
2640
-     */
2641
-    private function _set_category_object()
2642
-    {
2643
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2644
-            return;
2645
-        } //already have the category object so get out.
2646
-        // set default category object
2647
-        $this->_set_empty_category_object();
2648
-        // only set if we've got an id
2649
-        $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2650
-        if (! $category_ID) {
2651
-            return;
2652
-        }
2653
-        $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2654
-        if (! empty($term)) {
2655
-            $this->_category->category_name       = $term->name;
2656
-            $this->_category->category_identifier = $term->slug;
2657
-            $this->_category->category_desc       = $term->description;
2658
-            $this->_category->id                  = $term->term_id;
2659
-            $this->_category->parent              = $term->parent;
2660
-        }
2661
-    }
2662
-
2663
-
2664
-    /**
2665
-     * Clears out category properties.
2666
-     */
2667
-    private function _set_empty_category_object()
2668
-    {
2669
-        $this->_category                = new stdClass();
2670
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2671
-        $this->_category->id            = $this->_category->parent = 0;
2672
-    }
2673
-
2674
-
2675
-    /**
2676
-     * @throws DomainException
2677
-     * @throws EE_Error
2678
-     * @throws InvalidArgumentException
2679
-     * @throws InvalidDataTypeException
2680
-     * @throws InvalidInterfaceException
2681
-     */
2682
-    protected function _category_list_table()
2683
-    {
2684
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2685
-        $this->_admin_page_title .= ' ';
2686
-        $this->_admin_page_title .= $this->get_action_link_or_button(
2687
-            'add_category',
2688
-            'add_category',
2689
-            [],
2690
-            'add-new-h2'
2691
-        );
2692
-        $this->display_admin_list_table_page_with_sidebar();
2693
-    }
2694
-
2695
-
2696
-    /**
2697
-     * Output category details view.
2698
-     *
2699
-     * @throws EE_Error
2700
-     * @throws EE_Error
2701
-     */
2702
-    protected function _category_details($view)
2703
-    {
2704
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2705
-        $this->_set_add_edit_form_tags($route);
2706
-        $this->_set_category_object();
2707
-        $id            = ! empty($this->_category->id) ? $this->_category->id : '';
2708
-        $delete_action = 'delete_category';
2709
-        // custom redirect
2710
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2711
-            ['action' => 'category_list'],
2712
-            $this->_admin_base_url
2713
-        );
2714
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2715
-        // take care of contents
2716
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2717
-        $this->display_admin_page_with_sidebar();
2718
-    }
2719
-
2720
-
2721
-    /**
2722
-     * Output category details content.
2723
-     *
2724
-     * @throws DomainException
2725
-     */
2726
-    protected function _category_details_content(): string
2727
-    {
2728
-        $editor_args['category_desc'] = [
2729
-            'type'          => 'wp_editor',
2730
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2731
-            'class'         => 'my_editor_custom',
2732
-            'wpeditor_args' => ['media_buttons' => false],
2733
-        ];
2734
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2735
-        $all_terms                    = get_terms(
2736
-            [EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2737
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2738
-        );
2739
-        // setup category select for term parents.
2740
-        $category_select_values[] = [
2741
-            'text' => esc_html__('No Parent', 'event_espresso'),
2742
-            'id'   => 0,
2743
-        ];
2744
-        foreach ($all_terms as $term) {
2745
-            $category_select_values[] = [
2746
-                'text' => $term->name,
2747
-                'id'   => $term->term_id,
2748
-            ];
2749
-        }
2750
-        $category_select = EEH_Form_Fields::select_input(
2751
-            'category_parent',
2752
-            $category_select_values,
2753
-            $this->_category->parent
2754
-        );
2755
-        $template_args   = [
2756
-            'category'                 => $this->_category,
2757
-            'category_select'          => $category_select,
2758
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2759
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2760
-            'disable'                  => '',
2761
-            'disabled_message'         => false,
2762
-        ];
2763
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2764
-        return EEH_Template::display_template($template, $template_args, true);
2765
-    }
2766
-
2767
-
2768
-    /**
2769
-     * Handles deleting categories.
2770
-     *
2771
-     * @throws EE_Error
2772
-     */
2773
-    protected function _delete_categories()
2774
-    {
2775
-        $category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2776
-        foreach ($category_IDs as $category_ID) {
2777
-            $this->_delete_category($category_ID);
2778
-        }
2779
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2780
-        $query_args = [
2781
-            'action' => 'category_list',
2782
-        ];
2783
-        $this->_redirect_after_action(0, '', '', $query_args);
2784
-    }
2785
-
2786
-
2787
-    /**
2788
-     * Handles deleting specific category.
2789
-     *
2790
-     * @param int $cat_id
2791
-     */
2792
-    protected function _delete_category(int $cat_id)
2793
-    {
2794
-        $cat_id = absint($cat_id);
2795
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2796
-    }
2797
-
2798
-
2799
-    /**
2800
-     * Handles triggering the update or insertion of a new category.
2801
-     *
2802
-     * @param bool $new_category true means we're triggering the insert of a new category.
2803
-     * @throws EE_Error
2804
-     * @throws EE_Error
2805
-     */
2806
-    protected function _insert_or_update_category(bool $new_category)
2807
-    {
2808
-        $cat_id  = $this->_insert_category($new_category);
2809
-        $success = 0; // we already have a success message so lets not send another.
2810
-        if ($cat_id) {
2811
-            $query_args = [
2812
-                'action'     => 'edit_category',
2813
-                'EVT_CAT_ID' => $cat_id,
2814
-            ];
2815
-        } else {
2816
-            $query_args = ['action' => 'add_category'];
2817
-        }
2818
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2819
-    }
2820
-
2821
-
2822
-    /**
2823
-     * Inserts or updates category
2824
-     *
2825
-     * @param bool $new_category (true indicates we're updating a category).
2826
-     * @return bool|mixed|string
2827
-     */
2828
-    private function _insert_category(bool $new_category)
2829
-    {
2830
-        $category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2831
-        $category_name       = $this->request->getRequestParam('category_name', '');
2832
-        $category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2833
-        $category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2834
-        $category_identifier = $this->request->getRequestParam('category_identifier', '');
2835
-
2836
-        if (empty($category_name)) {
2837
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2838
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2839
-            return 0;
2840
-        }
2841
-        $term_args = [
2842
-            'name'        => $category_name,
2843
-            'description' => $category_desc,
2844
-            'parent'      => $category_parent,
2845
-        ];
2846
-        // was the category_identifier input disabled?
2847
-        if ($category_identifier) {
2848
-            $term_args['slug'] = $category_identifier;
2849
-        }
2850
-        $insert_ids = $new_category
2851
-            ? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2852
-            : wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2853
-
2854
-        if ($insert_ids instanceof WP_Error) {
2855
-            EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2856
-            return 0;
2857
-        }
2858
-        $category_ID = $insert_ids['term_id'] ?? 0;
2859
-        if (! $category_ID) {
2860
-            EE_Error::add_error(
2861
-                esc_html__(
2862
-                    'An error occurred and the category has not been saved to the database.',
2863
-                    'event_espresso'
2864
-                ),
2865
-                __FILE__,
2866
-                __FUNCTION__,
2867
-                __LINE__
2868
-            );
2869
-            return 0;
2870
-        }
2871
-        EE_Error::add_success(
2872
-            sprintf(
2873
-                esc_html__('The category %s was successfully saved', 'event_espresso'),
2874
-                $category_name
2875
-            )
2876
-        );
2877
-        return $category_ID;
2878
-    }
2879
-
2880
-
2881
-    /**
2882
-     * Gets categories or count of categories matching the arguments in the request.
2883
-     *
2884
-     * @param int  $per_page
2885
-     * @param int  $current_page
2886
-     * @param bool $count
2887
-     * @return EE_Term_Taxonomy[]|int
2888
-     * @throws EE_Error
2889
-     * @throws ReflectionException
2890
-     */
2891
-    public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2892
-    {
2893
-        // testing term stuff
2894
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2895
-        $order       = $this->request->getRequestParam('order', 'DESC');
2896
-        $limit       = ($current_page - 1) * $per_page;
2897
-        $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2898
-        $search_term = $this->request->getRequestParam('s');
2899
-        if ($search_term) {
2900
-            $search_term = '%' . $search_term . '%';
2901
-            $where['OR'] = [
2902
-                'Term.name'   => ['LIKE', $search_term],
2903
-                'description' => ['LIKE', $search_term],
2904
-            ];
2905
-        }
2906
-        $query_params = [
2907
-            $where,
2908
-            'order_by'   => [$orderby => $order],
2909
-            'limit'      => $limit . ',' . $per_page,
2910
-            'force_join' => ['Term'],
2911
-        ];
2912
-        return $count
2913
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2914
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2915
-    }
2916
-
2917
-    /* end category stuff */
2918
-
2919
-
2920
-    /**************/
2921
-
2922
-
2923
-    /**
2924
-     * Callback for the `ee_save_timezone_setting` ajax action.
2925
-     *
2926
-     * @throws EE_Error
2927
-     * @throws InvalidArgumentException
2928
-     * @throws InvalidDataTypeException
2929
-     * @throws InvalidInterfaceException
2930
-     */
2931
-    public function saveTimezoneString()
2932
-    {
2933
-        $timezone_string = $this->request->getRequestParam('timezone_selected');
2934
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2935
-            EE_Error::add_error(
2936
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2937
-                __FILE__,
2938
-                __FUNCTION__,
2939
-                __LINE__
2940
-            );
2941
-            $this->_template_args['error'] = true;
2942
-            $this->_return_json();
2943
-        }
2944
-
2945
-        update_option('timezone_string', $timezone_string);
2946
-        EE_Error::add_success(
2947
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2948
-        );
2949
-        $this->_template_args['success'] = true;
2950
-        $this->_return_json(true, ['action' => 'create_new']);
2951
-    }
2952
-
2953
-
2954
-    /**
2955 2614
      * @throws EE_Error
2956
-     * @deprecated 4.10.25.p
2957 2615
      */
2958
-    public function save_timezonestring_setting()
2959
-    {
2960
-        $this->saveTimezoneString();
2961
-    }
2616
+	protected function _template_settings()
2617
+	{
2618
+		$this->_admin_page_title              = esc_html__('Template Settings (Preview)', 'event_espresso');
2619
+		$this->_template_args['preview_img']  = '<img src="'
2620
+												. EVENTS_ASSETS_URL
2621
+												. '/images/'
2622
+												. 'caffeinated_template_features.jpg" alt="'
2623
+												. esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2624
+												. '" />';
2625
+		$this->_template_args['preview_text'] = '<strong>'
2626
+												. esc_html__(
2627
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2628
+													'event_espresso'
2629
+												) . '</strong>';
2630
+		$this->display_admin_caf_preview_page('template_settings_tab');
2631
+	}
2632
+
2633
+
2634
+	/** Event Category Stuff **/
2635
+	/**
2636
+	 * set the _category property with the category object for the loaded page.
2637
+	 *
2638
+	 * @access private
2639
+	 * @return void
2640
+	 */
2641
+	private function _set_category_object()
2642
+	{
2643
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2644
+			return;
2645
+		} //already have the category object so get out.
2646
+		// set default category object
2647
+		$this->_set_empty_category_object();
2648
+		// only set if we've got an id
2649
+		$category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2650
+		if (! $category_ID) {
2651
+			return;
2652
+		}
2653
+		$term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2654
+		if (! empty($term)) {
2655
+			$this->_category->category_name       = $term->name;
2656
+			$this->_category->category_identifier = $term->slug;
2657
+			$this->_category->category_desc       = $term->description;
2658
+			$this->_category->id                  = $term->term_id;
2659
+			$this->_category->parent              = $term->parent;
2660
+		}
2661
+	}
2662
+
2663
+
2664
+	/**
2665
+	 * Clears out category properties.
2666
+	 */
2667
+	private function _set_empty_category_object()
2668
+	{
2669
+		$this->_category                = new stdClass();
2670
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2671
+		$this->_category->id            = $this->_category->parent = 0;
2672
+	}
2673
+
2674
+
2675
+	/**
2676
+	 * @throws DomainException
2677
+	 * @throws EE_Error
2678
+	 * @throws InvalidArgumentException
2679
+	 * @throws InvalidDataTypeException
2680
+	 * @throws InvalidInterfaceException
2681
+	 */
2682
+	protected function _category_list_table()
2683
+	{
2684
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2685
+		$this->_admin_page_title .= ' ';
2686
+		$this->_admin_page_title .= $this->get_action_link_or_button(
2687
+			'add_category',
2688
+			'add_category',
2689
+			[],
2690
+			'add-new-h2'
2691
+		);
2692
+		$this->display_admin_list_table_page_with_sidebar();
2693
+	}
2694
+
2695
+
2696
+	/**
2697
+	 * Output category details view.
2698
+	 *
2699
+	 * @throws EE_Error
2700
+	 * @throws EE_Error
2701
+	 */
2702
+	protected function _category_details($view)
2703
+	{
2704
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2705
+		$this->_set_add_edit_form_tags($route);
2706
+		$this->_set_category_object();
2707
+		$id            = ! empty($this->_category->id) ? $this->_category->id : '';
2708
+		$delete_action = 'delete_category';
2709
+		// custom redirect
2710
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2711
+			['action' => 'category_list'],
2712
+			$this->_admin_base_url
2713
+		);
2714
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2715
+		// take care of contents
2716
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2717
+		$this->display_admin_page_with_sidebar();
2718
+	}
2719
+
2720
+
2721
+	/**
2722
+	 * Output category details content.
2723
+	 *
2724
+	 * @throws DomainException
2725
+	 */
2726
+	protected function _category_details_content(): string
2727
+	{
2728
+		$editor_args['category_desc'] = [
2729
+			'type'          => 'wp_editor',
2730
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2731
+			'class'         => 'my_editor_custom',
2732
+			'wpeditor_args' => ['media_buttons' => false],
2733
+		];
2734
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
2735
+		$all_terms                    = get_terms(
2736
+			[EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY],
2737
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
2738
+		);
2739
+		// setup category select for term parents.
2740
+		$category_select_values[] = [
2741
+			'text' => esc_html__('No Parent', 'event_espresso'),
2742
+			'id'   => 0,
2743
+		];
2744
+		foreach ($all_terms as $term) {
2745
+			$category_select_values[] = [
2746
+				'text' => $term->name,
2747
+				'id'   => $term->term_id,
2748
+			];
2749
+		}
2750
+		$category_select = EEH_Form_Fields::select_input(
2751
+			'category_parent',
2752
+			$category_select_values,
2753
+			$this->_category->parent
2754
+		);
2755
+		$template_args   = [
2756
+			'category'                 => $this->_category,
2757
+			'category_select'          => $category_select,
2758
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2759
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2760
+			'disable'                  => '',
2761
+			'disabled_message'         => false,
2762
+		];
2763
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2764
+		return EEH_Template::display_template($template, $template_args, true);
2765
+	}
2766
+
2767
+
2768
+	/**
2769
+	 * Handles deleting categories.
2770
+	 *
2771
+	 * @throws EE_Error
2772
+	 */
2773
+	protected function _delete_categories()
2774
+	{
2775
+		$category_IDs = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int', true);
2776
+		foreach ($category_IDs as $category_ID) {
2777
+			$this->_delete_category($category_ID);
2778
+		}
2779
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2780
+		$query_args = [
2781
+			'action' => 'category_list',
2782
+		];
2783
+		$this->_redirect_after_action(0, '', '', $query_args);
2784
+	}
2785
+
2786
+
2787
+	/**
2788
+	 * Handles deleting specific category.
2789
+	 *
2790
+	 * @param int $cat_id
2791
+	 */
2792
+	protected function _delete_category(int $cat_id)
2793
+	{
2794
+		$cat_id = absint($cat_id);
2795
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2796
+	}
2797
+
2798
+
2799
+	/**
2800
+	 * Handles triggering the update or insertion of a new category.
2801
+	 *
2802
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2803
+	 * @throws EE_Error
2804
+	 * @throws EE_Error
2805
+	 */
2806
+	protected function _insert_or_update_category(bool $new_category)
2807
+	{
2808
+		$cat_id  = $this->_insert_category($new_category);
2809
+		$success = 0; // we already have a success message so lets not send another.
2810
+		if ($cat_id) {
2811
+			$query_args = [
2812
+				'action'     => 'edit_category',
2813
+				'EVT_CAT_ID' => $cat_id,
2814
+			];
2815
+		} else {
2816
+			$query_args = ['action' => 'add_category'];
2817
+		}
2818
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2819
+	}
2820
+
2821
+
2822
+	/**
2823
+	 * Inserts or updates category
2824
+	 *
2825
+	 * @param bool $new_category (true indicates we're updating a category).
2826
+	 * @return bool|mixed|string
2827
+	 */
2828
+	private function _insert_category(bool $new_category)
2829
+	{
2830
+		$category_ID         = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2831
+		$category_name       = $this->request->getRequestParam('category_name', '');
2832
+		$category_desc       = $this->request->getRequestParam('category_desc', '', DataType::HTML);
2833
+		$category_parent     = $this->request->getRequestParam('category_parent', 0, DataType::INT);
2834
+		$category_identifier = $this->request->getRequestParam('category_identifier', '');
2835
+
2836
+		if (empty($category_name)) {
2837
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2838
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2839
+			return 0;
2840
+		}
2841
+		$term_args = [
2842
+			'name'        => $category_name,
2843
+			'description' => $category_desc,
2844
+			'parent'      => $category_parent,
2845
+		];
2846
+		// was the category_identifier input disabled?
2847
+		if ($category_identifier) {
2848
+			$term_args['slug'] = $category_identifier;
2849
+		}
2850
+		$insert_ids = $new_category
2851
+			? wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2852
+			: wp_update_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2853
+
2854
+		if ($insert_ids instanceof WP_Error) {
2855
+			EE_Error::add_error($insert_ids->get_error_message(), __FILE__, __FUNCTION__, __LINE__);
2856
+			return 0;
2857
+		}
2858
+		$category_ID = $insert_ids['term_id'] ?? 0;
2859
+		if (! $category_ID) {
2860
+			EE_Error::add_error(
2861
+				esc_html__(
2862
+					'An error occurred and the category has not been saved to the database.',
2863
+					'event_espresso'
2864
+				),
2865
+				__FILE__,
2866
+				__FUNCTION__,
2867
+				__LINE__
2868
+			);
2869
+			return 0;
2870
+		}
2871
+		EE_Error::add_success(
2872
+			sprintf(
2873
+				esc_html__('The category %s was successfully saved', 'event_espresso'),
2874
+				$category_name
2875
+			)
2876
+		);
2877
+		return $category_ID;
2878
+	}
2879
+
2880
+
2881
+	/**
2882
+	 * Gets categories or count of categories matching the arguments in the request.
2883
+	 *
2884
+	 * @param int  $per_page
2885
+	 * @param int  $current_page
2886
+	 * @param bool $count
2887
+	 * @return EE_Term_Taxonomy[]|int
2888
+	 * @throws EE_Error
2889
+	 * @throws ReflectionException
2890
+	 */
2891
+	public function get_categories(int $per_page = 10, int $current_page = 1, bool $count = false)
2892
+	{
2893
+		// testing term stuff
2894
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
2895
+		$order       = $this->request->getRequestParam('order', 'DESC');
2896
+		$limit       = ($current_page - 1) * $per_page;
2897
+		$where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2898
+		$search_term = $this->request->getRequestParam('s');
2899
+		if ($search_term) {
2900
+			$search_term = '%' . $search_term . '%';
2901
+			$where['OR'] = [
2902
+				'Term.name'   => ['LIKE', $search_term],
2903
+				'description' => ['LIKE', $search_term],
2904
+			];
2905
+		}
2906
+		$query_params = [
2907
+			$where,
2908
+			'order_by'   => [$orderby => $order],
2909
+			'limit'      => $limit . ',' . $per_page,
2910
+			'force_join' => ['Term'],
2911
+		];
2912
+		return $count
2913
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2914
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2915
+	}
2916
+
2917
+	/* end category stuff */
2918
+
2919
+
2920
+	/**************/
2921
+
2922
+
2923
+	/**
2924
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2925
+	 *
2926
+	 * @throws EE_Error
2927
+	 * @throws InvalidArgumentException
2928
+	 * @throws InvalidDataTypeException
2929
+	 * @throws InvalidInterfaceException
2930
+	 */
2931
+	public function saveTimezoneString()
2932
+	{
2933
+		$timezone_string = $this->request->getRequestParam('timezone_selected');
2934
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2935
+			EE_Error::add_error(
2936
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2937
+				__FILE__,
2938
+				__FUNCTION__,
2939
+				__LINE__
2940
+			);
2941
+			$this->_template_args['error'] = true;
2942
+			$this->_return_json();
2943
+		}
2944
+
2945
+		update_option('timezone_string', $timezone_string);
2946
+		EE_Error::add_success(
2947
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2948
+		);
2949
+		$this->_template_args['success'] = true;
2950
+		$this->_return_json(true, ['action' => 'create_new']);
2951
+	}
2952
+
2953
+
2954
+	/**
2955
+	 * @throws EE_Error
2956
+	 * @deprecated 4.10.25.p
2957
+	 */
2958
+	public function save_timezonestring_setting()
2959
+	{
2960
+		$this->saveTimezoneString();
2961
+	}
2962 2962
 }
Please login to merge, or discard this patch.
Spacing   +85 added lines, -85 removed lines patch added patch discarded remove patch
@@ -569,13 +569,13 @@  discard block
 block discarded – undo
569 569
     {
570 570
         wp_register_style(
571 571
             'events-admin-css',
572
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
572
+            EVENTS_ASSETS_URL.'events-admin-page.css',
573 573
             [],
574 574
             EVENT_ESPRESSO_VERSION
575 575
         );
576 576
         wp_register_style(
577 577
             'ee-cat-admin',
578
-            EVENTS_ASSETS_URL . 'ee-cat-admin.css',
578
+            EVENTS_ASSETS_URL.'ee-cat-admin.css',
579 579
             [],
580 580
             EVENT_ESPRESSO_VERSION
581 581
         );
@@ -584,7 +584,7 @@  discard block
 block discarded – undo
584 584
         // scripts
585 585
         wp_register_script(
586 586
             'event_editor_js',
587
-            EVENTS_ASSETS_URL . 'event_editor.js',
587
+            EVENTS_ASSETS_URL.'event_editor.js',
588 588
             ['ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'],
589 589
             EVENT_ESPRESSO_VERSION,
590 590
             true
@@ -610,16 +610,16 @@  discard block
 block discarded – undo
610 610
         wp_enqueue_style('espresso-ui-theme');
611 611
         wp_register_style(
612 612
             'event-editor-css',
613
-            EVENTS_ASSETS_URL . 'event-editor.css',
613
+            EVENTS_ASSETS_URL.'event-editor.css',
614 614
             ['ee-admin-css'],
615 615
             EVENT_ESPRESSO_VERSION
616 616
         );
617 617
         wp_enqueue_style('event-editor-css');
618 618
         // scripts
619
-        if (! $this->admin_config->useAdvancedEditor()) {
619
+        if ( ! $this->admin_config->useAdvancedEditor()) {
620 620
             wp_register_script(
621 621
                 'event-datetime-metabox',
622
-                EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
622
+                EVENTS_ASSETS_URL.'event-datetime-metabox.js',
623 623
                 ['event_editor_js', 'ee-datepicker'],
624 624
                 EVENT_ESPRESSO_VERSION
625 625
             );
@@ -689,15 +689,15 @@  discard block
 block discarded – undo
689 689
     public function verify_event_edit(?EE_Base_Class $event = null, string $req_type = '')
690 690
     {
691 691
         // don't need to do this when processing
692
-        if (! empty($req_type)) {
692
+        if ( ! empty($req_type)) {
693 693
             return;
694 694
         }
695 695
         // no event?
696
-        if (! $event instanceof EE_Event) {
696
+        if ( ! $event instanceof EE_Event) {
697 697
             $event = $this->_cpt_model_obj;
698 698
         }
699 699
         // STILL no event?
700
-        if (! $event instanceof EE_Event) {
700
+        if ( ! $event instanceof EE_Event) {
701 701
             return;
702 702
         }
703 703
         // don't need to keep calling this
@@ -742,7 +742,7 @@  discard block
 block discarded – undo
742 742
             );
743 743
         }
744 744
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
745
-        if (! $event->tickets_on_sale()) {
745
+        if ( ! $event->tickets_on_sale()) {
746 746
             return;
747 747
         }
748 748
         // made it here so show warning
@@ -791,7 +791,7 @@  discard block
 block discarded – undo
791 791
     {
792 792
         $has_timezone_string = get_option('timezone_string');
793 793
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
794
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
794
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists([])) {
795 795
             EE_Error::add_attention(
796 796
                 sprintf(
797 797
                     esc_html__(
@@ -860,7 +860,7 @@  discard block
 block discarded – undo
860 860
      */
861 861
     protected function _event_legend_items(): array
862 862
     {
863
-        $items    = [
863
+        $items = [
864 864
             'view_details'   => [
865 865
                 'class' => 'dashicons dashicons-visibility',
866 866
                 'desc'  => esc_html__('View Event', 'event_espresso'),
@@ -877,31 +877,31 @@  discard block
 block discarded – undo
877 877
         $items    = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
878 878
         $statuses = [
879 879
             'sold_out_status'  => [
880
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::sold_out,
880
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::sold_out,
881 881
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
882 882
             ],
883 883
             'active_status'    => [
884
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::active,
884
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::active,
885 885
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
886 886
             ],
887 887
             'upcoming_status'  => [
888
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::upcoming,
888
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::upcoming,
889 889
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
890 890
             ],
891 891
             'postponed_status' => [
892
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::postponed,
892
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::postponed,
893 893
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
894 894
             ],
895 895
             'cancelled_status' => [
896
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::cancelled,
896
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::cancelled,
897 897
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
898 898
             ],
899 899
             'expired_status'   => [
900
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::expired,
900
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::expired,
901 901
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
902 902
             ],
903 903
             'inactive_status'  => [
904
-                'class' => 'ee-status-legend ee-status-bg--' . EE_Datetime::inactive,
904
+                'class' => 'ee-status-legend ee-status-bg--'.EE_Datetime::inactive,
905 905
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
906 906
             ],
907 907
         ];
@@ -920,7 +920,7 @@  discard block
 block discarded – undo
920 920
      */
921 921
     private function _event_model(): EEM_Event
922 922
     {
923
-        if (! $this->_event_model instanceof EEM_Event) {
923
+        if ( ! $this->_event_model instanceof EEM_Event) {
924 924
             $this->_event_model = EE_Registry::instance()->load_model('Event');
925 925
         }
926 926
         return $this->_event_model;
@@ -975,12 +975,12 @@  discard block
 block discarded – undo
975 975
             '',
976 976
             'ee-admin-button-row ee-admin-button-row--align-start'
977 977
         );
978
-        $links_html       .= EEH_HTML::divx();
978
+        $links_html .= EEH_HTML::divx();
979 979
 
980 980
         $after_list_table['view_event_list_button'] = $links_html;
981 981
 
982 982
         $after_list_table['legend'] = $this->_display_legend($this->_event_legend_items());
983
-        $this->_admin_page_title    .= ' ' . $this->get_action_link_or_button(
983
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
984 984
                 'create_new',
985 985
                 'add',
986 986
                 [],
@@ -1044,13 +1044,13 @@  discard block
 block discarded – undo
1044 1044
             'EVT_timezone_string' => $this->request->getRequestParam('timezone_string'),
1045 1045
         ];
1046 1046
         // check if the new EDTR reg options meta box is being used, and if so, don't run updates for legacy version
1047
-        if (! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
-            $event_values['EVT_display_ticket_selector']     = $this->request->getRequestParam(
1047
+        if ( ! $this->admin_config->useAdvancedEditor() || ! $this->feature->allowed('use_reg_options_meta_box')) {
1048
+            $event_values['EVT_display_ticket_selector'] = $this->request->getRequestParam(
1049 1049
                 'display_ticket_selector',
1050 1050
                 false,
1051 1051
                 'bool'
1052 1052
             );
1053
-            $event_values['EVT_additional_limit']            = min(
1053
+            $event_values['EVT_additional_limit'] = min(
1054 1054
                 apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1055 1055
                 $this->request->getRequestParam(
1056 1056
                     'additional_limit',
@@ -1094,7 +1094,7 @@  discard block
 block discarded – undo
1094 1094
         // the following are default callbacks for event attachment updates
1095 1095
         // that can be overridden by caffeinated functionality and/or addons.
1096 1096
         $event_update_callbacks = [];
1097
-        if (! $this->admin_config->useAdvancedEditor()) {
1097
+        if ( ! $this->admin_config->useAdvancedEditor()) {
1098 1098
             $event_update_callbacks['_default_venue_update']   = [$this, '_default_venue_update'];
1099 1099
             $event_update_callbacks['_default_tickets_update'] = [$this, '_default_tickets_update'];
1100 1100
         }
@@ -1165,7 +1165,7 @@  discard block
 block discarded – undo
1165 1165
      */
1166 1166
     protected function _default_venue_update(EE_Event $event, array $data): bool
1167 1167
     {
1168
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1168
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1169 1169
         $venue_model = EE_Registry::instance()->load_model('Venue');
1170 1170
         $venue_id    = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1171 1171
         // very important.  If we don't have a venue name...
@@ -1196,7 +1196,7 @@  discard block
 block discarded – undo
1196 1196
             'status'              => 'publish',
1197 1197
         ];
1198 1198
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1199
-        if (! empty($venue_id)) {
1199
+        if ( ! empty($venue_id)) {
1200 1200
             $update_where  = [$venue_model->primary_key_name() => $venue_id];
1201 1201
             $rows_affected = $venue_model->update($venue_array, [$update_where]);
1202 1202
             // we've gotta make sure that the venue is always attached to a revision..
@@ -1246,9 +1246,9 @@  discard block
 block discarded – undo
1246 1246
             ];
1247 1247
             // if we have an id then let's get existing object first and then set the new values.
1248 1248
             //  Otherwise we instantiate a new object for save.
1249
-            if (! empty($datetime_data['DTT_ID'])) {
1249
+            if ( ! empty($datetime_data['DTT_ID'])) {
1250 1250
                 $datetime = EEM_Datetime::instance($event_timezone)->get_one_by_ID($datetime_data['DTT_ID']);
1251
-                if (! $datetime instanceof EE_Datetime) {
1251
+                if ( ! $datetime instanceof EE_Datetime) {
1252 1252
                     throw new RuntimeException(
1253 1253
                         sprintf(
1254 1254
                             esc_html__(
@@ -1267,7 +1267,7 @@  discard block
 block discarded – undo
1267 1267
             } else {
1268 1268
                 $datetime = EE_Datetime::new_instance($datetime_values, $event_timezone, $date_formats);
1269 1269
             }
1270
-            if (! $datetime instanceof EE_Datetime) {
1270
+            if ( ! $datetime instanceof EE_Datetime) {
1271 1271
                 throw new RuntimeException(
1272 1272
                     sprintf(
1273 1273
                         esc_html__(
@@ -1293,7 +1293,7 @@  discard block
 block discarded – undo
1293 1293
 
1294 1294
         // set up some default start and end dates in case those are not present in the incoming data
1295 1295
         $default_start_date = new DateTime('now', new DateTimeZone($event->get_timezone()));
1296
-        $default_start_date = $default_start_date->format($date_formats[0] . ' ' . $date_formats[1]);
1296
+        $default_start_date = $default_start_date->format($date_formats[0].' '.$date_formats[1]);
1297 1297
         // use the start date of the first datetime for the end date
1298 1298
         $first_datetime   = $event->first_datetime();
1299 1299
         $default_end_date = $first_datetime->start_date_and_time($date_formats[0], $date_formats[1]);
@@ -1301,7 +1301,7 @@  discard block
 block discarded – undo
1301 1301
         // now process the incoming data
1302 1302
         foreach ($data['edit_tickets'] as $row => $ticket_data) {
1303 1303
             $update_prices = false;
1304
-            $ticket_price  = $data['edit_prices'][ $row ][1]['PRC_amount'] ?? 0;
1304
+            $ticket_price  = $data['edit_prices'][$row][1]['PRC_amount'] ?? 0;
1305 1305
             // trim inputs to ensure any excess whitespace is removed.
1306 1306
             $ticket_data   = array_map('trim', $ticket_data);
1307 1307
             $ticket_values = [
@@ -1341,9 +1341,9 @@  discard block
 block discarded – undo
1341 1341
             // ticket didn't get removed or added to any datetime in the session but DID have it's items modified.
1342 1342
             // keep in mind that if the ticket has been sold (and we have changed pricing information),
1343 1343
             // then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1344
-            if (! empty($ticket_data['TKT_ID'])) {
1344
+            if ( ! empty($ticket_data['TKT_ID'])) {
1345 1345
                 $existing_ticket = EEM_Ticket::instance($event_timezone)->get_one_by_ID($ticket_data['TKT_ID']);
1346
-                if (! $existing_ticket instanceof EE_Ticket) {
1346
+                if ( ! $existing_ticket instanceof EE_Ticket) {
1347 1347
                     throw new RuntimeException(
1348 1348
                         sprintf(
1349 1349
                             esc_html__(
@@ -1392,7 +1392,7 @@  discard block
 block discarded – undo
1392 1392
                     $existing_ticket->save();
1393 1393
                     // make sure this ticket is still recorded in our $saved_tickets
1394 1394
                     // so we don't run it through the regular trash routine.
1395
-                    $saved_tickets[ $existing_ticket->ID() ] = $existing_ticket;
1395
+                    $saved_tickets[$existing_ticket->ID()] = $existing_ticket;
1396 1396
                     // create new ticket that's a copy of the existing except,
1397 1397
                     // (a new id of course and not archived) AND has the new TKT_price associated with it.
1398 1398
                     $new_ticket = clone $existing_ticket;
@@ -1409,7 +1409,7 @@  discard block
 block discarded – undo
1409 1409
                 $ticket                     = EE_Ticket::new_instance($ticket_values, $event_timezone, $date_formats);
1410 1410
                 $update_prices              = true;
1411 1411
             }
1412
-            if (! $ticket instanceof EE_Ticket) {
1412
+            if ( ! $ticket instanceof EE_Ticket) {
1413 1413
                 throw new RuntimeException(
1414 1414
                     sprintf(
1415 1415
                         esc_html__(
@@ -1433,10 +1433,10 @@  discard block
 block discarded – undo
1433 1433
             }
1434 1434
             // initially let's add the ticket to the datetime
1435 1435
             $datetime->_add_relation_to($ticket, 'Ticket');
1436
-            $saved_tickets[ $ticket->ID() ] = $ticket;
1436
+            $saved_tickets[$ticket->ID()] = $ticket;
1437 1437
             // add prices to ticket
1438
-            $prices_data = isset($data['edit_prices'][ $row ]) && is_array($data['edit_prices'][ $row ])
1439
-                ? $data['edit_prices'][ $row ]
1438
+            $prices_data = isset($data['edit_prices'][$row]) && is_array($data['edit_prices'][$row])
1439
+                ? $data['edit_prices'][$row]
1440 1440
                 : [];
1441 1441
             $this->_add_prices_to_ticket($prices_data, $ticket, $update_prices);
1442 1442
         }
@@ -1450,7 +1450,7 @@  discard block
 block discarded – undo
1450 1450
             $id = absint($id);
1451 1451
             // get the ticket for this id
1452 1452
             $ticket_to_remove = EEM_Ticket::instance()->get_one_by_ID($id);
1453
-            if (! $ticket_to_remove instanceof EE_Ticket) {
1453
+            if ( ! $ticket_to_remove instanceof EE_Ticket) {
1454 1454
                 continue;
1455 1455
             }
1456 1456
             // need to get all the related datetimes on this ticket and remove from every single one of them
@@ -1507,7 +1507,7 @@  discard block
 block discarded – undo
1507 1507
                     $price->set($field, $new_price);
1508 1508
                 }
1509 1509
             }
1510
-            if (! $price instanceof EE_Price) {
1510
+            if ( ! $price instanceof EE_Price) {
1511 1511
                 throw new RuntimeException(
1512 1512
                     sprintf(
1513 1513
                         esc_html__(
@@ -1548,13 +1548,13 @@  discard block
 block discarded – undo
1548 1548
     {
1549 1549
         // load formatter helper
1550 1550
         // args for getting related registrations
1551
-        $approved_query_args        = [
1551
+        $approved_query_args = [
1552 1552
             [
1553 1553
                 'REG_deleted' => 0,
1554 1554
                 'STS_ID'      => EEM_Registration::status_id_approved,
1555 1555
             ],
1556 1556
         ];
1557
-        $not_approved_query_args    = [
1557
+        $not_approved_query_args = [
1558 1558
             [
1559 1559
                 'REG_deleted' => 0,
1560 1560
                 'STS_ID'      => EEM_Registration::status_id_not_approved,
@@ -1620,7 +1620,7 @@  discard block
 block discarded – undo
1620 1620
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1621 1621
         // load template
1622 1622
         EEH_Template::display_template(
1623
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1623
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1624 1624
             $publish_box_extra_args
1625 1625
         );
1626 1626
     }
@@ -1651,7 +1651,7 @@  discard block
 block discarded – undo
1651 1651
         $this->verify_cpt_object();
1652 1652
         $use_advanced_editor = $this->admin_config->useAdvancedEditor();
1653 1653
         // check if the new EDTR reg options meta box is being used, and if so, don't load the legacy version
1654
-        if (! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1654
+        if ( ! $use_advanced_editor || ! $this->feature->allowed('use_reg_options_meta_box')) {
1655 1655
             $this->addMetaBox(
1656 1656
                 'espresso_event_editor_event_options',
1657 1657
                 esc_html__('Event Registration Options', 'event_espresso'),
@@ -1660,7 +1660,7 @@  discard block
 block discarded – undo
1660 1660
                 'side'
1661 1661
             );
1662 1662
         }
1663
-        if (! $use_advanced_editor) {
1663
+        if ( ! $use_advanced_editor) {
1664 1664
             $this->addMetaBox(
1665 1665
                 'espresso_event_editor_tickets',
1666 1666
                 esc_html__('Event Datetime & Ticket', 'event_espresso'),
@@ -1672,7 +1672,7 @@  discard block
 block discarded – undo
1672 1672
         } elseif ($this->feature->allowed('use_reg_options_meta_box')) {
1673 1673
             add_action(
1674 1674
                 'add_meta_boxes_espresso_events',
1675
-                function () {
1675
+                function() {
1676 1676
                     global $current_screen;
1677 1677
                     remove_meta_box('authordiv', $current_screen, 'normal');
1678 1678
                 },
@@ -1701,7 +1701,7 @@  discard block
 block discarded – undo
1701 1701
             'trash_icon'        => 'dashicons dashicons-lock',
1702 1702
             'disabled'          => '',
1703 1703
         ];
1704
-        $event_id      = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1704
+        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1705 1705
         /**
1706 1706
          * 1. Start with retrieving Datetimes
1707 1707
          * 2. Fore each datetime get related tickets
@@ -1727,24 +1727,24 @@  discard block
 block discarded – undo
1727 1727
                     'default_where_conditions' => 'none',
1728 1728
                 ]
1729 1729
             );
1730
-            if (! empty($related_tickets)) {
1730
+            if ( ! empty($related_tickets)) {
1731 1731
                 $template_args['total_ticket_rows'] = count($related_tickets);
1732 1732
                 $row                                = 0;
1733 1733
                 foreach ($related_tickets as $ticket) {
1734
-                    $existing_ticket_ids[]        = $ticket->get('TKT_ID');
1734
+                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1735 1735
                     $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1736 1736
                     $row++;
1737 1737
                 }
1738 1738
             } else {
1739 1739
                 $template_args['total_ticket_rows'] = 1;
1740 1740
                 /** @type EE_Ticket $ticket */
1741
-                $ticket                       = $ticket_model->create_default_object();
1741
+                $ticket = $ticket_model->create_default_object();
1742 1742
                 $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1743 1743
             }
1744 1744
         } else {
1745 1745
             $template_args['time'] = $times[0];
1746 1746
             /** @type EE_Ticket[] $tickets */
1747
-            $tickets                      = $ticket_model->get_all_default_tickets();
1747
+            $tickets = $ticket_model->get_all_default_tickets();
1748 1748
             $template_args['ticket_rows'] .= $this->_get_ticket_row($tickets[1]);
1749 1749
             // NOTE: we're just sending the first default row
1750 1750
             // (decaf can't manage default tickets so this should be sufficient);
@@ -1759,9 +1759,9 @@  discard block
 block discarded – undo
1759 1759
             $ticket_model->create_default_object(),
1760 1760
             true
1761 1761
         );
1762
-        $template                                  = apply_filters(
1762
+        $template = apply_filters(
1763 1763
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1764
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1764
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1765 1765
         );
1766 1766
         EEH_Template::display_template($template, $template_args);
1767 1767
     }
@@ -1781,7 +1781,7 @@  discard block
 block discarded – undo
1781 1781
     private function _get_ticket_row(EE_Ticket $ticket, bool $skeleton = false, int $row = 0): string
1782 1782
     {
1783 1783
         $template_args = [
1784
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1784
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1785 1785
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1786 1786
                 : '',
1787 1787
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1793,11 +1793,11 @@  discard block
 block discarded – undo
1793 1793
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1794 1794
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1795 1795
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1796
-            'trash_icon'          => ($skeleton || (! $ticket->get('TKT_deleted')))
1797
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1796
+            'trash_icon'          => ($skeleton || ( ! $ticket->get('TKT_deleted')))
1797
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1798 1798
                 ? 'dashicons dashicons-post-trash clickable'
1799 1799
                 : 'dashicons dashicons-lock',
1800
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1800
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1801 1801
                 : ' disabled=disabled',
1802 1802
         ];
1803 1803
         $price         = $ticket->ID() !== 0
@@ -1821,7 +1821,7 @@  discard block
 block discarded – undo
1821 1821
         }
1822 1822
         if (empty($template_args['TKT_end_date'])) {
1823 1823
             // get the earliest datetime (if present);
1824
-            $earliest_datetime             = $this->_cpt_model_obj->ID() > 0
1824
+            $earliest_datetime = $this->_cpt_model_obj->ID() > 0
1825 1825
                 ? $this->_cpt_model_obj->get_first_related(
1826 1826
                     'Datetime',
1827 1827
                     ['order_by' => ['DTT_EVT_start' => 'ASC']]
@@ -1834,7 +1834,7 @@  discard block
 block discarded – undo
1834 1834
         $template_args = array_merge($template_args, $price_args);
1835 1835
         $template      = apply_filters(
1836 1836
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1837
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1837
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1838 1838
             $ticket
1839 1839
         );
1840 1840
         return EEH_Template::display_template($template, $template_args, true);
@@ -1847,7 +1847,7 @@  discard block
 block discarded – undo
1847 1847
      */
1848 1848
     public function registration_options_meta_box()
1849 1849
     {
1850
-        $yes_no_values             = [
1850
+        $yes_no_values = [
1851 1851
             ['id' => true, 'text' => esc_html__('Yes', 'event_espresso')],
1852 1852
             ['id' => false, 'text' => esc_html__('No', 'event_espresso')],
1853 1853
         ];
@@ -1872,12 +1872,12 @@  discard block
 block discarded – undo
1872 1872
             'ee-input-width--reg',
1873 1873
             false
1874 1874
         );
1875
-        $template_args['display_description']             = EEH_Form_Fields::select_input(
1875
+        $template_args['display_description'] = EEH_Form_Fields::select_input(
1876 1876
             'display_desc',
1877 1877
             $yes_no_values,
1878 1878
             $this->_cpt_model_obj->display_description()
1879 1879
         );
1880
-        $template_args['display_ticket_selector']         = EEH_Form_Fields::select_input(
1880
+        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1881 1881
             'display_ticket_selector',
1882 1882
             $yes_no_values,
1883 1883
             $this->_cpt_model_obj->display_ticket_selector(),
@@ -1893,7 +1893,7 @@  discard block
 block discarded – undo
1893 1893
             $default_reg_status_values
1894 1894
         );
1895 1895
         EEH_Template::display_template(
1896
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1896
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1897 1897
             $template_args
1898 1898
         );
1899 1899
     }
@@ -1916,7 +1916,7 @@  discard block
 block discarded – undo
1916 1916
     {
1917 1917
         $EEM_Event   = $this->_event_model();
1918 1918
         $offset      = ($current_page - 1) * $per_page;
1919
-        $limit       = $count ? null : $offset . ',' . $per_page;
1919
+        $limit       = $count ? null : $offset.','.$per_page;
1920 1920
         $orderby     = $this->request->getRequestParam('orderby', 'EVT_ID');
1921 1921
         $order       = $this->request->getRequestParam('order', 'DESC');
1922 1922
         $month_range = $this->request->getRequestParam('month_range');
@@ -1953,10 +1953,10 @@  discard block
 block discarded – undo
1953 1953
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1954 1954
         if ($month_range) {
1955 1955
             $DateTime = new DateTime(
1956
-                $year_r . '-' . $month_r . '-01 00:00:00',
1956
+                $year_r.'-'.$month_r.'-01 00:00:00',
1957 1957
                 new DateTimeZone('UTC')
1958 1958
             );
1959
-            $start    = $DateTime->getTimestamp();
1959
+            $start = $DateTime->getTimestamp();
1960 1960
             // set the datetime to be the end of the month
1961 1961
             $DateTime->setDate(
1962 1962
                 $year_r,
@@ -1981,11 +1981,11 @@  discard block
 block discarded – undo
1981 1981
                                                         ->format(implode(' ', $start_formats));
1982 1982
             $where['Datetime.DTT_EVT_start'] = ['BETWEEN', [$start, $end]];
1983 1983
         }
1984
-        if (! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1984
+        if ( ! $this->capabilities->current_user_can('ee_read_others_events', 'get_events')) {
1985 1985
             $where['EVT_wp_user'] = get_current_user_id();
1986 1986
         } else {
1987
-            if (! isset($where['status'])) {
1988
-                if (! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1987
+            if ( ! isset($where['status'])) {
1988
+                if ( ! $this->capabilities->current_user_can('ee_read_private_events', 'get_events')) {
1989 1989
                     $where['OR'] = [
1990 1990
                         'status*restrict_private' => ['!=', 'private'],
1991 1991
                         'AND'                     => [
@@ -2007,7 +2007,7 @@  discard block
 block discarded – undo
2007 2007
         // search query handling
2008 2008
         $search_term = $this->request->getRequestParam('s');
2009 2009
         if ($search_term) {
2010
-            $search_term = '%' . $search_term . '%';
2010
+            $search_term = '%'.$search_term.'%';
2011 2011
             $where['OR'] = [
2012 2012
                 'EVT_name'       => ['LIKE', $search_term],
2013 2013
                 'EVT_desc'       => ['LIKE', $search_term],
@@ -2113,7 +2113,7 @@  discard block
 block discarded – undo
2113 2113
             // clean status
2114 2114
             $event_status = sanitize_key($event_status);
2115 2115
             // grab status
2116
-            if (! empty($event_status)) {
2116
+            if ( ! empty($event_status)) {
2117 2117
                 $success = $this->_change_event_status($this->EVT_ID, $event_status);
2118 2118
             } else {
2119 2119
                 $success = false;
@@ -2153,7 +2153,7 @@  discard block
 block discarded – undo
2153 2153
         // clean status
2154 2154
         $event_status = sanitize_key($event_status);
2155 2155
         // grab status
2156
-        if (! empty($event_status)) {
2156
+        if ( ! empty($event_status)) {
2157 2157
             $success = true;
2158 2158
             // determine the event id and set to array.
2159 2159
             $EVT_IDs = $this->request->getRequestParam('EVT_IDs', [], 'int', true);
@@ -2199,7 +2199,7 @@  discard block
 block discarded – undo
2199 2199
     private function _change_event_status(int $EVT_ID = 0, string $event_status = ''): bool
2200 2200
     {
2201 2201
         // grab event id
2202
-        if (! $EVT_ID) {
2202
+        if ( ! $EVT_ID) {
2203 2203
             $msg = esc_html__(
2204 2204
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2205 2205
                 'event_espresso'
@@ -2236,7 +2236,7 @@  discard block
 block discarded – undo
2236 2236
         // use class to change status
2237 2237
         $this->_cpt_model_obj->set_status($event_status);
2238 2238
         $success = $this->_cpt_model_obj->save();
2239
-        if (! $success) {
2239
+        if ( ! $success) {
2240 2240
             $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2241 2241
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2242 2242
             return false;
@@ -2303,7 +2303,7 @@  discard block
 block discarded – undo
2303 2303
      */
2304 2304
     protected function getModelObjNodeGroupPersister(): NodeGroupDao
2305 2305
     {
2306
-        if (! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2306
+        if ( ! $this->model_obj_node_group_persister instanceof NodeGroupDao) {
2307 2307
             $this->model_obj_node_group_persister =
2308 2308
                 $this->getLoader()->load('\EventEspresso\core\services\orm\tree_traversal\NodeGroupDao');
2309 2309
         }
@@ -2626,7 +2626,7 @@  discard block
 block discarded – undo
2626 2626
                                                 . esc_html__(
2627 2627
                                                     'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2628 2628
                                                     'event_espresso'
2629
-                                                ) . '</strong>';
2629
+                                                ).'</strong>';
2630 2630
         $this->display_admin_caf_preview_page('template_settings_tab');
2631 2631
     }
2632 2632
 
@@ -2647,11 +2647,11 @@  discard block
 block discarded – undo
2647 2647
         $this->_set_empty_category_object();
2648 2648
         // only set if we've got an id
2649 2649
         $category_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, DataType::INT);
2650
-        if (! $category_ID) {
2650
+        if ( ! $category_ID) {
2651 2651
             return;
2652 2652
         }
2653 2653
         $term = get_term($category_ID, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2654
-        if (! empty($term)) {
2654
+        if ( ! empty($term)) {
2655 2655
             $this->_category->category_name       = $term->name;
2656 2656
             $this->_category->category_identifier = $term->slug;
2657 2657
             $this->_category->category_desc       = $term->description;
@@ -2752,7 +2752,7 @@  discard block
 block discarded – undo
2752 2752
             $category_select_values,
2753 2753
             $this->_category->parent
2754 2754
         );
2755
-        $template_args   = [
2755
+        $template_args = [
2756 2756
             'category'                 => $this->_category,
2757 2757
             'category_select'          => $category_select,
2758 2758
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -2760,7 +2760,7 @@  discard block
 block discarded – undo
2760 2760
             'disable'                  => '',
2761 2761
             'disabled_message'         => false,
2762 2762
         ];
2763
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2763
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2764 2764
         return EEH_Template::display_template($template, $template_args, true);
2765 2765
     }
2766 2766
 
@@ -2856,7 +2856,7 @@  discard block
 block discarded – undo
2856 2856
             return 0;
2857 2857
         }
2858 2858
         $category_ID = $insert_ids['term_id'] ?? 0;
2859
-        if (! $category_ID) {
2859
+        if ( ! $category_ID) {
2860 2860
             EE_Error::add_error(
2861 2861
                 esc_html__(
2862 2862
                     'An error occurred and the category has not been saved to the database.',
@@ -2897,7 +2897,7 @@  discard block
 block discarded – undo
2897 2897
         $where       = ['taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY];
2898 2898
         $search_term = $this->request->getRequestParam('s');
2899 2899
         if ($search_term) {
2900
-            $search_term = '%' . $search_term . '%';
2900
+            $search_term = '%'.$search_term.'%';
2901 2901
             $where['OR'] = [
2902 2902
                 'Term.name'   => ['LIKE', $search_term],
2903 2903
                 'description' => ['LIKE', $search_term],
@@ -2906,7 +2906,7 @@  discard block
 block discarded – undo
2906 2906
         $query_params = [
2907 2907
             $where,
2908 2908
             'order_by'   => [$orderby => $order],
2909
-            'limit'      => $limit . ',' . $per_page,
2909
+            'limit'      => $limit.','.$per_page,
2910 2910
             'force_join' => ['Term'],
2911 2911
         ];
2912 2912
         return $count
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page.core.php 2 patches
Indentation   +4074 added lines, -4074 removed lines patch added patch discarded remove patch
@@ -18,2502 +18,2502 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class Messages_Admin_Page extends EE_Admin_Page
20 20
 {
21
-    private ?EEM_Message                   $MSG_MODEL                 = null;
21
+	private ?EEM_Message                   $MSG_MODEL                 = null;
22 22
 
23
-    private ?EEM_Message_Template          $MTP_MODEL                 = null;
23
+	private ?EEM_Message_Template          $MTP_MODEL                 = null;
24 24
 
25
-    private ?EEM_Message_Template_Group    $MTG_MODEL                 = null;
25
+	private ?EEM_Message_Template_Group    $MTG_MODEL                 = null;
26 26
 
27
-    protected ?EE_Message_Resource_Manager $_message_resource_manager = null;
27
+	protected ?EE_Message_Resource_Manager $_message_resource_manager = null;
28 28
 
29
-    protected ?EE_Message_Template_Group   $_message_template_group   = null;
29
+	protected ?EE_Message_Template_Group   $_message_template_group   = null;
30 30
 
31
-    protected ?EE_messenger                $_active_messenger         = null;
31
+	protected ?EE_messenger                $_active_messenger         = null;
32 32
 
33
-    protected ?MessageTemplateManager      $message_template_manager  = null;
33
+	protected ?MessageTemplateManager      $message_template_manager  = null;
34 34
 
35 35
 
36
-    /**
37
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
38
-     * IF there is no group then it gets automatically set to the Default template pack.
39
-     *
40
-     * @since 4.5.0
41
-     */
42
-    protected ?EE_Messages_Template_Pack $_template_pack            = null;
36
+	/**
37
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
38
+	 * IF there is no group then it gets automatically set to the Default template pack.
39
+	 *
40
+	 * @since 4.5.0
41
+	 */
42
+	protected ?EE_Messages_Template_Pack $_template_pack            = null;
43 43
 
44
-    protected array                      $_active_messengers        = [];
45
-
46
-    protected array                      $_active_message_types     = [];
44
+	protected array                      $_active_messengers        = [];
45
+
46
+	protected array                      $_active_message_types     = [];
47 47
 
48
-    protected array                      $_shortcodes               = [];
49
-
50
-    protected array                      $_m_mt_settings            = [];
48
+	protected array                      $_shortcodes               = [];
49
+
50
+	protected array                      $_m_mt_settings            = [];
51 51
 
52
-    protected string                     $_active_message_type_name = '';
52
+	protected string                     $_active_message_type_name = '';
53 53
 
54
-    protected string                     $_active_messenger_name    = '';
55
-
56
-    protected string                     $_context_switcher         = '';
54
+	protected string                     $_active_messenger_name    = '';
55
+
56
+	protected string                     $_context_switcher         = '';
57 57
 
58 58
 
59
-    /**
60
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
61
-     * group is.  If there is no group then it automatically gets set to default.
62
-     *
63
-     * @since 4.5.0
64
-     */
65
-    protected string $_variation = '';
66
-
67
-
68
-    /**
69
-     * @param bool $routing
70
-     * @throws EE_Error
71
-     * @throws ReflectionException
72
-     */
73
-    public function __construct($routing = true)
74
-    {
75
-        // make sure messages autoloader is running
76
-        EED_Messages::set_autoloaders();
77
-        parent::__construct($routing);
78
-    }
79
-
80
-
81
-    /**
82
-     * @return EEM_Message
83
-     * @throws EE_Error
84
-     * @throws ReflectionException
85
-     */
86
-    public function getMsgModel(): EEM_Message
87
-    {
88
-        if (! $this->MSG_MODEL instanceof EEM_Message) {
89
-            $this->MSG_MODEL = EEM_Message::instance();
90
-        }
91
-        return $this->MSG_MODEL;
92
-    }
93
-
94
-
95
-    /**
96
-     * @return EEM_Message_Template
97
-     * @throws EE_Error
98
-     * @throws ReflectionException
99
-     */
100
-    public function getMtpModel(): EEM_Message_Template
101
-    {
102
-        if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
103
-            $this->MTP_MODEL = EEM_Message_Template::instance();
104
-        }
105
-        return $this->MTP_MODEL;
106
-    }
107
-
108
-
109
-    /**
110
-     * @return EEM_Message_Template_Group
111
-     * @throws EE_Error
112
-     * @throws ReflectionException
113
-     */
114
-    public function getMtgModel(): EEM_Message_Template_Group
115
-    {
116
-        if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
117
-            $this->MTG_MODEL = EEM_Message_Template_Group::instance();
118
-        }
119
-        return $this->MTG_MODEL;
120
-    }
121
-
122
-
123
-    public function getMessageTemplateManager(): MessageTemplateManager
124
-    {
125
-        if (! $this->message_template_manager instanceof MessageTemplateManager) {
126
-            $this->message_template_manager = $this->loader->getShared(MessageTemplateManager::class);
127
-        }
128
-        return $this->message_template_manager;
129
-    }
130
-
131
-
132
-    /**
133
-     * @throws EE_Error
134
-     * @throws ReflectionException
135
-     */
136
-    protected function _init_page_props()
137
-    {
138
-        $this->page_slug        = EE_MSG_PG_SLUG;
139
-        $this->page_label       = esc_html__('Messages Settings', 'event_espresso');
140
-        $this->_admin_base_url  = EE_MSG_ADMIN_URL;
141
-        $this->_admin_base_path = EE_MSG_ADMIN;
142
-
143
-        $messenger                       = $this->request->getRequestParam('messenger', '');
144
-        $message_type                    = $this->request->getRequestParam('message_type', '');
145
-        $this->_active_messenger_name    = $this->request->getRequestParam('MTP_messenger', $messenger);
146
-        $this->_active_message_type_name = $this->request->getRequestParam('MTP_message_type', $message_type);
147
-
148
-        $this->_load_message_resource_manager();
149
-    }
150
-
151
-
152
-    protected function _load_message_resource_manager()
153
-    {
154
-        if (! $this->_message_resource_manager instanceof EE_Message_Resource_Manager) {
155
-            $this->_message_resource_manager = $this->loader->getShared(EE_Message_Resource_Manager::class);
156
-        }
157
-    }
158
-
159
-
160
-    /**
161
-     * Generate select input with provided messenger options array.
162
-     *
163
-     * @param array $messenger_options Array of messengers indexed by slug and values are the messenger labels.
164
-     * @return string
165
-     * @throws EE_Error
166
-     */
167
-    public function get_messengers_select_input($messenger_options)
168
-    {
169
-        // if empty or just one value then just return an empty string
170
-        if (
171
-            empty($messenger_options)
172
-            || ! is_array($messenger_options)
173
-            || count($messenger_options) === 1
174
-        ) {
175
-            return '';
176
-        }
177
-        // merge in default
178
-        $messenger_options = array_merge(
179
-            ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
180
-            $messenger_options
181
-        );
182
-        $input             = new EE_Select_Input(
183
-            $messenger_options,
184
-            [
185
-                'html_name'  => 'ee_messenger_filter_by',
186
-                'html_id'    => 'ee_messenger_filter_by',
187
-                'html_class' => 'wide',
188
-                'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
189
-            ]
190
-        );
191
-
192
-        return $input->get_html_for_input();
193
-    }
194
-
195
-
196
-    /**
197
-     * Generate select input with provided message type options array.
198
-     *
199
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
200
-     *                                    message type labels
201
-     * @return string
202
-     * @throws EE_Error
203
-     */
204
-    public function get_message_types_select_input($message_type_options)
205
-    {
206
-        // if empty or count of options is 1 then just return an empty string
207
-        if (
208
-            empty($message_type_options)
209
-            || ! is_array($message_type_options)
210
-            || count($message_type_options) === 1
211
-        ) {
212
-            return '';
213
-        }
214
-        // merge in default
215
-        $message_type_options = array_merge(
216
-            ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
217
-            $message_type_options
218
-        );
219
-        $input                = new EE_Select_Input(
220
-            $message_type_options,
221
-            [
222
-                'html_name'  => 'ee_message_type_filter_by',
223
-                'html_id'    => 'ee_message_type_filter_by',
224
-                'html_class' => 'wide',
225
-                'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
226
-            ]
227
-        );
228
-
229
-        return $input->get_html_for_input();
230
-    }
231
-
232
-
233
-    /**
234
-     * Generate select input with provide message type contexts array.
235
-     *
236
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
237
-     *                               context label.
238
-     * @return string
239
-     * @throws EE_Error
240
-     */
241
-    public function get_contexts_for_message_types_select_input($context_options)
242
-    {
243
-        // if empty or count of options is one then just return empty string
244
-        if (
245
-            empty($context_options)
246
-            || ! is_array($context_options)
247
-            || count($context_options) === 1
248
-        ) {
249
-            return '';
250
-        }
251
-        // merge in default
252
-        $context_options = array_merge(
253
-            ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
254
-            $context_options
255
-        );
256
-        $input           = new EE_Select_Input(
257
-            $context_options,
258
-            [
259
-                'html_name'  => 'ee_context_filter_by',
260
-                'html_id'    => 'ee_context_filter_by',
261
-                'html_class' => 'wide',
262
-                'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
263
-            ]
264
-        );
265
-
266
-        return $input->get_html_for_input();
267
-    }
268
-
269
-
270
-    protected function _ajax_hooks()
271
-    {
272
-        add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
273
-        add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
274
-        add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
275
-        add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
276
-        add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
277
-        add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
278
-    }
279
-
280
-
281
-    protected function _define_page_props()
282
-    {
283
-        $this->_admin_page_title = $this->page_label;
284
-        $this->_labels           = [
285
-            'buttons'    => [
286
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
287
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
288
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
289
-            ],
290
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
291
-        ];
292
-    }
293
-
294
-
295
-    /**
296
-     *        an array for storing key => value pairs of request actions and their corresponding methods
297
-     *
298
-     * @access protected
299
-     * @return void
300
-     */
301
-    protected function _set_page_routes()
302
-    {
303
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
304
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, DataType::INTEGER);
305
-        $MSG_ID = $this->request->getRequestParam('MSG_ID', 0, DataType::INTEGER);
306
-
307
-        $this->_page_routes = [
308
-            'default'                          => [
309
-                'func'       => [$this, '_message_queue_list_table'],
310
-                'capability' => 'ee_read_global_messages',
311
-            ],
312
-            'global_mtps'                      => [
313
-                'func'       => [$this, '_ee_default_messages_overview_list_table'],
314
-                'capability' => 'ee_read_global_messages',
315
-            ],
316
-            'custom_mtps'                      => [
317
-                'func'       => [$this, '_custom_mtps_preview'],
318
-                'capability' => 'ee_read_messages',
319
-            ],
320
-            'add_new_message_template'         => [
321
-                'func'       => [$this, 'insertMessageTemplate'],
322
-                'capability' => 'ee_edit_messages',
323
-                'noheader'   => true,
324
-            ],
325
-            'edit_message_template'            => [
326
-                'func'       => [$this, '_edit_message_template'],
327
-                'capability' => 'ee_edit_message',
328
-                'obj_id'     => $GRP_ID,
329
-            ],
330
-            'preview_message'                  => [
331
-                'func'               => [$this, '_preview_message'],
332
-                'capability'         => 'ee_read_message',
333
-                'obj_id'             => $GRP_ID,
334
-                'noheader'           => true,
335
-                'headers_sent_route' => 'display_preview_message',
336
-            ],
337
-            'display_preview_message'          => [
338
-                'func'       => [$this, '_display_preview_message'],
339
-                'capability' => 'ee_read_message',
340
-                'obj_id'     => $GRP_ID,
341
-            ],
342
-            'insert_message_template'          => [
343
-                'func'       => [$this, 'insertMessageTemplate'],
344
-                'capability' => 'ee_edit_messages',
345
-                'noheader'   => true,
346
-            ],
347
-            'update_message_template'          => [
348
-                'func'       => [$this, 'updateMessageTemplate'],
349
-                'capability' => 'ee_edit_message',
350
-                'obj_id'     => $GRP_ID,
351
-                'noheader'   => true,
352
-            ],
353
-            'trash_message_template'           => [
354
-                'func'       => [$this, '_trash_or_restore_message_template'],
355
-                'capability' => 'ee_delete_message',
356
-                'obj_id'     => $GRP_ID,
357
-                'args'       => ['trash' => true, 'all' => true],
358
-                'noheader'   => true,
359
-            ],
360
-            'trash_message_template_context'   => [
361
-                'func'       => [$this, '_trash_or_restore_message_template'],
362
-                'capability' => 'ee_delete_message',
363
-                'obj_id'     => $GRP_ID,
364
-                'args'       => ['trash' => true],
365
-                'noheader'   => true,
366
-            ],
367
-            'restore_message_template'         => [
368
-                'func'       => [$this, '_trash_or_restore_message_template'],
369
-                'capability' => 'ee_delete_message',
370
-                'obj_id'     => $GRP_ID,
371
-                'args'       => ['trash' => false, 'all' => true],
372
-                'noheader'   => true,
373
-            ],
374
-            'restore_message_template_context' => [
375
-                'func'       => [$this, '_trash_or_restore_message_template'],
376
-                'capability' => 'ee_delete_message',
377
-                'obj_id'     => $GRP_ID,
378
-                'args'       => ['trash' => false],
379
-                'noheader'   => true,
380
-            ],
381
-            'delete_message_template'          => [
382
-                'func'       => [$this, '_delete_message_template'],
383
-                'capability' => 'ee_delete_message',
384
-                'obj_id'     => $GRP_ID,
385
-                'noheader'   => true,
386
-            ],
387
-            'reset_to_default'                 => [
388
-                'func'       => [$this, '_reset_to_default_template'],
389
-                'capability' => 'ee_edit_message',
390
-                'obj_id'     => $GRP_ID,
391
-                'noheader'   => true,
392
-            ],
393
-            'settings'                         => [
394
-                'func'       => [$this, '_settings'],
395
-                'capability' => 'manage_options',
396
-            ],
397
-            'update_global_settings'           => [
398
-                'func'       => [$this, '_update_global_settings'],
399
-                'capability' => 'manage_options',
400
-                'noheader'   => true,
401
-            ],
402
-            'generate_now'                     => [
403
-                'func'       => [$this, '_generate_now'],
404
-                'capability' => 'ee_send_message',
405
-                'noheader'   => true,
406
-            ],
407
-            'generate_and_send_now'            => [
408
-                'func'       => [$this, '_generate_and_send_now'],
409
-                'capability' => 'ee_send_message',
410
-                'noheader'   => true,
411
-            ],
412
-            'queue_for_resending'              => [
413
-                'func'       => [$this, '_queue_for_resending'],
414
-                'capability' => 'ee_send_message',
415
-                'noheader'   => true,
416
-            ],
417
-            'send_now'                         => [
418
-                'func'       => [$this, '_send_now'],
419
-                'capability' => 'ee_send_message',
420
-                'noheader'   => true,
421
-            ],
422
-            'delete_ee_message'                => [
423
-                'func'       => [$this, '_delete_ee_messages'],
424
-                'capability' => 'ee_delete_messages',
425
-                'noheader'   => true,
426
-            ],
427
-            'delete_ee_messages'               => [
428
-                'func'       => [$this, '_delete_ee_messages'],
429
-                'capability' => 'ee_delete_messages',
430
-                'noheader'   => true,
431
-                'obj_id'     => $MSG_ID,
432
-            ],
433
-        ];
434
-    }
435
-
436
-
437
-    protected function _set_page_config()
438
-    {
439
-        $this->_page_config = [
440
-            'default'                  => [
441
-                'nav'           => [
442
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
443
-                    'icon'  => 'dashicons-email',
444
-                    'order' => 10,
445
-                ],
446
-                'list_table'    => 'EE_Message_List_Table',
447
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
448
-                'require_nonce' => false,
449
-            ],
450
-            'global_mtps'              => [
451
-                'nav'           => [
452
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
453
-                    'icon'  => 'dashicons-layout',
454
-                    'order' => 20,
455
-                ],
456
-                'list_table'    => 'Messages_Template_List_Table',
457
-                'help_tabs'     => [
458
-                    'messages_overview_help_tab'                                => [
459
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
460
-                        'filename' => 'messages_overview',
461
-                    ],
462
-                    'messages_overview_messages_table_column_headings_help_tab' => [
463
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
464
-                        'filename' => 'messages_overview_table_column_headings',
465
-                    ],
466
-                    'messages_overview_messages_filters_help_tab'               => [
467
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
468
-                        'filename' => 'messages_overview_filters',
469
-                    ],
470
-                    'messages_overview_messages_views_help_tab'                 => [
471
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
472
-                        'filename' => 'messages_overview_views',
473
-                    ],
474
-                    'message_overview_message_types_help_tab'                   => [
475
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
476
-                        'filename' => 'messages_overview_types',
477
-                    ],
478
-                    'messages_overview_messengers_help_tab'                     => [
479
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
480
-                        'filename' => 'messages_overview_messengers',
481
-                    ],
482
-                ],
483
-                'require_nonce' => false,
484
-            ],
485
-            'custom_mtps'              => [
486
-                'nav'           => [
487
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
488
-                    'icon'  => 'dashicons-admin-customizer',
489
-                    'order' => 30,
490
-                ],
491
-                'help_tabs'     => [],
492
-                'require_nonce' => false,
493
-            ],
494
-            'add_new_message_template' => [
495
-                'nav'           => [
496
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
497
-                    'icon'       => 'dashicons-plus-alt',
498
-                    'order'      => 5,
499
-                    'persistent' => false,
500
-                ],
501
-                'require_nonce' => false,
502
-            ],
503
-            'edit_message_template'    => [
504
-                'labels'        => [
505
-                    'buttons'    => [
506
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
507
-                    ],
508
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
509
-                ],
510
-                'nav'           => [
511
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
512
-                    'icon'       => 'dashicons-edit-large',
513
-                    'order'      => 5,
514
-                    'persistent' => false,
515
-                    'url'        => '',
516
-                ],
517
-                'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
518
-                'has_metaboxes' => true,
519
-                'help_tabs'     => [
520
-                    'edit_message_template'            => [
521
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
522
-                        'callback' => 'edit_message_template_help_tab',
523
-                    ],
524
-                    'message_templates_help_tab'       => [
525
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
526
-                        'filename' => 'messages_templates',
527
-                    ],
528
-                    'message_template_shortcodes'      => [
529
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
530
-                        'callback' => 'message_template_shortcodes_help_tab',
531
-                    ],
532
-                    'message_preview_help_tab'         => [
533
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
534
-                        'filename' => 'messages_preview',
535
-                    ],
536
-                    'messages_overview_other_help_tab' => [
537
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
538
-                        'filename' => 'messages_overview_other',
539
-                    ],
540
-                ],
541
-                'require_nonce' => false,
542
-            ],
543
-            'display_preview_message'  => [
544
-                'nav'           => [
545
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
546
-                    'icon'       => 'dashicons-visibility-bar',
547
-                    'order'      => 5,
548
-                    'url'        => '',
549
-                    'persistent' => false,
550
-                ],
551
-                'help_tabs'     => [
552
-                    'preview_message' => [
553
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
554
-                        'callback' => 'preview_message_help_tab',
555
-                    ],
556
-                ],
557
-                'require_nonce' => false,
558
-            ],
559
-            'settings'                 => [
560
-                'nav'           => [
561
-                    'label' => esc_html__('Settings', 'event_espresso'),
562
-                    'icon'  => 'dashicons-admin-generic',
563
-                    'order' => 40,
564
-                ],
565
-                'metaboxes'     => ['_messages_settings_metaboxes'],
566
-                'help_tabs'     => [
567
-                    'messages_settings_help_tab'               => [
568
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
569
-                        'filename' => 'messages_settings',
570
-                    ],
571
-                    'messages_settings_message_types_help_tab' => [
572
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
573
-                        'filename' => 'messages_settings_message_types',
574
-                    ],
575
-                    'messages_settings_messengers_help_tab'    => [
576
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
577
-                        'filename' => 'messages_settings_messengers',
578
-                    ],
579
-                ],
580
-                'require_nonce' => false,
581
-            ],
582
-        ];
583
-    }
584
-
585
-
586
-    protected function _add_screen_options()
587
-    {
588
-        // todo
589
-    }
590
-
591
-
592
-    protected function _add_screen_options_global_mtps()
593
-    {
594
-        /**
595
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
596
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
597
-         */
598
-        $page_title              = $this->_admin_page_title;
599
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
600
-        $this->_per_page_screen_option();
601
-        $this->_admin_page_title = $page_title;
602
-    }
603
-
604
-
605
-    protected function _add_screen_options_default()
606
-    {
607
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
608
-        $this->_per_page_screen_option();
609
-    }
610
-
611
-
612
-    // none of the below group are currently used for Messages
613
-    protected function _add_feature_pointers()
614
-    {
615
-    }
616
-
617
-
618
-    public function admin_init()
619
-    {
620
-    }
621
-
622
-
623
-    public function admin_notices()
624
-    {
625
-    }
626
-
627
-
628
-    public function admin_footer_scripts()
629
-    {
630
-    }
631
-
632
-
633
-    public function messages_help_tab()
634
-    {
635
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
636
-    }
637
-
638
-
639
-    public function messengers_help_tab()
640
-    {
641
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
642
-    }
643
-
644
-
645
-    public function message_types_help_tab()
646
-    {
647
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
648
-    }
649
-
650
-
651
-    public function messages_overview_help_tab()
652
-    {
653
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
654
-    }
655
-
656
-
657
-    public function message_templates_help_tab()
658
-    {
659
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
660
-    }
661
-
662
-
663
-    public function edit_message_template_help_tab()
664
-    {
665
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
666
-                        . esc_attr__('Editor Title', 'event_espresso')
667
-                        . '" />';
668
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
669
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
670
-                        . '" />';
671
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
672
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
673
-                        . '" />';
674
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
675
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
676
-                        . '" />';
677
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
678
-                        . esc_attr__('Publish Metabox', 'event_espresso')
679
-                        . '" />';
680
-        EEH_Template::display_template(
681
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
682
-            $args
683
-        );
684
-    }
685
-
686
-
687
-    /**
688
-     * @throws ReflectionException
689
-     * @throws EE_Error
690
-     */
691
-    public function message_template_shortcodes_help_tab()
692
-    {
693
-        $this->_set_shortcodes();
694
-        $args['shortcodes'] = $this->_shortcodes;
695
-        EEH_Template::display_template(
696
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
697
-            $args
698
-        );
699
-    }
700
-
701
-
702
-    public function preview_message_help_tab()
703
-    {
704
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
705
-    }
706
-
707
-
708
-    public function settings_help_tab()
709
-    {
710
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
711
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
712
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
713
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
714
-        $args['img3'] = '<div class="ee-switch">'
715
-                        . '<input class="ee-switch__input" id="ee-on-off-toggle-on" type="checkbox" checked>'
716
-                        . '<label class="ee-switch__toggle" for="ee-on-off-toggle-on"></label>'
717
-                        . '</div>';
718
-        $args['img4'] = '<div class="switch">'
719
-                        . '<input class="ee-switch__input" id="ee-on-off-toggle-off" type="checkbox">'
720
-                        . '<label class="ee-switch__toggle" for="ee-on-off-toggle-off"></label>'
721
-                        . '</div>';
722
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
723
-    }
724
-
725
-
726
-    public function load_scripts_styles()
727
-    {
728
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', [], EVENT_ESPRESSO_VERSION);
729
-        wp_enqueue_style('espresso_ee_msg');
730
-
731
-        wp_register_script(
732
-            'ee-messages-settings',
733
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
734
-            ['jquery-ui-droppable', 'ee-serialize-full-array'],
735
-            EVENT_ESPRESSO_VERSION,
736
-            true
737
-        );
738
-        wp_register_script(
739
-            'ee-msg-list-table-js',
740
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
741
-            ['ee-dialog'],
742
-            EVENT_ESPRESSO_VERSION
743
-        );
744
-    }
745
-
746
-
747
-    public function load_scripts_styles_default()
748
-    {
749
-        wp_enqueue_script('ee-msg-list-table-js');
750
-    }
751
-
752
-
753
-    public function wp_editor_css($mce_css)
754
-    {
755
-        // if we're on the edit_message_template route
756
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
757
-            $message_type_name = $this->_active_message_type_name;
758
-
759
-            // we're going to REPLACE the existing mce css
760
-            // we need to get the css file location from the active messenger
761
-            $mce_css = $this->_active_messenger->get_variation(
762
-                $this->_template_pack,
763
-                $message_type_name,
764
-                true,
765
-                'wpeditor',
766
-                $this->_variation
767
-            );
768
-        }
769
-
770
-        return $mce_css;
771
-    }
772
-
773
-
774
-    /**
775
-     * @throws EE_Error
776
-     * @throws ReflectionException
777
-     */
778
-    public function load_scripts_styles_edit_message_template()
779
-    {
780
-        $this->_set_shortcodes();
781
-
782
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
783
-            esc_html__(
784
-                'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
785
-                'event_espresso'
786
-            ),
787
-            $this->_message_template_group->messenger_obj()->label['singular'],
788
-            $this->_message_template_group->message_type_obj()->label['singular']
789
-        );
790
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
791
-            'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
792
-            'event_espresso'
793
-        );
794
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
795
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
796
-            'event_espresso'
797
-        );
798
-
799
-        wp_register_script(
800
-            'ee_msgs_edit_js',
801
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
802
-            ['jquery'],
803
-            EVENT_ESPRESSO_VERSION
804
-        );
805
-
806
-        wp_enqueue_script('ee_admin_js');
807
-        wp_enqueue_script('ee_msgs_edit_js');
808
-
809
-        // add in special css for tiny_mce
810
-        add_filter('mce_css', [$this, 'wp_editor_css']);
811
-    }
812
-
813
-
814
-    /**
815
-     * @throws EE_Error
816
-     * @throws ReflectionException
817
-     */
818
-    public function load_scripts_styles_display_preview_message()
819
-    {
820
-        $this->_set_message_template_group();
821
-        if ($this->_active_messenger_name) {
822
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
823
-                $this->_active_messenger_name
824
-            );
825
-        }
826
-
827
-        wp_enqueue_style(
828
-            'espresso_preview_css',
829
-            $this->_active_messenger->get_variation(
830
-                $this->_template_pack,
831
-                $this->_active_message_type_name,
832
-                true,
833
-                'preview',
834
-                $this->_variation
835
-            )
836
-        );
837
-    }
838
-
839
-
840
-    public function load_scripts_styles_settings()
841
-    {
842
-        wp_register_style(
843
-            'ee-message-settings',
844
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
845
-            [],
846
-            EVENT_ESPRESSO_VERSION
847
-        );
848
-        wp_enqueue_style('ee-text-links');
849
-        wp_enqueue_style('ee-message-settings');
850
-        wp_enqueue_script('ee-messages-settings');
851
-    }
852
-
853
-
854
-    /**
855
-     * set views array for List Table
856
-     */
857
-    public function _set_list_table_views_global_mtps()
858
-    {
859
-        $this->_views = [
860
-            'in_use' => [
861
-                'slug'  => 'in_use',
862
-                'label' => esc_html__('In Use', 'event_espresso'),
863
-                'count' => 0,
864
-            ],
865
-        ];
866
-    }
867
-
868
-
869
-    /**
870
-     * Set views array for the Custom Template List Table
871
-     */
872
-    public function _set_list_table_views_custom_mtps()
873
-    {
874
-        $this->_set_list_table_views_global_mtps();
875
-        $this->_views['in_use']['bulk_action'] = [
876
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
877
-        ];
878
-    }
879
-
880
-
881
-    /**
882
-     * set views array for message queue list table
883
-     *
884
-     * @throws InvalidDataTypeException
885
-     * @throws InvalidInterfaceException
886
-     * @throws InvalidArgumentException
887
-     * @throws EE_Error
888
-     * @throws ReflectionException
889
-     */
890
-    public function _set_list_table_views_default()
891
-    {
892
-        EE_Registry::instance()->load_helper('Template');
893
-
894
-        $common_bulk_actions = $this->capabilities->current_user_can(
895
-            'ee_send_message',
896
-            'message_list_table_bulk_actions'
897
-        )
898
-            ? [
899
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
900
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
901
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
902
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
903
-            ]
904
-            : [];
905
-
906
-        $delete_bulk_action = $this->capabilities->current_user_can(
907
-            'ee_delete_messages',
908
-            'message_list_table_bulk_actions'
909
-        )
910
-            ? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
911
-            : [];
912
-
913
-
914
-        $this->_views = [
915
-            'all' => [
916
-                'slug'        => 'all',
917
-                'label'       => esc_html__('All', 'event_espresso'),
918
-                'count'       => 0,
919
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
920
-            ],
921
-        ];
922
-
923
-
924
-        foreach ($this->getMsgModel()->all_statuses() as $status) {
925
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
926
-                continue;
927
-            }
928
-            $status_bulk_actions = $common_bulk_actions;
929
-            // unset bulk actions not applying to status
930
-            if (! empty($status_bulk_actions)) {
931
-                switch ($status) {
932
-                    case EEM_Message::status_idle:
933
-                    case EEM_Message::status_resend:
934
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
935
-                        break;
936
-
937
-                    case EEM_Message::status_failed:
938
-                    case EEM_Message::status_debug_only:
939
-                    case EEM_Message::status_messenger_executing:
940
-                        $status_bulk_actions = [];
941
-                        break;
942
-
943
-                    case EEM_Message::status_incomplete:
944
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
945
-                        break;
946
-
947
-                    case EEM_Message::status_retry:
948
-                    case EEM_Message::status_sent:
949
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
950
-                        break;
951
-                }
952
-            }
953
-
954
-            // skip adding messenger executing status to views because it will be included with the Failed view.
955
-            if ($status === EEM_Message::status_messenger_executing) {
956
-                continue;
957
-            }
958
-
959
-            $this->_views[ strtolower($status) ] = [
960
-                'slug'        => strtolower($status),
961
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
962
-                'count'       => 0,
963
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
964
-            ];
965
-        }
966
-    }
967
-
968
-
969
-    /**
970
-     * @throws EE_Error
971
-     */
972
-    protected function _ee_default_messages_overview_list_table()
973
-    {
974
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
975
-        $this->display_admin_list_table_page_with_no_sidebar();
976
-    }
977
-
978
-
979
-    /**
980
-     * @throws EE_Error
981
-     * @throws ReflectionException
982
-     */
983
-    protected function _message_queue_list_table()
984
-    {
985
-        $this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
986
-        $this->_template_args['per_column']        = 6;
987
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
988
-        $message_results                           = trim(EEM_Message::instance()->get_pretty_label_for_results());
989
-        $this->_template_args['before_list_table'] = ! empty($message_results) ? "<h3>{$message_results}</h3>" : '';
990
-        $this->display_admin_list_table_page_with_no_sidebar();
991
-    }
992
-
993
-
994
-    /**
995
-     * @throws EE_Error
996
-     */
997
-    protected function _message_legend_items()
998
-    {
999
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1000
-        $action_items       = [];
1001
-
1002
-        foreach ($action_css_classes as $action_item => $action_details) {
1003
-            if ($action_item === 'see_notifications_for') {
1004
-                continue;
1005
-            }
1006
-            $action_items[ $action_item ] = [
1007
-                'class' => $action_details['css_class'],
1008
-                'desc'  => $action_details['label'],
1009
-            ];
1010
-        }
1011
-
1012
-        /** @var array $status_items status legend setup */
1013
-        $status_items = [
1014
-            'sent_status'                => [
1015
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_sent,
1016
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1017
-            ],
1018
-            'idle_status'                => [
1019
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_idle,
1020
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1021
-            ],
1022
-            'failed_status'              => [
1023
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_failed,
1024
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1025
-            ],
1026
-            'messenger_executing_status' => [
1027
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_messenger_executing,
1028
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1029
-            ],
1030
-            'resend_status'              => [
1031
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_resend,
1032
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1033
-            ],
1034
-            'incomplete_status'          => [
1035
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_incomplete,
1036
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1037
-            ],
1038
-            'retry_status'               => [
1039
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_retry,
1040
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1041
-            ],
1042
-        ];
1043
-        if (EEM_Message::debug()) {
1044
-            $status_items['debug_only_status'] = [
1045
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_debug_only,
1046
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1047
-            ];
1048
-        }
1049
-
1050
-        return array_merge($action_items, $status_items);
1051
-    }
1052
-
1053
-
1054
-    /**
1055
-     * @throws EE_Error
1056
-     */
1057
-    protected function _custom_mtps_preview()
1058
-    {
1059
-        $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1060
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1061
-                                                . ' alt="' . esc_attr__(
1062
-                                                    'Preview Custom Message Templates screenshot',
1063
-                                                    'event_espresso'
1064
-                                                ) . '" />';
1065
-        $this->_template_args['preview_text'] = '<strong>'
1066
-                                                . esc_html__(
1067
-                                                    'Custom Message Templates 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 Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1068
-                                                    'event_espresso'
1069
-                                                )
1070
-                                                . '</strong>';
1071
-
1072
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1073
-    }
1074
-
1075
-
1076
-    /**
1077
-     * get_message_templates
1078
-     * This gets all the message templates for listing on the overview list.
1079
-     *
1080
-     * @param int    $per_page the amount of templates groups to show per page
1081
-     * @param string $type     the current _view we're getting templates for
1082
-     * @param bool   $count    return count?
1083
-     * @param bool   $all      disregard any paging info (get all data);
1084
-     * @param bool   $global   whether to return just global (true) or custom templates (false)
1085
-     * @return array|int
1086
-     * @throws EE_Error
1087
-     * @throws InvalidArgumentException
1088
-     * @throws InvalidDataTypeException
1089
-     * @throws InvalidInterfaceException
1090
-     * @throws ReflectionException
1091
-     */
1092
-    public function get_message_templates(
1093
-        int $per_page = 10,
1094
-        string $type = 'in_use',
1095
-        bool $count = false,
1096
-        bool $all = false,
1097
-        bool $global = true
1098
-    ) {
1099
-        $orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1100
-        // ensure that the orderby param is actually set within the request data
1101
-        $this->request->setRequestParam('orderby', $orderby);
1102
-        $order        = $this->request->getRequestParam('order', 'ASC');
1103
-        $current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
1104
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
1105
-
1106
-        $offset = ($current_page - 1) * $per_page;
1107
-        $limit  = $all ? null : [$offset, $per_page];
1108
-
1109
-        // options will match what is in the _views array property
1110
-        return $type === 'in_use'
1111
-            ? $this->getMtgModel()->get_all_active_message_templates(
1112
-                $orderby,
1113
-                $order,
1114
-                $limit,
1115
-                $count,
1116
-                $global,
1117
-                true
1118
-            )
1119
-            : $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1120
-                $orderby,
1121
-                $order,
1122
-                $limit,
1123
-                $count,
1124
-                $global
1125
-            );
1126
-    }
1127
-
1128
-
1129
-    /**
1130
-     * filters etc might need a list of installed message_types
1131
-     *
1132
-     * @return array an array of message type objects
1133
-     */
1134
-    public function get_installed_message_types(): array
1135
-    {
1136
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1137
-        $installed               = [];
1138
-
1139
-        foreach ($installed_message_types as $message_type) {
1140
-            $installed[ $message_type->name ] = $message_type;
1141
-        }
1142
-
1143
-        return $installed;
1144
-    }
1145
-
1146
-
1147
-    /**
1148
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1149
-     *
1150
-     * @param string     $message_type
1151
-     * @param string     $messenger
1152
-     * @param int|string $GRP_ID
1153
-     * @throws EE_error
1154
-     * @throws ReflectionException
1155
-     * @deprecated 5.0.8.p
1156
-     */
1157
-    public function add_message_template(string $message_type = '', string $messenger = '', $GRP_ID = '')
1158
-    {
1159
-        $this->insertMessageTemplate();
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * @param string $message_type     message type slug
1165
-     * @param string $messenger        messenger slug
1166
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1167
-     *                                 off of.
1168
-     * @throws EE_error
1169
-     * @throws ReflectionException
1170
-     * @deprecated 4.10.29.p
1171
-     */
1172
-    protected function _add_message_template($message_type, $messenger, $GRP_ID)
1173
-    {
1174
-        $this->insertMessageTemplate($message_type, $messenger, $GRP_ID);
1175
-    }
1176
-
1177
-
1178
-    /**
1179
-     * _edit_message_template
1180
-     *
1181
-     * @access protected
1182
-     * @return void
1183
-     * @throws InvalidIdentifierException
1184
-     * @throws DomainException
1185
-     * @throws EE_Error
1186
-     * @throws InvalidArgumentException
1187
-     * @throws ReflectionException
1188
-     * @throws InvalidDataTypeException
1189
-     * @throws InvalidInterfaceException
1190
-     */
1191
-    protected function _edit_message_template()
1192
-    {
1193
-        $template_fields = '';
1194
-        $sidebar_fields  = '';
1195
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1196
-        // valid html in the templates.
1197
-        add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1198
-
1199
-        $GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
1200
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', $GRP_ID, DataType::INTEGER);
1201
-
1202
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, DataType::INTEGER);
1203
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', $EVT_ID, DataType::INTEGER);
1204
-
1205
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1206
-        $message_template_group = $this->_message_template_group;
1207
-        $c_label                = $message_template_group->context_label();
1208
-        $c_config               = $message_template_group->contexts_config();
1209
-
1210
-        reset($c_config);
1211
-        $context = $this->request->getRequestParam('context', key($c_config));
1212
-        $context = strtolower($context);
1213
-
1214
-        $action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1215
-
1216
-        $edit_message_template_form_url = add_query_arg(
1217
-            ['action' => $action, 'noheader' => true],
1218
-            EE_MSG_ADMIN_URL
1219
-        );
1220
-
1221
-        // set active messenger for this view
1222
-        $this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1223
-            $message_template_group->messenger()
1224
-        );
1225
-        $this->_active_message_type_name = $message_template_group->message_type();
1226
-
1227
-
1228
-        // Do we have any validation errors?
1229
-        $validators = $this->_get_transient();
1230
-        $v_fields   = ! empty($validators) ? array_keys($validators) : [];
1231
-
1232
-
1233
-        // we need to assemble the title from Various details
1234
-        $context_label = sprintf(
1235
-            esc_html__('(%s %s)', 'event_espresso'),
1236
-            $c_config[ $context ]['label'],
1237
-            ucwords($c_label['label'])
1238
-        );
1239
-
1240
-        $title = sprintf(
1241
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1242
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1243
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1244
-            $context_label
1245
-        );
1246
-
1247
-        $this->_template_args['GRP_ID']           = $GRP_ID;
1248
-        $this->_template_args['message_template'] = $message_template_group;
1249
-        $this->_template_args['is_extra_fields']  = false;
1250
-
1251
-
1252
-        // let's get EEH_MSG_Template so we can get template form fields
1253
-        $template_field_structure = EEH_MSG_Template::get_fields(
1254
-            $message_template_group->messenger(),
1255
-            $message_template_group->message_type()
1256
-        );
1257
-
1258
-        if (! $template_field_structure) {
1259
-            $template_field_structure = false;
1260
-            $template_fields          = esc_html__(
1261
-                'There was an error in assembling the fields for this display (you should see an error message)',
1262
-                'event_espresso'
1263
-            );
1264
-        }
1265
-
1266
-        $message_templates = $message_template_group->context_templates();
1267
-
1268
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1269
-        // will get handled in the "extra" array.
1270
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1271
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1272
-                unset($template_field_structure[ $context ][ $reference_field ]);
1273
-            }
1274
-        }
1275
-
1276
-        // let's loop through the template_field_structure and actually assemble the input fields!
1277
-        if (! empty($template_field_structure)) {
1278
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1279
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1280
-                // the extra array and reset them.
1281
-                if ($template_field === 'extra') {
1282
-                    $this->_template_args['is_extra_fields'] = true;
1283
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1284
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1285
-                        $content          = $message_template instanceof EE_Message_Template
1286
-                            ? $message_template->get('MTP_content')
1287
-                            : '';
1288
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1289
-                            // let's verify if we need this extra field via the shortcodes parameter.
1290
-                            $continue = false;
1291
-                            if (isset($extra_array['shortcodes_required'])) {
1292
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1293
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1294
-                                        $continue = true;
1295
-                                    }
1296
-                                }
1297
-                                if ($continue) {
1298
-                                    continue;
1299
-                                }
1300
-                            }
1301
-
1302
-                            $field_id = $reference_field . '-' . $extra_field . '-content';
1303
-
1304
-                            $template_form_fields[ $field_id ]         = $extra_array;
1305
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1306
-                                                                         . $reference_field
1307
-                                                                         . '][content]['
1308
-                                                                         . $extra_field . ']';
1309
-                            $css_class                                 = $extra_array['css_class'] ?? '';
1310
-
1311
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1312
-                                                                              && in_array($extra_field, $v_fields, true)
1313
-                                                                              && (
1314
-                                                                                  is_array($validators[ $extra_field ])
1315
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1316
-                                                                              )
1317
-                                ? 'validate-error ' . $css_class
1318
-                                : $css_class;
1319
-
1320
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1321
-                                                                          && isset($content[ $extra_field ])
1322
-                                ? $content[ $extra_field ]
1323
-                                : '';
1324
-
1325
-                            // do we have a validation error?  if we do then let's use that value instead
1326
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1327
-                                ? $validators[ $extra_field ]['value']
1328
-                                : $template_form_fields[ $field_id ]['value'];
1329
-
1330
-
1331
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1332
-
1333
-                            // shortcode selector
1334
-                            $field_name_to_use                                   = $extra_field === 'main'
1335
-                                ? 'content'
1336
-                                : $extra_field;
1337
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1338
-                                $field_name_to_use,
1339
-                                $field_id
1340
-                            );
1341
-                        }
1342
-                        $template_field_MTP_id           = $reference_field . '-MTP_ID';
1343
-                        $template_field_template_name_id = $reference_field . '-name';
1344
-
1345
-                        $template_form_fields[ $template_field_MTP_id ] = [
1346
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1347
-                            'label'      => null,
1348
-                            'input'      => 'hidden',
1349
-                            'type'       => 'int',
1350
-                            'required'   => false,
1351
-                            'validation' => false,
1352
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1353
-                            'css_class'  => '',
1354
-                            'format'     => '%d',
1355
-                            'db-col'     => 'MTP_ID',
1356
-                        ];
1357
-
1358
-                        $template_form_fields[ $template_field_template_name_id ] = [
1359
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1360
-                            'label'      => null,
1361
-                            'input'      => 'hidden',
1362
-                            'type'       => 'string',
1363
-                            'required'   => false,
1364
-                            'validation' => true,
1365
-                            'value'      => $reference_field,
1366
-                            'css_class'  => '',
1367
-                            'format'     => '%s',
1368
-                            'db-col'     => 'MTP_template_field',
1369
-                        ];
1370
-                    }
1371
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1372
-                } else {
1373
-                    $field_id                                   = $template_field . '-content';
1374
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1375
-                    $template_form_fields[ $field_id ]['name']  =
1376
-                        'MTP_template_fields[' . $template_field . '][content]';
1377
-                    $message_template                           =
1378
-                        $message_templates[ $context ][ $template_field ] ?? null;
1379
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1380
-                                                                  && is_array($message_templates[ $context ])
1381
-                                                                  && $message_template instanceof EE_Message_Template
1382
-                        ? $message_template->get('MTP_content')
1383
-                        : '';
1384
-
1385
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1386
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1387
-                        ? $validators[ $template_field ]['value']
1388
-                        : $template_form_fields[ $field_id ]['value'];
1389
-
1390
-
1391
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1392
-                    $css_class                                      = $field_setup_array['css_class'] ?? '';
1393
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1394
-                                                                      && in_array($template_field, $v_fields, true)
1395
-                                                                      && isset($validators[ $template_field ]['msg'])
1396
-                        ? 'validate-error ' . $css_class
1397
-                        : $css_class;
1398
-
1399
-                    // shortcode selector
1400
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1401
-                        $template_field,
1402
-                        $field_id
1403
-                    );
1404
-                }
1405
-
1406
-                // k took care of content field(s) now let's take care of others.
1407
-
1408
-                $template_field_MTP_id                 = $template_field . '-MTP_ID';
1409
-                $template_field_field_template_name_id = $template_field . '-name';
1410
-
1411
-                // foreach template field there are actually two form fields created
1412
-                $template_form_fields[ $template_field_MTP_id ] = [
1413
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1414
-                    'label'      => null,
1415
-                    'input'      => 'hidden',
1416
-                    'type'       => 'int',
1417
-                    'required'   => false,
1418
-                    'validation' => true,
1419
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1420
-                    'css_class'  => '',
1421
-                    'format'     => '%d',
1422
-                    'db-col'     => 'MTP_ID',
1423
-                ];
1424
-
1425
-                $template_form_fields[ $template_field_field_template_name_id ] = [
1426
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1427
-                    'label'      => null,
1428
-                    'input'      => 'hidden',
1429
-                    'type'       => 'string',
1430
-                    'required'   => false,
1431
-                    'validation' => true,
1432
-                    'value'      => $template_field,
1433
-                    'css_class'  => '',
1434
-                    'format'     => '%s',
1435
-                    'db-col'     => 'MTP_template_field',
1436
-                ];
1437
-            }
1438
-
1439
-            // add other fields
1440
-            $template_form_fields['ee-msg-current-context'] = [
1441
-                'name'       => 'MTP_context',
1442
-                'label'      => null,
1443
-                'input'      => 'hidden',
1444
-                'type'       => 'string',
1445
-                'required'   => false,
1446
-                'validation' => true,
1447
-                'value'      => $context,
1448
-                'css_class'  => '',
1449
-                'format'     => '%s',
1450
-                'db-col'     => 'MTP_context',
1451
-            ];
1452
-
1453
-            $template_form_fields['ee-msg-grp-id'] = [
1454
-                'name'       => 'GRP_ID',
1455
-                'label'      => null,
1456
-                'input'      => 'hidden',
1457
-                'type'       => 'int',
1458
-                'required'   => false,
1459
-                'validation' => true,
1460
-                'value'      => $GRP_ID,
1461
-                'css_class'  => '',
1462
-                'format'     => '%d',
1463
-                'db-col'     => 'GRP_ID',
1464
-            ];
1465
-
1466
-            $template_form_fields['ee-msg-messenger'] = [
1467
-                'name'       => 'MTP_messenger',
1468
-                'label'      => null,
1469
-                'input'      => 'hidden',
1470
-                'type'       => 'string',
1471
-                'required'   => false,
1472
-                'validation' => true,
1473
-                'value'      => $message_template_group->messenger(),
1474
-                'css_class'  => '',
1475
-                'format'     => '%s',
1476
-                'db-col'     => 'MTP_messenger',
1477
-            ];
1478
-
1479
-            $template_form_fields['ee-msg-message-type'] = [
1480
-                'name'       => 'MTP_message_type',
1481
-                'label'      => null,
1482
-                'input'      => 'hidden',
1483
-                'type'       => 'string',
1484
-                'required'   => false,
1485
-                'validation' => true,
1486
-                'value'      => $message_template_group->message_type(),
1487
-                'css_class'  => '',
1488
-                'format'     => '%s',
1489
-                'db-col'     => 'MTP_message_type',
1490
-            ];
1491
-
1492
-            $sidebar_form_fields['ee-msg-is-global'] = [
1493
-                'name'       => 'MTP_is_global',
1494
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1495
-                'input'      => 'hidden',
1496
-                'type'       => 'int',
1497
-                'required'   => false,
1498
-                'validation' => true,
1499
-                'value'      => $message_template_group->get('MTP_is_global'),
1500
-                'css_class'  => '',
1501
-                'format'     => '%d',
1502
-                'db-col'     => 'MTP_is_global',
1503
-            ];
1504
-
1505
-            $sidebar_form_fields['ee-msg-is-override'] = [
1506
-                'name'       => 'MTP_is_override',
1507
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1508
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1509
-                'type'       => 'int',
1510
-                'required'   => false,
1511
-                'validation' => true,
1512
-                'value'      => $message_template_group->get('MTP_is_override'),
1513
-                'css_class'  => '',
1514
-                'format'     => '%d',
1515
-                'db-col'     => 'MTP_is_override',
1516
-            ];
1517
-
1518
-            $sidebar_form_fields['ee-msg-is-active'] = [
1519
-                'name'       => 'MTP_is_active',
1520
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1521
-                'input'      => 'hidden',
1522
-                'type'       => 'int',
1523
-                'required'   => false,
1524
-                'validation' => true,
1525
-                'value'      => $message_template_group->is_active(),
1526
-                'css_class'  => '',
1527
-                'format'     => '%d',
1528
-                'db-col'     => 'MTP_is_active',
1529
-            ];
1530
-
1531
-            $sidebar_form_fields['ee-msg-deleted'] = [
1532
-                'name'       => 'MTP_deleted',
1533
-                'label'      => null,
1534
-                'input'      => 'hidden',
1535
-                'type'       => 'int',
1536
-                'required'   => false,
1537
-                'validation' => true,
1538
-                'value'      => $message_template_group->get('MTP_deleted'),
1539
-                'css_class'  => '',
1540
-                'format'     => '%d',
1541
-                'db-col'     => 'MTP_deleted',
1542
-            ];
1543
-            $sidebar_form_fields['ee-msg-author']  = [
1544
-                'name'       => 'MTP_user_id',
1545
-                'label'      => esc_html__('Author', 'event_espresso'),
1546
-                'input'      => 'hidden',
1547
-                'type'       => 'int',
1548
-                'required'   => false,
1549
-                'validation' => false,
1550
-                'value'      => $message_template_group->user(),
1551
-                'format'     => '%d',
1552
-                'db-col'     => 'MTP_user_id',
1553
-            ];
1554
-
1555
-            $sidebar_form_fields['ee-msg-route'] = [
1556
-                'name'  => 'action',
1557
-                'input' => 'hidden',
1558
-                'type'  => 'string',
1559
-                'value' => $action,
1560
-            ];
1561
-
1562
-            $sidebar_form_fields['ee-msg-id']        = [
1563
-                'name'  => 'id',
1564
-                'input' => 'hidden',
1565
-                'type'  => 'int',
1566
-                'value' => $GRP_ID,
1567
-            ];
1568
-            $sidebar_form_fields['ee-msg-evt-nonce'] = [
1569
-                'name'  => $action . '_nonce',
1570
-                'input' => 'hidden',
1571
-                'type'  => 'string',
1572
-                'value' => wp_create_nonce($action . '_nonce'),
1573
-            ];
1574
-
1575
-            $template_switch = $this->request->getRequestParam('template_switch');
1576
-            if ($template_switch) {
1577
-                $sidebar_form_fields['ee-msg-template-switch'] = [
1578
-                    'name'  => 'template_switch',
1579
-                    'input' => 'hidden',
1580
-                    'type'  => 'int',
1581
-                    'value' => 1,
1582
-                ];
1583
-            }
1584
-
1585
-
1586
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1587
-            $sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1588
-        } //end if ( !empty($template_field_structure) )
1589
-
1590
-        // set extra content for publish box
1591
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1592
-        $this->_set_publish_post_box_vars(
1593
-            'id',
1594
-            $GRP_ID,
1595
-            '',
1596
-            add_query_arg(
1597
-                ['action' => $message_template_group->is_global() ? 'global_mtps' : 'custom_mtps'],
1598
-                $this->_admin_base_url
1599
-            ),
1600
-            true
1601
-        );
1602
-
1603
-        // add preview button
1604
-        $preview_url    = parent::add_query_args_and_nonce(
1605
-            [
1606
-                'message_type' => $message_template_group->message_type(),
1607
-                'messenger'    => $message_template_group->messenger(),
1608
-                'context'      => $context,
1609
-                'GRP_ID'       => $GRP_ID,
1610
-                'evt_id'       => $EVT_ID ?: false,
1611
-                'action'       => 'preview_message',
1612
-            ],
1613
-            $this->_admin_base_url
1614
-        );
1615
-        $preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1616
-                          . esc_html__('Preview', 'event_espresso')
1617
-                          . '</a>';
1618
-
1619
-
1620
-        // setup context switcher
1621
-        $this->_set_context_switcher(
1622
-            $message_template_group,
1623
-            [
1624
-                'page'    => 'espresso_messages',
1625
-                'action'  => 'edit_message_template',
1626
-                'id'      => $GRP_ID,
1627
-                'evt_id'  => $EVT_ID,
1628
-                'context' => $context,
1629
-                'extra'   => $preview_button,
1630
-            ]
1631
-        );
1632
-
1633
-        // main box
1634
-        $this->_template_args['template_fields']                         = $template_fields;
1635
-        $this->_template_args['sidebar_box_id']                          = 'details';
1636
-        $this->_template_args['action']                                  = $action;
1637
-        $this->_template_args['context']                                 = $context;
1638
-        $this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1639
-        $this->_template_args['learn_more_about_message_templates_link'] =
1640
-            $this->_learn_more_about_message_templates_link();
1641
-
1642
-        $this->_template_args['before_admin_page_content'] = '<div class="ee-msg-admin-header">';
1643
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1644
-            $message_template_group,
1645
-            $context,
1646
-            $context_label
1647
-        );
1648
-        $this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1649
-        $this->_template_args['before_admin_page_content'] .= '</div>';
1650
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1651
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1652
-
1653
-        $this->_template_path = $this->_template_args['GRP_ID']
1654
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1655
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1656
-
1657
-        // send along EE_Message_Template_Group object for further template use.
1658
-        $this->_template_args['MTP'] = $message_template_group;
1659
-
1660
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1661
-            $this->_template_path,
1662
-            $this->_template_args,
1663
-            true
1664
-        );
1665
-
1666
-        // finally, let's set the admin_page title
1667
-        $this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1668
-
1669
-        // we need to take care of setting the shortcodes property for use elsewhere.
1670
-        $this->_set_shortcodes();
1671
-
1672
-        // final template wrapper
1673
-        $this->display_admin_page_with_sidebar();
1674
-    }
1675
-
1676
-
1677
-    public function filter_tinymce_init($mceInit, $editor_id)
1678
-    {
1679
-        return $mceInit;
1680
-    }
1681
-
1682
-
1683
-    public function add_context_switcher()
1684
-    {
1685
-        return $this->_context_switcher;
1686
-    }
1687
-
1688
-
1689
-    /**
1690
-     * Adds the activation/deactivation toggle for the message template context.
1691
-     *
1692
-     * @param EE_Message_Template_Group $message_template_group
1693
-     * @param string                    $context
1694
-     * @param string                    $context_label
1695
-     * @return string
1696
-     * @throws DomainException
1697
-     * @throws EE_Error
1698
-     * @throws InvalidIdentifierException
1699
-     * @throws ReflectionException
1700
-     */
1701
-    protected function add_active_context_element(
1702
-        EE_Message_Template_Group $message_template_group,
1703
-        $context,
1704
-        $context_label
1705
-    ) {
1706
-        $template_args = [
1707
-            'context'                   => $context,
1708
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1709
-            'is_active'                 => $message_template_group->is_context_active($context),
1710
-            'on_off_action'             => $message_template_group->is_context_active($context)
1711
-                ? 'context-off'
1712
-                : 'context-on',
1713
-            'context_label'             => str_replace(['(', ')'], '', $context_label),
1714
-            'message_template_group_id' => $message_template_group->ID(),
1715
-        ];
1716
-        return EEH_Template::display_template(
1717
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1718
-            $template_args,
1719
-            true
1720
-        );
1721
-    }
1722
-
1723
-
1724
-    /**
1725
-     * Ajax callback for `toggle_context_template` ajax action.
1726
-     * Handles toggling the message context on or off.
1727
-     *
1728
-     * @throws EE_Error
1729
-     * @throws InvalidArgumentException
1730
-     * @throws InvalidDataTypeException
1731
-     * @throws InvalidIdentifierException
1732
-     * @throws InvalidInterfaceException
1733
-     * @throws ReflectionException
1734
-     */
1735
-    public function toggle_context_template()
1736
-    {
1737
-        $success = true;
1738
-        // check for required data
1739
-        if (
1740
-            ! (
1741
-                $this->request->requestParamIsSet('message_template_group_id')
1742
-                && $this->request->requestParamIsSet('context')
1743
-                && $this->request->requestParamIsSet('status')
1744
-            )
1745
-        ) {
1746
-            EE_Error::add_error(
1747
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1748
-                __FILE__,
1749
-                __FUNCTION__,
1750
-                __LINE__
1751
-            );
1752
-            $success = false;
1753
-        }
1754
-
1755
-        $nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1756
-        $context = $this->request->getRequestParam('context', '');
1757
-        $status  = $this->request->getRequestParam('status', '');
1758
-
1759
-        $this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1760
-
1761
-        if ($status !== 'off' && $status !== 'on') {
1762
-            EE_Error::add_error(
1763
-                sprintf(
1764
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1765
-                    $status
1766
-                ),
1767
-                __FILE__,
1768
-                __FUNCTION__,
1769
-                __LINE__
1770
-            );
1771
-            $success = false;
1772
-        }
1773
-        $message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, DataType::INTEGER);
1774
-        $message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1775
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1776
-            EE_Error::add_error(
1777
-                sprintf(
1778
-                    esc_html__(
1779
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1780
-                        'event_espresso'
1781
-                    ),
1782
-                    $message_template_group_id,
1783
-                    'EE_Message_Template_Group'
1784
-                ),
1785
-                __FILE__,
1786
-                __FUNCTION__,
1787
-                __LINE__
1788
-            );
1789
-            $success = false;
1790
-        }
1791
-        if ($success) {
1792
-            $success = $status === 'off'
1793
-                ? $message_template_group->deactivate_context($context)
1794
-                : $message_template_group->activate_context($context);
1795
-        }
1796
-        $this->_template_args['success'] = $success;
1797
-        $this->_return_json();
1798
-    }
1799
-
1800
-
1801
-    public function _add_form_element_before()
1802
-    {
1803
-        return '<form method="post" action="'
1804
-               . $this->_template_args['edit_message_template_form_url']
1805
-               . '" id="ee-msg-edit-frm">';
1806
-    }
1807
-
1808
-
1809
-    public function _add_form_element_after()
1810
-    {
1811
-        return '</form>';
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     * This executes switching the template pack for a message template.
1817
-     *
1818
-     * @throws EE_Error
1819
-     * @throws InvalidDataTypeException
1820
-     * @throws InvalidInterfaceException
1821
-     * @throws InvalidArgumentException
1822
-     * @throws ReflectionException
1823
-     * @since 4.5.0
1824
-     */
1825
-    public function switch_template_pack()
1826
-    {
1827
-        $GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1828
-        $template_pack = $this->request->getRequestParam('template_pack', '');
1829
-
1830
-        // verify we have needed values.
1831
-        if (empty($GRP_ID) || empty($template_pack)) {
1832
-            $this->_template_args['error'] = true;
1833
-            EE_Error::add_error(
1834
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1835
-                __FILE__,
1836
-                __FUNCTION__,
1837
-                __LINE__
1838
-            );
1839
-        } else {
1840
-            // get template, set the new template_pack and then reset to default
1841
-            /** @var EE_Message_Template_Group $message_template_group */
1842
-            $message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
1843
-
1844
-            $message_template_group->set_template_pack_name($template_pack);
1845
-            $this->request->setRequestParam('msgr', $message_template_group->messenger());
1846
-            $this->request->setRequestParam('mt', $message_template_group->message_type());
1847
-
1848
-            $query_args = $this->_reset_to_default_template();
1849
-
1850
-            if (empty($query_args['id'])) {
1851
-                EE_Error::add_error(
1852
-                    esc_html__(
1853
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
1854
-                        'event_espresso'
1855
-                    ),
1856
-                    __FILE__,
1857
-                    __FUNCTION__,
1858
-                    __LINE__
1859
-                );
1860
-                $this->_template_args['error'] = true;
1861
-            } else {
1862
-                $template_label       = $message_template_group->get_template_pack()->label;
1863
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1864
-                EE_Error::add_success(
1865
-                    sprintf(
1866
-                        esc_html__(
1867
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1868
-                            'event_espresso'
1869
-                        ),
1870
-                        $template_label,
1871
-                        $template_pack_labels->template_pack
1872
-                    )
1873
-                );
1874
-                // generate the redirect url for js.
1875
-                $url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1876
-
1877
-                $this->_template_args['data']['redirect_url'] = $url;
1878
-                $this->_template_args['success']              = true;
1879
-            }
1880
-
1881
-            $this->_return_json();
1882
-        }
1883
-    }
1884
-
1885
-
1886
-    /**
1887
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
1888
-     * they want.
1889
-     *
1890
-     * @access protected
1891
-     * @return array|void
1892
-     * @throws EE_Error
1893
-     * @throws InvalidArgumentException
1894
-     * @throws InvalidDataTypeException
1895
-     * @throws InvalidInterfaceException
1896
-     * @throws ReflectionException
1897
-     */
1898
-    protected function _reset_to_default_template()
1899
-    {
1900
-        $templates    = [];
1901
-        $GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1902
-        $messenger    = $this->request->getRequestParam('msgr');
1903
-        $message_type = $this->request->getRequestParam('mt');
1904
-        // we need to make sure we've got the info we need.
1905
-        if (! ($GRP_ID && $messenger && $message_type)) {
1906
-            EE_Error::add_error(
1907
-                esc_html__(
1908
-                    'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
1909
-                    'event_espresso'
1910
-                ),
1911
-                __FILE__,
1912
-                __FUNCTION__,
1913
-                __LINE__
1914
-            );
1915
-        }
1916
-
1917
-        // all templates will be reset to whatever the defaults are
1918
-        // for the global template matching the messenger and message type.
1919
-        $success = ! empty($GRP_ID);
1920
-
1921
-        if ($success) {
1922
-            // let's first determine if the incoming template is a global template,
1923
-            // if it isn't then we need to get the global template matching messenger and message type.
1924
-            // $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
1925
-
1926
-
1927
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
1928
-            $success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplates($GRP_ID);
1929
-
1930
-            if ($success) {
1931
-                // if successfully deleted, lets generate the new ones.
1932
-                // Note. We set GLOBAL to true, because resets on ANY template
1933
-                // will use the related global template defaults for regeneration.
1934
-                // This means that if a custom template is reset it resets to whatever the related global template is.
1935
-                // HOWEVER, we DO keep the template pack and template variation set
1936
-                // for the current custom template when resetting.
1937
-                $templates = $this->getMessageTemplateManager()->generateNewTemplates(
1938
-                    $messenger,
1939
-                    $message_type,
1940
-                    $GRP_ID,
1941
-                    true
1942
-                );
1943
-            }
1944
-        }
1945
-
1946
-        // any error messages?
1947
-        if (! $success) {
1948
-            EE_Error::add_error(
1949
-                esc_html__(
1950
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
1951
-                    'event_espresso'
1952
-                ),
1953
-                __FILE__,
1954
-                __FUNCTION__,
1955
-                __LINE__
1956
-            );
1957
-        }
1958
-
1959
-        // all good, let's add a success message!
1960
-        if ($success && ! empty($templates)) {
1961
-            // the info for the template we generated is the first element in the returned array
1962
-            EE_Error::overwrite_success();
1963
-            EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
1964
-        }
1965
-
1966
-
1967
-        $query_args = [
1968
-            'id'      => $templates['GRP_ID'] ?? null,
1969
-            'context' => $templates['MTP_context'] ?? null,
1970
-            'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
1971
-        ];
1972
-
1973
-        // if called via ajax then we return query args otherwise redirect
1974
-        if ($this->request->isAjax()) {
1975
-            return $query_args;
1976
-        }
1977
-        $this->_redirect_after_action(false, '', '', $query_args, true);
1978
-    }
1979
-
1980
-
1981
-    /**
1982
-     * Retrieve and set the message preview for display.
1983
-     *
1984
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
1985
-     * @return string
1986
-     * @throws ReflectionException
1987
-     * @throws EE_Error
1988
-     * @throws InvalidArgumentException
1989
-     * @throws InvalidDataTypeException
1990
-     * @throws InvalidInterfaceException
1991
-     */
1992
-    public function _preview_message($send = false)
1993
-    {
1994
-        // first make sure we've got the necessary parameters
1995
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1996
-        if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
1997
-            EE_Error::add_error(
1998
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
1999
-                __FILE__,
2000
-                __FUNCTION__,
2001
-                __LINE__
2002
-            );
2003
-        }
2004
-
2005
-        $context = $this->request->getRequestParam('context');
2006
-        // get the preview!
2007
-        $preview = EED_Messages::preview_message(
2008
-            $this->_active_message_type_name,
2009
-            $context,
2010
-            $this->_active_messenger_name,
2011
-            $send
2012
-        );
2013
-
2014
-        if ($send) {
2015
-            return $preview;
2016
-        }
2017
-
2018
-        // if we have an evt_id set on the request, use it.
2019
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, DataType::INTEGER);
2020
-
2021
-        // let's add a button to go back to the edit view
2022
-        $query_args             = [
2023
-            'id'      => $GRP_ID,
2024
-            'evt_id'  => $EVT_ID,
2025
-            'context' => $context,
2026
-            'action'  => 'edit_message_template',
2027
-        ];
2028
-        $go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2029
-        $preview_button         = '<a href="'
2030
-                                  . $go_back_url
2031
-                                  . '" class="button--secondary messages-preview-go-back-button">'
2032
-                                  . esc_html__('Go Back to Edit', 'event_espresso')
2033
-                                  . '</a>';
2034
-        $message_types          = $this->get_installed_message_types();
2035
-        $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2036
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2037
-            ? ucwords($active_messenger->label['singular'])
2038
-            : esc_html__('Unknown Messenger', 'event_espresso');
2039
-        // let's provide a helpful title for context
2040
-        $preview_title = sprintf(
2041
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2042
-            $active_messenger_label,
2043
-            ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2044
-        );
2045
-        if (empty($preview)) {
2046
-            $this->noEventsErrorMessage();
2047
-        }
2048
-        // setup display of preview.
2049
-        $this->_admin_page_title                    = $preview_title;
2050
-        $this->_template_args['admin_page_title']   = $preview_title;
2051
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2052
-        $this->_template_args['data']['force_json'] = true;
2053
-
2054
-        return '';
2055
-    }
2056
-
2057
-
2058
-    /**
2059
-     * Used to set an error if there are no events available for generating a preview/test send.
2060
-     *
2061
-     * @param bool $test_send Whether the error should be generated for the context of a test send.
2062
-     */
2063
-    protected function noEventsErrorMessage($test_send = false)
2064
-    {
2065
-        $events_url = parent::add_query_args_and_nonce(
2066
-            [
2067
-                'action' => 'default',
2068
-                'page'   => 'espresso_events',
2069
-            ],
2070
-            admin_url('admin.php')
2071
-        );
2072
-        $message    = $test_send
2073
-            ? esc_html__(
2074
-                'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2075
-                'event_espresso'
2076
-            )
2077
-            : esc_html__(
2078
-                'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2079
-                'event_espresso'
2080
-            );
2081
-
2082
-        EE_Error::add_attention(
2083
-            sprintf(
2084
-                $message,
2085
-                "<a href='{$events_url}'>",
2086
-                '</a>'
2087
-            )
2088
-        );
2089
-    }
2090
-
2091
-
2092
-    /**
2093
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2094
-     * gets called automatically.
2095
-     *
2096
-     * @return void
2097
-     * @throws EE_Error
2098
-     * @since 4.5.0
2099
-     */
2100
-    protected function _display_preview_message()
2101
-    {
2102
-        $this->display_admin_page_with_no_sidebar();
2103
-    }
2104
-
2105
-
2106
-    /**
2107
-     * registers metaboxes that should show up on the "edit_message_template" page
2108
-     *
2109
-     * @access protected
2110
-     * @return void
2111
-     */
2112
-    protected function _register_edit_meta_boxes()
2113
-    {
2114
-        $this->addMetaBox(
2115
-            'mtp_valid_shortcodes',
2116
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2117
-            [$this, 'shortcode_meta_box'],
2118
-            $this->_current_screen->id,
2119
-            'side'
2120
-        );
2121
-        $this->addMetaBox(
2122
-            'mtp_extra_actions',
2123
-            esc_html__('Extra Actions', 'event_espresso'),
2124
-            [$this, 'extra_actions_meta_box'],
2125
-            $this->_current_screen->id,
2126
-            'side',
2127
-            'high'
2128
-        );
2129
-        $this->addMetaBox(
2130
-            'mtp_templates',
2131
-            esc_html__('Template Styles', 'event_espresso'),
2132
-            [$this, 'template_pack_meta_box'],
2133
-            $this->_current_screen->id,
2134
-            'side',
2135
-            'high'
2136
-        );
2137
-    }
2138
-
2139
-
2140
-    /**
2141
-     * metabox content for all template pack and variation selection.
2142
-     *
2143
-     * @return void
2144
-     * @throws DomainException
2145
-     * @throws EE_Error
2146
-     * @throws InvalidArgumentException
2147
-     * @throws ReflectionException
2148
-     * @throws InvalidDataTypeException
2149
-     * @throws InvalidInterfaceException
2150
-     * @since 4.5.0
2151
-     */
2152
-    public function template_pack_meta_box()
2153
-    {
2154
-        $this->_set_message_template_group();
2155
-
2156
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2157
-
2158
-        $tp_select_values = [];
2159
-
2160
-        foreach ($tp_collection as $tp) {
2161
-            // only include template packs that support this messenger and message type!
2162
-            $supports = $tp->get_supports();
2163
-            if (
2164
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2165
-                || ! in_array(
2166
-                    $this->_message_template_group->message_type(),
2167
-                    $supports[ $this->_message_template_group->messenger() ],
2168
-                    true
2169
-                )
2170
-            ) {
2171
-                // not supported
2172
-                continue;
2173
-            }
2174
-
2175
-            $tp_select_values[] = [
2176
-                'text' => $tp->label,
2177
-                'id'   => $tp->dbref,
2178
-            ];
2179
-        }
2180
-
2181
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2182
-        // the default template pack.  This still allows for the odd template pack to override.
2183
-        if (empty($tp_select_values)) {
2184
-            $tp_select_values[] = [
2185
-                'text' => esc_html__('Default', 'event_espresso'),
2186
-                'id'   => 'default',
2187
-            ];
2188
-        }
2189
-
2190
-        // setup variation select values for the currently selected template.
2191
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2192
-            $this->_message_template_group->messenger(),
2193
-            $this->_message_template_group->message_type()
2194
-        );
2195
-        $variations_select_values = [];
2196
-        foreach ($variations as $variation => $label) {
2197
-            $variations_select_values[] = [
2198
-                'text' => $label,
2199
-                'id'   => $variation,
2200
-            ];
2201
-        }
2202
-
2203
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2204
-
2205
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2206
-            'MTP_template_pack',
2207
-            $tp_select_values,
2208
-            $this->_message_template_group->get_template_pack_name()
2209
-        );
2210
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2211
-            'MTP_template_variation',
2212
-            $variations_select_values,
2213
-            $this->_message_template_group->get_template_pack_variation()
2214
-        );
2215
-        $template_args['template_pack_label']            = $template_pack_labels->template_pack;
2216
-        $template_args['template_variation_label']       = $template_pack_labels->template_variation;
2217
-        $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2218
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2219
-
2220
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2221
-
2222
-        EEH_Template::display_template($template, $template_args);
2223
-    }
2224
-
2225
-
2226
-    /**
2227
-     * This meta box holds any extra actions related to Message Templates
2228
-     * For now, this includes Resetting templates to defaults and sending a test email.
2229
-     *
2230
-     * @access  public
2231
-     * @return void
2232
-     * @throws EE_Error
2233
-     */
2234
-    public function extra_actions_meta_box()
2235
-    {
2236
-        $template_form_fields = [];
2237
-
2238
-        $extra_args = [
2239
-            'msgr'   => $this->_message_template_group->messenger(),
2240
-            'mt'     => $this->_message_template_group->message_type(),
2241
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2242
-        ];
2243
-        // first we need to see if there are any fields
2244
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2245
-
2246
-        if (! empty($fields)) {
2247
-            // yup there be fields
2248
-            foreach ($fields as $field => $config) {
2249
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2250
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2251
-                $default  = $config['default'] ?? '';
2252
-                $default  = $config['value'] ?? $default;
2253
-
2254
-                // if type is hidden and the value is empty
2255
-                // something may have gone wrong so let's correct with the defaults
2256
-                $fix                = $config['input'] === 'hidden'
2257
-                                      && isset($existing[ $field ])
2258
-                                      && empty($existing[ $field ])
2259
-                    ? $default
2260
-                    : '';
2261
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2262
-                    ? $existing[ $field ]
2263
-                    : $fix;
2264
-
2265
-                $template_form_fields[ $field_id ] = [
2266
-                    'name'       => 'test_settings_fld[' . $field . ']',
2267
-                    'label'      => $config['label'],
2268
-                    'input'      => $config['input'],
2269
-                    'type'       => $config['type'],
2270
-                    'required'   => $config['required'],
2271
-                    'validation' => $config['validation'],
2272
-                    'value'      => $existing[ $field ] ?? $default,
2273
-                    'css_class'  => $config['css_class'],
2274
-                    'options'    => $config['options'] ?? [],
2275
-                    'default'    => $default,
2276
-                    'format'     => $config['format'],
2277
-                ];
2278
-            }
2279
-        }
2280
-
2281
-        $test_settings_html = ! empty($template_form_fields)
2282
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2283
-            : '';
2284
-
2285
-        // print out $test_settings_fields
2286
-        if (! empty($test_settings_html)) {
2287
-            $test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2288
-            $test_settings_html .= 'name="test_button" value="';
2289
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2290
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2291
-        }
2292
-
2293
-        // and button
2294
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2295
-        $test_settings_html .= '<p>';
2296
-        $test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2297
-        $test_settings_html .= '</p>';
2298
-        $test_settings_html .= $this->get_action_link_or_button(
2299
-            'reset_to_default',
2300
-            'reset',
2301
-            $extra_args,
2302
-            'button--primary reset-default-button'
2303
-        );
2304
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2305
-        echo wp_kses($test_settings_html, AllowedTags::getWithFormTags());
2306
-    }
2307
-
2308
-
2309
-    /**
2310
-     * This returns the shortcode selector skeleton for a given context and field.
2311
-     *
2312
-     * @param string $field           The name of the field retrieving shortcodes for.
2313
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2314
-     * @return string
2315
-     * @throws DomainException
2316
-     * @throws EE_Error
2317
-     * @throws InvalidArgumentException
2318
-     * @throws ReflectionException
2319
-     * @throws InvalidDataTypeException
2320
-     * @throws InvalidInterfaceException
2321
-     * @since 4.9.rc.000
2322
-     */
2323
-    protected function _get_shortcode_selector($field, $linked_input_id)
2324
-    {
2325
-        $template_args = [
2326
-            'shortcodes'      => $this->_get_shortcodes([$field]),
2327
-            'fieldname'       => $field,
2328
-            'linked_input_id' => $linked_input_id,
2329
-        ];
2330
-
2331
-        return EEH_Template::display_template(
2332
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2333
-            $template_args,
2334
-            true
2335
-        );
2336
-    }
2337
-
2338
-
2339
-    /**
2340
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2341
-     * page)
2342
-     *
2343
-     * @access public
2344
-     * @return void
2345
-     * @throws EE_Error
2346
-     * @throws InvalidArgumentException
2347
-     * @throws ReflectionException
2348
-     * @throws InvalidDataTypeException
2349
-     * @throws InvalidInterfaceException
2350
-     */
2351
-    public function shortcode_meta_box()
2352
-    {
2353
-        $shortcodes = $this->_get_shortcodes([], false);
2354
-        // just make sure the shortcodes property is set
2355
-        // $messenger = $this->_message_template_group->messenger_obj();
2356
-        // now let's set the content depending on the status of the shortcodes array
2357
-        if (empty($shortcodes)) {
2358
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2359
-            return;
2360
-        }
2361
-        ?>
59
+	/**
60
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
61
+	 * group is.  If there is no group then it automatically gets set to default.
62
+	 *
63
+	 * @since 4.5.0
64
+	 */
65
+	protected string $_variation = '';
66
+
67
+
68
+	/**
69
+	 * @param bool $routing
70
+	 * @throws EE_Error
71
+	 * @throws ReflectionException
72
+	 */
73
+	public function __construct($routing = true)
74
+	{
75
+		// make sure messages autoloader is running
76
+		EED_Messages::set_autoloaders();
77
+		parent::__construct($routing);
78
+	}
79
+
80
+
81
+	/**
82
+	 * @return EEM_Message
83
+	 * @throws EE_Error
84
+	 * @throws ReflectionException
85
+	 */
86
+	public function getMsgModel(): EEM_Message
87
+	{
88
+		if (! $this->MSG_MODEL instanceof EEM_Message) {
89
+			$this->MSG_MODEL = EEM_Message::instance();
90
+		}
91
+		return $this->MSG_MODEL;
92
+	}
93
+
94
+
95
+	/**
96
+	 * @return EEM_Message_Template
97
+	 * @throws EE_Error
98
+	 * @throws ReflectionException
99
+	 */
100
+	public function getMtpModel(): EEM_Message_Template
101
+	{
102
+		if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
103
+			$this->MTP_MODEL = EEM_Message_Template::instance();
104
+		}
105
+		return $this->MTP_MODEL;
106
+	}
107
+
108
+
109
+	/**
110
+	 * @return EEM_Message_Template_Group
111
+	 * @throws EE_Error
112
+	 * @throws ReflectionException
113
+	 */
114
+	public function getMtgModel(): EEM_Message_Template_Group
115
+	{
116
+		if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
117
+			$this->MTG_MODEL = EEM_Message_Template_Group::instance();
118
+		}
119
+		return $this->MTG_MODEL;
120
+	}
121
+
122
+
123
+	public function getMessageTemplateManager(): MessageTemplateManager
124
+	{
125
+		if (! $this->message_template_manager instanceof MessageTemplateManager) {
126
+			$this->message_template_manager = $this->loader->getShared(MessageTemplateManager::class);
127
+		}
128
+		return $this->message_template_manager;
129
+	}
130
+
131
+
132
+	/**
133
+	 * @throws EE_Error
134
+	 * @throws ReflectionException
135
+	 */
136
+	protected function _init_page_props()
137
+	{
138
+		$this->page_slug        = EE_MSG_PG_SLUG;
139
+		$this->page_label       = esc_html__('Messages Settings', 'event_espresso');
140
+		$this->_admin_base_url  = EE_MSG_ADMIN_URL;
141
+		$this->_admin_base_path = EE_MSG_ADMIN;
142
+
143
+		$messenger                       = $this->request->getRequestParam('messenger', '');
144
+		$message_type                    = $this->request->getRequestParam('message_type', '');
145
+		$this->_active_messenger_name    = $this->request->getRequestParam('MTP_messenger', $messenger);
146
+		$this->_active_message_type_name = $this->request->getRequestParam('MTP_message_type', $message_type);
147
+
148
+		$this->_load_message_resource_manager();
149
+	}
150
+
151
+
152
+	protected function _load_message_resource_manager()
153
+	{
154
+		if (! $this->_message_resource_manager instanceof EE_Message_Resource_Manager) {
155
+			$this->_message_resource_manager = $this->loader->getShared(EE_Message_Resource_Manager::class);
156
+		}
157
+	}
158
+
159
+
160
+	/**
161
+	 * Generate select input with provided messenger options array.
162
+	 *
163
+	 * @param array $messenger_options Array of messengers indexed by slug and values are the messenger labels.
164
+	 * @return string
165
+	 * @throws EE_Error
166
+	 */
167
+	public function get_messengers_select_input($messenger_options)
168
+	{
169
+		// if empty or just one value then just return an empty string
170
+		if (
171
+			empty($messenger_options)
172
+			|| ! is_array($messenger_options)
173
+			|| count($messenger_options) === 1
174
+		) {
175
+			return '';
176
+		}
177
+		// merge in default
178
+		$messenger_options = array_merge(
179
+			['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
180
+			$messenger_options
181
+		);
182
+		$input             = new EE_Select_Input(
183
+			$messenger_options,
184
+			[
185
+				'html_name'  => 'ee_messenger_filter_by',
186
+				'html_id'    => 'ee_messenger_filter_by',
187
+				'html_class' => 'wide',
188
+				'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
189
+			]
190
+		);
191
+
192
+		return $input->get_html_for_input();
193
+	}
194
+
195
+
196
+	/**
197
+	 * Generate select input with provided message type options array.
198
+	 *
199
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
200
+	 *                                    message type labels
201
+	 * @return string
202
+	 * @throws EE_Error
203
+	 */
204
+	public function get_message_types_select_input($message_type_options)
205
+	{
206
+		// if empty or count of options is 1 then just return an empty string
207
+		if (
208
+			empty($message_type_options)
209
+			|| ! is_array($message_type_options)
210
+			|| count($message_type_options) === 1
211
+		) {
212
+			return '';
213
+		}
214
+		// merge in default
215
+		$message_type_options = array_merge(
216
+			['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
217
+			$message_type_options
218
+		);
219
+		$input                = new EE_Select_Input(
220
+			$message_type_options,
221
+			[
222
+				'html_name'  => 'ee_message_type_filter_by',
223
+				'html_id'    => 'ee_message_type_filter_by',
224
+				'html_class' => 'wide',
225
+				'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
226
+			]
227
+		);
228
+
229
+		return $input->get_html_for_input();
230
+	}
231
+
232
+
233
+	/**
234
+	 * Generate select input with provide message type contexts array.
235
+	 *
236
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
237
+	 *                               context label.
238
+	 * @return string
239
+	 * @throws EE_Error
240
+	 */
241
+	public function get_contexts_for_message_types_select_input($context_options)
242
+	{
243
+		// if empty or count of options is one then just return empty string
244
+		if (
245
+			empty($context_options)
246
+			|| ! is_array($context_options)
247
+			|| count($context_options) === 1
248
+		) {
249
+			return '';
250
+		}
251
+		// merge in default
252
+		$context_options = array_merge(
253
+			['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
254
+			$context_options
255
+		);
256
+		$input           = new EE_Select_Input(
257
+			$context_options,
258
+			[
259
+				'html_name'  => 'ee_context_filter_by',
260
+				'html_id'    => 'ee_context_filter_by',
261
+				'html_class' => 'wide',
262
+				'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
263
+			]
264
+		);
265
+
266
+		return $input->get_html_for_input();
267
+	}
268
+
269
+
270
+	protected function _ajax_hooks()
271
+	{
272
+		add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
273
+		add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
274
+		add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
275
+		add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
276
+		add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
277
+		add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
278
+	}
279
+
280
+
281
+	protected function _define_page_props()
282
+	{
283
+		$this->_admin_page_title = $this->page_label;
284
+		$this->_labels           = [
285
+			'buttons'    => [
286
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
287
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
288
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
289
+			],
290
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
291
+		];
292
+	}
293
+
294
+
295
+	/**
296
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
297
+	 *
298
+	 * @access protected
299
+	 * @return void
300
+	 */
301
+	protected function _set_page_routes()
302
+	{
303
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
304
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, DataType::INTEGER);
305
+		$MSG_ID = $this->request->getRequestParam('MSG_ID', 0, DataType::INTEGER);
306
+
307
+		$this->_page_routes = [
308
+			'default'                          => [
309
+				'func'       => [$this, '_message_queue_list_table'],
310
+				'capability' => 'ee_read_global_messages',
311
+			],
312
+			'global_mtps'                      => [
313
+				'func'       => [$this, '_ee_default_messages_overview_list_table'],
314
+				'capability' => 'ee_read_global_messages',
315
+			],
316
+			'custom_mtps'                      => [
317
+				'func'       => [$this, '_custom_mtps_preview'],
318
+				'capability' => 'ee_read_messages',
319
+			],
320
+			'add_new_message_template'         => [
321
+				'func'       => [$this, 'insertMessageTemplate'],
322
+				'capability' => 'ee_edit_messages',
323
+				'noheader'   => true,
324
+			],
325
+			'edit_message_template'            => [
326
+				'func'       => [$this, '_edit_message_template'],
327
+				'capability' => 'ee_edit_message',
328
+				'obj_id'     => $GRP_ID,
329
+			],
330
+			'preview_message'                  => [
331
+				'func'               => [$this, '_preview_message'],
332
+				'capability'         => 'ee_read_message',
333
+				'obj_id'             => $GRP_ID,
334
+				'noheader'           => true,
335
+				'headers_sent_route' => 'display_preview_message',
336
+			],
337
+			'display_preview_message'          => [
338
+				'func'       => [$this, '_display_preview_message'],
339
+				'capability' => 'ee_read_message',
340
+				'obj_id'     => $GRP_ID,
341
+			],
342
+			'insert_message_template'          => [
343
+				'func'       => [$this, 'insertMessageTemplate'],
344
+				'capability' => 'ee_edit_messages',
345
+				'noheader'   => true,
346
+			],
347
+			'update_message_template'          => [
348
+				'func'       => [$this, 'updateMessageTemplate'],
349
+				'capability' => 'ee_edit_message',
350
+				'obj_id'     => $GRP_ID,
351
+				'noheader'   => true,
352
+			],
353
+			'trash_message_template'           => [
354
+				'func'       => [$this, '_trash_or_restore_message_template'],
355
+				'capability' => 'ee_delete_message',
356
+				'obj_id'     => $GRP_ID,
357
+				'args'       => ['trash' => true, 'all' => true],
358
+				'noheader'   => true,
359
+			],
360
+			'trash_message_template_context'   => [
361
+				'func'       => [$this, '_trash_or_restore_message_template'],
362
+				'capability' => 'ee_delete_message',
363
+				'obj_id'     => $GRP_ID,
364
+				'args'       => ['trash' => true],
365
+				'noheader'   => true,
366
+			],
367
+			'restore_message_template'         => [
368
+				'func'       => [$this, '_trash_or_restore_message_template'],
369
+				'capability' => 'ee_delete_message',
370
+				'obj_id'     => $GRP_ID,
371
+				'args'       => ['trash' => false, 'all' => true],
372
+				'noheader'   => true,
373
+			],
374
+			'restore_message_template_context' => [
375
+				'func'       => [$this, '_trash_or_restore_message_template'],
376
+				'capability' => 'ee_delete_message',
377
+				'obj_id'     => $GRP_ID,
378
+				'args'       => ['trash' => false],
379
+				'noheader'   => true,
380
+			],
381
+			'delete_message_template'          => [
382
+				'func'       => [$this, '_delete_message_template'],
383
+				'capability' => 'ee_delete_message',
384
+				'obj_id'     => $GRP_ID,
385
+				'noheader'   => true,
386
+			],
387
+			'reset_to_default'                 => [
388
+				'func'       => [$this, '_reset_to_default_template'],
389
+				'capability' => 'ee_edit_message',
390
+				'obj_id'     => $GRP_ID,
391
+				'noheader'   => true,
392
+			],
393
+			'settings'                         => [
394
+				'func'       => [$this, '_settings'],
395
+				'capability' => 'manage_options',
396
+			],
397
+			'update_global_settings'           => [
398
+				'func'       => [$this, '_update_global_settings'],
399
+				'capability' => 'manage_options',
400
+				'noheader'   => true,
401
+			],
402
+			'generate_now'                     => [
403
+				'func'       => [$this, '_generate_now'],
404
+				'capability' => 'ee_send_message',
405
+				'noheader'   => true,
406
+			],
407
+			'generate_and_send_now'            => [
408
+				'func'       => [$this, '_generate_and_send_now'],
409
+				'capability' => 'ee_send_message',
410
+				'noheader'   => true,
411
+			],
412
+			'queue_for_resending'              => [
413
+				'func'       => [$this, '_queue_for_resending'],
414
+				'capability' => 'ee_send_message',
415
+				'noheader'   => true,
416
+			],
417
+			'send_now'                         => [
418
+				'func'       => [$this, '_send_now'],
419
+				'capability' => 'ee_send_message',
420
+				'noheader'   => true,
421
+			],
422
+			'delete_ee_message'                => [
423
+				'func'       => [$this, '_delete_ee_messages'],
424
+				'capability' => 'ee_delete_messages',
425
+				'noheader'   => true,
426
+			],
427
+			'delete_ee_messages'               => [
428
+				'func'       => [$this, '_delete_ee_messages'],
429
+				'capability' => 'ee_delete_messages',
430
+				'noheader'   => true,
431
+				'obj_id'     => $MSG_ID,
432
+			],
433
+		];
434
+	}
435
+
436
+
437
+	protected function _set_page_config()
438
+	{
439
+		$this->_page_config = [
440
+			'default'                  => [
441
+				'nav'           => [
442
+					'label' => esc_html__('Message Activity', 'event_espresso'),
443
+					'icon'  => 'dashicons-email',
444
+					'order' => 10,
445
+				],
446
+				'list_table'    => 'EE_Message_List_Table',
447
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
448
+				'require_nonce' => false,
449
+			],
450
+			'global_mtps'              => [
451
+				'nav'           => [
452
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
453
+					'icon'  => 'dashicons-layout',
454
+					'order' => 20,
455
+				],
456
+				'list_table'    => 'Messages_Template_List_Table',
457
+				'help_tabs'     => [
458
+					'messages_overview_help_tab'                                => [
459
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
460
+						'filename' => 'messages_overview',
461
+					],
462
+					'messages_overview_messages_table_column_headings_help_tab' => [
463
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
464
+						'filename' => 'messages_overview_table_column_headings',
465
+					],
466
+					'messages_overview_messages_filters_help_tab'               => [
467
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
468
+						'filename' => 'messages_overview_filters',
469
+					],
470
+					'messages_overview_messages_views_help_tab'                 => [
471
+						'title'    => esc_html__('Message Views', 'event_espresso'),
472
+						'filename' => 'messages_overview_views',
473
+					],
474
+					'message_overview_message_types_help_tab'                   => [
475
+						'title'    => esc_html__('Message Types', 'event_espresso'),
476
+						'filename' => 'messages_overview_types',
477
+					],
478
+					'messages_overview_messengers_help_tab'                     => [
479
+						'title'    => esc_html__('Messengers', 'event_espresso'),
480
+						'filename' => 'messages_overview_messengers',
481
+					],
482
+				],
483
+				'require_nonce' => false,
484
+			],
485
+			'custom_mtps'              => [
486
+				'nav'           => [
487
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
488
+					'icon'  => 'dashicons-admin-customizer',
489
+					'order' => 30,
490
+				],
491
+				'help_tabs'     => [],
492
+				'require_nonce' => false,
493
+			],
494
+			'add_new_message_template' => [
495
+				'nav'           => [
496
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
497
+					'icon'       => 'dashicons-plus-alt',
498
+					'order'      => 5,
499
+					'persistent' => false,
500
+				],
501
+				'require_nonce' => false,
502
+			],
503
+			'edit_message_template'    => [
504
+				'labels'        => [
505
+					'buttons'    => [
506
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
507
+					],
508
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
509
+				],
510
+				'nav'           => [
511
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
512
+					'icon'       => 'dashicons-edit-large',
513
+					'order'      => 5,
514
+					'persistent' => false,
515
+					'url'        => '',
516
+				],
517
+				'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
518
+				'has_metaboxes' => true,
519
+				'help_tabs'     => [
520
+					'edit_message_template'            => [
521
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
522
+						'callback' => 'edit_message_template_help_tab',
523
+					],
524
+					'message_templates_help_tab'       => [
525
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
526
+						'filename' => 'messages_templates',
527
+					],
528
+					'message_template_shortcodes'      => [
529
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
530
+						'callback' => 'message_template_shortcodes_help_tab',
531
+					],
532
+					'message_preview_help_tab'         => [
533
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
534
+						'filename' => 'messages_preview',
535
+					],
536
+					'messages_overview_other_help_tab' => [
537
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
538
+						'filename' => 'messages_overview_other',
539
+					],
540
+				],
541
+				'require_nonce' => false,
542
+			],
543
+			'display_preview_message'  => [
544
+				'nav'           => [
545
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
546
+					'icon'       => 'dashicons-visibility-bar',
547
+					'order'      => 5,
548
+					'url'        => '',
549
+					'persistent' => false,
550
+				],
551
+				'help_tabs'     => [
552
+					'preview_message' => [
553
+						'title'    => esc_html__('About Previews', 'event_espresso'),
554
+						'callback' => 'preview_message_help_tab',
555
+					],
556
+				],
557
+				'require_nonce' => false,
558
+			],
559
+			'settings'                 => [
560
+				'nav'           => [
561
+					'label' => esc_html__('Settings', 'event_espresso'),
562
+					'icon'  => 'dashicons-admin-generic',
563
+					'order' => 40,
564
+				],
565
+				'metaboxes'     => ['_messages_settings_metaboxes'],
566
+				'help_tabs'     => [
567
+					'messages_settings_help_tab'               => [
568
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
569
+						'filename' => 'messages_settings',
570
+					],
571
+					'messages_settings_message_types_help_tab' => [
572
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
573
+						'filename' => 'messages_settings_message_types',
574
+					],
575
+					'messages_settings_messengers_help_tab'    => [
576
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
577
+						'filename' => 'messages_settings_messengers',
578
+					],
579
+				],
580
+				'require_nonce' => false,
581
+			],
582
+		];
583
+	}
584
+
585
+
586
+	protected function _add_screen_options()
587
+	{
588
+		// todo
589
+	}
590
+
591
+
592
+	protected function _add_screen_options_global_mtps()
593
+	{
594
+		/**
595
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
596
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
597
+		 */
598
+		$page_title              = $this->_admin_page_title;
599
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
600
+		$this->_per_page_screen_option();
601
+		$this->_admin_page_title = $page_title;
602
+	}
603
+
604
+
605
+	protected function _add_screen_options_default()
606
+	{
607
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
608
+		$this->_per_page_screen_option();
609
+	}
610
+
611
+
612
+	// none of the below group are currently used for Messages
613
+	protected function _add_feature_pointers()
614
+	{
615
+	}
616
+
617
+
618
+	public function admin_init()
619
+	{
620
+	}
621
+
622
+
623
+	public function admin_notices()
624
+	{
625
+	}
626
+
627
+
628
+	public function admin_footer_scripts()
629
+	{
630
+	}
631
+
632
+
633
+	public function messages_help_tab()
634
+	{
635
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
636
+	}
637
+
638
+
639
+	public function messengers_help_tab()
640
+	{
641
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
642
+	}
643
+
644
+
645
+	public function message_types_help_tab()
646
+	{
647
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
648
+	}
649
+
650
+
651
+	public function messages_overview_help_tab()
652
+	{
653
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
654
+	}
655
+
656
+
657
+	public function message_templates_help_tab()
658
+	{
659
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
660
+	}
661
+
662
+
663
+	public function edit_message_template_help_tab()
664
+	{
665
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
666
+						. esc_attr__('Editor Title', 'event_espresso')
667
+						. '" />';
668
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
669
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
670
+						. '" />';
671
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
672
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
673
+						. '" />';
674
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
675
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
676
+						. '" />';
677
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
678
+						. esc_attr__('Publish Metabox', 'event_espresso')
679
+						. '" />';
680
+		EEH_Template::display_template(
681
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
682
+			$args
683
+		);
684
+	}
685
+
686
+
687
+	/**
688
+	 * @throws ReflectionException
689
+	 * @throws EE_Error
690
+	 */
691
+	public function message_template_shortcodes_help_tab()
692
+	{
693
+		$this->_set_shortcodes();
694
+		$args['shortcodes'] = $this->_shortcodes;
695
+		EEH_Template::display_template(
696
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
697
+			$args
698
+		);
699
+	}
700
+
701
+
702
+	public function preview_message_help_tab()
703
+	{
704
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
705
+	}
706
+
707
+
708
+	public function settings_help_tab()
709
+	{
710
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
711
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
712
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
713
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
714
+		$args['img3'] = '<div class="ee-switch">'
715
+						. '<input class="ee-switch__input" id="ee-on-off-toggle-on" type="checkbox" checked>'
716
+						. '<label class="ee-switch__toggle" for="ee-on-off-toggle-on"></label>'
717
+						. '</div>';
718
+		$args['img4'] = '<div class="switch">'
719
+						. '<input class="ee-switch__input" id="ee-on-off-toggle-off" type="checkbox">'
720
+						. '<label class="ee-switch__toggle" for="ee-on-off-toggle-off"></label>'
721
+						. '</div>';
722
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
723
+	}
724
+
725
+
726
+	public function load_scripts_styles()
727
+	{
728
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', [], EVENT_ESPRESSO_VERSION);
729
+		wp_enqueue_style('espresso_ee_msg');
730
+
731
+		wp_register_script(
732
+			'ee-messages-settings',
733
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
734
+			['jquery-ui-droppable', 'ee-serialize-full-array'],
735
+			EVENT_ESPRESSO_VERSION,
736
+			true
737
+		);
738
+		wp_register_script(
739
+			'ee-msg-list-table-js',
740
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
741
+			['ee-dialog'],
742
+			EVENT_ESPRESSO_VERSION
743
+		);
744
+	}
745
+
746
+
747
+	public function load_scripts_styles_default()
748
+	{
749
+		wp_enqueue_script('ee-msg-list-table-js');
750
+	}
751
+
752
+
753
+	public function wp_editor_css($mce_css)
754
+	{
755
+		// if we're on the edit_message_template route
756
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
757
+			$message_type_name = $this->_active_message_type_name;
758
+
759
+			// we're going to REPLACE the existing mce css
760
+			// we need to get the css file location from the active messenger
761
+			$mce_css = $this->_active_messenger->get_variation(
762
+				$this->_template_pack,
763
+				$message_type_name,
764
+				true,
765
+				'wpeditor',
766
+				$this->_variation
767
+			);
768
+		}
769
+
770
+		return $mce_css;
771
+	}
772
+
773
+
774
+	/**
775
+	 * @throws EE_Error
776
+	 * @throws ReflectionException
777
+	 */
778
+	public function load_scripts_styles_edit_message_template()
779
+	{
780
+		$this->_set_shortcodes();
781
+
782
+		EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
783
+			esc_html__(
784
+				'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
785
+				'event_espresso'
786
+			),
787
+			$this->_message_template_group->messenger_obj()->label['singular'],
788
+			$this->_message_template_group->message_type_obj()->label['singular']
789
+		);
790
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
791
+			'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
792
+			'event_espresso'
793
+		);
794
+		EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
795
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
796
+			'event_espresso'
797
+		);
798
+
799
+		wp_register_script(
800
+			'ee_msgs_edit_js',
801
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
802
+			['jquery'],
803
+			EVENT_ESPRESSO_VERSION
804
+		);
805
+
806
+		wp_enqueue_script('ee_admin_js');
807
+		wp_enqueue_script('ee_msgs_edit_js');
808
+
809
+		// add in special css for tiny_mce
810
+		add_filter('mce_css', [$this, 'wp_editor_css']);
811
+	}
812
+
813
+
814
+	/**
815
+	 * @throws EE_Error
816
+	 * @throws ReflectionException
817
+	 */
818
+	public function load_scripts_styles_display_preview_message()
819
+	{
820
+		$this->_set_message_template_group();
821
+		if ($this->_active_messenger_name) {
822
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
823
+				$this->_active_messenger_name
824
+			);
825
+		}
826
+
827
+		wp_enqueue_style(
828
+			'espresso_preview_css',
829
+			$this->_active_messenger->get_variation(
830
+				$this->_template_pack,
831
+				$this->_active_message_type_name,
832
+				true,
833
+				'preview',
834
+				$this->_variation
835
+			)
836
+		);
837
+	}
838
+
839
+
840
+	public function load_scripts_styles_settings()
841
+	{
842
+		wp_register_style(
843
+			'ee-message-settings',
844
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
845
+			[],
846
+			EVENT_ESPRESSO_VERSION
847
+		);
848
+		wp_enqueue_style('ee-text-links');
849
+		wp_enqueue_style('ee-message-settings');
850
+		wp_enqueue_script('ee-messages-settings');
851
+	}
852
+
853
+
854
+	/**
855
+	 * set views array for List Table
856
+	 */
857
+	public function _set_list_table_views_global_mtps()
858
+	{
859
+		$this->_views = [
860
+			'in_use' => [
861
+				'slug'  => 'in_use',
862
+				'label' => esc_html__('In Use', 'event_espresso'),
863
+				'count' => 0,
864
+			],
865
+		];
866
+	}
867
+
868
+
869
+	/**
870
+	 * Set views array for the Custom Template List Table
871
+	 */
872
+	public function _set_list_table_views_custom_mtps()
873
+	{
874
+		$this->_set_list_table_views_global_mtps();
875
+		$this->_views['in_use']['bulk_action'] = [
876
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
877
+		];
878
+	}
879
+
880
+
881
+	/**
882
+	 * set views array for message queue list table
883
+	 *
884
+	 * @throws InvalidDataTypeException
885
+	 * @throws InvalidInterfaceException
886
+	 * @throws InvalidArgumentException
887
+	 * @throws EE_Error
888
+	 * @throws ReflectionException
889
+	 */
890
+	public function _set_list_table_views_default()
891
+	{
892
+		EE_Registry::instance()->load_helper('Template');
893
+
894
+		$common_bulk_actions = $this->capabilities->current_user_can(
895
+			'ee_send_message',
896
+			'message_list_table_bulk_actions'
897
+		)
898
+			? [
899
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
900
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
901
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
902
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
903
+			]
904
+			: [];
905
+
906
+		$delete_bulk_action = $this->capabilities->current_user_can(
907
+			'ee_delete_messages',
908
+			'message_list_table_bulk_actions'
909
+		)
910
+			? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
911
+			: [];
912
+
913
+
914
+		$this->_views = [
915
+			'all' => [
916
+				'slug'        => 'all',
917
+				'label'       => esc_html__('All', 'event_espresso'),
918
+				'count'       => 0,
919
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
920
+			],
921
+		];
922
+
923
+
924
+		foreach ($this->getMsgModel()->all_statuses() as $status) {
925
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
926
+				continue;
927
+			}
928
+			$status_bulk_actions = $common_bulk_actions;
929
+			// unset bulk actions not applying to status
930
+			if (! empty($status_bulk_actions)) {
931
+				switch ($status) {
932
+					case EEM_Message::status_idle:
933
+					case EEM_Message::status_resend:
934
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
935
+						break;
936
+
937
+					case EEM_Message::status_failed:
938
+					case EEM_Message::status_debug_only:
939
+					case EEM_Message::status_messenger_executing:
940
+						$status_bulk_actions = [];
941
+						break;
942
+
943
+					case EEM_Message::status_incomplete:
944
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
945
+						break;
946
+
947
+					case EEM_Message::status_retry:
948
+					case EEM_Message::status_sent:
949
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
950
+						break;
951
+				}
952
+			}
953
+
954
+			// skip adding messenger executing status to views because it will be included with the Failed view.
955
+			if ($status === EEM_Message::status_messenger_executing) {
956
+				continue;
957
+			}
958
+
959
+			$this->_views[ strtolower($status) ] = [
960
+				'slug'        => strtolower($status),
961
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
962
+				'count'       => 0,
963
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
964
+			];
965
+		}
966
+	}
967
+
968
+
969
+	/**
970
+	 * @throws EE_Error
971
+	 */
972
+	protected function _ee_default_messages_overview_list_table()
973
+	{
974
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
975
+		$this->display_admin_list_table_page_with_no_sidebar();
976
+	}
977
+
978
+
979
+	/**
980
+	 * @throws EE_Error
981
+	 * @throws ReflectionException
982
+	 */
983
+	protected function _message_queue_list_table()
984
+	{
985
+		$this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
986
+		$this->_template_args['per_column']        = 6;
987
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
988
+		$message_results                           = trim(EEM_Message::instance()->get_pretty_label_for_results());
989
+		$this->_template_args['before_list_table'] = ! empty($message_results) ? "<h3>{$message_results}</h3>" : '';
990
+		$this->display_admin_list_table_page_with_no_sidebar();
991
+	}
992
+
993
+
994
+	/**
995
+	 * @throws EE_Error
996
+	 */
997
+	protected function _message_legend_items()
998
+	{
999
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1000
+		$action_items       = [];
1001
+
1002
+		foreach ($action_css_classes as $action_item => $action_details) {
1003
+			if ($action_item === 'see_notifications_for') {
1004
+				continue;
1005
+			}
1006
+			$action_items[ $action_item ] = [
1007
+				'class' => $action_details['css_class'],
1008
+				'desc'  => $action_details['label'],
1009
+			];
1010
+		}
1011
+
1012
+		/** @var array $status_items status legend setup */
1013
+		$status_items = [
1014
+			'sent_status'                => [
1015
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_sent,
1016
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1017
+			],
1018
+			'idle_status'                => [
1019
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_idle,
1020
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1021
+			],
1022
+			'failed_status'              => [
1023
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_failed,
1024
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1025
+			],
1026
+			'messenger_executing_status' => [
1027
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_messenger_executing,
1028
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1029
+			],
1030
+			'resend_status'              => [
1031
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_resend,
1032
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1033
+			],
1034
+			'incomplete_status'          => [
1035
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_incomplete,
1036
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1037
+			],
1038
+			'retry_status'               => [
1039
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_retry,
1040
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1041
+			],
1042
+		];
1043
+		if (EEM_Message::debug()) {
1044
+			$status_items['debug_only_status'] = [
1045
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_debug_only,
1046
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1047
+			];
1048
+		}
1049
+
1050
+		return array_merge($action_items, $status_items);
1051
+	}
1052
+
1053
+
1054
+	/**
1055
+	 * @throws EE_Error
1056
+	 */
1057
+	protected function _custom_mtps_preview()
1058
+	{
1059
+		$this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1060
+		$this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1061
+												. ' alt="' . esc_attr__(
1062
+													'Preview Custom Message Templates screenshot',
1063
+													'event_espresso'
1064
+												) . '" />';
1065
+		$this->_template_args['preview_text'] = '<strong>'
1066
+												. esc_html__(
1067
+													'Custom Message Templates 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 Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
1068
+													'event_espresso'
1069
+												)
1070
+												. '</strong>';
1071
+
1072
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1073
+	}
1074
+
1075
+
1076
+	/**
1077
+	 * get_message_templates
1078
+	 * This gets all the message templates for listing on the overview list.
1079
+	 *
1080
+	 * @param int    $per_page the amount of templates groups to show per page
1081
+	 * @param string $type     the current _view we're getting templates for
1082
+	 * @param bool   $count    return count?
1083
+	 * @param bool   $all      disregard any paging info (get all data);
1084
+	 * @param bool   $global   whether to return just global (true) or custom templates (false)
1085
+	 * @return array|int
1086
+	 * @throws EE_Error
1087
+	 * @throws InvalidArgumentException
1088
+	 * @throws InvalidDataTypeException
1089
+	 * @throws InvalidInterfaceException
1090
+	 * @throws ReflectionException
1091
+	 */
1092
+	public function get_message_templates(
1093
+		int $per_page = 10,
1094
+		string $type = 'in_use',
1095
+		bool $count = false,
1096
+		bool $all = false,
1097
+		bool $global = true
1098
+	) {
1099
+		$orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1100
+		// ensure that the orderby param is actually set within the request data
1101
+		$this->request->setRequestParam('orderby', $orderby);
1102
+		$order        = $this->request->getRequestParam('order', 'ASC');
1103
+		$current_page = $this->request->getRequestParam('paged', 1, DataType::INTEGER);
1104
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, DataType::INTEGER);
1105
+
1106
+		$offset = ($current_page - 1) * $per_page;
1107
+		$limit  = $all ? null : [$offset, $per_page];
1108
+
1109
+		// options will match what is in the _views array property
1110
+		return $type === 'in_use'
1111
+			? $this->getMtgModel()->get_all_active_message_templates(
1112
+				$orderby,
1113
+				$order,
1114
+				$limit,
1115
+				$count,
1116
+				$global,
1117
+				true
1118
+			)
1119
+			: $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1120
+				$orderby,
1121
+				$order,
1122
+				$limit,
1123
+				$count,
1124
+				$global
1125
+			);
1126
+	}
1127
+
1128
+
1129
+	/**
1130
+	 * filters etc might need a list of installed message_types
1131
+	 *
1132
+	 * @return array an array of message type objects
1133
+	 */
1134
+	public function get_installed_message_types(): array
1135
+	{
1136
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1137
+		$installed               = [];
1138
+
1139
+		foreach ($installed_message_types as $message_type) {
1140
+			$installed[ $message_type->name ] = $message_type;
1141
+		}
1142
+
1143
+		return $installed;
1144
+	}
1145
+
1146
+
1147
+	/**
1148
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1149
+	 *
1150
+	 * @param string     $message_type
1151
+	 * @param string     $messenger
1152
+	 * @param int|string $GRP_ID
1153
+	 * @throws EE_error
1154
+	 * @throws ReflectionException
1155
+	 * @deprecated 5.0.8.p
1156
+	 */
1157
+	public function add_message_template(string $message_type = '', string $messenger = '', $GRP_ID = '')
1158
+	{
1159
+		$this->insertMessageTemplate();
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * @param string $message_type     message type slug
1165
+	 * @param string $messenger        messenger slug
1166
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1167
+	 *                                 off of.
1168
+	 * @throws EE_error
1169
+	 * @throws ReflectionException
1170
+	 * @deprecated 4.10.29.p
1171
+	 */
1172
+	protected function _add_message_template($message_type, $messenger, $GRP_ID)
1173
+	{
1174
+		$this->insertMessageTemplate($message_type, $messenger, $GRP_ID);
1175
+	}
1176
+
1177
+
1178
+	/**
1179
+	 * _edit_message_template
1180
+	 *
1181
+	 * @access protected
1182
+	 * @return void
1183
+	 * @throws InvalidIdentifierException
1184
+	 * @throws DomainException
1185
+	 * @throws EE_Error
1186
+	 * @throws InvalidArgumentException
1187
+	 * @throws ReflectionException
1188
+	 * @throws InvalidDataTypeException
1189
+	 * @throws InvalidInterfaceException
1190
+	 */
1191
+	protected function _edit_message_template()
1192
+	{
1193
+		$template_fields = '';
1194
+		$sidebar_fields  = '';
1195
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1196
+		// valid html in the templates.
1197
+		add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1198
+
1199
+		$GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
1200
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', $GRP_ID, DataType::INTEGER);
1201
+
1202
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, DataType::INTEGER);
1203
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', $EVT_ID, DataType::INTEGER);
1204
+
1205
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1206
+		$message_template_group = $this->_message_template_group;
1207
+		$c_label                = $message_template_group->context_label();
1208
+		$c_config               = $message_template_group->contexts_config();
1209
+
1210
+		reset($c_config);
1211
+		$context = $this->request->getRequestParam('context', key($c_config));
1212
+		$context = strtolower($context);
1213
+
1214
+		$action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1215
+
1216
+		$edit_message_template_form_url = add_query_arg(
1217
+			['action' => $action, 'noheader' => true],
1218
+			EE_MSG_ADMIN_URL
1219
+		);
1220
+
1221
+		// set active messenger for this view
1222
+		$this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1223
+			$message_template_group->messenger()
1224
+		);
1225
+		$this->_active_message_type_name = $message_template_group->message_type();
1226
+
1227
+
1228
+		// Do we have any validation errors?
1229
+		$validators = $this->_get_transient();
1230
+		$v_fields   = ! empty($validators) ? array_keys($validators) : [];
1231
+
1232
+
1233
+		// we need to assemble the title from Various details
1234
+		$context_label = sprintf(
1235
+			esc_html__('(%s %s)', 'event_espresso'),
1236
+			$c_config[ $context ]['label'],
1237
+			ucwords($c_label['label'])
1238
+		);
1239
+
1240
+		$title = sprintf(
1241
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1242
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1243
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1244
+			$context_label
1245
+		);
1246
+
1247
+		$this->_template_args['GRP_ID']           = $GRP_ID;
1248
+		$this->_template_args['message_template'] = $message_template_group;
1249
+		$this->_template_args['is_extra_fields']  = false;
1250
+
1251
+
1252
+		// let's get EEH_MSG_Template so we can get template form fields
1253
+		$template_field_structure = EEH_MSG_Template::get_fields(
1254
+			$message_template_group->messenger(),
1255
+			$message_template_group->message_type()
1256
+		);
1257
+
1258
+		if (! $template_field_structure) {
1259
+			$template_field_structure = false;
1260
+			$template_fields          = esc_html__(
1261
+				'There was an error in assembling the fields for this display (you should see an error message)',
1262
+				'event_espresso'
1263
+			);
1264
+		}
1265
+
1266
+		$message_templates = $message_template_group->context_templates();
1267
+
1268
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1269
+		// will get handled in the "extra" array.
1270
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1271
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1272
+				unset($template_field_structure[ $context ][ $reference_field ]);
1273
+			}
1274
+		}
1275
+
1276
+		// let's loop through the template_field_structure and actually assemble the input fields!
1277
+		if (! empty($template_field_structure)) {
1278
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1279
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1280
+				// the extra array and reset them.
1281
+				if ($template_field === 'extra') {
1282
+					$this->_template_args['is_extra_fields'] = true;
1283
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1284
+						$message_template = $message_templates[ $context ][ $reference_field ];
1285
+						$content          = $message_template instanceof EE_Message_Template
1286
+							? $message_template->get('MTP_content')
1287
+							: '';
1288
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1289
+							// let's verify if we need this extra field via the shortcodes parameter.
1290
+							$continue = false;
1291
+							if (isset($extra_array['shortcodes_required'])) {
1292
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1293
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1294
+										$continue = true;
1295
+									}
1296
+								}
1297
+								if ($continue) {
1298
+									continue;
1299
+								}
1300
+							}
1301
+
1302
+							$field_id = $reference_field . '-' . $extra_field . '-content';
1303
+
1304
+							$template_form_fields[ $field_id ]         = $extra_array;
1305
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1306
+																		 . $reference_field
1307
+																		 . '][content]['
1308
+																		 . $extra_field . ']';
1309
+							$css_class                                 = $extra_array['css_class'] ?? '';
1310
+
1311
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1312
+																			  && in_array($extra_field, $v_fields, true)
1313
+																			  && (
1314
+																				  is_array($validators[ $extra_field ])
1315
+																				  && isset($validators[ $extra_field ]['msg'])
1316
+																			  )
1317
+								? 'validate-error ' . $css_class
1318
+								: $css_class;
1319
+
1320
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1321
+																		  && isset($content[ $extra_field ])
1322
+								? $content[ $extra_field ]
1323
+								: '';
1324
+
1325
+							// do we have a validation error?  if we do then let's use that value instead
1326
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1327
+								? $validators[ $extra_field ]['value']
1328
+								: $template_form_fields[ $field_id ]['value'];
1329
+
1330
+
1331
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1332
+
1333
+							// shortcode selector
1334
+							$field_name_to_use                                   = $extra_field === 'main'
1335
+								? 'content'
1336
+								: $extra_field;
1337
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1338
+								$field_name_to_use,
1339
+								$field_id
1340
+							);
1341
+						}
1342
+						$template_field_MTP_id           = $reference_field . '-MTP_ID';
1343
+						$template_field_template_name_id = $reference_field . '-name';
1344
+
1345
+						$template_form_fields[ $template_field_MTP_id ] = [
1346
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1347
+							'label'      => null,
1348
+							'input'      => 'hidden',
1349
+							'type'       => 'int',
1350
+							'required'   => false,
1351
+							'validation' => false,
1352
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1353
+							'css_class'  => '',
1354
+							'format'     => '%d',
1355
+							'db-col'     => 'MTP_ID',
1356
+						];
1357
+
1358
+						$template_form_fields[ $template_field_template_name_id ] = [
1359
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1360
+							'label'      => null,
1361
+							'input'      => 'hidden',
1362
+							'type'       => 'string',
1363
+							'required'   => false,
1364
+							'validation' => true,
1365
+							'value'      => $reference_field,
1366
+							'css_class'  => '',
1367
+							'format'     => '%s',
1368
+							'db-col'     => 'MTP_template_field',
1369
+						];
1370
+					}
1371
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1372
+				} else {
1373
+					$field_id                                   = $template_field . '-content';
1374
+					$template_form_fields[ $field_id ]          = $field_setup_array;
1375
+					$template_form_fields[ $field_id ]['name']  =
1376
+						'MTP_template_fields[' . $template_field . '][content]';
1377
+					$message_template                           =
1378
+						$message_templates[ $context ][ $template_field ] ?? null;
1379
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1380
+																  && is_array($message_templates[ $context ])
1381
+																  && $message_template instanceof EE_Message_Template
1382
+						? $message_template->get('MTP_content')
1383
+						: '';
1384
+
1385
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1386
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1387
+						? $validators[ $template_field ]['value']
1388
+						: $template_form_fields[ $field_id ]['value'];
1389
+
1390
+
1391
+					$template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1392
+					$css_class                                      = $field_setup_array['css_class'] ?? '';
1393
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1394
+																	  && in_array($template_field, $v_fields, true)
1395
+																	  && isset($validators[ $template_field ]['msg'])
1396
+						? 'validate-error ' . $css_class
1397
+						: $css_class;
1398
+
1399
+					// shortcode selector
1400
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1401
+						$template_field,
1402
+						$field_id
1403
+					);
1404
+				}
1405
+
1406
+				// k took care of content field(s) now let's take care of others.
1407
+
1408
+				$template_field_MTP_id                 = $template_field . '-MTP_ID';
1409
+				$template_field_field_template_name_id = $template_field . '-name';
1410
+
1411
+				// foreach template field there are actually two form fields created
1412
+				$template_form_fields[ $template_field_MTP_id ] = [
1413
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1414
+					'label'      => null,
1415
+					'input'      => 'hidden',
1416
+					'type'       => 'int',
1417
+					'required'   => false,
1418
+					'validation' => true,
1419
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1420
+					'css_class'  => '',
1421
+					'format'     => '%d',
1422
+					'db-col'     => 'MTP_ID',
1423
+				];
1424
+
1425
+				$template_form_fields[ $template_field_field_template_name_id ] = [
1426
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1427
+					'label'      => null,
1428
+					'input'      => 'hidden',
1429
+					'type'       => 'string',
1430
+					'required'   => false,
1431
+					'validation' => true,
1432
+					'value'      => $template_field,
1433
+					'css_class'  => '',
1434
+					'format'     => '%s',
1435
+					'db-col'     => 'MTP_template_field',
1436
+				];
1437
+			}
1438
+
1439
+			// add other fields
1440
+			$template_form_fields['ee-msg-current-context'] = [
1441
+				'name'       => 'MTP_context',
1442
+				'label'      => null,
1443
+				'input'      => 'hidden',
1444
+				'type'       => 'string',
1445
+				'required'   => false,
1446
+				'validation' => true,
1447
+				'value'      => $context,
1448
+				'css_class'  => '',
1449
+				'format'     => '%s',
1450
+				'db-col'     => 'MTP_context',
1451
+			];
1452
+
1453
+			$template_form_fields['ee-msg-grp-id'] = [
1454
+				'name'       => 'GRP_ID',
1455
+				'label'      => null,
1456
+				'input'      => 'hidden',
1457
+				'type'       => 'int',
1458
+				'required'   => false,
1459
+				'validation' => true,
1460
+				'value'      => $GRP_ID,
1461
+				'css_class'  => '',
1462
+				'format'     => '%d',
1463
+				'db-col'     => 'GRP_ID',
1464
+			];
1465
+
1466
+			$template_form_fields['ee-msg-messenger'] = [
1467
+				'name'       => 'MTP_messenger',
1468
+				'label'      => null,
1469
+				'input'      => 'hidden',
1470
+				'type'       => 'string',
1471
+				'required'   => false,
1472
+				'validation' => true,
1473
+				'value'      => $message_template_group->messenger(),
1474
+				'css_class'  => '',
1475
+				'format'     => '%s',
1476
+				'db-col'     => 'MTP_messenger',
1477
+			];
1478
+
1479
+			$template_form_fields['ee-msg-message-type'] = [
1480
+				'name'       => 'MTP_message_type',
1481
+				'label'      => null,
1482
+				'input'      => 'hidden',
1483
+				'type'       => 'string',
1484
+				'required'   => false,
1485
+				'validation' => true,
1486
+				'value'      => $message_template_group->message_type(),
1487
+				'css_class'  => '',
1488
+				'format'     => '%s',
1489
+				'db-col'     => 'MTP_message_type',
1490
+			];
1491
+
1492
+			$sidebar_form_fields['ee-msg-is-global'] = [
1493
+				'name'       => 'MTP_is_global',
1494
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1495
+				'input'      => 'hidden',
1496
+				'type'       => 'int',
1497
+				'required'   => false,
1498
+				'validation' => true,
1499
+				'value'      => $message_template_group->get('MTP_is_global'),
1500
+				'css_class'  => '',
1501
+				'format'     => '%d',
1502
+				'db-col'     => 'MTP_is_global',
1503
+			];
1504
+
1505
+			$sidebar_form_fields['ee-msg-is-override'] = [
1506
+				'name'       => 'MTP_is_override',
1507
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1508
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1509
+				'type'       => 'int',
1510
+				'required'   => false,
1511
+				'validation' => true,
1512
+				'value'      => $message_template_group->get('MTP_is_override'),
1513
+				'css_class'  => '',
1514
+				'format'     => '%d',
1515
+				'db-col'     => 'MTP_is_override',
1516
+			];
1517
+
1518
+			$sidebar_form_fields['ee-msg-is-active'] = [
1519
+				'name'       => 'MTP_is_active',
1520
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1521
+				'input'      => 'hidden',
1522
+				'type'       => 'int',
1523
+				'required'   => false,
1524
+				'validation' => true,
1525
+				'value'      => $message_template_group->is_active(),
1526
+				'css_class'  => '',
1527
+				'format'     => '%d',
1528
+				'db-col'     => 'MTP_is_active',
1529
+			];
1530
+
1531
+			$sidebar_form_fields['ee-msg-deleted'] = [
1532
+				'name'       => 'MTP_deleted',
1533
+				'label'      => null,
1534
+				'input'      => 'hidden',
1535
+				'type'       => 'int',
1536
+				'required'   => false,
1537
+				'validation' => true,
1538
+				'value'      => $message_template_group->get('MTP_deleted'),
1539
+				'css_class'  => '',
1540
+				'format'     => '%d',
1541
+				'db-col'     => 'MTP_deleted',
1542
+			];
1543
+			$sidebar_form_fields['ee-msg-author']  = [
1544
+				'name'       => 'MTP_user_id',
1545
+				'label'      => esc_html__('Author', 'event_espresso'),
1546
+				'input'      => 'hidden',
1547
+				'type'       => 'int',
1548
+				'required'   => false,
1549
+				'validation' => false,
1550
+				'value'      => $message_template_group->user(),
1551
+				'format'     => '%d',
1552
+				'db-col'     => 'MTP_user_id',
1553
+			];
1554
+
1555
+			$sidebar_form_fields['ee-msg-route'] = [
1556
+				'name'  => 'action',
1557
+				'input' => 'hidden',
1558
+				'type'  => 'string',
1559
+				'value' => $action,
1560
+			];
1561
+
1562
+			$sidebar_form_fields['ee-msg-id']        = [
1563
+				'name'  => 'id',
1564
+				'input' => 'hidden',
1565
+				'type'  => 'int',
1566
+				'value' => $GRP_ID,
1567
+			];
1568
+			$sidebar_form_fields['ee-msg-evt-nonce'] = [
1569
+				'name'  => $action . '_nonce',
1570
+				'input' => 'hidden',
1571
+				'type'  => 'string',
1572
+				'value' => wp_create_nonce($action . '_nonce'),
1573
+			];
1574
+
1575
+			$template_switch = $this->request->getRequestParam('template_switch');
1576
+			if ($template_switch) {
1577
+				$sidebar_form_fields['ee-msg-template-switch'] = [
1578
+					'name'  => 'template_switch',
1579
+					'input' => 'hidden',
1580
+					'type'  => 'int',
1581
+					'value' => 1,
1582
+				];
1583
+			}
1584
+
1585
+
1586
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1587
+			$sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1588
+		} //end if ( !empty($template_field_structure) )
1589
+
1590
+		// set extra content for publish box
1591
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1592
+		$this->_set_publish_post_box_vars(
1593
+			'id',
1594
+			$GRP_ID,
1595
+			'',
1596
+			add_query_arg(
1597
+				['action' => $message_template_group->is_global() ? 'global_mtps' : 'custom_mtps'],
1598
+				$this->_admin_base_url
1599
+			),
1600
+			true
1601
+		);
1602
+
1603
+		// add preview button
1604
+		$preview_url    = parent::add_query_args_and_nonce(
1605
+			[
1606
+				'message_type' => $message_template_group->message_type(),
1607
+				'messenger'    => $message_template_group->messenger(),
1608
+				'context'      => $context,
1609
+				'GRP_ID'       => $GRP_ID,
1610
+				'evt_id'       => $EVT_ID ?: false,
1611
+				'action'       => 'preview_message',
1612
+			],
1613
+			$this->_admin_base_url
1614
+		);
1615
+		$preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1616
+						  . esc_html__('Preview', 'event_espresso')
1617
+						  . '</a>';
1618
+
1619
+
1620
+		// setup context switcher
1621
+		$this->_set_context_switcher(
1622
+			$message_template_group,
1623
+			[
1624
+				'page'    => 'espresso_messages',
1625
+				'action'  => 'edit_message_template',
1626
+				'id'      => $GRP_ID,
1627
+				'evt_id'  => $EVT_ID,
1628
+				'context' => $context,
1629
+				'extra'   => $preview_button,
1630
+			]
1631
+		);
1632
+
1633
+		// main box
1634
+		$this->_template_args['template_fields']                         = $template_fields;
1635
+		$this->_template_args['sidebar_box_id']                          = 'details';
1636
+		$this->_template_args['action']                                  = $action;
1637
+		$this->_template_args['context']                                 = $context;
1638
+		$this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1639
+		$this->_template_args['learn_more_about_message_templates_link'] =
1640
+			$this->_learn_more_about_message_templates_link();
1641
+
1642
+		$this->_template_args['before_admin_page_content'] = '<div class="ee-msg-admin-header">';
1643
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1644
+			$message_template_group,
1645
+			$context,
1646
+			$context_label
1647
+		);
1648
+		$this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1649
+		$this->_template_args['before_admin_page_content'] .= '</div>';
1650
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1651
+		$this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1652
+
1653
+		$this->_template_path = $this->_template_args['GRP_ID']
1654
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1655
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1656
+
1657
+		// send along EE_Message_Template_Group object for further template use.
1658
+		$this->_template_args['MTP'] = $message_template_group;
1659
+
1660
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1661
+			$this->_template_path,
1662
+			$this->_template_args,
1663
+			true
1664
+		);
1665
+
1666
+		// finally, let's set the admin_page title
1667
+		$this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1668
+
1669
+		// we need to take care of setting the shortcodes property for use elsewhere.
1670
+		$this->_set_shortcodes();
1671
+
1672
+		// final template wrapper
1673
+		$this->display_admin_page_with_sidebar();
1674
+	}
1675
+
1676
+
1677
+	public function filter_tinymce_init($mceInit, $editor_id)
1678
+	{
1679
+		return $mceInit;
1680
+	}
1681
+
1682
+
1683
+	public function add_context_switcher()
1684
+	{
1685
+		return $this->_context_switcher;
1686
+	}
1687
+
1688
+
1689
+	/**
1690
+	 * Adds the activation/deactivation toggle for the message template context.
1691
+	 *
1692
+	 * @param EE_Message_Template_Group $message_template_group
1693
+	 * @param string                    $context
1694
+	 * @param string                    $context_label
1695
+	 * @return string
1696
+	 * @throws DomainException
1697
+	 * @throws EE_Error
1698
+	 * @throws InvalidIdentifierException
1699
+	 * @throws ReflectionException
1700
+	 */
1701
+	protected function add_active_context_element(
1702
+		EE_Message_Template_Group $message_template_group,
1703
+		$context,
1704
+		$context_label
1705
+	) {
1706
+		$template_args = [
1707
+			'context'                   => $context,
1708
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1709
+			'is_active'                 => $message_template_group->is_context_active($context),
1710
+			'on_off_action'             => $message_template_group->is_context_active($context)
1711
+				? 'context-off'
1712
+				: 'context-on',
1713
+			'context_label'             => str_replace(['(', ')'], '', $context_label),
1714
+			'message_template_group_id' => $message_template_group->ID(),
1715
+		];
1716
+		return EEH_Template::display_template(
1717
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1718
+			$template_args,
1719
+			true
1720
+		);
1721
+	}
1722
+
1723
+
1724
+	/**
1725
+	 * Ajax callback for `toggle_context_template` ajax action.
1726
+	 * Handles toggling the message context on or off.
1727
+	 *
1728
+	 * @throws EE_Error
1729
+	 * @throws InvalidArgumentException
1730
+	 * @throws InvalidDataTypeException
1731
+	 * @throws InvalidIdentifierException
1732
+	 * @throws InvalidInterfaceException
1733
+	 * @throws ReflectionException
1734
+	 */
1735
+	public function toggle_context_template()
1736
+	{
1737
+		$success = true;
1738
+		// check for required data
1739
+		if (
1740
+			! (
1741
+				$this->request->requestParamIsSet('message_template_group_id')
1742
+				&& $this->request->requestParamIsSet('context')
1743
+				&& $this->request->requestParamIsSet('status')
1744
+			)
1745
+		) {
1746
+			EE_Error::add_error(
1747
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1748
+				__FILE__,
1749
+				__FUNCTION__,
1750
+				__LINE__
1751
+			);
1752
+			$success = false;
1753
+		}
1754
+
1755
+		$nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1756
+		$context = $this->request->getRequestParam('context', '');
1757
+		$status  = $this->request->getRequestParam('status', '');
1758
+
1759
+		$this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1760
+
1761
+		if ($status !== 'off' && $status !== 'on') {
1762
+			EE_Error::add_error(
1763
+				sprintf(
1764
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1765
+					$status
1766
+				),
1767
+				__FILE__,
1768
+				__FUNCTION__,
1769
+				__LINE__
1770
+			);
1771
+			$success = false;
1772
+		}
1773
+		$message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, DataType::INTEGER);
1774
+		$message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1775
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1776
+			EE_Error::add_error(
1777
+				sprintf(
1778
+					esc_html__(
1779
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1780
+						'event_espresso'
1781
+					),
1782
+					$message_template_group_id,
1783
+					'EE_Message_Template_Group'
1784
+				),
1785
+				__FILE__,
1786
+				__FUNCTION__,
1787
+				__LINE__
1788
+			);
1789
+			$success = false;
1790
+		}
1791
+		if ($success) {
1792
+			$success = $status === 'off'
1793
+				? $message_template_group->deactivate_context($context)
1794
+				: $message_template_group->activate_context($context);
1795
+		}
1796
+		$this->_template_args['success'] = $success;
1797
+		$this->_return_json();
1798
+	}
1799
+
1800
+
1801
+	public function _add_form_element_before()
1802
+	{
1803
+		return '<form method="post" action="'
1804
+			   . $this->_template_args['edit_message_template_form_url']
1805
+			   . '" id="ee-msg-edit-frm">';
1806
+	}
1807
+
1808
+
1809
+	public function _add_form_element_after()
1810
+	{
1811
+		return '</form>';
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 * This executes switching the template pack for a message template.
1817
+	 *
1818
+	 * @throws EE_Error
1819
+	 * @throws InvalidDataTypeException
1820
+	 * @throws InvalidInterfaceException
1821
+	 * @throws InvalidArgumentException
1822
+	 * @throws ReflectionException
1823
+	 * @since 4.5.0
1824
+	 */
1825
+	public function switch_template_pack()
1826
+	{
1827
+		$GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1828
+		$template_pack = $this->request->getRequestParam('template_pack', '');
1829
+
1830
+		// verify we have needed values.
1831
+		if (empty($GRP_ID) || empty($template_pack)) {
1832
+			$this->_template_args['error'] = true;
1833
+			EE_Error::add_error(
1834
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
1835
+				__FILE__,
1836
+				__FUNCTION__,
1837
+				__LINE__
1838
+			);
1839
+		} else {
1840
+			// get template, set the new template_pack and then reset to default
1841
+			/** @var EE_Message_Template_Group $message_template_group */
1842
+			$message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
1843
+
1844
+			$message_template_group->set_template_pack_name($template_pack);
1845
+			$this->request->setRequestParam('msgr', $message_template_group->messenger());
1846
+			$this->request->setRequestParam('mt', $message_template_group->message_type());
1847
+
1848
+			$query_args = $this->_reset_to_default_template();
1849
+
1850
+			if (empty($query_args['id'])) {
1851
+				EE_Error::add_error(
1852
+					esc_html__(
1853
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
1854
+						'event_espresso'
1855
+					),
1856
+					__FILE__,
1857
+					__FUNCTION__,
1858
+					__LINE__
1859
+				);
1860
+				$this->_template_args['error'] = true;
1861
+			} else {
1862
+				$template_label       = $message_template_group->get_template_pack()->label;
1863
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
1864
+				EE_Error::add_success(
1865
+					sprintf(
1866
+						esc_html__(
1867
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
1868
+							'event_espresso'
1869
+						),
1870
+						$template_label,
1871
+						$template_pack_labels->template_pack
1872
+					)
1873
+				);
1874
+				// generate the redirect url for js.
1875
+				$url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1876
+
1877
+				$this->_template_args['data']['redirect_url'] = $url;
1878
+				$this->_template_args['success']              = true;
1879
+			}
1880
+
1881
+			$this->_return_json();
1882
+		}
1883
+	}
1884
+
1885
+
1886
+	/**
1887
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
1888
+	 * they want.
1889
+	 *
1890
+	 * @access protected
1891
+	 * @return array|void
1892
+	 * @throws EE_Error
1893
+	 * @throws InvalidArgumentException
1894
+	 * @throws InvalidDataTypeException
1895
+	 * @throws InvalidInterfaceException
1896
+	 * @throws ReflectionException
1897
+	 */
1898
+	protected function _reset_to_default_template()
1899
+	{
1900
+		$templates    = [];
1901
+		$GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1902
+		$messenger    = $this->request->getRequestParam('msgr');
1903
+		$message_type = $this->request->getRequestParam('mt');
1904
+		// we need to make sure we've got the info we need.
1905
+		if (! ($GRP_ID && $messenger && $message_type)) {
1906
+			EE_Error::add_error(
1907
+				esc_html__(
1908
+					'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
1909
+					'event_espresso'
1910
+				),
1911
+				__FILE__,
1912
+				__FUNCTION__,
1913
+				__LINE__
1914
+			);
1915
+		}
1916
+
1917
+		// all templates will be reset to whatever the defaults are
1918
+		// for the global template matching the messenger and message type.
1919
+		$success = ! empty($GRP_ID);
1920
+
1921
+		if ($success) {
1922
+			// let's first determine if the incoming template is a global template,
1923
+			// if it isn't then we need to get the global template matching messenger and message type.
1924
+			// $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
1925
+
1926
+
1927
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
1928
+			$success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplates($GRP_ID);
1929
+
1930
+			if ($success) {
1931
+				// if successfully deleted, lets generate the new ones.
1932
+				// Note. We set GLOBAL to true, because resets on ANY template
1933
+				// will use the related global template defaults for regeneration.
1934
+				// This means that if a custom template is reset it resets to whatever the related global template is.
1935
+				// HOWEVER, we DO keep the template pack and template variation set
1936
+				// for the current custom template when resetting.
1937
+				$templates = $this->getMessageTemplateManager()->generateNewTemplates(
1938
+					$messenger,
1939
+					$message_type,
1940
+					$GRP_ID,
1941
+					true
1942
+				);
1943
+			}
1944
+		}
1945
+
1946
+		// any error messages?
1947
+		if (! $success) {
1948
+			EE_Error::add_error(
1949
+				esc_html__(
1950
+					'Something went wrong with deleting existing templates. Unable to reset to default',
1951
+					'event_espresso'
1952
+				),
1953
+				__FILE__,
1954
+				__FUNCTION__,
1955
+				__LINE__
1956
+			);
1957
+		}
1958
+
1959
+		// all good, let's add a success message!
1960
+		if ($success && ! empty($templates)) {
1961
+			// the info for the template we generated is the first element in the returned array
1962
+			EE_Error::overwrite_success();
1963
+			EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
1964
+		}
1965
+
1966
+
1967
+		$query_args = [
1968
+			'id'      => $templates['GRP_ID'] ?? null,
1969
+			'context' => $templates['MTP_context'] ?? null,
1970
+			'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
1971
+		];
1972
+
1973
+		// if called via ajax then we return query args otherwise redirect
1974
+		if ($this->request->isAjax()) {
1975
+			return $query_args;
1976
+		}
1977
+		$this->_redirect_after_action(false, '', '', $query_args, true);
1978
+	}
1979
+
1980
+
1981
+	/**
1982
+	 * Retrieve and set the message preview for display.
1983
+	 *
1984
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
1985
+	 * @return string
1986
+	 * @throws ReflectionException
1987
+	 * @throws EE_Error
1988
+	 * @throws InvalidArgumentException
1989
+	 * @throws InvalidDataTypeException
1990
+	 * @throws InvalidInterfaceException
1991
+	 */
1992
+	public function _preview_message($send = false)
1993
+	{
1994
+		// first make sure we've got the necessary parameters
1995
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1996
+		if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
1997
+			EE_Error::add_error(
1998
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
1999
+				__FILE__,
2000
+				__FUNCTION__,
2001
+				__LINE__
2002
+			);
2003
+		}
2004
+
2005
+		$context = $this->request->getRequestParam('context');
2006
+		// get the preview!
2007
+		$preview = EED_Messages::preview_message(
2008
+			$this->_active_message_type_name,
2009
+			$context,
2010
+			$this->_active_messenger_name,
2011
+			$send
2012
+		);
2013
+
2014
+		if ($send) {
2015
+			return $preview;
2016
+		}
2017
+
2018
+		// if we have an evt_id set on the request, use it.
2019
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, DataType::INTEGER);
2020
+
2021
+		// let's add a button to go back to the edit view
2022
+		$query_args             = [
2023
+			'id'      => $GRP_ID,
2024
+			'evt_id'  => $EVT_ID,
2025
+			'context' => $context,
2026
+			'action'  => 'edit_message_template',
2027
+		];
2028
+		$go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2029
+		$preview_button         = '<a href="'
2030
+								  . $go_back_url
2031
+								  . '" class="button--secondary messages-preview-go-back-button">'
2032
+								  . esc_html__('Go Back to Edit', 'event_espresso')
2033
+								  . '</a>';
2034
+		$message_types          = $this->get_installed_message_types();
2035
+		$active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2036
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2037
+			? ucwords($active_messenger->label['singular'])
2038
+			: esc_html__('Unknown Messenger', 'event_espresso');
2039
+		// let's provide a helpful title for context
2040
+		$preview_title = sprintf(
2041
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2042
+			$active_messenger_label,
2043
+			ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2044
+		);
2045
+		if (empty($preview)) {
2046
+			$this->noEventsErrorMessage();
2047
+		}
2048
+		// setup display of preview.
2049
+		$this->_admin_page_title                    = $preview_title;
2050
+		$this->_template_args['admin_page_title']   = $preview_title;
2051
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2052
+		$this->_template_args['data']['force_json'] = true;
2053
+
2054
+		return '';
2055
+	}
2056
+
2057
+
2058
+	/**
2059
+	 * Used to set an error if there are no events available for generating a preview/test send.
2060
+	 *
2061
+	 * @param bool $test_send Whether the error should be generated for the context of a test send.
2062
+	 */
2063
+	protected function noEventsErrorMessage($test_send = false)
2064
+	{
2065
+		$events_url = parent::add_query_args_and_nonce(
2066
+			[
2067
+				'action' => 'default',
2068
+				'page'   => 'espresso_events',
2069
+			],
2070
+			admin_url('admin.php')
2071
+		);
2072
+		$message    = $test_send
2073
+			? esc_html__(
2074
+				'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2075
+				'event_espresso'
2076
+			)
2077
+			: esc_html__(
2078
+				'There is no preview for this message template available because there are no events created yet. The preview system uses actual events for generating the preview. %1$sGo see your events%2$s!',
2079
+				'event_espresso'
2080
+			);
2081
+
2082
+		EE_Error::add_attention(
2083
+			sprintf(
2084
+				$message,
2085
+				"<a href='{$events_url}'>",
2086
+				'</a>'
2087
+			)
2088
+		);
2089
+	}
2090
+
2091
+
2092
+	/**
2093
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2094
+	 * gets called automatically.
2095
+	 *
2096
+	 * @return void
2097
+	 * @throws EE_Error
2098
+	 * @since 4.5.0
2099
+	 */
2100
+	protected function _display_preview_message()
2101
+	{
2102
+		$this->display_admin_page_with_no_sidebar();
2103
+	}
2104
+
2105
+
2106
+	/**
2107
+	 * registers metaboxes that should show up on the "edit_message_template" page
2108
+	 *
2109
+	 * @access protected
2110
+	 * @return void
2111
+	 */
2112
+	protected function _register_edit_meta_boxes()
2113
+	{
2114
+		$this->addMetaBox(
2115
+			'mtp_valid_shortcodes',
2116
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2117
+			[$this, 'shortcode_meta_box'],
2118
+			$this->_current_screen->id,
2119
+			'side'
2120
+		);
2121
+		$this->addMetaBox(
2122
+			'mtp_extra_actions',
2123
+			esc_html__('Extra Actions', 'event_espresso'),
2124
+			[$this, 'extra_actions_meta_box'],
2125
+			$this->_current_screen->id,
2126
+			'side',
2127
+			'high'
2128
+		);
2129
+		$this->addMetaBox(
2130
+			'mtp_templates',
2131
+			esc_html__('Template Styles', 'event_espresso'),
2132
+			[$this, 'template_pack_meta_box'],
2133
+			$this->_current_screen->id,
2134
+			'side',
2135
+			'high'
2136
+		);
2137
+	}
2138
+
2139
+
2140
+	/**
2141
+	 * metabox content for all template pack and variation selection.
2142
+	 *
2143
+	 * @return void
2144
+	 * @throws DomainException
2145
+	 * @throws EE_Error
2146
+	 * @throws InvalidArgumentException
2147
+	 * @throws ReflectionException
2148
+	 * @throws InvalidDataTypeException
2149
+	 * @throws InvalidInterfaceException
2150
+	 * @since 4.5.0
2151
+	 */
2152
+	public function template_pack_meta_box()
2153
+	{
2154
+		$this->_set_message_template_group();
2155
+
2156
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2157
+
2158
+		$tp_select_values = [];
2159
+
2160
+		foreach ($tp_collection as $tp) {
2161
+			// only include template packs that support this messenger and message type!
2162
+			$supports = $tp->get_supports();
2163
+			if (
2164
+				! isset($supports[ $this->_message_template_group->messenger() ])
2165
+				|| ! in_array(
2166
+					$this->_message_template_group->message_type(),
2167
+					$supports[ $this->_message_template_group->messenger() ],
2168
+					true
2169
+				)
2170
+			) {
2171
+				// not supported
2172
+				continue;
2173
+			}
2174
+
2175
+			$tp_select_values[] = [
2176
+				'text' => $tp->label,
2177
+				'id'   => $tp->dbref,
2178
+			];
2179
+		}
2180
+
2181
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2182
+		// the default template pack.  This still allows for the odd template pack to override.
2183
+		if (empty($tp_select_values)) {
2184
+			$tp_select_values[] = [
2185
+				'text' => esc_html__('Default', 'event_espresso'),
2186
+				'id'   => 'default',
2187
+			];
2188
+		}
2189
+
2190
+		// setup variation select values for the currently selected template.
2191
+		$variations               = $this->_message_template_group->get_template_pack()->get_variations(
2192
+			$this->_message_template_group->messenger(),
2193
+			$this->_message_template_group->message_type()
2194
+		);
2195
+		$variations_select_values = [];
2196
+		foreach ($variations as $variation => $label) {
2197
+			$variations_select_values[] = [
2198
+				'text' => $label,
2199
+				'id'   => $variation,
2200
+			];
2201
+		}
2202
+
2203
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2204
+
2205
+		$template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2206
+			'MTP_template_pack',
2207
+			$tp_select_values,
2208
+			$this->_message_template_group->get_template_pack_name()
2209
+		);
2210
+		$template_args['variations_selector']            = EEH_Form_Fields::select_input(
2211
+			'MTP_template_variation',
2212
+			$variations_select_values,
2213
+			$this->_message_template_group->get_template_pack_variation()
2214
+		);
2215
+		$template_args['template_pack_label']            = $template_pack_labels->template_pack;
2216
+		$template_args['template_variation_label']       = $template_pack_labels->template_variation;
2217
+		$template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2218
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2219
+
2220
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2221
+
2222
+		EEH_Template::display_template($template, $template_args);
2223
+	}
2224
+
2225
+
2226
+	/**
2227
+	 * This meta box holds any extra actions related to Message Templates
2228
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2229
+	 *
2230
+	 * @access  public
2231
+	 * @return void
2232
+	 * @throws EE_Error
2233
+	 */
2234
+	public function extra_actions_meta_box()
2235
+	{
2236
+		$template_form_fields = [];
2237
+
2238
+		$extra_args = [
2239
+			'msgr'   => $this->_message_template_group->messenger(),
2240
+			'mt'     => $this->_message_template_group->message_type(),
2241
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2242
+		];
2243
+		// first we need to see if there are any fields
2244
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2245
+
2246
+		if (! empty($fields)) {
2247
+			// yup there be fields
2248
+			foreach ($fields as $field => $config) {
2249
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2250
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2251
+				$default  = $config['default'] ?? '';
2252
+				$default  = $config['value'] ?? $default;
2253
+
2254
+				// if type is hidden and the value is empty
2255
+				// something may have gone wrong so let's correct with the defaults
2256
+				$fix                = $config['input'] === 'hidden'
2257
+									  && isset($existing[ $field ])
2258
+									  && empty($existing[ $field ])
2259
+					? $default
2260
+					: '';
2261
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2262
+					? $existing[ $field ]
2263
+					: $fix;
2264
+
2265
+				$template_form_fields[ $field_id ] = [
2266
+					'name'       => 'test_settings_fld[' . $field . ']',
2267
+					'label'      => $config['label'],
2268
+					'input'      => $config['input'],
2269
+					'type'       => $config['type'],
2270
+					'required'   => $config['required'],
2271
+					'validation' => $config['validation'],
2272
+					'value'      => $existing[ $field ] ?? $default,
2273
+					'css_class'  => $config['css_class'],
2274
+					'options'    => $config['options'] ?? [],
2275
+					'default'    => $default,
2276
+					'format'     => $config['format'],
2277
+				];
2278
+			}
2279
+		}
2280
+
2281
+		$test_settings_html = ! empty($template_form_fields)
2282
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2283
+			: '';
2284
+
2285
+		// print out $test_settings_fields
2286
+		if (! empty($test_settings_html)) {
2287
+			$test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2288
+			$test_settings_html .= 'name="test_button" value="';
2289
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2290
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2291
+		}
2292
+
2293
+		// and button
2294
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2295
+		$test_settings_html .= '<p>';
2296
+		$test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2297
+		$test_settings_html .= '</p>';
2298
+		$test_settings_html .= $this->get_action_link_or_button(
2299
+			'reset_to_default',
2300
+			'reset',
2301
+			$extra_args,
2302
+			'button--primary reset-default-button'
2303
+		);
2304
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2305
+		echo wp_kses($test_settings_html, AllowedTags::getWithFormTags());
2306
+	}
2307
+
2308
+
2309
+	/**
2310
+	 * This returns the shortcode selector skeleton for a given context and field.
2311
+	 *
2312
+	 * @param string $field           The name of the field retrieving shortcodes for.
2313
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2314
+	 * @return string
2315
+	 * @throws DomainException
2316
+	 * @throws EE_Error
2317
+	 * @throws InvalidArgumentException
2318
+	 * @throws ReflectionException
2319
+	 * @throws InvalidDataTypeException
2320
+	 * @throws InvalidInterfaceException
2321
+	 * @since 4.9.rc.000
2322
+	 */
2323
+	protected function _get_shortcode_selector($field, $linked_input_id)
2324
+	{
2325
+		$template_args = [
2326
+			'shortcodes'      => $this->_get_shortcodes([$field]),
2327
+			'fieldname'       => $field,
2328
+			'linked_input_id' => $linked_input_id,
2329
+		];
2330
+
2331
+		return EEH_Template::display_template(
2332
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2333
+			$template_args,
2334
+			true
2335
+		);
2336
+	}
2337
+
2338
+
2339
+	/**
2340
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2341
+	 * page)
2342
+	 *
2343
+	 * @access public
2344
+	 * @return void
2345
+	 * @throws EE_Error
2346
+	 * @throws InvalidArgumentException
2347
+	 * @throws ReflectionException
2348
+	 * @throws InvalidDataTypeException
2349
+	 * @throws InvalidInterfaceException
2350
+	 */
2351
+	public function shortcode_meta_box()
2352
+	{
2353
+		$shortcodes = $this->_get_shortcodes([], false);
2354
+		// just make sure the shortcodes property is set
2355
+		// $messenger = $this->_message_template_group->messenger_obj();
2356
+		// now let's set the content depending on the status of the shortcodes array
2357
+		if (empty($shortcodes)) {
2358
+			echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2359
+			return;
2360
+		}
2361
+		?>
2362 2362
         <div style="float:right; margin-top:10px">
2363 2363
             <?php echo wp_kses($this->_get_help_tab_link('message_template_shortcodes'), AllowedTags::getAllowedTags());
2364
-            ?>
2364
+			?>
2365 2365
         </div>
2366 2366
         <p class="small-text">
2367 2367
             <?php printf(
2368
-                esc_html__(
2369
-                    'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2370
-                    'event_espresso'
2371
-                ),
2372
-                '<span class="dashicons dashicons-shortcode"></span>'
2373
-            ); ?>
2368
+				esc_html__(
2369
+					'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2370
+					'event_espresso'
2371
+				),
2372
+				'<span class="dashicons dashicons-shortcode"></span>'
2373
+			); ?>
2374 2374
         </p>
2375 2375
         <?php
2376
-    }
2377
-
2378
-
2379
-    /**
2380
-     * used to set the $_shortcodes property for when its needed elsewhere.
2381
-     *
2382
-     * @access protected
2383
-     * @return void
2384
-     * @throws EE_Error
2385
-     * @throws InvalidArgumentException
2386
-     * @throws ReflectionException
2387
-     * @throws InvalidDataTypeException
2388
-     * @throws InvalidInterfaceException
2389
-     */
2390
-    protected function _set_shortcodes()
2391
-    {
2392
-        // no need to run this if the property is already set
2393
-        if (! empty($this->_shortcodes)) {
2394
-            return;
2395
-        }
2396
-
2397
-        $this->_shortcodes = $this->_get_shortcodes();
2398
-    }
2399
-
2400
-
2401
-    /**
2402
-     * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2403
-     * property)
2404
-     *
2405
-     * @access  protected
2406
-     * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2407
-     *                         for. Defaults to all (for the given context)
2408
-     * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2409
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2410
-     *                         true just an array of shortcode/label pairs.
2411
-     * @throws EE_Error
2412
-     * @throws InvalidArgumentException
2413
-     * @throws ReflectionException
2414
-     * @throws InvalidDataTypeException
2415
-     * @throws InvalidInterfaceException
2416
-     */
2417
-    protected function _get_shortcodes(array $fields = [], bool $merged = true): array
2418
-    {
2419
-        $this->_set_message_template_group();
2420
-
2421
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2422
-        $GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2423
-        if (empty($GRP_ID)) {
2424
-            return [];
2425
-        }
2426
-        $context = $this->request->getRequestParam(
2427
-            'messenger',
2428
-            key($this->_message_template_group->contexts_config())
2429
-        );
2430
-        return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2431
-    }
2432
-
2433
-
2434
-    /**
2435
-     * This sets the _message_template property (containing the called message_template object)
2436
-     *
2437
-     * @access protected
2438
-     * @return void
2439
-     * @throws EE_Error
2440
-     * @throws InvalidArgumentException
2441
-     * @throws ReflectionException
2442
-     * @throws InvalidDataTypeException
2443
-     * @throws InvalidInterfaceException
2444
-     */
2445
-    protected function _set_message_template_group()
2446
-    {
2447
-        // get out if this is already set.
2448
-        if (! empty($this->_message_template_group)) {
2449
-            return;
2450
-        }
2451
-
2452
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
2453
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, DataType::INTEGER);
2454
-
2455
-        // let's get the message templates
2456
-        $this->_message_template_group = ! empty($GRP_ID)
2457
-            ? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2458
-            : $this->getMtgModel()->create_default_object();
2459
-
2460
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2461
-        $this->_variation     = $this->_message_template_group->get_template_pack_variation();
2462
-    }
2463
-
2464
-
2465
-    /**
2466
-     * sets up a context switcher for edit forms
2467
-     *
2468
-     * @access  protected
2469
-     * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2470
-     * @param array                     $args                  various things the context switcher needs.
2471
-     * @throws EE_Error
2472
-     */
2473
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, array $args)
2474
-    {
2475
-        $context_details = $template_group_object->contexts_config();
2476
-        $context_label   = $template_group_object->context_label();
2477
-        ob_start();
2478
-        ?>
2376
+	}
2377
+
2378
+
2379
+	/**
2380
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2381
+	 *
2382
+	 * @access protected
2383
+	 * @return void
2384
+	 * @throws EE_Error
2385
+	 * @throws InvalidArgumentException
2386
+	 * @throws ReflectionException
2387
+	 * @throws InvalidDataTypeException
2388
+	 * @throws InvalidInterfaceException
2389
+	 */
2390
+	protected function _set_shortcodes()
2391
+	{
2392
+		// no need to run this if the property is already set
2393
+		if (! empty($this->_shortcodes)) {
2394
+			return;
2395
+		}
2396
+
2397
+		$this->_shortcodes = $this->_get_shortcodes();
2398
+	}
2399
+
2400
+
2401
+	/**
2402
+	 * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2403
+	 * property)
2404
+	 *
2405
+	 * @access  protected
2406
+	 * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2407
+	 *                         for. Defaults to all (for the given context)
2408
+	 * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2409
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2410
+	 *                         true just an array of shortcode/label pairs.
2411
+	 * @throws EE_Error
2412
+	 * @throws InvalidArgumentException
2413
+	 * @throws ReflectionException
2414
+	 * @throws InvalidDataTypeException
2415
+	 * @throws InvalidInterfaceException
2416
+	 */
2417
+	protected function _get_shortcodes(array $fields = [], bool $merged = true): array
2418
+	{
2419
+		$this->_set_message_template_group();
2420
+
2421
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2422
+		$GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2423
+		if (empty($GRP_ID)) {
2424
+			return [];
2425
+		}
2426
+		$context = $this->request->getRequestParam(
2427
+			'messenger',
2428
+			key($this->_message_template_group->contexts_config())
2429
+		);
2430
+		return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2431
+	}
2432
+
2433
+
2434
+	/**
2435
+	 * This sets the _message_template property (containing the called message_template object)
2436
+	 *
2437
+	 * @access protected
2438
+	 * @return void
2439
+	 * @throws EE_Error
2440
+	 * @throws InvalidArgumentException
2441
+	 * @throws ReflectionException
2442
+	 * @throws InvalidDataTypeException
2443
+	 * @throws InvalidInterfaceException
2444
+	 */
2445
+	protected function _set_message_template_group()
2446
+	{
2447
+		// get out if this is already set.
2448
+		if (! empty($this->_message_template_group)) {
2449
+			return;
2450
+		}
2451
+
2452
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
2453
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, DataType::INTEGER);
2454
+
2455
+		// let's get the message templates
2456
+		$this->_message_template_group = ! empty($GRP_ID)
2457
+			? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2458
+			: $this->getMtgModel()->create_default_object();
2459
+
2460
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2461
+		$this->_variation     = $this->_message_template_group->get_template_pack_variation();
2462
+	}
2463
+
2464
+
2465
+	/**
2466
+	 * sets up a context switcher for edit forms
2467
+	 *
2468
+	 * @access  protected
2469
+	 * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2470
+	 * @param array                     $args                  various things the context switcher needs.
2471
+	 * @throws EE_Error
2472
+	 */
2473
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, array $args)
2474
+	{
2475
+		$context_details = $template_group_object->contexts_config();
2476
+		$context_label   = $template_group_object->context_label();
2477
+		ob_start();
2478
+		?>
2479 2479
         <div class="ee-msg-switcher-container">
2480 2480
             <form method="get" action="<?php echo esc_url_raw(EE_MSG_ADMIN_URL); ?>" id="ee-msg-context-switcher-frm">
2481 2481
                 <?php
2482
-                foreach ($args as $name => $value) {
2483
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2484
-                        continue;
2485
-                    }
2486
-                    ?>
2482
+				foreach ($args as $name => $value) {
2483
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2484
+						continue;
2485
+					}
2486
+					?>
2487 2487
                     <input type="hidden"
2488 2488
                            name="<?php echo esc_attr($name); ?>"
2489 2489
                            value="<?php echo esc_attr($value); ?>"
2490 2490
                     />
2491 2491
                     <?php
2492
-                }
2493
-                // setup nonce_url
2494
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2495
-                $id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2496
-                ?>
2492
+				}
2493
+				// setup nonce_url
2494
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2495
+				$id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2496
+				?>
2497 2497
                 <label for='<?php echo esc_attr($id); ?>' class='screen-reader-text'>
2498 2498
                     <?php esc_html_e('message context options', 'event_espresso'); ?>
2499 2499
                 </label>
2500 2500
                 <select id="<?php echo esc_attr($id); ?>" name="context">
2501 2501
                     <?php
2502
-                    $context_templates = $template_group_object->context_templates();
2503
-                    if (is_array($context_templates)) :
2504
-                        foreach ($context_templates as $context => $template_fields) :
2505
-                            $checked = ($context === $args['context']) ? 'selected' : '';
2506
-                            ?>
2502
+					$context_templates = $template_group_object->context_templates();
2503
+					if (is_array($context_templates)) :
2504
+						foreach ($context_templates as $context => $template_fields) :
2505
+							$checked = ($context === $args['context']) ? 'selected' : '';
2506
+							?>
2507 2507
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2508 2508
                                 <?php echo esc_html($context_details[ $context ]['label']); ?>
2509 2509
                             </option>
2510 2510
                         <?php endforeach;
2511
-                    endif; ?>
2511
+					endif; ?>
2512 2512
                 </select>
2513 2513
                 <?php $button_text = sprintf(
2514
-                    esc_html__('Switch %s', 'event_espresso'),
2515
-                    ucwords($context_label['label'])
2516
-                ); ?>
2514
+					esc_html__('Switch %s', 'event_espresso'),
2515
+					ucwords($context_label['label'])
2516
+				); ?>
2517 2517
                 <input class='button--secondary'
2518 2518
                        id="submit-msg-context-switcher-sbmt"
2519 2519
                        type="submit"
@@ -2523,1622 +2523,1622 @@  discard block
 block discarded – undo
2523 2523
             <?php echo wp_kses($args['extra'], AllowedTags::getWithFormTags()); ?>
2524 2524
         </div> <!-- end .ee-msg-switcher-container -->
2525 2525
         <?php $this->_context_switcher = ob_get_clean();
2526
-    }
2527
-
2528
-
2529
-    /**
2530
-     * @throws EE_Error
2531
-     * @throws ReflectionException
2532
-     * @deprecated 5.0.8.p
2533
-     */
2534
-    protected function _insert_or_update_message_template($new = false)
2535
-    {
2536
-        if ($new) {
2537
-            $this->insertMessageTemplate();
2538
-        } else {
2539
-            $this->updateMessageTemplate();
2540
-        }
2541
-    }
2542
-
2543
-
2544
-    /**
2545
-     * @throws EE_Error
2546
-     * @throws ReflectionException
2547
-     */
2548
-    protected function insertMessageTemplate(): void
2549
-    {
2550
-        $success   = true;
2551
-        $templates = [];
2552
-        try {
2553
-            $templates = $this->getMessageTemplateManager()->generateNewTemplates();
2554
-        } catch (Exception $exception) {
2555
-            $success = false;
2556
-            EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2557
-        }
2558
-
2559
-        /** @var MessageTemplateRequestData $form_data */
2560
-        $form_data = $this->loader->getShared(MessageTemplateRequestData::class);
2561
-        $this->_redirect_after_action(
2562
-            $success && isset($templates['GRP_ID'], $templates['MTP_context']),
2563
-            $this->generateUpdateDescription($form_data->messenger(), $form_data->messageType(), $form_data->context()),
2564
-            'created',
2565
-            [
2566
-                'id'      => $templates['GRP_ID'] ?? 0,
2567
-                'context' => $templates['MTP_context'] ?? '',
2568
-                'action'  => 'edit_message_template',
2569
-            ],
2570
-            $this->performTestSendAfterUpdate($form_data->messenger(), $form_data->messageType(), $form_data->context())
2571
-        );
2572
-    }
2573
-
2574
-
2575
-    /**
2576
-     * @throws EE_Error
2577
-     * @throws ReflectionException
2578
-     */
2579
-    protected function updateMessageTemplate(): void
2580
-    {
2581
-        $success = true;
2582
-        try {
2583
-            $this->getMessageTemplateManager()->updateExistingTemplates();
2584
-        } catch (Exception $exception) {
2585
-            $success = false;
2586
-            EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2587
-        }
2588
-
2589
-        /** @var MessageTemplateRequestData $form_data */
2590
-        $form_data = $this->loader->getShared(MessageTemplateRequestData::class);
2591
-
2592
-        $this->_redirect_after_action(
2593
-            $success,
2594
-            $this->generateUpdateDescription($form_data->messenger(), $form_data->messageType(), $form_data->context()),
2595
-            'updated',
2596
-            [
2597
-                'id'      => $form_data->groupID(),
2598
-                'context' => $form_data->context(),
2599
-                'action'  => 'edit_message_template',
2600
-            ],
2601
-            $this->performTestSendAfterUpdate($form_data->messenger(), $form_data->messageType(), $form_data->context())
2602
-        );
2603
-    }
2604
-
2605
-
2606
-    /**
2607
-     * @param string $messenger
2608
-     * @param string $message_type
2609
-     * @param string $context
2610
-     * @return string
2611
-     * @since 4.10.29.p
2612
-     */
2613
-    private function generateUpdateDescription(string $messenger, string $message_type, string $context): string
2614
-    {
2615
-        // need the message type and messenger objects to be able to use the labels for the notices
2616
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger);
2617
-        $messenger_label  = $messenger_object instanceof EE_messenger
2618
-            ? ucwords($messenger_object->label['singular'])
2619
-            : '';
2620
-
2621
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type);
2622
-        $message_type_label  = $message_type_object instanceof EE_message_type
2623
-            ? ucwords($message_type_object->label['singular'])
2624
-            : '';
2625
-
2626
-        $context   = ucwords(str_replace('_', ' ', $context));
2627
-        $item_desc = $messenger_label && $message_type_label
2628
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2629
-            : '';
2630
-        $item_desc .= 'Message Template';
2631
-        return $item_desc;
2632
-    }
2633
-
2634
-
2635
-    /**
2636
-     * @param string $messenger
2637
-     * @param string $message_type
2638
-     * @param string $context
2639
-     * @return bool
2640
-     * @throws EE_Error
2641
-     * @throws ReflectionException
2642
-     * @since 4.10.29.p
2643
-     */
2644
-    private function performTestSendAfterUpdate(string $messenger, string $message_type, string $context): bool
2645
-    {
2646
-        // was a test send triggered?
2647
-        if ($this->request->requestParamIsSet('test_button')) {
2648
-            EE_Error::overwrite_success();
2649
-            $this->_do_test_send($context, $messenger, $message_type);
2650
-            return true;
2651
-        }
2652
-        return false;
2653
-    }
2654
-
2655
-
2656
-    /**
2657
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
2658
-     *
2659
-     * @param string $context      what context being tested
2660
-     * @param string $messenger    messenger being tested
2661
-     * @param string $message_type message type being tested
2662
-     * @throws EE_Error
2663
-     * @throws InvalidArgumentException
2664
-     * @throws InvalidDataTypeException
2665
-     * @throws InvalidInterfaceException
2666
-     * @throws ReflectionException
2667
-     */
2668
-    protected function _do_test_send(string $context, string $messenger, string $message_type)
2669
-    {
2670
-        // set things up for preview
2671
-        $this->request->setRequestParam('messenger', $messenger);
2672
-        $this->request->setRequestParam('message_type', $message_type);
2673
-        $this->request->setRequestParam('context', $context);
2674
-        $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
2675
-
2676
-        $active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
2677
-        $test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
2678
-
2679
-        // let's save any existing fields that might be required by the messenger
2680
-        if (
2681
-            ! empty($test_settings_fld)
2682
-            && $active_messenger instanceof EE_messenger
2683
-            && apply_filters(
2684
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
2685
-                true,
2686
-                $test_settings_fld,
2687
-                $active_messenger
2688
-            )
2689
-        ) {
2690
-            $active_messenger->set_existing_test_settings($test_settings_fld);
2691
-        }
2692
-
2693
-        /**
2694
-         * Use filter to add additional controls on whether message can send or not
2695
-         */
2696
-        if (
2697
-            apply_filters(
2698
-                'FHEE__Messages_Admin_Page__do_test_send__can_send',
2699
-                true,
2700
-                $context,
2701
-                $this->request->requestParams(),
2702
-                $messenger,
2703
-                $message_type
2704
-            )
2705
-        ) {
2706
-            if (EEM_Event::instance()->count() > 0) {
2707
-                $success = $this->_preview_message(true);
2708
-                if ($success) {
2709
-                    EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
2710
-                } else {
2711
-                    EE_Error::add_error(
2712
-                        esc_html__('The test message was not sent', 'event_espresso'),
2713
-                        __FILE__,
2714
-                        __FUNCTION__,
2715
-                        __LINE__
2716
-                    );
2717
-                }
2718
-            } else {
2719
-                $this->noEventsErrorMessage(true);
2720
-            }
2721
-        }
2722
-    }
2723
-
2724
-
2725
-    /**
2726
-     * [_trash_or_restore_message_template]
2727
-     *
2728
-     * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
2729
-     * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
2730
-     *                        an individual context (FALSE).
2731
-     * @return void
2732
-     * @throws EE_Error
2733
-     * @throws InvalidArgumentException
2734
-     * @throws InvalidDataTypeException
2735
-     * @throws InvalidInterfaceException
2736
-     * @throws ReflectionException
2737
-     */
2738
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
2739
-    {
2740
-        $success = 1;
2741
-
2742
-        // incoming GRP_IDs
2743
-        if ($all) {
2744
-            // Checkboxes
2745
-            $checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2746
-            if (! empty($checkboxes)) {
2747
-                // if array has more than one element then success message should be plural.
2748
-                // todo: what about nonce?
2749
-                $success = count($checkboxes) > 1 ? 2 : 1;
2750
-
2751
-                // cycle through checkboxes
2752
-                foreach (array_keys($checkboxes) as $GRP_ID) {
2753
-                    $trashed_or_restored = $trash
2754
-                        ? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2755
-                        : $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2756
-                    if (! $trashed_or_restored) {
2757
-                        $success = 0;
2758
-                    }
2759
-                }
2760
-            } else {
2761
-                // grab single GRP_ID and handle
2762
-                $GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2763
-                if (! empty($GRP_ID)) {
2764
-                    $trashed_or_restored = $trash
2765
-                        ? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2766
-                        : $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2767
-                    if (! $trashed_or_restored) {
2768
-                        $success = 0;
2769
-                    }
2770
-                } else {
2771
-                    $success = 0;
2772
-                }
2773
-            }
2774
-        }
2775
-
2776
-        $action_desc = $trash
2777
-            ? esc_html__('moved to the trash', 'event_espresso')
2778
-            : esc_html__('restored', 'event_espresso');
2779
-
2780
-        $template_switch = $this->request->getRequestParam('template_switch', false, DataType::BOOLEAN);
2781
-        $action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
2782
-
2783
-        $item_desc = $all ? _n(
2784
-            'Message Template Group',
2785
-            'Message Template Groups',
2786
-            $success,
2787
-            'event_espresso'
2788
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
2789
-
2790
-        $item_desc = $template_switch
2791
-            ? _n('template', 'templates', $success, 'event_espresso')
2792
-            : $item_desc;
2793
-
2794
-        $this->_redirect_after_action(
2795
-            $success,
2796
-            $item_desc,
2797
-            $action_desc,
2798
-            [
2799
-                'action' => $this->request->getRequestParam('return'),
2800
-            ]
2801
-        );
2802
-    }
2803
-
2804
-
2805
-    /**
2806
-     * [_delete_message_template]
2807
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
2808
-     *
2809
-     * @return void
2810
-     * @throws EE_Error
2811
-     * @throws InvalidArgumentException
2812
-     * @throws InvalidDataTypeException
2813
-     * @throws InvalidInterfaceException
2814
-     * @throws ReflectionException
2815
-     */
2816
-    protected function _delete_message_template()
2817
-    {
2818
-        // checkboxes
2819
-        $checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2820
-        if (! empty($checkboxes)) {
2821
-            // if array has more than one element then success message should be plural
2822
-            $success = count($checkboxes) > 1 ? 2 : 1;
2823
-
2824
-            // cycle through bulk action checkboxes
2825
-            foreach (array_keys($checkboxes) as $GRP_ID) {
2826
-                $success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplateGroup($GRP_ID) ? $success
2827
-                    : false;
2828
-            }
2829
-        } else {
2830
-            // grab single grp_id and delete
2831
-            $GRP_ID  = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2832
-            $success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplateGroup($GRP_ID);
2833
-        }
2834
-
2835
-        $this->_redirect_after_action(
2836
-            $success,
2837
-            'Message Templates',
2838
-            'deleted',
2839
-            [
2840
-                'action' => $this->request->getRequestParam('return'),
2841
-            ]
2842
-        );
2843
-    }
2844
-
2845
-
2846
-    /**
2847
-     *    _learn_more_about_message_templates_link
2848
-     *
2849
-     * @access protected
2850
-     * @return string
2851
-     */
2852
-    protected function _learn_more_about_message_templates_link()
2853
-    {
2854
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
2855
-               . esc_html__('learn more about how message templates works', 'event_espresso')
2856
-               . '</a>';
2857
-    }
2858
-
2859
-
2860
-    /**
2861
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
2862
-     * ajax and other routes.
2863
-     *
2864
-     * @return void
2865
-     * @throws DomainException
2866
-     * @throws EE_Error
2867
-     */
2868
-    protected function _settings()
2869
-    {
2870
-        $this->_set_m_mt_settings();
2871
-        // let's setup the messenger tabs
2872
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
2873
-            $this->_m_mt_settings['messenger_tabs'],
2874
-            'messenger_links',
2875
-            '|',
2876
-            $this->request->getRequestParam('selected_messenger', 'email')
2877
-        );
2878
-
2879
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
2880
-        $this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
2881
-
2882
-        $this->display_admin_page_with_sidebar();
2883
-    }
2884
-
2885
-
2886
-    /**
2887
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
2888
-     *
2889
-     * @access protected
2890
-     * @return void
2891
-     * @throws DomainException
2892
-     */
2893
-    protected function _set_m_mt_settings()
2894
-    {
2895
-        // first if this is already set then lets get out no need to regenerate data.
2896
-        if (! empty($this->_m_mt_settings)) {
2897
-            return;
2898
-        }
2899
-
2900
-        // get all installed messengers and message_types
2901
-        $messengers    = $this->_message_resource_manager->installed_messengers();
2902
-        $message_types = $this->_message_resource_manager->installed_message_types();
2903
-
2904
-
2905
-        // assemble the array for the _tab_text_links helper
2906
-
2907
-        foreach ($messengers as $messenger) {
2908
-            $active                                                     =
2909
-                $this->_message_resource_manager->is_messenger_active($messenger->name);
2910
-            $class                                                      =
2911
-                'ee-messenger-' . sanitize_key($messenger->label['singular']);
2912
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
2913
-                'label' => ucwords($messenger->label['singular']),
2914
-                'class' => $active ? "{$class} messenger-active" : $class,
2915
-                'href'  => $messenger->name,
2916
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
2917
-                'slug'  => $messenger->name,
2918
-                'obj'   => $messenger,
2919
-                'icon'  => $active
2920
-                    ? '<span class="dashicons dashicons-yes-alt"></span>'
2921
-                    : '<span class="dashicons dashicons-remove"></span>',
2922
-            ];
2923
-
2924
-
2925
-            $message_types_for_messenger = $messenger->get_valid_message_types();
2926
-
2927
-            foreach ($message_types as $message_type) {
2928
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
2929
-                // it shouldn't show in either the inactive OR active metabox.
2930
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
2931
-                    continue;
2932
-                }
2933
-
2934
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
2935
-                    $messenger->name,
2936
-                    $message_type->name
2937
-                )
2938
-                    ? 'active'
2939
-                    : 'inactive';
2940
-
2941
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
2942
-                    'label'    => ucwords($message_type->label['singular']),
2943
-                    'class'    => 'message-type-' . $a_or_i,
2944
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2945
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2946
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2947
-                    'title'    => $a_or_i === 'active'
2948
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2949
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
2950
-                    'content'  => $a_or_i === 'active'
2951
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
2952
-                        : $this->_message_type_settings_content($message_type, $messenger),
2953
-                    'slug'     => $message_type->name,
2954
-                    'active'   => $a_or_i === 'active',
2955
-                    'obj'      => $message_type,
2956
-                ];
2957
-            }
2958
-        }
2959
-    }
2960
-
2961
-
2962
-    /**
2963
-     * This just prepares the content for the message type settings
2964
-     *
2965
-     * @param EE_message_type $message_type The message type object
2966
-     * @param EE_messenger    $messenger    The messenger object
2967
-     * @param boolean         $active       Whether the message type is active or not
2968
-     * @return string html output for the content
2969
-     * @throws DomainException
2970
-     */
2971
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
2972
-    {
2973
-        // get message type fields
2974
-        $fields                                         = $message_type->get_admin_settings_fields();
2975
-        $settings_template_args['template_form_fields'] = '';
2976
-
2977
-        if (! empty($fields) && $active) {
2978
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2979
-            foreach ($fields as $fldname => $fldprops) {
2980
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2981
-                $template_form_field[ $field_id ] = [
2982
-                    'name'       => 'message_type_settings[' . $fldname . ']',
2983
-                    'label'      => $fldprops['label'],
2984
-                    'input'      => $fldprops['field_type'],
2985
-                    'type'       => $fldprops['value_type'],
2986
-                    'required'   => $fldprops['required'],
2987
-                    'validation' => $fldprops['validation'],
2988
-                    'value'      => $existing_settings[ $fldname ] ?? $fldprops['default'],
2989
-                    'options'    => $fldprops['options'] ?? [],
2990
-                    'default'    => $existing_settings[ $fldname ] ?? $fldprops['default'],
2991
-                    'css_class'  => 'no-drag',
2992
-                    'format'     => $fldprops['format'],
2993
-                ];
2994
-            }
2995
-
2996
-
2997
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
2998
-                ? $this->_generate_admin_form_fields(
2999
-                    $template_form_field,
3000
-                    'string',
3001
-                    'ee_mt_activate_form'
3002
-                )
3003
-                : '';
3004
-        }
3005
-
3006
-        $settings_template_args['description'] = $message_type->description;
3007
-        // we also need some hidden fields
3008
-        $hidden_fields = [
3009
-            'message_type_settings[messenger]' . $message_type->name    => [
3010
-                'type'  => 'hidden',
3011
-                'value' => $messenger->name,
3012
-            ],
3013
-            'message_type_settings[message_type]' . $message_type->name => [
3014
-                'type'  => 'hidden',
3015
-                'value' => $message_type->name,
3016
-            ],
3017
-            'type' . $message_type->name                                => [
3018
-                'type'  => 'hidden',
3019
-                'value' => 'message_type',
3020
-            ],
3021
-        ];
3022
-
3023
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3024
-            $hidden_fields,
3025
-            'array'
3026
-        );
3027
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3028
-            ? ' hidden'
3029
-            : '';
3030
-
3031
-
3032
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3033
-        return EEH_Template::display_template($template, $settings_template_args, true);
3034
-    }
3035
-
3036
-
3037
-    /**
3038
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3039
-     *
3040
-     * @access protected
3041
-     * @return void
3042
-     * @throws DomainException
3043
-     */
3044
-    protected function _messages_settings_metaboxes()
3045
-    {
3046
-        $this->_set_m_mt_settings();
3047
-        $m_boxes         = $mt_boxes = [];
3048
-        $m_template_args = $mt_template_args = [];
3049
-
3050
-        $selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3051
-
3052
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3053
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3054
-                $is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3055
-                $hide_on_message     = $is_messenger_active ? '' : 'hidden';
3056
-                $hide_off_message    = $is_messenger_active ? 'hidden' : '';
3057
-
3058
-                // messenger meta boxes
3059
-                $active         = $selected_messenger === $messenger;
3060
-                $active_mt_tabs = $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'] ?? '';
3061
-
3062
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3063
-                    esc_html__('%s Settings', 'event_espresso'),
3064
-                    $tab_array['label']
3065
-                );
3066
-
3067
-                $m_template_args[ $messenger . '_a_box' ] = [
3068
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3069
-                    'inactive_message_types' => isset(
3070
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3071
-                    )
3072
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3073
-                        : '',
3074
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3075
-                    'hidden'                 => $active ? '' : ' hidden',
3076
-                    'hide_on_message'        => $hide_on_message,
3077
-                    'messenger'              => $messenger,
3078
-                    'active'                 => $active,
3079
-                ];
3080
-
3081
-                // message type meta boxes
3082
-                // (which is really just the inactive container for each messenger
3083
-                // showing inactive message types for that messenger)
3084
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3085
-                $mt_template_args[ $messenger . '_i_box' ] = [
3086
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3087
-                    'inactive_message_types' => isset(
3088
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3089
-                    )
3090
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3091
-                        : '',
3092
-                    'hidden'                 => $active ? '' : ' hidden',
3093
-                    'hide_on_message'        => $hide_on_message,
3094
-                    'hide_off_message'       => $hide_off_message,
3095
-                    'messenger'              => $messenger,
3096
-                    'active'                 => $active,
3097
-                ];
3098
-            }
3099
-        }
3100
-
3101
-
3102
-        // register messenger metaboxes
3103
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3104
-        foreach ($m_boxes as $box => $label) {
3105
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3106
-            $msgr          = str_replace('_a_box', '', $box);
3107
-            $this->addMetaBox(
3108
-                'espresso_' . $msgr . '_settings',
3109
-                $label,
3110
-                function ($post, $metabox) {
3111
-                    EEH_Template::display_template(
3112
-                        $metabox['args']['template_path'],
3113
-                        $metabox['args']['template_args']
3114
-                    );
3115
-                },
3116
-                $this->_current_screen->id,
3117
-                'normal',
3118
-                'high',
3119
-                $callback_args
3120
-            );
3121
-        }
3122
-
3123
-        // register message type metaboxes
3124
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3125
-        foreach ($mt_boxes as $box => $label) {
3126
-            $callback_args = [
3127
-                'template_path' => $mt_template_path,
3128
-                'template_args' => $mt_template_args[ $box ],
3129
-            ];
3130
-            $mt            = str_replace('_i_box', '', $box);
3131
-            $this->addMetaBox(
3132
-                'espresso_' . $mt . '_inactive_mts',
3133
-                $label,
3134
-                function ($post, $metabox) {
3135
-                    EEH_Template::display_template(
3136
-                        $metabox['args']['template_path'],
3137
-                        $metabox['args']['template_args']
3138
-                    );
3139
-                },
3140
-                $this->_current_screen->id,
3141
-                'side',
3142
-                'high',
3143
-                $callback_args
3144
-            );
3145
-        }
3146
-
3147
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3148
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3149
-        if (is_main_site()) {
3150
-            $this->addMetaBox(
3151
-                'espresso_global_message_settings',
3152
-                esc_html__('Global Message Settings', 'event_espresso'),
3153
-                [$this, 'global_messages_settings_metabox_content'],
3154
-                $this->_current_screen->id,
3155
-                'normal',
3156
-                'low',
3157
-                []
3158
-            );
3159
-        }
3160
-    }
3161
-
3162
-
3163
-    /**
3164
-     *  This generates the content for the global messages settings metabox.
3165
-     *
3166
-     * @return void
3167
-     * @throws EE_Error
3168
-     * @throws InvalidArgumentException
3169
-     * @throws ReflectionException
3170
-     * @throws InvalidDataTypeException
3171
-     * @throws InvalidInterfaceException
3172
-     */
3173
-    public function global_messages_settings_metabox_content()
3174
-    {
3175
-        $form = $this->_generate_global_settings_form();
3176
-        echo wp_kses(
3177
-            $form->form_open(
3178
-                $this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3179
-                'POST'
3180
-            ),
3181
-            AllowedTags::getWithFormTags()
3182
-        );
3183
-        echo wp_kses($form->get_html(), AllowedTags::getWithFormTags());
3184
-        echo wp_kses($form->form_close(), AllowedTags::getWithFormTags());
3185
-    }
3186
-
3187
-
3188
-    /**
3189
-     * This generates and returns the form object for the global messages settings.
3190
-     *
3191
-     * @return EE_Form_Section_Proper
3192
-     * @throws EE_Error
3193
-     * @throws InvalidArgumentException
3194
-     * @throws ReflectionException
3195
-     * @throws InvalidDataTypeException
3196
-     * @throws InvalidInterfaceException
3197
-     */
3198
-    protected function _generate_global_settings_form()
3199
-    {
3200
-        /** @var EE_Network_Core_Config $network_config */
3201
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3202
-
3203
-        return new EE_Form_Section_Proper(
3204
-            [
3205
-                'name'            => 'global_messages_settings',
3206
-                'html_id'         => 'global_messages_settings',
3207
-                'html_class'      => 'form-table',
3208
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3209
-                'subsections'     => apply_filters(
3210
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3211
-                    [
3212
-                        'do_messages_on_same_request' => new EE_Select_Input(
3213
-                            [
3214
-                                true  => esc_html__('On the same request', 'event_espresso'),
3215
-                                false => esc_html__('On a separate request', 'event_espresso'),
3216
-                            ],
3217
-                            [
3218
-                                'default'         => $network_config->do_messages_on_same_request,
3219
-                                'html_label_text' => esc_html__(
3220
-                                    'Generate and send all messages:',
3221
-                                    'event_espresso'
3222
-                                ),
3223
-                                'html_help_text'  => esc_html__(
3224
-                                    'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3225
-                                    'event_espresso'
3226
-                                ),
3227
-                            ]
3228
-                        ),
3229
-                        'delete_threshold'            => new EE_Select_Input(
3230
-                            [
3231
-                                0  => esc_html__('Forever', 'event_espresso'),
3232
-                                3  => esc_html__('3 Months', 'event_espresso'),
3233
-                                6  => esc_html__('6 Months', 'event_espresso'),
3234
-                                9  => esc_html__('9 Months', 'event_espresso'),
3235
-                                12 => esc_html__('12 Months', 'event_espresso'),
3236
-                                24 => esc_html__('24 Months', 'event_espresso'),
3237
-                                36 => esc_html__('36 Months', 'event_espresso'),
3238
-                            ],
3239
-                            [
3240
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3241
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3242
-                                'html_help_text'  => esc_html__(
3243
-                                    'You can control how long a record of processed messages is kept via this option.',
3244
-                                    'event_espresso'
3245
-                                ),
3246
-                            ]
3247
-                        ),
3248
-                        'update_settings'             => new EE_Submit_Input(
3249
-                            [
3250
-                                'default'         => esc_html__('Update', 'event_espresso'),
3251
-                                'html_label_text' => '',
3252
-                            ]
3253
-                        ),
3254
-                    ]
3255
-                ),
3256
-            ]
3257
-        );
3258
-    }
3259
-
3260
-
3261
-    /**
3262
-     * This handles updating the global settings set on the admin page.
3263
-     *
3264
-     * @throws EE_Error
3265
-     * @throws InvalidDataTypeException
3266
-     * @throws InvalidInterfaceException
3267
-     * @throws InvalidArgumentException
3268
-     * @throws ReflectionException
3269
-     */
3270
-    protected function _update_global_settings()
3271
-    {
3272
-        /** @var EE_Network_Core_Config $network_config */
3273
-        $network_config  = EE_Registry::instance()->NET_CFG->core;
3274
-        $messages_config = EE_Registry::instance()->CFG->messages;
3275
-        $form            = $this->_generate_global_settings_form();
3276
-        if ($form->was_submitted()) {
3277
-            $form->receive_form_submission();
3278
-            if ($form->is_valid()) {
3279
-                $valid_data = $form->valid_data();
3280
-                \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 3);
3281
-                foreach ($valid_data as $property => $value) {
3282
-                    $setter = 'set_' . $property;
3283
-                    if (method_exists($network_config, $setter)) {
3284
-                        $network_config->{$setter}($value);
3285
-                    } elseif (
3286
-                        property_exists($network_config, $property)
3287
-                        && $network_config->{$property} !== $value
3288
-                    ) {
3289
-                        $network_config->{$property} = $value;
3290
-                    } elseif (
3291
-                        property_exists($messages_config, $property)
3292
-                        && $messages_config->{$property} !== $value
3293
-                    ) {
3294
-                        $messages_config->{$property} = $value;
3295
-                    }
3296
-                }
3297
-                // only update if the form submission was valid!
3298
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3299
-                EE_Registry::instance()->CFG->update_espresso_config();
3300
-                EE_Error::overwrite_success();
3301
-                EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3302
-            }
3303
-        }
3304
-        $this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3305
-    }
3306
-
3307
-
3308
-    /**
3309
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3310
-     *
3311
-     * @param array $tab_array This is an array of message type tab details used to generate the tabs
3312
-     * @return string html formatted tabs
3313
-     * @throws DomainException
3314
-     */
3315
-    protected function _get_mt_tabs($tab_array)
3316
-    {
3317
-        $tab_array = (array) $tab_array;
3318
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3319
-        $tabs      = '';
3320
-
3321
-        foreach ($tab_array as $tab) {
3322
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3323
-        }
3324
-
3325
-        return $tabs;
3326
-    }
3327
-
3328
-
3329
-    /**
3330
-     * This prepares the content of the messenger meta box admin settings
3331
-     *
3332
-     * @param EE_messenger $messenger The messenger we're setting up content for
3333
-     * @return string html formatted content
3334
-     * @throws DomainException
3335
-     */
3336
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3337
-    {
3338
-        $fields = $messenger->get_admin_settings_fields();
3339
-
3340
-        $settings_template_args['template_form_fields'] = '';
3341
-        // is $messenger active?
3342
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3343
-
3344
-
3345
-        if (! empty($fields)) {
3346
-            $existing_settings = $messenger->get_existing_admin_settings();
3347
-
3348
-            foreach ($fields as $field_name => $field_props) {
3349
-                $field_id                         = $messenger->name . '-' . $field_name;
3350
-                $template_form_field[ $field_id ] = [
3351
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3352
-                    'label'      => $field_props['label'],
3353
-                    'input'      => $field_props['field_type'],
3354
-                    'type'       => $field_props['value_type'],
3355
-                    'required'   => $field_props['required'],
3356
-                    'validation' => $field_props['validation'],
3357
-                    'value'      => $existing_settings[ $field_id ] ?? $field_props['default'],
3358
-                    'css_class'  => '',
3359
-                    'format'     => $field_props['format'],
3360
-                ];
3361
-            }
3362
-
3363
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3364
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3365
-                : '';
3366
-        }
3367
-
3368
-        // we also need some hidden fields
3369
-        $settings_template_args['hidden_fields'] = [
3370
-            'messenger_settings[messenger]' . $messenger->name => [
3371
-                'type'  => 'hidden',
3372
-                'value' => $messenger->name,
3373
-            ],
3374
-            'type' . $messenger->name                          => [
3375
-                'type'  => 'hidden',
3376
-                'value' => 'messenger',
3377
-            ],
3378
-        ];
3379
-
3380
-        // make sure any active message types that are existing are included in the hidden fields
3381
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3382
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3383
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3384
-                    'type'  => 'hidden',
3385
-                    'value' => $mt,
3386
-                ];
3387
-            }
3388
-        }
3389
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3390
-            $settings_template_args['hidden_fields'],
3391
-            'array'
3392
-        );
3393
-        $active                                  =
3394
-            $this->_message_resource_manager->is_messenger_active($messenger->name);
3395
-
3396
-        $settings_template_args['messenger']           = $messenger->name;
3397
-        $settings_template_args['description']         = $messenger->description;
3398
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3399
-
3400
-
3401
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3402
-            $messenger->name
3403
-        )
3404
-            ? $settings_template_args['show_hide_edit_form']
3405
-            : ' hidden';
3406
-
3407
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3408
-            ? ' hidden'
3409
-            : $settings_template_args['show_hide_edit_form'];
3410
-
3411
-
3412
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3413
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3414
-        $settings_template_args['on_off_status'] = $active;
3415
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3416
-        return EEH_Template::display_template(
3417
-            $template,
3418
-            $settings_template_args,
3419
-            true
3420
-        );
3421
-    }
3422
-
3423
-
3424
-    /**
3425
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3426
-     *
3427
-     * @throws DomainException
3428
-     * @throws EE_Error
3429
-     * @throws InvalidDataTypeException
3430
-     * @throws InvalidInterfaceException
3431
-     * @throws InvalidArgumentException
3432
-     * @throws ReflectionException
3433
-     */
3434
-    public function activate_messenger_toggle()
3435
-    {
3436
-        $success = true;
3437
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3438
-        // let's check that we have required data
3439
-
3440
-        if (! $this->_active_messenger_name) {
3441
-            EE_Error::add_error(
3442
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3443
-                __FILE__,
3444
-                __FUNCTION__,
3445
-                __LINE__
3446
-            );
3447
-            $success = false;
3448
-        }
3449
-
3450
-        // do a nonce check here since we're not arriving via a normal route
3451
-        $nonce     = $this->request->getRequestParam('activate_nonce', '');
3452
-        $nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
3453
-
3454
-        $this->_verify_nonce($nonce, $nonce_ref);
3455
-
3456
-
3457
-        $status = $this->request->getRequestParam('status');
3458
-        if (! $status) {
3459
-            EE_Error::add_error(
3460
-                esc_html__(
3461
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3462
-                    'event_espresso'
3463
-                ),
3464
-                __FILE__,
3465
-                __FUNCTION__,
3466
-                __LINE__
3467
-            );
3468
-            $success = false;
3469
-        }
3470
-
3471
-        // do check to verify we have a valid status.
3472
-        if ($status !== 'off' && $status !== 'on') {
3473
-            EE_Error::add_error(
3474
-                sprintf(
3475
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3476
-                    $status
3477
-                ),
3478
-                __FILE__,
3479
-                __FUNCTION__,
3480
-                __LINE__
3481
-            );
3482
-            $success = false;
3483
-        }
3484
-
3485
-        if ($success) {
3486
-            // made it here?  Stop dawdling then!!
3487
-            $success = $status === 'off'
3488
-                ? $this->_deactivate_messenger($this->_active_messenger_name)
3489
-                : $this->_activate_messenger($this->_active_messenger_name);
3490
-        }
3491
-
3492
-        $this->_template_args['success'] = $success;
3493
-
3494
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
3495
-        $this->_return_json();
3496
-    }
3497
-
3498
-
3499
-    /**
3500
-     * used by ajax from the messages settings page to activate|deactivate a message type
3501
-     *
3502
-     * @throws DomainException
3503
-     * @throws EE_Error
3504
-     * @throws ReflectionException
3505
-     * @throws InvalidDataTypeException
3506
-     * @throws InvalidInterfaceException
3507
-     * @throws InvalidArgumentException
3508
-     */
3509
-    public function activate_mt_toggle()
3510
-    {
3511
-        $success = true;
3512
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3513
-
3514
-        // let's make sure we have the necessary data
3515
-        if (! $this->_active_message_type_name) {
3516
-            EE_Error::add_error(
3517
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3518
-                __FILE__,
3519
-                __FUNCTION__,
3520
-                __LINE__
3521
-            );
3522
-            $success = false;
3523
-        }
3524
-
3525
-        if (! $this->_active_messenger_name) {
3526
-            EE_Error::add_error(
3527
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3528
-                __FILE__,
3529
-                __FUNCTION__,
3530
-                __LINE__
3531
-            );
3532
-            $success = false;
3533
-        }
3534
-
3535
-        $status = $this->request->getRequestParam('status');
3536
-        if (! $status) {
3537
-            EE_Error::add_error(
3538
-                esc_html__(
3539
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3540
-                    'event_espresso'
3541
-                ),
3542
-                __FILE__,
3543
-                __FUNCTION__,
3544
-                __LINE__
3545
-            );
3546
-            $success = false;
3547
-        }
3548
-
3549
-
3550
-        // do check to verify we have a valid status.
3551
-        if ($status !== 'activate' && $status !== 'deactivate') {
3552
-            EE_Error::add_error(
3553
-                sprintf(
3554
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3555
-                    $status
3556
-                ),
3557
-                __FILE__,
3558
-                __FUNCTION__,
3559
-                __LINE__
3560
-            );
3561
-            $success = false;
3562
-        }
3563
-
3564
-
3565
-        // do a nonce check here since we're not arriving via a normal route
3566
-        $nonce = $this->request->getRequestParam('mt_nonce', '');
3567
-        $this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
3568
-
3569
-        if ($success) {
3570
-            // made it here? um, what are you waiting for then?
3571
-            $success = $status === 'deactivate'
3572
-                ? $this->_deactivate_message_type_for_messenger(
3573
-                    $this->_active_messenger_name,
3574
-                    $this->_active_message_type_name
3575
-                )
3576
-                : $this->_activate_message_type_for_messenger(
3577
-                    $this->_active_messenger_name,
3578
-                    $this->_active_message_type_name
3579
-                );
3580
-        }
3581
-
3582
-        $this->_template_args['success'] = $success;
3583
-        $this->_return_json();
3584
-    }
3585
-
3586
-
3587
-    /**
3588
-     * Takes care of processing activating a messenger and preparing the appropriate response.
3589
-     *
3590
-     * @param string $messenger_name The name of the messenger being activated
3591
-     * @return bool
3592
-     * @throws DomainException
3593
-     * @throws EE_Error
3594
-     * @throws InvalidArgumentException
3595
-     * @throws ReflectionException
3596
-     * @throws InvalidDataTypeException
3597
-     * @throws InvalidInterfaceException
3598
-     */
3599
-    protected function _activate_messenger($messenger_name)
3600
-    {
3601
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3602
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
3603
-            ? $active_messenger->get_default_message_types()
3604
-            : [];
3605
-
3606
-        // ensure is active
3607
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
3608
-
3609
-        // set response_data for reload
3610
-        foreach ($message_types_to_activate as $message_type_name) {
3611
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3612
-            if (
3613
-                $this->_message_resource_manager->is_message_type_active_for_messenger(
3614
-                    $messenger_name,
3615
-                    $message_type_name
3616
-                )
3617
-                && $message_type instanceof EE_message_type
3618
-            ) {
3619
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
3620
-                if ($message_type->get_admin_settings_fields()) {
3621
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
3622
-                }
3623
-            }
3624
-        }
3625
-
3626
-        // add success message for activating messenger
3627
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3628
-    }
3629
-
3630
-
3631
-    /**
3632
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
3633
-     *
3634
-     * @param string $messenger_name The name of the messenger being activated
3635
-     * @return bool
3636
-     * @throws DomainException
3637
-     * @throws EE_Error
3638
-     * @throws InvalidArgumentException
3639
-     * @throws ReflectionException
3640
-     * @throws InvalidDataTypeException
3641
-     * @throws InvalidInterfaceException
3642
-     */
3643
-    protected function _deactivate_messenger($messenger_name)
3644
-    {
3645
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3646
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
3647
-
3648
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3649
-    }
3650
-
3651
-
3652
-    /**
3653
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3654
-     *
3655
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
3656
-     * @param string $message_type_name The name of the message type being activated for the messenger
3657
-     * @return bool
3658
-     * @throws DomainException
3659
-     * @throws EE_Error
3660
-     * @throws InvalidArgumentException
3661
-     * @throws ReflectionException
3662
-     * @throws InvalidDataTypeException
3663
-     * @throws InvalidInterfaceException
3664
-     */
3665
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3666
-    {
3667
-        $active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
3668
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3669
-
3670
-        // ensure is active
3671
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
3672
-
3673
-        // set response for load
3674
-        if (
3675
-            $this->_message_resource_manager->is_message_type_active_for_messenger(
3676
-                $messenger_name,
3677
-                $message_type_name
3678
-            )
3679
-        ) {
3680
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
3681
-            if ($message_type_to_activate->get_admin_settings_fields()) {
3682
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
3683
-            }
3684
-        }
3685
-
3686
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
3687
-            $active_messenger,
3688
-            $message_type_to_activate
3689
-        );
3690
-    }
3691
-
3692
-
3693
-    /**
3694
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3695
-     *
3696
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3697
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
3698
-     * @return bool
3699
-     * @throws DomainException
3700
-     * @throws EE_Error
3701
-     * @throws InvalidArgumentException
3702
-     * @throws ReflectionException
3703
-     * @throws InvalidDataTypeException
3704
-     * @throws InvalidInterfaceException
3705
-     */
3706
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3707
-    {
3708
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3709
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3710
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3711
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3712
-
3713
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
3714
-            $active_messenger,
3715
-            $message_type_to_deactivate
3716
-        );
3717
-    }
3718
-
3719
-
3720
-    /**
3721
-     * This just initializes the defaults for activating messenger and message type responses.
3722
-     */
3723
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
3724
-    {
3725
-        $this->_template_args['data']['active_mts'] = [];
3726
-        $this->_template_args['data']['mt_reload']  = [];
3727
-    }
3728
-
3729
-
3730
-    /**
3731
-     * Setup appropriate response for activating a messenger and/or message types
3732
-     *
3733
-     * @param EE_messenger         $messenger
3734
-     * @param EE_message_type|null $message_type
3735
-     * @return bool
3736
-     * @throws DomainException
3737
-     * @throws EE_Error
3738
-     * @throws InvalidArgumentException
3739
-     * @throws ReflectionException
3740
-     * @throws InvalidDataTypeException
3741
-     * @throws InvalidInterfaceException
3742
-     */
3743
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
3744
-        $messenger,
3745
-        EE_Message_Type $message_type = null
3746
-    ) {
3747
-        // if $messenger isn't a valid messenger object then get out.
3748
-        if (! $messenger instanceof EE_Messenger) {
3749
-            EE_Error::add_error(
3750
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
3751
-                __FILE__,
3752
-                __FUNCTION__,
3753
-                __LINE__
3754
-            );
3755
-            return false;
3756
-        }
3757
-        // activated
3758
-        if ($this->_template_args['data']['active_mts']) {
3759
-            EE_Error::overwrite_success();
3760
-            // activated a message type with the messenger
3761
-            if ($message_type instanceof EE_message_type) {
3762
-                EE_Error::add_success(
3763
-                    sprintf(
3764
-                        esc_html__(
3765
-                            '%s message type has been successfully activated with the %s messenger',
3766
-                            'event_espresso'
3767
-                        ),
3768
-                        ucwords($message_type->label['singular']),
3769
-                        ucwords($messenger->label['singular'])
3770
-                    )
3771
-                );
3772
-
3773
-                // if message type was invoice then let's make sure we activate the invoice payment method.
3774
-                if ($message_type->name === 'invoice') {
3775
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
3776
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3777
-                    if ($pm instanceof EE_Payment_Method) {
3778
-                        EE_Error::add_attention(
3779
-                            esc_html__(
3780
-                                'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
3781
-                                'event_espresso'
3782
-                            )
3783
-                        );
3784
-                    }
3785
-                }
3786
-                // just toggles the entire messenger
3787
-            } else {
3788
-                EE_Error::add_success(
3789
-                    sprintf(
3790
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
3791
-                        ucwords($messenger->label['singular'])
3792
-                    )
3793
-                );
3794
-            }
3795
-
3796
-            return true;
3797
-
3798
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3799
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3800
-            // in which case we just give a success message for the messenger being successfully activated.
3801
-        } else {
3802
-            if (! $messenger->get_default_message_types()) {
3803
-                // messenger doesn't have any default message types so still a success.
3804
-                EE_Error::add_success(
3805
-                    sprintf(
3806
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
3807
-                        ucwords($messenger->label['singular'])
3808
-                    )
3809
-                );
3810
-
3811
-                return true;
3812
-            } else {
3813
-                EE_Error::add_error(
3814
-                    $message_type instanceof EE_message_type
3815
-                        ? sprintf(
3816
-                        esc_html__(
3817
-                            '%s message type was not successfully activated with the %s messenger',
3818
-                            'event_espresso'
3819
-                        ),
3820
-                        ucwords($message_type->label['singular']),
3821
-                        ucwords($messenger->label['singular'])
3822
-                    )
3823
-                        : sprintf(
3824
-                        esc_html__('%s messenger was not successfully activated', 'event_espresso'),
3825
-                        ucwords($messenger->label['singular'])
3826
-                    ),
3827
-                    __FILE__,
3828
-                    __FUNCTION__,
3829
-                    __LINE__
3830
-                );
3831
-
3832
-                return false;
3833
-            }
3834
-        }
3835
-    }
3836
-
3837
-
3838
-    /**
3839
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
3840
-     *
3841
-     * @param EE_messenger         $messenger
3842
-     * @param EE_message_type|null $message_type
3843
-     * @return bool
3844
-     * @throws DomainException
3845
-     * @throws EE_Error
3846
-     * @throws InvalidArgumentException
3847
-     * @throws ReflectionException
3848
-     * @throws InvalidDataTypeException
3849
-     * @throws InvalidInterfaceException
3850
-     */
3851
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3852
-        $messenger,
3853
-        EE_message_type $message_type = null
3854
-    ) {
3855
-        EE_Error::overwrite_success();
3856
-
3857
-        // if $messenger isn't a valid messenger object then get out.
3858
-        if (! $messenger instanceof EE_Messenger) {
3859
-            EE_Error::add_error(
3860
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3861
-                __FILE__,
3862
-                __FUNCTION__,
3863
-                __LINE__
3864
-            );
3865
-
3866
-            return false;
3867
-        }
3868
-
3869
-        if ($message_type instanceof EE_message_type) {
3870
-            $message_type_name = $message_type->name;
3871
-            EE_Error::add_success(
3872
-                sprintf(
3873
-                    esc_html__(
3874
-                        '%s message type has been successfully deactivated for the %s messenger.',
3875
-                        'event_espresso'
3876
-                    ),
3877
-                    ucwords($message_type->label['singular']),
3878
-                    ucwords($messenger->label['singular'])
3879
-                )
3880
-            );
3881
-        } else {
3882
-            $message_type_name = '';
3883
-            EE_Error::add_success(
3884
-                sprintf(
3885
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
3886
-                    ucwords($messenger->label['singular'])
3887
-                )
3888
-            );
3889
-        }
3890
-
3891
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3892
-        if (
3893
-            $messenger->name === 'html'
3894
-            && (
3895
-                is_null($message_type)
3896
-                || $message_type_name === 'invoice'
3897
-            )
3898
-        ) {
3899
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
3900
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3901
-            if ($count_updated > 0) {
3902
-                $msg = $message_type_name === 'invoice'
3903
-                    ? esc_html__(
3904
-                        'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
3905
-                        'event_espresso'
3906
-                    )
3907
-                    : esc_html__(
3908
-                        'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
3909
-                        'event_espresso'
3910
-                    );
3911
-                EE_Error::add_attention($msg);
3912
-            }
3913
-        }
3914
-
3915
-        return true;
3916
-    }
3917
-
3918
-
3919
-    /**
3920
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3921
-     *
3922
-     * @throws DomainException
3923
-     * @throws EE_Error
3924
-     * @throws EE_Error
3925
-     */
3926
-    public function update_mt_form()
3927
-    {
3928
-        if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
3929
-            EE_Error::add_error(
3930
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
3931
-                __FILE__,
3932
-                __FUNCTION__,
3933
-                __LINE__
3934
-            );
3935
-            $this->_return_json();
3936
-        }
3937
-
3938
-        $message_types = $this->get_installed_message_types();
3939
-        $message_type  = $message_types[ $this->_active_message_type_name ];
3940
-        $messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
3941
-        $content       = $this->_message_type_settings_content($message_type, $messenger, true);
3942
-
3943
-        $this->_template_args['success'] = true;
3944
-        $this->_template_args['content'] = $content;
3945
-        $this->_return_json();
3946
-    }
3947
-
3948
-
3949
-    /**
3950
-     * this handles saving the settings for a messenger or message type
3951
-     *
3952
-     * @throws EE_Error
3953
-     * @throws EE_Error
3954
-     */
3955
-    public function save_settings()
3956
-    {
3957
-        $type = $this->request->getRequestParam('type');
3958
-        if (! $type) {
3959
-            EE_Error::add_error(
3960
-                esc_html__(
3961
-                    'Cannot save settings because type is unknown (messenger settings or message type settings?)',
3962
-                    'event_espresso'
3963
-                ),
3964
-                __FILE__,
3965
-                __FUNCTION__,
3966
-                __LINE__
3967
-            );
3968
-            $this->_template_args['error'] = true;
3969
-            $this->_return_json();
3970
-        }
3971
-
3972
-
3973
-        if ($type === 'messenger') {
3974
-            // this should be an array.
3975
-            $settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
3976
-            $messenger = $settings['messenger'];
3977
-            // remove messenger and message_types from settings array
3978
-            unset($settings['messenger'], $settings['message_types']);
3979
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3980
-        } elseif ($type === 'message_type') {
3981
-            $settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
3982
-            $messenger    = $settings['messenger'];
3983
-            $message_type = $settings['message_type'];
3984
-            // remove messenger and message_types from settings array
3985
-            unset($settings['messenger'], $settings['message_types']);
3986
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3987
-        }
3988
-
3989
-        // okay we should have the data all setup.  Now we just update!
3990
-        $success = $this->_message_resource_manager->update_active_messengers_option();
3991
-
3992
-        if ($success) {
3993
-            EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
3994
-        } else {
3995
-            EE_Error::add_error(
3996
-                esc_html__('Settings did not get updated', 'event_espresso'),
3997
-                __FILE__,
3998
-                __FUNCTION__,
3999
-                __LINE__
4000
-            );
4001
-        }
4002
-
4003
-        $this->_template_args['success'] = $success;
4004
-        $this->_return_json();
4005
-    }
4006
-
4007
-
4008
-
4009
-
4010
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4011
-
4012
-
4013
-    /**
4014
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4015
-     * However, this does not send immediately, it just queues for sending.
4016
-     *
4017
-     * @throws EE_Error
4018
-     * @throws InvalidDataTypeException
4019
-     * @throws InvalidInterfaceException
4020
-     * @throws InvalidArgumentException
4021
-     * @throws ReflectionException
4022
-     * @since 4.9.0
4023
-     */
4024
-    protected function _generate_now()
4025
-    {
4026
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4027
-        $this->_redirect_after_action(false, '', '', [], true);
4028
-    }
4029
-
4030
-
4031
-    /**
4032
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4033
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4034
-     *
4035
-     * @throws EE_Error
4036
-     * @throws InvalidDataTypeException
4037
-     * @throws InvalidInterfaceException
4038
-     * @throws InvalidArgumentException
4039
-     * @throws ReflectionException
4040
-     * @since 4.9.0
4041
-     */
4042
-    protected function _generate_and_send_now()
4043
-    {
4044
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4045
-        $this->_redirect_after_action(false, '', '', [], true);
4046
-    }
4047
-
4048
-
4049
-    /**
4050
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4051
-     *
4052
-     * @throws EE_Error
4053
-     * @throws InvalidDataTypeException
4054
-     * @throws InvalidInterfaceException
4055
-     * @throws InvalidArgumentException
4056
-     * @throws ReflectionException
4057
-     * @since 4.9.0
4058
-     */
4059
-    protected function _queue_for_resending()
4060
-    {
4061
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4062
-        $this->_redirect_after_action(false, '', '', [], true);
4063
-    }
4064
-
4065
-
4066
-    /**
4067
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4068
-     *
4069
-     * @throws EE_Error
4070
-     * @throws InvalidDataTypeException
4071
-     * @throws InvalidInterfaceException
4072
-     * @throws InvalidArgumentException
4073
-     * @throws ReflectionException
4074
-     * @since 4.9.0
4075
-     */
4076
-    protected function _send_now()
4077
-    {
4078
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4079
-        $this->_redirect_after_action(false, '', '', [], true);
4080
-    }
4081
-
4082
-
4083
-    /**
4084
-     * Deletes EE_messages for IDs in the request.
4085
-     *
4086
-     * @throws EE_Error
4087
-     * @throws InvalidDataTypeException
4088
-     * @throws InvalidInterfaceException
4089
-     * @throws InvalidArgumentException
4090
-     * @throws ReflectionException
4091
-     * @since 4.9.0
4092
-     */
4093
-    protected function _delete_ee_messages()
4094
-    {
4095
-        $MSG_IDs       = $this->_get_msg_ids_from_request();
4096
-        $deleted_count = 0;
4097
-        foreach ($MSG_IDs as $MSG_ID) {
4098
-            if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4099
-                $deleted_count++;
4100
-            }
4101
-        }
4102
-        if ($deleted_count) {
4103
-            EE_Error::add_success(
4104
-                esc_html(
4105
-                    _n(
4106
-                        'Message successfully deleted',
4107
-                        'Messages successfully deleted',
4108
-                        $deleted_count,
4109
-                        'event_espresso'
4110
-                    )
4111
-                )
4112
-            );
4113
-        } else {
4114
-            EE_Error::add_error(
4115
-                _n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4116
-                __FILE__,
4117
-                __FUNCTION__,
4118
-                __LINE__
4119
-            );
4120
-        }
4121
-        $this->_redirect_after_action(false, '', '', [], true);
4122
-    }
4123
-
4124
-
4125
-    /**
4126
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4127
-     *
4128
-     * @return array
4129
-     * @since 4.9.0
4130
-     */
4131
-    protected function _get_msg_ids_from_request()
4132
-    {
4133
-        $MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4134
-        if (empty($MSG_IDs)) {
4135
-            return [];
4136
-        }
4137
-        // if 'MSG_ID' was just a single ID (not an array)
4138
-        // then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4139
-        // otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4140
-        return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4141
-            ? $MSG_IDs
4142
-            : array_keys($MSG_IDs);
4143
-    }
2526
+	}
2527
+
2528
+
2529
+	/**
2530
+	 * @throws EE_Error
2531
+	 * @throws ReflectionException
2532
+	 * @deprecated 5.0.8.p
2533
+	 */
2534
+	protected function _insert_or_update_message_template($new = false)
2535
+	{
2536
+		if ($new) {
2537
+			$this->insertMessageTemplate();
2538
+		} else {
2539
+			$this->updateMessageTemplate();
2540
+		}
2541
+	}
2542
+
2543
+
2544
+	/**
2545
+	 * @throws EE_Error
2546
+	 * @throws ReflectionException
2547
+	 */
2548
+	protected function insertMessageTemplate(): void
2549
+	{
2550
+		$success   = true;
2551
+		$templates = [];
2552
+		try {
2553
+			$templates = $this->getMessageTemplateManager()->generateNewTemplates();
2554
+		} catch (Exception $exception) {
2555
+			$success = false;
2556
+			EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2557
+		}
2558
+
2559
+		/** @var MessageTemplateRequestData $form_data */
2560
+		$form_data = $this->loader->getShared(MessageTemplateRequestData::class);
2561
+		$this->_redirect_after_action(
2562
+			$success && isset($templates['GRP_ID'], $templates['MTP_context']),
2563
+			$this->generateUpdateDescription($form_data->messenger(), $form_data->messageType(), $form_data->context()),
2564
+			'created',
2565
+			[
2566
+				'id'      => $templates['GRP_ID'] ?? 0,
2567
+				'context' => $templates['MTP_context'] ?? '',
2568
+				'action'  => 'edit_message_template',
2569
+			],
2570
+			$this->performTestSendAfterUpdate($form_data->messenger(), $form_data->messageType(), $form_data->context())
2571
+		);
2572
+	}
2573
+
2574
+
2575
+	/**
2576
+	 * @throws EE_Error
2577
+	 * @throws ReflectionException
2578
+	 */
2579
+	protected function updateMessageTemplate(): void
2580
+	{
2581
+		$success = true;
2582
+		try {
2583
+			$this->getMessageTemplateManager()->updateExistingTemplates();
2584
+		} catch (Exception $exception) {
2585
+			$success = false;
2586
+			EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__);
2587
+		}
2588
+
2589
+		/** @var MessageTemplateRequestData $form_data */
2590
+		$form_data = $this->loader->getShared(MessageTemplateRequestData::class);
2591
+
2592
+		$this->_redirect_after_action(
2593
+			$success,
2594
+			$this->generateUpdateDescription($form_data->messenger(), $form_data->messageType(), $form_data->context()),
2595
+			'updated',
2596
+			[
2597
+				'id'      => $form_data->groupID(),
2598
+				'context' => $form_data->context(),
2599
+				'action'  => 'edit_message_template',
2600
+			],
2601
+			$this->performTestSendAfterUpdate($form_data->messenger(), $form_data->messageType(), $form_data->context())
2602
+		);
2603
+	}
2604
+
2605
+
2606
+	/**
2607
+	 * @param string $messenger
2608
+	 * @param string $message_type
2609
+	 * @param string $context
2610
+	 * @return string
2611
+	 * @since 4.10.29.p
2612
+	 */
2613
+	private function generateUpdateDescription(string $messenger, string $message_type, string $context): string
2614
+	{
2615
+		// need the message type and messenger objects to be able to use the labels for the notices
2616
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger);
2617
+		$messenger_label  = $messenger_object instanceof EE_messenger
2618
+			? ucwords($messenger_object->label['singular'])
2619
+			: '';
2620
+
2621
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type);
2622
+		$message_type_label  = $message_type_object instanceof EE_message_type
2623
+			? ucwords($message_type_object->label['singular'])
2624
+			: '';
2625
+
2626
+		$context   = ucwords(str_replace('_', ' ', $context));
2627
+		$item_desc = $messenger_label && $message_type_label
2628
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2629
+			: '';
2630
+		$item_desc .= 'Message Template';
2631
+		return $item_desc;
2632
+	}
2633
+
2634
+
2635
+	/**
2636
+	 * @param string $messenger
2637
+	 * @param string $message_type
2638
+	 * @param string $context
2639
+	 * @return bool
2640
+	 * @throws EE_Error
2641
+	 * @throws ReflectionException
2642
+	 * @since 4.10.29.p
2643
+	 */
2644
+	private function performTestSendAfterUpdate(string $messenger, string $message_type, string $context): bool
2645
+	{
2646
+		// was a test send triggered?
2647
+		if ($this->request->requestParamIsSet('test_button')) {
2648
+			EE_Error::overwrite_success();
2649
+			$this->_do_test_send($context, $messenger, $message_type);
2650
+			return true;
2651
+		}
2652
+		return false;
2653
+	}
2654
+
2655
+
2656
+	/**
2657
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
2658
+	 *
2659
+	 * @param string $context      what context being tested
2660
+	 * @param string $messenger    messenger being tested
2661
+	 * @param string $message_type message type being tested
2662
+	 * @throws EE_Error
2663
+	 * @throws InvalidArgumentException
2664
+	 * @throws InvalidDataTypeException
2665
+	 * @throws InvalidInterfaceException
2666
+	 * @throws ReflectionException
2667
+	 */
2668
+	protected function _do_test_send(string $context, string $messenger, string $message_type)
2669
+	{
2670
+		// set things up for preview
2671
+		$this->request->setRequestParam('messenger', $messenger);
2672
+		$this->request->setRequestParam('message_type', $message_type);
2673
+		$this->request->setRequestParam('context', $context);
2674
+		$this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
2675
+
2676
+		$active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
2677
+		$test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
2678
+
2679
+		// let's save any existing fields that might be required by the messenger
2680
+		if (
2681
+			! empty($test_settings_fld)
2682
+			&& $active_messenger instanceof EE_messenger
2683
+			&& apply_filters(
2684
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
2685
+				true,
2686
+				$test_settings_fld,
2687
+				$active_messenger
2688
+			)
2689
+		) {
2690
+			$active_messenger->set_existing_test_settings($test_settings_fld);
2691
+		}
2692
+
2693
+		/**
2694
+		 * Use filter to add additional controls on whether message can send or not
2695
+		 */
2696
+		if (
2697
+			apply_filters(
2698
+				'FHEE__Messages_Admin_Page__do_test_send__can_send',
2699
+				true,
2700
+				$context,
2701
+				$this->request->requestParams(),
2702
+				$messenger,
2703
+				$message_type
2704
+			)
2705
+		) {
2706
+			if (EEM_Event::instance()->count() > 0) {
2707
+				$success = $this->_preview_message(true);
2708
+				if ($success) {
2709
+					EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
2710
+				} else {
2711
+					EE_Error::add_error(
2712
+						esc_html__('The test message was not sent', 'event_espresso'),
2713
+						__FILE__,
2714
+						__FUNCTION__,
2715
+						__LINE__
2716
+					);
2717
+				}
2718
+			} else {
2719
+				$this->noEventsErrorMessage(true);
2720
+			}
2721
+		}
2722
+	}
2723
+
2724
+
2725
+	/**
2726
+	 * [_trash_or_restore_message_template]
2727
+	 *
2728
+	 * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
2729
+	 * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
2730
+	 *                        an individual context (FALSE).
2731
+	 * @return void
2732
+	 * @throws EE_Error
2733
+	 * @throws InvalidArgumentException
2734
+	 * @throws InvalidDataTypeException
2735
+	 * @throws InvalidInterfaceException
2736
+	 * @throws ReflectionException
2737
+	 */
2738
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
2739
+	{
2740
+		$success = 1;
2741
+
2742
+		// incoming GRP_IDs
2743
+		if ($all) {
2744
+			// Checkboxes
2745
+			$checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2746
+			if (! empty($checkboxes)) {
2747
+				// if array has more than one element then success message should be plural.
2748
+				// todo: what about nonce?
2749
+				$success = count($checkboxes) > 1 ? 2 : 1;
2750
+
2751
+				// cycle through checkboxes
2752
+				foreach (array_keys($checkboxes) as $GRP_ID) {
2753
+					$trashed_or_restored = $trash
2754
+						? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2755
+						: $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2756
+					if (! $trashed_or_restored) {
2757
+						$success = 0;
2758
+					}
2759
+				}
2760
+			} else {
2761
+				// grab single GRP_ID and handle
2762
+				$GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2763
+				if (! empty($GRP_ID)) {
2764
+					$trashed_or_restored = $trash
2765
+						? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2766
+						: $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2767
+					if (! $trashed_or_restored) {
2768
+						$success = 0;
2769
+					}
2770
+				} else {
2771
+					$success = 0;
2772
+				}
2773
+			}
2774
+		}
2775
+
2776
+		$action_desc = $trash
2777
+			? esc_html__('moved to the trash', 'event_espresso')
2778
+			: esc_html__('restored', 'event_espresso');
2779
+
2780
+		$template_switch = $this->request->getRequestParam('template_switch', false, DataType::BOOLEAN);
2781
+		$action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
2782
+
2783
+		$item_desc = $all ? _n(
2784
+			'Message Template Group',
2785
+			'Message Template Groups',
2786
+			$success,
2787
+			'event_espresso'
2788
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
2789
+
2790
+		$item_desc = $template_switch
2791
+			? _n('template', 'templates', $success, 'event_espresso')
2792
+			: $item_desc;
2793
+
2794
+		$this->_redirect_after_action(
2795
+			$success,
2796
+			$item_desc,
2797
+			$action_desc,
2798
+			[
2799
+				'action' => $this->request->getRequestParam('return'),
2800
+			]
2801
+		);
2802
+	}
2803
+
2804
+
2805
+	/**
2806
+	 * [_delete_message_template]
2807
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
2808
+	 *
2809
+	 * @return void
2810
+	 * @throws EE_Error
2811
+	 * @throws InvalidArgumentException
2812
+	 * @throws InvalidDataTypeException
2813
+	 * @throws InvalidInterfaceException
2814
+	 * @throws ReflectionException
2815
+	 */
2816
+	protected function _delete_message_template()
2817
+	{
2818
+		// checkboxes
2819
+		$checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2820
+		if (! empty($checkboxes)) {
2821
+			// if array has more than one element then success message should be plural
2822
+			$success = count($checkboxes) > 1 ? 2 : 1;
2823
+
2824
+			// cycle through bulk action checkboxes
2825
+			foreach (array_keys($checkboxes) as $GRP_ID) {
2826
+				$success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplateGroup($GRP_ID) ? $success
2827
+					: false;
2828
+			}
2829
+		} else {
2830
+			// grab single grp_id and delete
2831
+			$GRP_ID  = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2832
+			$success = $this->getMessageTemplateManager()->permanentlyDeleteMessageTemplateGroup($GRP_ID);
2833
+		}
2834
+
2835
+		$this->_redirect_after_action(
2836
+			$success,
2837
+			'Message Templates',
2838
+			'deleted',
2839
+			[
2840
+				'action' => $this->request->getRequestParam('return'),
2841
+			]
2842
+		);
2843
+	}
2844
+
2845
+
2846
+	/**
2847
+	 *    _learn_more_about_message_templates_link
2848
+	 *
2849
+	 * @access protected
2850
+	 * @return string
2851
+	 */
2852
+	protected function _learn_more_about_message_templates_link()
2853
+	{
2854
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
2855
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
2856
+			   . '</a>';
2857
+	}
2858
+
2859
+
2860
+	/**
2861
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
2862
+	 * ajax and other routes.
2863
+	 *
2864
+	 * @return void
2865
+	 * @throws DomainException
2866
+	 * @throws EE_Error
2867
+	 */
2868
+	protected function _settings()
2869
+	{
2870
+		$this->_set_m_mt_settings();
2871
+		// let's setup the messenger tabs
2872
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
2873
+			$this->_m_mt_settings['messenger_tabs'],
2874
+			'messenger_links',
2875
+			'|',
2876
+			$this->request->getRequestParam('selected_messenger', 'email')
2877
+		);
2878
+
2879
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
2880
+		$this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
2881
+
2882
+		$this->display_admin_page_with_sidebar();
2883
+	}
2884
+
2885
+
2886
+	/**
2887
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
2888
+	 *
2889
+	 * @access protected
2890
+	 * @return void
2891
+	 * @throws DomainException
2892
+	 */
2893
+	protected function _set_m_mt_settings()
2894
+	{
2895
+		// first if this is already set then lets get out no need to regenerate data.
2896
+		if (! empty($this->_m_mt_settings)) {
2897
+			return;
2898
+		}
2899
+
2900
+		// get all installed messengers and message_types
2901
+		$messengers    = $this->_message_resource_manager->installed_messengers();
2902
+		$message_types = $this->_message_resource_manager->installed_message_types();
2903
+
2904
+
2905
+		// assemble the array for the _tab_text_links helper
2906
+
2907
+		foreach ($messengers as $messenger) {
2908
+			$active                                                     =
2909
+				$this->_message_resource_manager->is_messenger_active($messenger->name);
2910
+			$class                                                      =
2911
+				'ee-messenger-' . sanitize_key($messenger->label['singular']);
2912
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
2913
+				'label' => ucwords($messenger->label['singular']),
2914
+				'class' => $active ? "{$class} messenger-active" : $class,
2915
+				'href'  => $messenger->name,
2916
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
2917
+				'slug'  => $messenger->name,
2918
+				'obj'   => $messenger,
2919
+				'icon'  => $active
2920
+					? '<span class="dashicons dashicons-yes-alt"></span>'
2921
+					: '<span class="dashicons dashicons-remove"></span>',
2922
+			];
2923
+
2924
+
2925
+			$message_types_for_messenger = $messenger->get_valid_message_types();
2926
+
2927
+			foreach ($message_types as $message_type) {
2928
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
2929
+				// it shouldn't show in either the inactive OR active metabox.
2930
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
2931
+					continue;
2932
+				}
2933
+
2934
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
2935
+					$messenger->name,
2936
+					$message_type->name
2937
+				)
2938
+					? 'active'
2939
+					: 'inactive';
2940
+
2941
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
2942
+					'label'    => ucwords($message_type->label['singular']),
2943
+					'class'    => 'message-type-' . $a_or_i,
2944
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2945
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2946
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2947
+					'title'    => $a_or_i === 'active'
2948
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2949
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
2950
+					'content'  => $a_or_i === 'active'
2951
+						? $this->_message_type_settings_content($message_type, $messenger, true)
2952
+						: $this->_message_type_settings_content($message_type, $messenger),
2953
+					'slug'     => $message_type->name,
2954
+					'active'   => $a_or_i === 'active',
2955
+					'obj'      => $message_type,
2956
+				];
2957
+			}
2958
+		}
2959
+	}
2960
+
2961
+
2962
+	/**
2963
+	 * This just prepares the content for the message type settings
2964
+	 *
2965
+	 * @param EE_message_type $message_type The message type object
2966
+	 * @param EE_messenger    $messenger    The messenger object
2967
+	 * @param boolean         $active       Whether the message type is active or not
2968
+	 * @return string html output for the content
2969
+	 * @throws DomainException
2970
+	 */
2971
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
2972
+	{
2973
+		// get message type fields
2974
+		$fields                                         = $message_type->get_admin_settings_fields();
2975
+		$settings_template_args['template_form_fields'] = '';
2976
+
2977
+		if (! empty($fields) && $active) {
2978
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2979
+			foreach ($fields as $fldname => $fldprops) {
2980
+				$field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2981
+				$template_form_field[ $field_id ] = [
2982
+					'name'       => 'message_type_settings[' . $fldname . ']',
2983
+					'label'      => $fldprops['label'],
2984
+					'input'      => $fldprops['field_type'],
2985
+					'type'       => $fldprops['value_type'],
2986
+					'required'   => $fldprops['required'],
2987
+					'validation' => $fldprops['validation'],
2988
+					'value'      => $existing_settings[ $fldname ] ?? $fldprops['default'],
2989
+					'options'    => $fldprops['options'] ?? [],
2990
+					'default'    => $existing_settings[ $fldname ] ?? $fldprops['default'],
2991
+					'css_class'  => 'no-drag',
2992
+					'format'     => $fldprops['format'],
2993
+				];
2994
+			}
2995
+
2996
+
2997
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
2998
+				? $this->_generate_admin_form_fields(
2999
+					$template_form_field,
3000
+					'string',
3001
+					'ee_mt_activate_form'
3002
+				)
3003
+				: '';
3004
+		}
3005
+
3006
+		$settings_template_args['description'] = $message_type->description;
3007
+		// we also need some hidden fields
3008
+		$hidden_fields = [
3009
+			'message_type_settings[messenger]' . $message_type->name    => [
3010
+				'type'  => 'hidden',
3011
+				'value' => $messenger->name,
3012
+			],
3013
+			'message_type_settings[message_type]' . $message_type->name => [
3014
+				'type'  => 'hidden',
3015
+				'value' => $message_type->name,
3016
+			],
3017
+			'type' . $message_type->name                                => [
3018
+				'type'  => 'hidden',
3019
+				'value' => 'message_type',
3020
+			],
3021
+		];
3022
+
3023
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3024
+			$hidden_fields,
3025
+			'array'
3026
+		);
3027
+		$settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3028
+			? ' hidden'
3029
+			: '';
3030
+
3031
+
3032
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3033
+		return EEH_Template::display_template($template, $settings_template_args, true);
3034
+	}
3035
+
3036
+
3037
+	/**
3038
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3039
+	 *
3040
+	 * @access protected
3041
+	 * @return void
3042
+	 * @throws DomainException
3043
+	 */
3044
+	protected function _messages_settings_metaboxes()
3045
+	{
3046
+		$this->_set_m_mt_settings();
3047
+		$m_boxes         = $mt_boxes = [];
3048
+		$m_template_args = $mt_template_args = [];
3049
+
3050
+		$selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3051
+
3052
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3053
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3054
+				$is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3055
+				$hide_on_message     = $is_messenger_active ? '' : 'hidden';
3056
+				$hide_off_message    = $is_messenger_active ? 'hidden' : '';
3057
+
3058
+				// messenger meta boxes
3059
+				$active         = $selected_messenger === $messenger;
3060
+				$active_mt_tabs = $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'] ?? '';
3061
+
3062
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3063
+					esc_html__('%s Settings', 'event_espresso'),
3064
+					$tab_array['label']
3065
+				);
3066
+
3067
+				$m_template_args[ $messenger . '_a_box' ] = [
3068
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3069
+					'inactive_message_types' => isset(
3070
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3071
+					)
3072
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3073
+						: '',
3074
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3075
+					'hidden'                 => $active ? '' : ' hidden',
3076
+					'hide_on_message'        => $hide_on_message,
3077
+					'messenger'              => $messenger,
3078
+					'active'                 => $active,
3079
+				];
3080
+
3081
+				// message type meta boxes
3082
+				// (which is really just the inactive container for each messenger
3083
+				// showing inactive message types for that messenger)
3084
+				$mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3085
+				$mt_template_args[ $messenger . '_i_box' ] = [
3086
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3087
+					'inactive_message_types' => isset(
3088
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3089
+					)
3090
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3091
+						: '',
3092
+					'hidden'                 => $active ? '' : ' hidden',
3093
+					'hide_on_message'        => $hide_on_message,
3094
+					'hide_off_message'       => $hide_off_message,
3095
+					'messenger'              => $messenger,
3096
+					'active'                 => $active,
3097
+				];
3098
+			}
3099
+		}
3100
+
3101
+
3102
+		// register messenger metaboxes
3103
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3104
+		foreach ($m_boxes as $box => $label) {
3105
+			$callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3106
+			$msgr          = str_replace('_a_box', '', $box);
3107
+			$this->addMetaBox(
3108
+				'espresso_' . $msgr . '_settings',
3109
+				$label,
3110
+				function ($post, $metabox) {
3111
+					EEH_Template::display_template(
3112
+						$metabox['args']['template_path'],
3113
+						$metabox['args']['template_args']
3114
+					);
3115
+				},
3116
+				$this->_current_screen->id,
3117
+				'normal',
3118
+				'high',
3119
+				$callback_args
3120
+			);
3121
+		}
3122
+
3123
+		// register message type metaboxes
3124
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3125
+		foreach ($mt_boxes as $box => $label) {
3126
+			$callback_args = [
3127
+				'template_path' => $mt_template_path,
3128
+				'template_args' => $mt_template_args[ $box ],
3129
+			];
3130
+			$mt            = str_replace('_i_box', '', $box);
3131
+			$this->addMetaBox(
3132
+				'espresso_' . $mt . '_inactive_mts',
3133
+				$label,
3134
+				function ($post, $metabox) {
3135
+					EEH_Template::display_template(
3136
+						$metabox['args']['template_path'],
3137
+						$metabox['args']['template_args']
3138
+					);
3139
+				},
3140
+				$this->_current_screen->id,
3141
+				'side',
3142
+				'high',
3143
+				$callback_args
3144
+			);
3145
+		}
3146
+
3147
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3148
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3149
+		if (is_main_site()) {
3150
+			$this->addMetaBox(
3151
+				'espresso_global_message_settings',
3152
+				esc_html__('Global Message Settings', 'event_espresso'),
3153
+				[$this, 'global_messages_settings_metabox_content'],
3154
+				$this->_current_screen->id,
3155
+				'normal',
3156
+				'low',
3157
+				[]
3158
+			);
3159
+		}
3160
+	}
3161
+
3162
+
3163
+	/**
3164
+	 *  This generates the content for the global messages settings metabox.
3165
+	 *
3166
+	 * @return void
3167
+	 * @throws EE_Error
3168
+	 * @throws InvalidArgumentException
3169
+	 * @throws ReflectionException
3170
+	 * @throws InvalidDataTypeException
3171
+	 * @throws InvalidInterfaceException
3172
+	 */
3173
+	public function global_messages_settings_metabox_content()
3174
+	{
3175
+		$form = $this->_generate_global_settings_form();
3176
+		echo wp_kses(
3177
+			$form->form_open(
3178
+				$this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3179
+				'POST'
3180
+			),
3181
+			AllowedTags::getWithFormTags()
3182
+		);
3183
+		echo wp_kses($form->get_html(), AllowedTags::getWithFormTags());
3184
+		echo wp_kses($form->form_close(), AllowedTags::getWithFormTags());
3185
+	}
3186
+
3187
+
3188
+	/**
3189
+	 * This generates and returns the form object for the global messages settings.
3190
+	 *
3191
+	 * @return EE_Form_Section_Proper
3192
+	 * @throws EE_Error
3193
+	 * @throws InvalidArgumentException
3194
+	 * @throws ReflectionException
3195
+	 * @throws InvalidDataTypeException
3196
+	 * @throws InvalidInterfaceException
3197
+	 */
3198
+	protected function _generate_global_settings_form()
3199
+	{
3200
+		/** @var EE_Network_Core_Config $network_config */
3201
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3202
+
3203
+		return new EE_Form_Section_Proper(
3204
+			[
3205
+				'name'            => 'global_messages_settings',
3206
+				'html_id'         => 'global_messages_settings',
3207
+				'html_class'      => 'form-table',
3208
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3209
+				'subsections'     => apply_filters(
3210
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3211
+					[
3212
+						'do_messages_on_same_request' => new EE_Select_Input(
3213
+							[
3214
+								true  => esc_html__('On the same request', 'event_espresso'),
3215
+								false => esc_html__('On a separate request', 'event_espresso'),
3216
+							],
3217
+							[
3218
+								'default'         => $network_config->do_messages_on_same_request,
3219
+								'html_label_text' => esc_html__(
3220
+									'Generate and send all messages:',
3221
+									'event_espresso'
3222
+								),
3223
+								'html_help_text'  => esc_html__(
3224
+									'By default the messages system uses a more efficient means of processing messages on separate requests and utilizes the wp-cron scheduling system.  This makes things execute faster for people registering for your events.  However, if the wp-cron system is disabled on your site and there is no alternative in place, then you can change this so messages are always executed on the same request.',
3225
+									'event_espresso'
3226
+								),
3227
+							]
3228
+						),
3229
+						'delete_threshold'            => new EE_Select_Input(
3230
+							[
3231
+								0  => esc_html__('Forever', 'event_espresso'),
3232
+								3  => esc_html__('3 Months', 'event_espresso'),
3233
+								6  => esc_html__('6 Months', 'event_espresso'),
3234
+								9  => esc_html__('9 Months', 'event_espresso'),
3235
+								12 => esc_html__('12 Months', 'event_espresso'),
3236
+								24 => esc_html__('24 Months', 'event_espresso'),
3237
+								36 => esc_html__('36 Months', 'event_espresso'),
3238
+							],
3239
+							[
3240
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3241
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3242
+								'html_help_text'  => esc_html__(
3243
+									'You can control how long a record of processed messages is kept via this option.',
3244
+									'event_espresso'
3245
+								),
3246
+							]
3247
+						),
3248
+						'update_settings'             => new EE_Submit_Input(
3249
+							[
3250
+								'default'         => esc_html__('Update', 'event_espresso'),
3251
+								'html_label_text' => '',
3252
+							]
3253
+						),
3254
+					]
3255
+				),
3256
+			]
3257
+		);
3258
+	}
3259
+
3260
+
3261
+	/**
3262
+	 * This handles updating the global settings set on the admin page.
3263
+	 *
3264
+	 * @throws EE_Error
3265
+	 * @throws InvalidDataTypeException
3266
+	 * @throws InvalidInterfaceException
3267
+	 * @throws InvalidArgumentException
3268
+	 * @throws ReflectionException
3269
+	 */
3270
+	protected function _update_global_settings()
3271
+	{
3272
+		/** @var EE_Network_Core_Config $network_config */
3273
+		$network_config  = EE_Registry::instance()->NET_CFG->core;
3274
+		$messages_config = EE_Registry::instance()->CFG->messages;
3275
+		$form            = $this->_generate_global_settings_form();
3276
+		if ($form->was_submitted()) {
3277
+			$form->receive_form_submission();
3278
+			if ($form->is_valid()) {
3279
+				$valid_data = $form->valid_data();
3280
+				\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 3);
3281
+				foreach ($valid_data as $property => $value) {
3282
+					$setter = 'set_' . $property;
3283
+					if (method_exists($network_config, $setter)) {
3284
+						$network_config->{$setter}($value);
3285
+					} elseif (
3286
+						property_exists($network_config, $property)
3287
+						&& $network_config->{$property} !== $value
3288
+					) {
3289
+						$network_config->{$property} = $value;
3290
+					} elseif (
3291
+						property_exists($messages_config, $property)
3292
+						&& $messages_config->{$property} !== $value
3293
+					) {
3294
+						$messages_config->{$property} = $value;
3295
+					}
3296
+				}
3297
+				// only update if the form submission was valid!
3298
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3299
+				EE_Registry::instance()->CFG->update_espresso_config();
3300
+				EE_Error::overwrite_success();
3301
+				EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3302
+			}
3303
+		}
3304
+		$this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3305
+	}
3306
+
3307
+
3308
+	/**
3309
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3310
+	 *
3311
+	 * @param array $tab_array This is an array of message type tab details used to generate the tabs
3312
+	 * @return string html formatted tabs
3313
+	 * @throws DomainException
3314
+	 */
3315
+	protected function _get_mt_tabs($tab_array)
3316
+	{
3317
+		$tab_array = (array) $tab_array;
3318
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3319
+		$tabs      = '';
3320
+
3321
+		foreach ($tab_array as $tab) {
3322
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3323
+		}
3324
+
3325
+		return $tabs;
3326
+	}
3327
+
3328
+
3329
+	/**
3330
+	 * This prepares the content of the messenger meta box admin settings
3331
+	 *
3332
+	 * @param EE_messenger $messenger The messenger we're setting up content for
3333
+	 * @return string html formatted content
3334
+	 * @throws DomainException
3335
+	 */
3336
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3337
+	{
3338
+		$fields = $messenger->get_admin_settings_fields();
3339
+
3340
+		$settings_template_args['template_form_fields'] = '';
3341
+		// is $messenger active?
3342
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3343
+
3344
+
3345
+		if (! empty($fields)) {
3346
+			$existing_settings = $messenger->get_existing_admin_settings();
3347
+
3348
+			foreach ($fields as $field_name => $field_props) {
3349
+				$field_id                         = $messenger->name . '-' . $field_name;
3350
+				$template_form_field[ $field_id ] = [
3351
+					'name'       => 'messenger_settings[' . $field_id . ']',
3352
+					'label'      => $field_props['label'],
3353
+					'input'      => $field_props['field_type'],
3354
+					'type'       => $field_props['value_type'],
3355
+					'required'   => $field_props['required'],
3356
+					'validation' => $field_props['validation'],
3357
+					'value'      => $existing_settings[ $field_id ] ?? $field_props['default'],
3358
+					'css_class'  => '',
3359
+					'format'     => $field_props['format'],
3360
+				];
3361
+			}
3362
+
3363
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3364
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3365
+				: '';
3366
+		}
3367
+
3368
+		// we also need some hidden fields
3369
+		$settings_template_args['hidden_fields'] = [
3370
+			'messenger_settings[messenger]' . $messenger->name => [
3371
+				'type'  => 'hidden',
3372
+				'value' => $messenger->name,
3373
+			],
3374
+			'type' . $messenger->name                          => [
3375
+				'type'  => 'hidden',
3376
+				'value' => 'messenger',
3377
+			],
3378
+		];
3379
+
3380
+		// make sure any active message types that are existing are included in the hidden fields
3381
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3382
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3383
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3384
+					'type'  => 'hidden',
3385
+					'value' => $mt,
3386
+				];
3387
+			}
3388
+		}
3389
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3390
+			$settings_template_args['hidden_fields'],
3391
+			'array'
3392
+		);
3393
+		$active                                  =
3394
+			$this->_message_resource_manager->is_messenger_active($messenger->name);
3395
+
3396
+		$settings_template_args['messenger']           = $messenger->name;
3397
+		$settings_template_args['description']         = $messenger->description;
3398
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3399
+
3400
+
3401
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3402
+			$messenger->name
3403
+		)
3404
+			? $settings_template_args['show_hide_edit_form']
3405
+			: ' hidden';
3406
+
3407
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3408
+			? ' hidden'
3409
+			: $settings_template_args['show_hide_edit_form'];
3410
+
3411
+
3412
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3413
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3414
+		$settings_template_args['on_off_status'] = $active;
3415
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3416
+		return EEH_Template::display_template(
3417
+			$template,
3418
+			$settings_template_args,
3419
+			true
3420
+		);
3421
+	}
3422
+
3423
+
3424
+	/**
3425
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3426
+	 *
3427
+	 * @throws DomainException
3428
+	 * @throws EE_Error
3429
+	 * @throws InvalidDataTypeException
3430
+	 * @throws InvalidInterfaceException
3431
+	 * @throws InvalidArgumentException
3432
+	 * @throws ReflectionException
3433
+	 */
3434
+	public function activate_messenger_toggle()
3435
+	{
3436
+		$success = true;
3437
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3438
+		// let's check that we have required data
3439
+
3440
+		if (! $this->_active_messenger_name) {
3441
+			EE_Error::add_error(
3442
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3443
+				__FILE__,
3444
+				__FUNCTION__,
3445
+				__LINE__
3446
+			);
3447
+			$success = false;
3448
+		}
3449
+
3450
+		// do a nonce check here since we're not arriving via a normal route
3451
+		$nonce     = $this->request->getRequestParam('activate_nonce', '');
3452
+		$nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
3453
+
3454
+		$this->_verify_nonce($nonce, $nonce_ref);
3455
+
3456
+
3457
+		$status = $this->request->getRequestParam('status');
3458
+		if (! $status) {
3459
+			EE_Error::add_error(
3460
+				esc_html__(
3461
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3462
+					'event_espresso'
3463
+				),
3464
+				__FILE__,
3465
+				__FUNCTION__,
3466
+				__LINE__
3467
+			);
3468
+			$success = false;
3469
+		}
3470
+
3471
+		// do check to verify we have a valid status.
3472
+		if ($status !== 'off' && $status !== 'on') {
3473
+			EE_Error::add_error(
3474
+				sprintf(
3475
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
3476
+					$status
3477
+				),
3478
+				__FILE__,
3479
+				__FUNCTION__,
3480
+				__LINE__
3481
+			);
3482
+			$success = false;
3483
+		}
3484
+
3485
+		if ($success) {
3486
+			// made it here?  Stop dawdling then!!
3487
+			$success = $status === 'off'
3488
+				? $this->_deactivate_messenger($this->_active_messenger_name)
3489
+				: $this->_activate_messenger($this->_active_messenger_name);
3490
+		}
3491
+
3492
+		$this->_template_args['success'] = $success;
3493
+
3494
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
3495
+		$this->_return_json();
3496
+	}
3497
+
3498
+
3499
+	/**
3500
+	 * used by ajax from the messages settings page to activate|deactivate a message type
3501
+	 *
3502
+	 * @throws DomainException
3503
+	 * @throws EE_Error
3504
+	 * @throws ReflectionException
3505
+	 * @throws InvalidDataTypeException
3506
+	 * @throws InvalidInterfaceException
3507
+	 * @throws InvalidArgumentException
3508
+	 */
3509
+	public function activate_mt_toggle()
3510
+	{
3511
+		$success = true;
3512
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3513
+
3514
+		// let's make sure we have the necessary data
3515
+		if (! $this->_active_message_type_name) {
3516
+			EE_Error::add_error(
3517
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3518
+				__FILE__,
3519
+				__FUNCTION__,
3520
+				__LINE__
3521
+			);
3522
+			$success = false;
3523
+		}
3524
+
3525
+		if (! $this->_active_messenger_name) {
3526
+			EE_Error::add_error(
3527
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3528
+				__FILE__,
3529
+				__FUNCTION__,
3530
+				__LINE__
3531
+			);
3532
+			$success = false;
3533
+		}
3534
+
3535
+		$status = $this->request->getRequestParam('status');
3536
+		if (! $status) {
3537
+			EE_Error::add_error(
3538
+				esc_html__(
3539
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
3540
+					'event_espresso'
3541
+				),
3542
+				__FILE__,
3543
+				__FUNCTION__,
3544
+				__LINE__
3545
+			);
3546
+			$success = false;
3547
+		}
3548
+
3549
+
3550
+		// do check to verify we have a valid status.
3551
+		if ($status !== 'activate' && $status !== 'deactivate') {
3552
+			EE_Error::add_error(
3553
+				sprintf(
3554
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
3555
+					$status
3556
+				),
3557
+				__FILE__,
3558
+				__FUNCTION__,
3559
+				__LINE__
3560
+			);
3561
+			$success = false;
3562
+		}
3563
+
3564
+
3565
+		// do a nonce check here since we're not arriving via a normal route
3566
+		$nonce = $this->request->getRequestParam('mt_nonce', '');
3567
+		$this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
3568
+
3569
+		if ($success) {
3570
+			// made it here? um, what are you waiting for then?
3571
+			$success = $status === 'deactivate'
3572
+				? $this->_deactivate_message_type_for_messenger(
3573
+					$this->_active_messenger_name,
3574
+					$this->_active_message_type_name
3575
+				)
3576
+				: $this->_activate_message_type_for_messenger(
3577
+					$this->_active_messenger_name,
3578
+					$this->_active_message_type_name
3579
+				);
3580
+		}
3581
+
3582
+		$this->_template_args['success'] = $success;
3583
+		$this->_return_json();
3584
+	}
3585
+
3586
+
3587
+	/**
3588
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
3589
+	 *
3590
+	 * @param string $messenger_name The name of the messenger being activated
3591
+	 * @return bool
3592
+	 * @throws DomainException
3593
+	 * @throws EE_Error
3594
+	 * @throws InvalidArgumentException
3595
+	 * @throws ReflectionException
3596
+	 * @throws InvalidDataTypeException
3597
+	 * @throws InvalidInterfaceException
3598
+	 */
3599
+	protected function _activate_messenger($messenger_name)
3600
+	{
3601
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
3602
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
3603
+			? $active_messenger->get_default_message_types()
3604
+			: [];
3605
+
3606
+		// ensure is active
3607
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
3608
+
3609
+		// set response_data for reload
3610
+		foreach ($message_types_to_activate as $message_type_name) {
3611
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
3612
+			if (
3613
+				$this->_message_resource_manager->is_message_type_active_for_messenger(
3614
+					$messenger_name,
3615
+					$message_type_name
3616
+				)
3617
+				&& $message_type instanceof EE_message_type
3618
+			) {
3619
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
3620
+				if ($message_type->get_admin_settings_fields()) {
3621
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
3622
+				}
3623
+			}
3624
+		}
3625
+
3626
+		// add success message for activating messenger
3627
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
3628
+	}
3629
+
3630
+
3631
+	/**
3632
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
3633
+	 *
3634
+	 * @param string $messenger_name The name of the messenger being activated
3635
+	 * @return bool
3636
+	 * @throws DomainException
3637
+	 * @throws EE_Error
3638
+	 * @throws InvalidArgumentException
3639
+	 * @throws ReflectionException
3640
+	 * @throws InvalidDataTypeException
3641
+	 * @throws InvalidInterfaceException
3642
+	 */
3643
+	protected function _deactivate_messenger($messenger_name)
3644
+	{
3645
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3646
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
3647
+
3648
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
3649
+	}
3650
+
3651
+
3652
+	/**
3653
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
3654
+	 *
3655
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
3656
+	 * @param string $message_type_name The name of the message type being activated for the messenger
3657
+	 * @return bool
3658
+	 * @throws DomainException
3659
+	 * @throws EE_Error
3660
+	 * @throws InvalidArgumentException
3661
+	 * @throws ReflectionException
3662
+	 * @throws InvalidDataTypeException
3663
+	 * @throws InvalidInterfaceException
3664
+	 */
3665
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
3666
+	{
3667
+		$active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
3668
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
3669
+
3670
+		// ensure is active
3671
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
3672
+
3673
+		// set response for load
3674
+		if (
3675
+			$this->_message_resource_manager->is_message_type_active_for_messenger(
3676
+				$messenger_name,
3677
+				$message_type_name
3678
+			)
3679
+		) {
3680
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
3681
+			if ($message_type_to_activate->get_admin_settings_fields()) {
3682
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
3683
+			}
3684
+		}
3685
+
3686
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
3687
+			$active_messenger,
3688
+			$message_type_to_activate
3689
+		);
3690
+	}
3691
+
3692
+
3693
+	/**
3694
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
3695
+	 *
3696
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
3697
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
3698
+	 * @return bool
3699
+	 * @throws DomainException
3700
+	 * @throws EE_Error
3701
+	 * @throws InvalidArgumentException
3702
+	 * @throws ReflectionException
3703
+	 * @throws InvalidDataTypeException
3704
+	 * @throws InvalidInterfaceException
3705
+	 */
3706
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
3707
+	{
3708
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
3709
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
3710
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
3711
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
3712
+
3713
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
3714
+			$active_messenger,
3715
+			$message_type_to_deactivate
3716
+		);
3717
+	}
3718
+
3719
+
3720
+	/**
3721
+	 * This just initializes the defaults for activating messenger and message type responses.
3722
+	 */
3723
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
3724
+	{
3725
+		$this->_template_args['data']['active_mts'] = [];
3726
+		$this->_template_args['data']['mt_reload']  = [];
3727
+	}
3728
+
3729
+
3730
+	/**
3731
+	 * Setup appropriate response for activating a messenger and/or message types
3732
+	 *
3733
+	 * @param EE_messenger         $messenger
3734
+	 * @param EE_message_type|null $message_type
3735
+	 * @return bool
3736
+	 * @throws DomainException
3737
+	 * @throws EE_Error
3738
+	 * @throws InvalidArgumentException
3739
+	 * @throws ReflectionException
3740
+	 * @throws InvalidDataTypeException
3741
+	 * @throws InvalidInterfaceException
3742
+	 */
3743
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
3744
+		$messenger,
3745
+		EE_Message_Type $message_type = null
3746
+	) {
3747
+		// if $messenger isn't a valid messenger object then get out.
3748
+		if (! $messenger instanceof EE_Messenger) {
3749
+			EE_Error::add_error(
3750
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
3751
+				__FILE__,
3752
+				__FUNCTION__,
3753
+				__LINE__
3754
+			);
3755
+			return false;
3756
+		}
3757
+		// activated
3758
+		if ($this->_template_args['data']['active_mts']) {
3759
+			EE_Error::overwrite_success();
3760
+			// activated a message type with the messenger
3761
+			if ($message_type instanceof EE_message_type) {
3762
+				EE_Error::add_success(
3763
+					sprintf(
3764
+						esc_html__(
3765
+							'%s message type has been successfully activated with the %s messenger',
3766
+							'event_espresso'
3767
+						),
3768
+						ucwords($message_type->label['singular']),
3769
+						ucwords($messenger->label['singular'])
3770
+					)
3771
+				);
3772
+
3773
+				// if message type was invoice then let's make sure we activate the invoice payment method.
3774
+				if ($message_type->name === 'invoice') {
3775
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
3776
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
3777
+					if ($pm instanceof EE_Payment_Method) {
3778
+						EE_Error::add_attention(
3779
+							esc_html__(
3780
+								'Activating the invoice message type also automatically activates the invoice payment method.  If you do not wish the invoice payment method to be active, or to change its settings, visit the payment method admin page.',
3781
+								'event_espresso'
3782
+							)
3783
+						);
3784
+					}
3785
+				}
3786
+				// just toggles the entire messenger
3787
+			} else {
3788
+				EE_Error::add_success(
3789
+					sprintf(
3790
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
3791
+						ucwords($messenger->label['singular'])
3792
+					)
3793
+				);
3794
+			}
3795
+
3796
+			return true;
3797
+
3798
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
3799
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3800
+			// in which case we just give a success message for the messenger being successfully activated.
3801
+		} else {
3802
+			if (! $messenger->get_default_message_types()) {
3803
+				// messenger doesn't have any default message types so still a success.
3804
+				EE_Error::add_success(
3805
+					sprintf(
3806
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
3807
+						ucwords($messenger->label['singular'])
3808
+					)
3809
+				);
3810
+
3811
+				return true;
3812
+			} else {
3813
+				EE_Error::add_error(
3814
+					$message_type instanceof EE_message_type
3815
+						? sprintf(
3816
+						esc_html__(
3817
+							'%s message type was not successfully activated with the %s messenger',
3818
+							'event_espresso'
3819
+						),
3820
+						ucwords($message_type->label['singular']),
3821
+						ucwords($messenger->label['singular'])
3822
+					)
3823
+						: sprintf(
3824
+						esc_html__('%s messenger was not successfully activated', 'event_espresso'),
3825
+						ucwords($messenger->label['singular'])
3826
+					),
3827
+					__FILE__,
3828
+					__FUNCTION__,
3829
+					__LINE__
3830
+				);
3831
+
3832
+				return false;
3833
+			}
3834
+		}
3835
+	}
3836
+
3837
+
3838
+	/**
3839
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
3840
+	 *
3841
+	 * @param EE_messenger         $messenger
3842
+	 * @param EE_message_type|null $message_type
3843
+	 * @return bool
3844
+	 * @throws DomainException
3845
+	 * @throws EE_Error
3846
+	 * @throws InvalidArgumentException
3847
+	 * @throws ReflectionException
3848
+	 * @throws InvalidDataTypeException
3849
+	 * @throws InvalidInterfaceException
3850
+	 */
3851
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
3852
+		$messenger,
3853
+		EE_message_type $message_type = null
3854
+	) {
3855
+		EE_Error::overwrite_success();
3856
+
3857
+		// if $messenger isn't a valid messenger object then get out.
3858
+		if (! $messenger instanceof EE_Messenger) {
3859
+			EE_Error::add_error(
3860
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3861
+				__FILE__,
3862
+				__FUNCTION__,
3863
+				__LINE__
3864
+			);
3865
+
3866
+			return false;
3867
+		}
3868
+
3869
+		if ($message_type instanceof EE_message_type) {
3870
+			$message_type_name = $message_type->name;
3871
+			EE_Error::add_success(
3872
+				sprintf(
3873
+					esc_html__(
3874
+						'%s message type has been successfully deactivated for the %s messenger.',
3875
+						'event_espresso'
3876
+					),
3877
+					ucwords($message_type->label['singular']),
3878
+					ucwords($messenger->label['singular'])
3879
+				)
3880
+			);
3881
+		} else {
3882
+			$message_type_name = '';
3883
+			EE_Error::add_success(
3884
+				sprintf(
3885
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
3886
+					ucwords($messenger->label['singular'])
3887
+				)
3888
+			);
3889
+		}
3890
+
3891
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
3892
+		if (
3893
+			$messenger->name === 'html'
3894
+			&& (
3895
+				is_null($message_type)
3896
+				|| $message_type_name === 'invoice'
3897
+			)
3898
+		) {
3899
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
3900
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
3901
+			if ($count_updated > 0) {
3902
+				$msg = $message_type_name === 'invoice'
3903
+					? esc_html__(
3904
+						'Deactivating the invoice message type also automatically deactivates the invoice payment method. In order for invoices to be generated the invoice message type must be active. If you completed this action by mistake, simply reactivate the invoice message type and then visit the payment methods admin page to reactivate the invoice payment method.',
3905
+						'event_espresso'
3906
+					)
3907
+					: esc_html__(
3908
+						'Deactivating the html messenger also automatically deactivates the invoice payment method.  In order for invoices to be generated the html messenger must be be active.  If you completed this action by mistake, simply reactivate the html messenger, then visit the payment methods admin page to reactivate the invoice payment method.',
3909
+						'event_espresso'
3910
+					);
3911
+				EE_Error::add_attention($msg);
3912
+			}
3913
+		}
3914
+
3915
+		return true;
3916
+	}
3917
+
3918
+
3919
+	/**
3920
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
3921
+	 *
3922
+	 * @throws DomainException
3923
+	 * @throws EE_Error
3924
+	 * @throws EE_Error
3925
+	 */
3926
+	public function update_mt_form()
3927
+	{
3928
+		if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
3929
+			EE_Error::add_error(
3930
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
3931
+				__FILE__,
3932
+				__FUNCTION__,
3933
+				__LINE__
3934
+			);
3935
+			$this->_return_json();
3936
+		}
3937
+
3938
+		$message_types = $this->get_installed_message_types();
3939
+		$message_type  = $message_types[ $this->_active_message_type_name ];
3940
+		$messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
3941
+		$content       = $this->_message_type_settings_content($message_type, $messenger, true);
3942
+
3943
+		$this->_template_args['success'] = true;
3944
+		$this->_template_args['content'] = $content;
3945
+		$this->_return_json();
3946
+	}
3947
+
3948
+
3949
+	/**
3950
+	 * this handles saving the settings for a messenger or message type
3951
+	 *
3952
+	 * @throws EE_Error
3953
+	 * @throws EE_Error
3954
+	 */
3955
+	public function save_settings()
3956
+	{
3957
+		$type = $this->request->getRequestParam('type');
3958
+		if (! $type) {
3959
+			EE_Error::add_error(
3960
+				esc_html__(
3961
+					'Cannot save settings because type is unknown (messenger settings or message type settings?)',
3962
+					'event_espresso'
3963
+				),
3964
+				__FILE__,
3965
+				__FUNCTION__,
3966
+				__LINE__
3967
+			);
3968
+			$this->_template_args['error'] = true;
3969
+			$this->_return_json();
3970
+		}
3971
+
3972
+
3973
+		if ($type === 'messenger') {
3974
+			// this should be an array.
3975
+			$settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
3976
+			$messenger = $settings['messenger'];
3977
+			// remove messenger and message_types from settings array
3978
+			unset($settings['messenger'], $settings['message_types']);
3979
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
3980
+		} elseif ($type === 'message_type') {
3981
+			$settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
3982
+			$messenger    = $settings['messenger'];
3983
+			$message_type = $settings['message_type'];
3984
+			// remove messenger and message_types from settings array
3985
+			unset($settings['messenger'], $settings['message_types']);
3986
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
3987
+		}
3988
+
3989
+		// okay we should have the data all setup.  Now we just update!
3990
+		$success = $this->_message_resource_manager->update_active_messengers_option();
3991
+
3992
+		if ($success) {
3993
+			EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
3994
+		} else {
3995
+			EE_Error::add_error(
3996
+				esc_html__('Settings did not get updated', 'event_espresso'),
3997
+				__FILE__,
3998
+				__FUNCTION__,
3999
+				__LINE__
4000
+			);
4001
+		}
4002
+
4003
+		$this->_template_args['success'] = $success;
4004
+		$this->_return_json();
4005
+	}
4006
+
4007
+
4008
+
4009
+
4010
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4011
+
4012
+
4013
+	/**
4014
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4015
+	 * However, this does not send immediately, it just queues for sending.
4016
+	 *
4017
+	 * @throws EE_Error
4018
+	 * @throws InvalidDataTypeException
4019
+	 * @throws InvalidInterfaceException
4020
+	 * @throws InvalidArgumentException
4021
+	 * @throws ReflectionException
4022
+	 * @since 4.9.0
4023
+	 */
4024
+	protected function _generate_now()
4025
+	{
4026
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4027
+		$this->_redirect_after_action(false, '', '', [], true);
4028
+	}
4029
+
4030
+
4031
+	/**
4032
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4033
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4034
+	 *
4035
+	 * @throws EE_Error
4036
+	 * @throws InvalidDataTypeException
4037
+	 * @throws InvalidInterfaceException
4038
+	 * @throws InvalidArgumentException
4039
+	 * @throws ReflectionException
4040
+	 * @since 4.9.0
4041
+	 */
4042
+	protected function _generate_and_send_now()
4043
+	{
4044
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4045
+		$this->_redirect_after_action(false, '', '', [], true);
4046
+	}
4047
+
4048
+
4049
+	/**
4050
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4051
+	 *
4052
+	 * @throws EE_Error
4053
+	 * @throws InvalidDataTypeException
4054
+	 * @throws InvalidInterfaceException
4055
+	 * @throws InvalidArgumentException
4056
+	 * @throws ReflectionException
4057
+	 * @since 4.9.0
4058
+	 */
4059
+	protected function _queue_for_resending()
4060
+	{
4061
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4062
+		$this->_redirect_after_action(false, '', '', [], true);
4063
+	}
4064
+
4065
+
4066
+	/**
4067
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4068
+	 *
4069
+	 * @throws EE_Error
4070
+	 * @throws InvalidDataTypeException
4071
+	 * @throws InvalidInterfaceException
4072
+	 * @throws InvalidArgumentException
4073
+	 * @throws ReflectionException
4074
+	 * @since 4.9.0
4075
+	 */
4076
+	protected function _send_now()
4077
+	{
4078
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4079
+		$this->_redirect_after_action(false, '', '', [], true);
4080
+	}
4081
+
4082
+
4083
+	/**
4084
+	 * Deletes EE_messages for IDs in the request.
4085
+	 *
4086
+	 * @throws EE_Error
4087
+	 * @throws InvalidDataTypeException
4088
+	 * @throws InvalidInterfaceException
4089
+	 * @throws InvalidArgumentException
4090
+	 * @throws ReflectionException
4091
+	 * @since 4.9.0
4092
+	 */
4093
+	protected function _delete_ee_messages()
4094
+	{
4095
+		$MSG_IDs       = $this->_get_msg_ids_from_request();
4096
+		$deleted_count = 0;
4097
+		foreach ($MSG_IDs as $MSG_ID) {
4098
+			if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4099
+				$deleted_count++;
4100
+			}
4101
+		}
4102
+		if ($deleted_count) {
4103
+			EE_Error::add_success(
4104
+				esc_html(
4105
+					_n(
4106
+						'Message successfully deleted',
4107
+						'Messages successfully deleted',
4108
+						$deleted_count,
4109
+						'event_espresso'
4110
+					)
4111
+				)
4112
+			);
4113
+		} else {
4114
+			EE_Error::add_error(
4115
+				_n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4116
+				__FILE__,
4117
+				__FUNCTION__,
4118
+				__LINE__
4119
+			);
4120
+		}
4121
+		$this->_redirect_after_action(false, '', '', [], true);
4122
+	}
4123
+
4124
+
4125
+	/**
4126
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4127
+	 *
4128
+	 * @return array
4129
+	 * @since 4.9.0
4130
+	 */
4131
+	protected function _get_msg_ids_from_request()
4132
+	{
4133
+		$MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4134
+		if (empty($MSG_IDs)) {
4135
+			return [];
4136
+		}
4137
+		// if 'MSG_ID' was just a single ID (not an array)
4138
+		// then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4139
+		// otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4140
+		return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4141
+			? $MSG_IDs
4142
+			: array_keys($MSG_IDs);
4143
+	}
4144 4144
 }
Please login to merge, or discard this patch.
Spacing   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -85,7 +85,7 @@  discard block
 block discarded – undo
85 85
      */
86 86
     public function getMsgModel(): EEM_Message
87 87
     {
88
-        if (! $this->MSG_MODEL instanceof EEM_Message) {
88
+        if ( ! $this->MSG_MODEL instanceof EEM_Message) {
89 89
             $this->MSG_MODEL = EEM_Message::instance();
90 90
         }
91 91
         return $this->MSG_MODEL;
@@ -99,7 +99,7 @@  discard block
 block discarded – undo
99 99
      */
100 100
     public function getMtpModel(): EEM_Message_Template
101 101
     {
102
-        if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
102
+        if ( ! $this->MTP_MODEL instanceof EEM_Message_Template) {
103 103
             $this->MTP_MODEL = EEM_Message_Template::instance();
104 104
         }
105 105
         return $this->MTP_MODEL;
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
      */
114 114
     public function getMtgModel(): EEM_Message_Template_Group
115 115
     {
116
-        if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
116
+        if ( ! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
117 117
             $this->MTG_MODEL = EEM_Message_Template_Group::instance();
118 118
         }
119 119
         return $this->MTG_MODEL;
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
 
123 123
     public function getMessageTemplateManager(): MessageTemplateManager
124 124
     {
125
-        if (! $this->message_template_manager instanceof MessageTemplateManager) {
125
+        if ( ! $this->message_template_manager instanceof MessageTemplateManager) {
126 126
             $this->message_template_manager = $this->loader->getShared(MessageTemplateManager::class);
127 127
         }
128 128
         return $this->message_template_manager;
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
 
152 152
     protected function _load_message_resource_manager()
153 153
     {
154
-        if (! $this->_message_resource_manager instanceof EE_Message_Resource_Manager) {
154
+        if ( ! $this->_message_resource_manager instanceof EE_Message_Resource_Manager) {
155 155
             $this->_message_resource_manager = $this->loader->getShared(EE_Message_Resource_Manager::class);
156 156
         }
157 157
     }
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
             ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
180 180
             $messenger_options
181 181
         );
182
-        $input             = new EE_Select_Input(
182
+        $input = new EE_Select_Input(
183 183
             $messenger_options,
184 184
             [
185 185
                 'html_name'  => 'ee_messenger_filter_by',
@@ -216,7 +216,7 @@  discard block
 block discarded – undo
216 216
             ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
217 217
             $message_type_options
218 218
         );
219
-        $input                = new EE_Select_Input(
219
+        $input = new EE_Select_Input(
220 220
             $message_type_options,
221 221
             [
222 222
                 'html_name'  => 'ee_message_type_filter_by',
@@ -253,7 +253,7 @@  discard block
 block discarded – undo
253 253
             ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
254 254
             $context_options
255 255
         );
256
-        $input           = new EE_Select_Input(
256
+        $input = new EE_Select_Input(
257 257
             $context_options,
258 258
             [
259 259
                 'html_name'  => 'ee_context_filter_by',
@@ -632,53 +632,53 @@  discard block
 block discarded – undo
632 632
 
633 633
     public function messages_help_tab()
634 634
     {
635
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
635
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_help_tab.template.php');
636 636
     }
637 637
 
638 638
 
639 639
     public function messengers_help_tab()
640 640
     {
641
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
641
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messenger_help_tab.template.php');
642 642
     }
643 643
 
644 644
 
645 645
     public function message_types_help_tab()
646 646
     {
647
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
647
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_type_help_tab.template.php');
648 648
     }
649 649
 
650 650
 
651 651
     public function messages_overview_help_tab()
652 652
     {
653
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
653
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_overview_help_tab.template.php');
654 654
     }
655 655
 
656 656
 
657 657
     public function message_templates_help_tab()
658 658
     {
659
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
659
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_message_templates_help_tab.template.php');
660 660
     }
661 661
 
662 662
 
663 663
     public function edit_message_template_help_tab()
664 664
     {
665
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
665
+        $args['img1'] = '<img src="'.EE_MSG_ASSETS_URL.'images/editor.png'.'" alt="'
666 666
                         . esc_attr__('Editor Title', 'event_espresso')
667 667
                         . '" />';
668
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
668
+        $args['img2'] = '<img src="'.EE_MSG_ASSETS_URL.'images/switch-context.png'.'" alt="'
669 669
                         . esc_attr__('Context Switcher and Preview', 'event_espresso')
670 670
                         . '" />';
671
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
671
+        $args['img3'] = '<img class="left" src="'.EE_MSG_ASSETS_URL.'images/form-fields.png'.'" alt="'
672 672
                         . esc_attr__('Message Template Form Fields', 'event_espresso')
673 673
                         . '" />';
674
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
674
+        $args['img4'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/shortcodes-metabox.png'.'" alt="'
675 675
                         . esc_attr__('Shortcodes Metabox', 'event_espresso')
676 676
                         . '" />';
677
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
677
+        $args['img5'] = '<img class="right" src="'.EE_MSG_ASSETS_URL.'images/publish-meta-box.png'.'" alt="'
678 678
                         . esc_attr__('Publish Metabox', 'event_espresso')
679 679
                         . '" />';
680 680
         EEH_Template::display_template(
681
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
681
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_templates_editor_help_tab.template.php',
682 682
             $args
683 683
         );
684 684
     }
@@ -693,7 +693,7 @@  discard block
 block discarded – undo
693 693
         $this->_set_shortcodes();
694 694
         $args['shortcodes'] = $this->_shortcodes;
695 695
         EEH_Template::display_template(
696
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
696
+            EE_MSG_TEMPLATE_PATH.'ee_msg_messages_shortcodes_help_tab.template.php',
697 697
             $args
698 698
         );
699 699
     }
@@ -701,16 +701,16 @@  discard block
 block discarded – undo
701 701
 
702 702
     public function preview_message_help_tab()
703 703
     {
704
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
704
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_preview_help_tab.template.php');
705 705
     }
706 706
 
707 707
 
708 708
     public function settings_help_tab()
709 709
     {
710
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
711
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
712
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
713
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
710
+        $args['img1'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'
711
+                        . '" alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />';
712
+        $args['img2'] = '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
713
+                        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />';
714 714
         $args['img3'] = '<div class="ee-switch">'
715 715
                         . '<input class="ee-switch__input" id="ee-on-off-toggle-on" type="checkbox" checked>'
716 716
                         . '<label class="ee-switch__toggle" for="ee-on-off-toggle-on"></label>'
@@ -719,25 +719,25 @@  discard block
 block discarded – undo
719 719
                         . '<input class="ee-switch__input" id="ee-on-off-toggle-off" type="checkbox">'
720 720
                         . '<label class="ee-switch__toggle" for="ee-on-off-toggle-off"></label>'
721 721
                         . '</div>';
722
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
722
+        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH.'ee_msg_messages_settings_help_tab.template.php', $args);
723 723
     }
724 724
 
725 725
 
726 726
     public function load_scripts_styles()
727 727
     {
728
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', [], EVENT_ESPRESSO_VERSION);
728
+        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL.'ee_message_admin.css', [], EVENT_ESPRESSO_VERSION);
729 729
         wp_enqueue_style('espresso_ee_msg');
730 730
 
731 731
         wp_register_script(
732 732
             'ee-messages-settings',
733
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
733
+            EE_MSG_ASSETS_URL.'ee-messages-settings.js',
734 734
             ['jquery-ui-droppable', 'ee-serialize-full-array'],
735 735
             EVENT_ESPRESSO_VERSION,
736 736
             true
737 737
         );
738 738
         wp_register_script(
739 739
             'ee-msg-list-table-js',
740
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
740
+            EE_MSG_ASSETS_URL.'ee_message_admin_list_table.js',
741 741
             ['ee-dialog'],
742 742
             EVENT_ESPRESSO_VERSION
743 743
         );
@@ -779,7 +779,7 @@  discard block
 block discarded – undo
779 779
     {
780 780
         $this->_set_shortcodes();
781 781
 
782
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
782
+        EE_Registry::$i18n_js_strings['confirm_default_reset'] = sprintf(
783 783
             esc_html__(
784 784
                 'Are you sure you want to reset the %s %s message templates?  Remember continuing will reset the templates for all contexts in this messenger and message type group.',
785 785
                 'event_espresso'
@@ -791,14 +791,14 @@  discard block
 block discarded – undo
791 791
             'Switching the template pack for a messages template will reset the content for the template so the new layout is loaded.  Any custom content in the existing template will be lost. Are you sure you wish to do this?',
792 792
             'event_espresso'
793 793
         );
794
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
794
+        EE_Registry::$i18n_js_strings['server_error'] = esc_html__(
795 795
             'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
796 796
             'event_espresso'
797 797
         );
798 798
 
799 799
         wp_register_script(
800 800
             'ee_msgs_edit_js',
801
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
801
+            EE_MSG_ASSETS_URL.'ee_message_editor.js',
802 802
             ['jquery'],
803 803
             EVENT_ESPRESSO_VERSION
804 804
         );
@@ -841,7 +841,7 @@  discard block
 block discarded – undo
841 841
     {
842 842
         wp_register_style(
843 843
             'ee-message-settings',
844
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
844
+            EE_MSG_ASSETS_URL.'ee_message_settings.css',
845 845
             [],
846 846
             EVENT_ESPRESSO_VERSION
847 847
         );
@@ -927,7 +927,7 @@  discard block
 block discarded – undo
927 927
             }
928 928
             $status_bulk_actions = $common_bulk_actions;
929 929
             // unset bulk actions not applying to status
930
-            if (! empty($status_bulk_actions)) {
930
+            if ( ! empty($status_bulk_actions)) {
931 931
                 switch ($status) {
932 932
                     case EEM_Message::status_idle:
933 933
                     case EEM_Message::status_resend:
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
                 continue;
957 957
             }
958 958
 
959
-            $this->_views[ strtolower($status) ] = [
959
+            $this->_views[strtolower($status)] = [
960 960
                 'slug'        => strtolower($status),
961 961
                 'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
962 962
                 'count'       => 0,
@@ -1003,7 +1003,7 @@  discard block
 block discarded – undo
1003 1003
             if ($action_item === 'see_notifications_for') {
1004 1004
                 continue;
1005 1005
             }
1006
-            $action_items[ $action_item ] = [
1006
+            $action_items[$action_item] = [
1007 1007
                 'class' => $action_details['css_class'],
1008 1008
                 'desc'  => $action_details['label'],
1009 1009
             ];
@@ -1012,37 +1012,37 @@  discard block
 block discarded – undo
1012 1012
         /** @var array $status_items status legend setup */
1013 1013
         $status_items = [
1014 1014
             'sent_status'                => [
1015
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_sent,
1015
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_sent,
1016 1016
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1017 1017
             ],
1018 1018
             'idle_status'                => [
1019
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_idle,
1019
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_idle,
1020 1020
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1021 1021
             ],
1022 1022
             'failed_status'              => [
1023
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_failed,
1023
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_failed,
1024 1024
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1025 1025
             ],
1026 1026
             'messenger_executing_status' => [
1027
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_messenger_executing,
1027
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_messenger_executing,
1028 1028
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1029 1029
             ],
1030 1030
             'resend_status'              => [
1031
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_resend,
1031
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_resend,
1032 1032
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1033 1033
             ],
1034 1034
             'incomplete_status'          => [
1035
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_incomplete,
1035
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_incomplete,
1036 1036
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1037 1037
             ],
1038 1038
             'retry_status'               => [
1039
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_retry,
1039
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_retry,
1040 1040
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1041 1041
             ],
1042 1042
         ];
1043 1043
         if (EEM_Message::debug()) {
1044 1044
             $status_items['debug_only_status'] = [
1045
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Message::status_debug_only,
1045
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Message::status_debug_only,
1046 1046
                 'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1047 1047
             ];
1048 1048
         }
@@ -1057,11 +1057,11 @@  discard block
 block discarded – undo
1057 1057
     protected function _custom_mtps_preview()
1058 1058
     {
1059 1059
         $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1060
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1061
-                                                . ' alt="' . esc_attr__(
1060
+        $this->_template_args['preview_img']  = '<img src="'.EE_MSG_ASSETS_URL.'images/custom_mtps_preview.png"'
1061
+                                                . ' alt="'.esc_attr__(
1062 1062
                                                     'Preview Custom Message Templates screenshot',
1063 1063
                                                     'event_espresso'
1064
-                                                ) . '" />';
1064
+                                                ).'" />';
1065 1065
         $this->_template_args['preview_text'] = '<strong>'
1066 1066
                                                 . esc_html__(
1067 1067
                                                     'Custom Message Templates 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 Custom Message Templates feature, you are able to create custom message templates and assign them on a per-event basis.',
@@ -1137,7 +1137,7 @@  discard block
 block discarded – undo
1137 1137
         $installed               = [];
1138 1138
 
1139 1139
         foreach ($installed_message_types as $message_type) {
1140
-            $installed[ $message_type->name ] = $message_type;
1140
+            $installed[$message_type->name] = $message_type;
1141 1141
         }
1142 1142
 
1143 1143
         return $installed;
@@ -1233,7 +1233,7 @@  discard block
 block discarded – undo
1233 1233
         // we need to assemble the title from Various details
1234 1234
         $context_label = sprintf(
1235 1235
             esc_html__('(%s %s)', 'event_espresso'),
1236
-            $c_config[ $context ]['label'],
1236
+            $c_config[$context]['label'],
1237 1237
             ucwords($c_label['label'])
1238 1238
         );
1239 1239
 
@@ -1255,7 +1255,7 @@  discard block
 block discarded – undo
1255 1255
             $message_template_group->message_type()
1256 1256
         );
1257 1257
 
1258
-        if (! $template_field_structure) {
1258
+        if ( ! $template_field_structure) {
1259 1259
             $template_field_structure = false;
1260 1260
             $template_fields          = esc_html__(
1261 1261
                 'There was an error in assembling the fields for this display (you should see an error message)',
@@ -1267,21 +1267,21 @@  discard block
 block discarded – undo
1267 1267
 
1268 1268
         // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1269 1269
         // will get handled in the "extra" array.
1270
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1271
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1272
-                unset($template_field_structure[ $context ][ $reference_field ]);
1270
+        if (is_array($template_field_structure[$context]) && isset($template_field_structure[$context]['extra'])) {
1271
+            foreach ($template_field_structure[$context]['extra'] as $reference_field => $new_fields) {
1272
+                unset($template_field_structure[$context][$reference_field]);
1273 1273
             }
1274 1274
         }
1275 1275
 
1276 1276
         // let's loop through the template_field_structure and actually assemble the input fields!
1277
-        if (! empty($template_field_structure)) {
1278
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1277
+        if ( ! empty($template_field_structure)) {
1278
+            foreach ($template_field_structure[$context] as $template_field => $field_setup_array) {
1279 1279
                 // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1280 1280
                 // the extra array and reset them.
1281 1281
                 if ($template_field === 'extra') {
1282 1282
                     $this->_template_args['is_extra_fields'] = true;
1283 1283
                     foreach ($field_setup_array as $reference_field => $new_fields_array) {
1284
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1284
+                        $message_template = $message_templates[$context][$reference_field];
1285 1285
                         $content          = $message_template instanceof EE_Message_Template
1286 1286
                             ? $message_template->get('MTP_content')
1287 1287
                             : '';
@@ -1290,7 +1290,7 @@  discard block
 block discarded – undo
1290 1290
                             $continue = false;
1291 1291
                             if (isset($extra_array['shortcodes_required'])) {
1292 1292
                                 foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1293
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1293
+                                    if ( ! array_key_exists($shortcode, $this->_shortcodes)) {
1294 1294
                                         $continue = true;
1295 1295
                                     }
1296 1296
                                 }
@@ -1299,51 +1299,51 @@  discard block
 block discarded – undo
1299 1299
                                 }
1300 1300
                             }
1301 1301
 
1302
-                            $field_id = $reference_field . '-' . $extra_field . '-content';
1302
+                            $field_id = $reference_field.'-'.$extra_field.'-content';
1303 1303
 
1304
-                            $template_form_fields[ $field_id ]         = $extra_array;
1305
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1304
+                            $template_form_fields[$field_id]         = $extra_array;
1305
+                            $template_form_fields[$field_id]['name'] = 'MTP_template_fields['
1306 1306
                                                                          . $reference_field
1307 1307
                                                                          . '][content]['
1308
-                                                                         . $extra_field . ']';
1309
-                            $css_class                                 = $extra_array['css_class'] ?? '';
1308
+                                                                         . $extra_field.']';
1309
+                            $css_class = $extra_array['css_class'] ?? '';
1310 1310
 
1311
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1311
+                            $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1312 1312
                                                                               && in_array($extra_field, $v_fields, true)
1313 1313
                                                                               && (
1314
-                                                                                  is_array($validators[ $extra_field ])
1315
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1314
+                                                                                  is_array($validators[$extra_field])
1315
+                                                                                  && isset($validators[$extra_field]['msg'])
1316 1316
                                                                               )
1317
-                                ? 'validate-error ' . $css_class
1317
+                                ? 'validate-error '.$css_class
1318 1318
                                 : $css_class;
1319 1319
 
1320
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1321
-                                                                          && isset($content[ $extra_field ])
1322
-                                ? $content[ $extra_field ]
1320
+                            $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1321
+                                                                          && isset($content[$extra_field])
1322
+                                ? $content[$extra_field]
1323 1323
                                 : '';
1324 1324
 
1325 1325
                             // do we have a validation error?  if we do then let's use that value instead
1326
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1327
-                                ? $validators[ $extra_field ]['value']
1328
-                                : $template_form_fields[ $field_id ]['value'];
1326
+                            $template_form_fields[$field_id]['value'] = isset($validators[$extra_field])
1327
+                                ? $validators[$extra_field]['value']
1328
+                                : $template_form_fields[$field_id]['value'];
1329 1329
 
1330 1330
 
1331
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1331
+                            $template_form_fields[$field_id]['db-col'] = 'MTP_content';
1332 1332
 
1333 1333
                             // shortcode selector
1334 1334
                             $field_name_to_use                                   = $extra_field === 'main'
1335 1335
                                 ? 'content'
1336 1336
                                 : $extra_field;
1337
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1337
+                            $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1338 1338
                                 $field_name_to_use,
1339 1339
                                 $field_id
1340 1340
                             );
1341 1341
                         }
1342
-                        $template_field_MTP_id           = $reference_field . '-MTP_ID';
1343
-                        $template_field_template_name_id = $reference_field . '-name';
1342
+                        $template_field_MTP_id           = $reference_field.'-MTP_ID';
1343
+                        $template_field_template_name_id = $reference_field.'-name';
1344 1344
 
1345
-                        $template_form_fields[ $template_field_MTP_id ] = [
1346
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1345
+                        $template_form_fields[$template_field_MTP_id] = [
1346
+                            'name'       => 'MTP_template_fields['.$reference_field.'][MTP_ID]',
1347 1347
                             'label'      => null,
1348 1348
                             'input'      => 'hidden',
1349 1349
                             'type'       => 'int',
@@ -1355,8 +1355,8 @@  discard block
 block discarded – undo
1355 1355
                             'db-col'     => 'MTP_ID',
1356 1356
                         ];
1357 1357
 
1358
-                        $template_form_fields[ $template_field_template_name_id ] = [
1359
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1358
+                        $template_form_fields[$template_field_template_name_id] = [
1359
+                            'name'       => 'MTP_template_fields['.$reference_field.'][name]',
1360 1360
                             'label'      => null,
1361 1361
                             'input'      => 'hidden',
1362 1362
                             'type'       => 'string',
@@ -1370,34 +1370,34 @@  discard block
 block discarded – undo
1370 1370
                     }
1371 1371
                     continue; // skip the next stuff, we got the necessary fields here for this dataset.
1372 1372
                 } else {
1373
-                    $field_id                                   = $template_field . '-content';
1374
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1375
-                    $template_form_fields[ $field_id ]['name']  =
1376
-                        'MTP_template_fields[' . $template_field . '][content]';
1373
+                    $field_id                                   = $template_field.'-content';
1374
+                    $template_form_fields[$field_id]          = $field_setup_array;
1375
+                    $template_form_fields[$field_id]['name']  =
1376
+                        'MTP_template_fields['.$template_field.'][content]';
1377 1377
                     $message_template                           =
1378
-                        $message_templates[ $context ][ $template_field ] ?? null;
1379
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1380
-                                                                  && is_array($message_templates[ $context ])
1378
+                        $message_templates[$context][$template_field] ?? null;
1379
+                    $template_form_fields[$field_id]['value'] = ! empty($message_templates)
1380
+                                                                  && is_array($message_templates[$context])
1381 1381
                                                                   && $message_template instanceof EE_Message_Template
1382 1382
                         ? $message_template->get('MTP_content')
1383 1383
                         : '';
1384 1384
 
1385 1385
                     // do we have a validator error for this field?  if we do then we'll use that value instead
1386
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1387
-                        ? $validators[ $template_field ]['value']
1388
-                        : $template_form_fields[ $field_id ]['value'];
1386
+                    $template_form_fields[$field_id]['value'] = isset($validators[$template_field])
1387
+                        ? $validators[$template_field]['value']
1388
+                        : $template_form_fields[$field_id]['value'];
1389 1389
 
1390 1390
 
1391
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1391
+                    $template_form_fields[$field_id]['db-col']    = 'MTP_content';
1392 1392
                     $css_class                                      = $field_setup_array['css_class'] ?? '';
1393
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1393
+                    $template_form_fields[$field_id]['css_class'] = ! empty($v_fields)
1394 1394
                                                                       && in_array($template_field, $v_fields, true)
1395
-                                                                      && isset($validators[ $template_field ]['msg'])
1396
-                        ? 'validate-error ' . $css_class
1395
+                                                                      && isset($validators[$template_field]['msg'])
1396
+                        ? 'validate-error '.$css_class
1397 1397
                         : $css_class;
1398 1398
 
1399 1399
                     // shortcode selector
1400
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1400
+                    $template_form_fields[$field_id]['append_content'] = $this->_get_shortcode_selector(
1401 1401
                         $template_field,
1402 1402
                         $field_id
1403 1403
                     );
@@ -1405,12 +1405,12 @@  discard block
 block discarded – undo
1405 1405
 
1406 1406
                 // k took care of content field(s) now let's take care of others.
1407 1407
 
1408
-                $template_field_MTP_id                 = $template_field . '-MTP_ID';
1409
-                $template_field_field_template_name_id = $template_field . '-name';
1408
+                $template_field_MTP_id                 = $template_field.'-MTP_ID';
1409
+                $template_field_field_template_name_id = $template_field.'-name';
1410 1410
 
1411 1411
                 // foreach template field there are actually two form fields created
1412
-                $template_form_fields[ $template_field_MTP_id ] = [
1413
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1412
+                $template_form_fields[$template_field_MTP_id] = [
1413
+                    'name'       => 'MTP_template_fields['.$template_field.'][MTP_ID]',
1414 1414
                     'label'      => null,
1415 1415
                     'input'      => 'hidden',
1416 1416
                     'type'       => 'int',
@@ -1422,8 +1422,8 @@  discard block
 block discarded – undo
1422 1422
                     'db-col'     => 'MTP_ID',
1423 1423
                 ];
1424 1424
 
1425
-                $template_form_fields[ $template_field_field_template_name_id ] = [
1426
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1425
+                $template_form_fields[$template_field_field_template_name_id] = [
1426
+                    'name'       => 'MTP_template_fields['.$template_field.'][name]',
1427 1427
                     'label'      => null,
1428 1428
                     'input'      => 'hidden',
1429 1429
                     'type'       => 'string',
@@ -1540,7 +1540,7 @@  discard block
 block discarded – undo
1540 1540
                 'format'     => '%d',
1541 1541
                 'db-col'     => 'MTP_deleted',
1542 1542
             ];
1543
-            $sidebar_form_fields['ee-msg-author']  = [
1543
+            $sidebar_form_fields['ee-msg-author'] = [
1544 1544
                 'name'       => 'MTP_user_id',
1545 1545
                 'label'      => esc_html__('Author', 'event_espresso'),
1546 1546
                 'input'      => 'hidden',
@@ -1559,17 +1559,17 @@  discard block
 block discarded – undo
1559 1559
                 'value' => $action,
1560 1560
             ];
1561 1561
 
1562
-            $sidebar_form_fields['ee-msg-id']        = [
1562
+            $sidebar_form_fields['ee-msg-id'] = [
1563 1563
                 'name'  => 'id',
1564 1564
                 'input' => 'hidden',
1565 1565
                 'type'  => 'int',
1566 1566
                 'value' => $GRP_ID,
1567 1567
             ];
1568 1568
             $sidebar_form_fields['ee-msg-evt-nonce'] = [
1569
-                'name'  => $action . '_nonce',
1569
+                'name'  => $action.'_nonce',
1570 1570
                 'input' => 'hidden',
1571 1571
                 'type'  => 'string',
1572
-                'value' => wp_create_nonce($action . '_nonce'),
1572
+                'value' => wp_create_nonce($action.'_nonce'),
1573 1573
             ];
1574 1574
 
1575 1575
             $template_switch = $this->request->getRequestParam('template_switch');
@@ -1601,7 +1601,7 @@  discard block
 block discarded – undo
1601 1601
         );
1602 1602
 
1603 1603
         // add preview button
1604
-        $preview_url    = parent::add_query_args_and_nonce(
1604
+        $preview_url = parent::add_query_args_and_nonce(
1605 1605
             [
1606 1606
                 'message_type' => $message_template_group->message_type(),
1607 1607
                 'messenger'    => $message_template_group->messenger(),
@@ -1612,7 +1612,7 @@  discard block
 block discarded – undo
1612 1612
             ],
1613 1613
             $this->_admin_base_url
1614 1614
         );
1615
-        $preview_button = '<a href="' . $preview_url . '" class="button--secondary messages-preview-button">'
1615
+        $preview_button = '<a href="'.$preview_url.'" class="button--secondary messages-preview-button">'
1616 1616
                           . esc_html__('Preview', 'event_espresso')
1617 1617
                           . '</a>';
1618 1618
 
@@ -1648,11 +1648,11 @@  discard block
 block discarded – undo
1648 1648
         $this->_template_args['before_admin_page_content'] .= $this->add_context_switcher();
1649 1649
         $this->_template_args['before_admin_page_content'] .= '</div>';
1650 1650
         $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1651
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1651
+        $this->_template_args['after_admin_page_content'] = $this->_add_form_element_after();
1652 1652
 
1653 1653
         $this->_template_path = $this->_template_args['GRP_ID']
1654 1654
             ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1655
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1655
+            : EE_MSG_TEMPLATE_PATH.'ee_msg_details_main_add_meta_box.template.php';
1656 1656
 
1657 1657
         // send along EE_Message_Template_Group object for further template use.
1658 1658
         $this->_template_args['MTP'] = $message_template_group;
@@ -1705,7 +1705,7 @@  discard block
 block discarded – undo
1705 1705
     ) {
1706 1706
         $template_args = [
1707 1707
             'context'                   => $context,
1708
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1708
+            'nonce'                     => wp_create_nonce('activate_'.$context.'_toggle_nonce'),
1709 1709
             'is_active'                 => $message_template_group->is_context_active($context),
1710 1710
             'on_off_action'             => $message_template_group->is_context_active($context)
1711 1711
                 ? 'context-off'
@@ -1714,7 +1714,7 @@  discard block
 block discarded – undo
1714 1714
             'message_template_group_id' => $message_template_group->ID(),
1715 1715
         ];
1716 1716
         return EEH_Template::display_template(
1717
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1717
+            EE_MSG_TEMPLATE_PATH.'ee_msg_editor_active_context_element.template.php',
1718 1718
             $template_args,
1719 1719
             true
1720 1720
         );
@@ -1772,7 +1772,7 @@  discard block
 block discarded – undo
1772 1772
         }
1773 1773
         $message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, DataType::INTEGER);
1774 1774
         $message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1775
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1775
+        if ( ! $message_template_group instanceof EE_Message_Template_Group) {
1776 1776
             EE_Error::add_error(
1777 1777
                 sprintf(
1778 1778
                     esc_html__(
@@ -1902,7 +1902,7 @@  discard block
 block discarded – undo
1902 1902
         $messenger    = $this->request->getRequestParam('msgr');
1903 1903
         $message_type = $this->request->getRequestParam('mt');
1904 1904
         // we need to make sure we've got the info we need.
1905
-        if (! ($GRP_ID && $messenger && $message_type)) {
1905
+        if ( ! ($GRP_ID && $messenger && $message_type)) {
1906 1906
             EE_Error::add_error(
1907 1907
                 esc_html__(
1908 1908
                     'In order to reset the template to its default we require the messenger, message type, and message template GRP_ID to know what is being reset.  At least one of these is missing.',
@@ -1944,7 +1944,7 @@  discard block
 block discarded – undo
1944 1944
         }
1945 1945
 
1946 1946
         // any error messages?
1947
-        if (! $success) {
1947
+        if ( ! $success) {
1948 1948
             EE_Error::add_error(
1949 1949
                 esc_html__(
1950 1950
                     'Something went wrong with deleting existing templates. Unable to reset to default',
@@ -1993,7 +1993,7 @@  discard block
 block discarded – undo
1993 1993
     {
1994 1994
         // first make sure we've got the necessary parameters
1995 1995
         $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, DataType::INTEGER);
1996
-        if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
1996
+        if ( ! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
1997 1997
             EE_Error::add_error(
1998 1998
                 esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
1999 1999
                 __FILE__,
@@ -2019,7 +2019,7 @@  discard block
 block discarded – undo
2019 2019
         $EVT_ID = $this->request->getRequestParam('evt_id', 0, DataType::INTEGER);
2020 2020
 
2021 2021
         // let's add a button to go back to the edit view
2022
-        $query_args             = [
2022
+        $query_args = [
2023 2023
             'id'      => $GRP_ID,
2024 2024
             'evt_id'  => $EVT_ID,
2025 2025
             'context' => $context,
@@ -2040,7 +2040,7 @@  discard block
 block discarded – undo
2040 2040
         $preview_title = sprintf(
2041 2041
             esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2042 2042
             $active_messenger_label,
2043
-            ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2043
+            ucwords($message_types[$this->_active_message_type_name]->label['singular'])
2044 2044
         );
2045 2045
         if (empty($preview)) {
2046 2046
             $this->noEventsErrorMessage();
@@ -2048,7 +2048,7 @@  discard block
 block discarded – undo
2048 2048
         // setup display of preview.
2049 2049
         $this->_admin_page_title                    = $preview_title;
2050 2050
         $this->_template_args['admin_page_title']   = $preview_title;
2051
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2051
+        $this->_template_args['admin_page_content'] = $preview_button.'<br />'.$preview;
2052 2052
         $this->_template_args['data']['force_json'] = true;
2053 2053
 
2054 2054
         return '';
@@ -2069,7 +2069,7 @@  discard block
 block discarded – undo
2069 2069
             ],
2070 2070
             admin_url('admin.php')
2071 2071
         );
2072
-        $message    = $test_send
2072
+        $message = $test_send
2073 2073
             ? esc_html__(
2074 2074
                 'A test message could not be sent for this message template because there are no events created yet. The preview system uses actual events for generating the test message. %1$sGo see your events%2$s!',
2075 2075
                 'event_espresso'
@@ -2161,10 +2161,10 @@  discard block
 block discarded – undo
2161 2161
             // only include template packs that support this messenger and message type!
2162 2162
             $supports = $tp->get_supports();
2163 2163
             if (
2164
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2164
+                ! isset($supports[$this->_message_template_group->messenger()])
2165 2165
                 || ! in_array(
2166 2166
                     $this->_message_template_group->message_type(),
2167
-                    $supports[ $this->_message_template_group->messenger() ],
2167
+                    $supports[$this->_message_template_group->messenger()],
2168 2168
                     true
2169 2169
                 )
2170 2170
             ) {
@@ -2188,7 +2188,7 @@  discard block
 block discarded – undo
2188 2188
         }
2189 2189
 
2190 2190
         // setup variation select values for the currently selected template.
2191
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2191
+        $variations = $this->_message_template_group->get_template_pack()->get_variations(
2192 2192
             $this->_message_template_group->messenger(),
2193 2193
             $this->_message_template_group->message_type()
2194 2194
         );
@@ -2202,12 +2202,12 @@  discard block
 block discarded – undo
2202 2202
 
2203 2203
         $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2204 2204
 
2205
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2205
+        $template_args['template_packs_selector'] = EEH_Form_Fields::select_input(
2206 2206
             'MTP_template_pack',
2207 2207
             $tp_select_values,
2208 2208
             $this->_message_template_group->get_template_pack_name()
2209 2209
         );
2210
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2210
+        $template_args['variations_selector'] = EEH_Form_Fields::select_input(
2211 2211
             'MTP_template_variation',
2212 2212
             $variations_select_values,
2213 2213
             $this->_message_template_group->get_template_pack_variation()
@@ -2217,7 +2217,7 @@  discard block
 block discarded – undo
2217 2217
         $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2218 2218
         $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2219 2219
 
2220
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2220
+        $template = EE_MSG_TEMPLATE_PATH.'template_pack_and_variations_metabox.template.php';
2221 2221
 
2222 2222
         EEH_Template::display_template($template, $template_args);
2223 2223
     }
@@ -2243,33 +2243,33 @@  discard block
 block discarded – undo
2243 2243
         // first we need to see if there are any fields
2244 2244
         $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2245 2245
 
2246
-        if (! empty($fields)) {
2246
+        if ( ! empty($fields)) {
2247 2247
             // yup there be fields
2248 2248
             foreach ($fields as $field => $config) {
2249
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2249
+                $field_id = $this->_message_template_group->messenger().'_'.$field;
2250 2250
                 $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2251 2251
                 $default  = $config['default'] ?? '';
2252 2252
                 $default  = $config['value'] ?? $default;
2253 2253
 
2254 2254
                 // if type is hidden and the value is empty
2255 2255
                 // something may have gone wrong so let's correct with the defaults
2256
-                $fix                = $config['input'] === 'hidden'
2257
-                                      && isset($existing[ $field ])
2258
-                                      && empty($existing[ $field ])
2256
+                $fix = $config['input'] === 'hidden'
2257
+                                      && isset($existing[$field])
2258
+                                      && empty($existing[$field])
2259 2259
                     ? $default
2260 2260
                     : '';
2261
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2262
-                    ? $existing[ $field ]
2261
+                $existing[$field] = isset($existing[$field]) && empty($fix)
2262
+                    ? $existing[$field]
2263 2263
                     : $fix;
2264 2264
 
2265
-                $template_form_fields[ $field_id ] = [
2266
-                    'name'       => 'test_settings_fld[' . $field . ']',
2265
+                $template_form_fields[$field_id] = [
2266
+                    'name'       => 'test_settings_fld['.$field.']',
2267 2267
                     'label'      => $config['label'],
2268 2268
                     'input'      => $config['input'],
2269 2269
                     'type'       => $config['type'],
2270 2270
                     'required'   => $config['required'],
2271 2271
                     'validation' => $config['validation'],
2272
-                    'value'      => $existing[ $field ] ?? $default,
2272
+                    'value'      => $existing[$field] ?? $default,
2273 2273
                     'css_class'  => $config['css_class'],
2274 2274
                     'options'    => $config['options'] ?? [],
2275 2275
                     'default'    => $default,
@@ -2283,7 +2283,7 @@  discard block
 block discarded – undo
2283 2283
             : '';
2284 2284
 
2285 2285
         // print out $test_settings_fields
2286
-        if (! empty($test_settings_html)) {
2286
+        if ( ! empty($test_settings_html)) {
2287 2287
             $test_settings_html .= '<input type="submit" class="button--primary mtp-test-button alignright" ';
2288 2288
             $test_settings_html .= 'name="test_button" value="';
2289 2289
             $test_settings_html .= esc_html__('Test Send', 'event_espresso');
@@ -2329,7 +2329,7 @@  discard block
 block discarded – undo
2329 2329
         ];
2330 2330
 
2331 2331
         return EEH_Template::display_template(
2332
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2332
+            EE_MSG_TEMPLATE_PATH.'shortcode_selector_skeleton.template.php',
2333 2333
             $template_args,
2334 2334
             true
2335 2335
         );
@@ -2355,7 +2355,7 @@  discard block
 block discarded – undo
2355 2355
         // $messenger = $this->_message_template_group->messenger_obj();
2356 2356
         // now let's set the content depending on the status of the shortcodes array
2357 2357
         if (empty($shortcodes)) {
2358
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2358
+            echo '<p>'.esc_html__('There are no valid shortcodes available', 'event_espresso').'</p>';
2359 2359
             return;
2360 2360
         }
2361 2361
         ?>
@@ -2390,7 +2390,7 @@  discard block
 block discarded – undo
2390 2390
     protected function _set_shortcodes()
2391 2391
     {
2392 2392
         // no need to run this if the property is already set
2393
-        if (! empty($this->_shortcodes)) {
2393
+        if ( ! empty($this->_shortcodes)) {
2394 2394
             return;
2395 2395
         }
2396 2396
 
@@ -2445,7 +2445,7 @@  discard block
 block discarded – undo
2445 2445
     protected function _set_message_template_group()
2446 2446
     {
2447 2447
         // get out if this is already set.
2448
-        if (! empty($this->_message_template_group)) {
2448
+        if ( ! empty($this->_message_template_group)) {
2449 2449
             return;
2450 2450
         }
2451 2451
 
@@ -2491,8 +2491,8 @@  discard block
 block discarded – undo
2491 2491
                     <?php
2492 2492
                 }
2493 2493
                 // setup nonce_url
2494
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2495
-                $id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2494
+                wp_nonce_field($args['action'].'_nonce', $args['action'].'_nonce', false);
2495
+                $id = 'ee-'.sanitize_key($context_label['label']).'-select';
2496 2496
                 ?>
2497 2497
                 <label for='<?php echo esc_attr($id); ?>' class='screen-reader-text'>
2498 2498
                     <?php esc_html_e('message context options', 'event_espresso'); ?>
@@ -2505,7 +2505,7 @@  discard block
 block discarded – undo
2505 2505
                             $checked = ($context === $args['context']) ? 'selected' : '';
2506 2506
                             ?>
2507 2507
                             <option value="<?php echo esc_attr($context); ?>" <?php echo esc_attr($checked); ?>>
2508
-                                <?php echo esc_html($context_details[ $context ]['label']); ?>
2508
+                                <?php echo esc_html($context_details[$context]['label']); ?>
2509 2509
                             </option>
2510 2510
                         <?php endforeach;
2511 2511
                     endif; ?>
@@ -2625,7 +2625,7 @@  discard block
 block discarded – undo
2625 2625
 
2626 2626
         $context   = ucwords(str_replace('_', ' ', $context));
2627 2627
         $item_desc = $messenger_label && $message_type_label
2628
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
2628
+            ? $messenger_label.' '.$message_type_label.' '.$context.' '
2629 2629
             : '';
2630 2630
         $item_desc .= 'Message Template';
2631 2631
         return $item_desc;
@@ -2743,7 +2743,7 @@  discard block
 block discarded – undo
2743 2743
         if ($all) {
2744 2744
             // Checkboxes
2745 2745
             $checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2746
-            if (! empty($checkboxes)) {
2746
+            if ( ! empty($checkboxes)) {
2747 2747
                 // if array has more than one element then success message should be plural.
2748 2748
                 // todo: what about nonce?
2749 2749
                 $success = count($checkboxes) > 1 ? 2 : 1;
@@ -2753,18 +2753,18 @@  discard block
 block discarded – undo
2753 2753
                     $trashed_or_restored = $trash
2754 2754
                         ? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2755 2755
                         : $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2756
-                    if (! $trashed_or_restored) {
2756
+                    if ( ! $trashed_or_restored) {
2757 2757
                         $success = 0;
2758 2758
                     }
2759 2759
                 }
2760 2760
             } else {
2761 2761
                 // grab single GRP_ID and handle
2762 2762
                 $GRP_ID = $this->request->getRequestParam('id', 0, DataType::INTEGER);
2763
-                if (! empty($GRP_ID)) {
2763
+                if ( ! empty($GRP_ID)) {
2764 2764
                     $trashed_or_restored = $trash
2765 2765
                         ? $this->getMessageTemplateManager()->trashMessageTemplate($GRP_ID)
2766 2766
                         : $this->getMessageTemplateManager()->restoreMessageTemplate($GRP_ID);
2767
-                    if (! $trashed_or_restored) {
2767
+                    if ( ! $trashed_or_restored) {
2768 2768
                         $success = 0;
2769 2769
                     }
2770 2770
                 } else {
@@ -2817,7 +2817,7 @@  discard block
 block discarded – undo
2817 2817
     {
2818 2818
         // checkboxes
2819 2819
         $checkboxes = $this->request->getRequestParam('checkbox', [], DataType::INTEGER, true);
2820
-        if (! empty($checkboxes)) {
2820
+        if ( ! empty($checkboxes)) {
2821 2821
             // if array has more than one element then success message should be plural
2822 2822
             $success = count($checkboxes) > 1 ? 2 : 1;
2823 2823
 
@@ -2893,7 +2893,7 @@  discard block
 block discarded – undo
2893 2893
     protected function _set_m_mt_settings()
2894 2894
     {
2895 2895
         // first if this is already set then lets get out no need to regenerate data.
2896
-        if (! empty($this->_m_mt_settings)) {
2896
+        if ( ! empty($this->_m_mt_settings)) {
2897 2897
             return;
2898 2898
         }
2899 2899
 
@@ -2908,8 +2908,8 @@  discard block
 block discarded – undo
2908 2908
             $active                                                     =
2909 2909
                 $this->_message_resource_manager->is_messenger_active($messenger->name);
2910 2910
             $class                                                      =
2911
-                'ee-messenger-' . sanitize_key($messenger->label['singular']);
2912
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
2911
+                'ee-messenger-'.sanitize_key($messenger->label['singular']);
2912
+            $this->_m_mt_settings['messenger_tabs'][$messenger->name] = [
2913 2913
                 'label' => ucwords($messenger->label['singular']),
2914 2914
                 'class' => $active ? "{$class} messenger-active" : $class,
2915 2915
                 'href'  => $messenger->name,
@@ -2927,7 +2927,7 @@  discard block
 block discarded – undo
2927 2927
             foreach ($message_types as $message_type) {
2928 2928
                 // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
2929 2929
                 // it shouldn't show in either the inactive OR active metabox.
2930
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
2930
+                if ( ! in_array($message_type->name, $message_types_for_messenger, true)) {
2931 2931
                     continue;
2932 2932
                 }
2933 2933
 
@@ -2938,12 +2938,12 @@  discard block
 block discarded – undo
2938 2938
                     ? 'active'
2939 2939
                     : 'inactive';
2940 2940
 
2941
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
2941
+                $this->_m_mt_settings['message_type_tabs'][$messenger->name][$a_or_i][$message_type->name] = [
2942 2942
                     'label'    => ucwords($message_type->label['singular']),
2943
-                    'class'    => 'message-type-' . $a_or_i,
2944
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
2945
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
2946
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
2943
+                    'class'    => 'message-type-'.$a_or_i,
2944
+                    'slug_id'  => $message_type->name.'-messagetype-'.$messenger->name,
2945
+                    'mt_nonce' => wp_create_nonce($message_type->name.'_nonce'),
2946
+                    'href'     => 'espresso_'.$message_type->name.'_message_type_settings',
2947 2947
                     'title'    => $a_or_i === 'active'
2948 2948
                         ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
2949 2949
                         : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
@@ -2974,20 +2974,20 @@  discard block
 block discarded – undo
2974 2974
         $fields                                         = $message_type->get_admin_settings_fields();
2975 2975
         $settings_template_args['template_form_fields'] = '';
2976 2976
 
2977
-        if (! empty($fields) && $active) {
2977
+        if ( ! empty($fields) && $active) {
2978 2978
             $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
2979 2979
             foreach ($fields as $fldname => $fldprops) {
2980
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
2981
-                $template_form_field[ $field_id ] = [
2982
-                    'name'       => 'message_type_settings[' . $fldname . ']',
2980
+                $field_id                         = $messenger->name.'-'.$message_type->name.'-'.$fldname;
2981
+                $template_form_field[$field_id] = [
2982
+                    'name'       => 'message_type_settings['.$fldname.']',
2983 2983
                     'label'      => $fldprops['label'],
2984 2984
                     'input'      => $fldprops['field_type'],
2985 2985
                     'type'       => $fldprops['value_type'],
2986 2986
                     'required'   => $fldprops['required'],
2987 2987
                     'validation' => $fldprops['validation'],
2988
-                    'value'      => $existing_settings[ $fldname ] ?? $fldprops['default'],
2988
+                    'value'      => $existing_settings[$fldname] ?? $fldprops['default'],
2989 2989
                     'options'    => $fldprops['options'] ?? [],
2990
-                    'default'    => $existing_settings[ $fldname ] ?? $fldprops['default'],
2990
+                    'default'    => $existing_settings[$fldname] ?? $fldprops['default'],
2991 2991
                     'css_class'  => 'no-drag',
2992 2992
                     'format'     => $fldprops['format'],
2993 2993
                 ];
@@ -3006,15 +3006,15 @@  discard block
 block discarded – undo
3006 3006
         $settings_template_args['description'] = $message_type->description;
3007 3007
         // we also need some hidden fields
3008 3008
         $hidden_fields = [
3009
-            'message_type_settings[messenger]' . $message_type->name    => [
3009
+            'message_type_settings[messenger]'.$message_type->name    => [
3010 3010
                 'type'  => 'hidden',
3011 3011
                 'value' => $messenger->name,
3012 3012
             ],
3013
-            'message_type_settings[message_type]' . $message_type->name => [
3013
+            'message_type_settings[message_type]'.$message_type->name => [
3014 3014
                 'type'  => 'hidden',
3015 3015
                 'value' => $message_type->name,
3016 3016
             ],
3017
-            'type' . $message_type->name                                => [
3017
+            'type'.$message_type->name                                => [
3018 3018
                 'type'  => 'hidden',
3019 3019
                 'value' => 'message_type',
3020 3020
             ],
@@ -3024,12 +3024,12 @@  discard block
 block discarded – undo
3024 3024
             $hidden_fields,
3025 3025
             'array'
3026 3026
         );
3027
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3027
+        $settings_template_args['show_form'] = empty($settings_template_args['template_form_fields'])
3028 3028
             ? ' hidden'
3029 3029
             : '';
3030 3030
 
3031 3031
 
3032
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3032
+        $template = EE_MSG_TEMPLATE_PATH.'ee_msg_mt_settings_content.template.php';
3033 3033
         return EEH_Template::display_template($template, $settings_template_args, true);
3034 3034
     }
3035 3035
 
@@ -3057,19 +3057,19 @@  discard block
 block discarded – undo
3057 3057
 
3058 3058
                 // messenger meta boxes
3059 3059
                 $active         = $selected_messenger === $messenger;
3060
-                $active_mt_tabs = $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'] ?? '';
3060
+                $active_mt_tabs = $this->_m_mt_settings['message_type_tabs'][$messenger]['active'] ?? '';
3061 3061
 
3062
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3062
+                $m_boxes[$messenger.'_a_box'] = sprintf(
3063 3063
                     esc_html__('%s Settings', 'event_espresso'),
3064 3064
                     $tab_array['label']
3065 3065
                 );
3066 3066
 
3067
-                $m_template_args[ $messenger . '_a_box' ] = [
3067
+                $m_template_args[$messenger.'_a_box'] = [
3068 3068
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3069 3069
                     'inactive_message_types' => isset(
3070
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3070
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3071 3071
                     )
3072
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3072
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3073 3073
                         : '',
3074 3074
                     'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3075 3075
                     'hidden'                 => $active ? '' : ' hidden',
@@ -3081,13 +3081,13 @@  discard block
 block discarded – undo
3081 3081
                 // message type meta boxes
3082 3082
                 // (which is really just the inactive container for each messenger
3083 3083
                 // showing inactive message types for that messenger)
3084
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3085
-                $mt_template_args[ $messenger . '_i_box' ] = [
3084
+                $mt_boxes[$messenger.'_i_box']         = esc_html__('Inactive Message Types', 'event_espresso');
3085
+                $mt_template_args[$messenger.'_i_box'] = [
3086 3086
                     'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3087 3087
                     'inactive_message_types' => isset(
3088
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3088
+                        $this->_m_mt_settings['message_type_tabs'][$messenger]['inactive']
3089 3089
                     )
3090
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3090
+                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][$messenger]['inactive'])
3091 3091
                         : '',
3092 3092
                     'hidden'                 => $active ? '' : ' hidden',
3093 3093
                     'hide_on_message'        => $hide_on_message,
@@ -3100,14 +3100,14 @@  discard block
 block discarded – undo
3100 3100
 
3101 3101
 
3102 3102
         // register messenger metaboxes
3103
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3103
+        $m_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_mt_meta_box.template.php';
3104 3104
         foreach ($m_boxes as $box => $label) {
3105
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3105
+            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[$box]];
3106 3106
             $msgr          = str_replace('_a_box', '', $box);
3107 3107
             $this->addMetaBox(
3108
-                'espresso_' . $msgr . '_settings',
3108
+                'espresso_'.$msgr.'_settings',
3109 3109
                 $label,
3110
-                function ($post, $metabox) {
3110
+                function($post, $metabox) {
3111 3111
                     EEH_Template::display_template(
3112 3112
                         $metabox['args']['template_path'],
3113 3113
                         $metabox['args']['template_args']
@@ -3121,17 +3121,17 @@  discard block
 block discarded – undo
3121 3121
         }
3122 3122
 
3123 3123
         // register message type metaboxes
3124
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3124
+        $mt_template_path = EE_MSG_TEMPLATE_PATH.'ee_msg_details_messenger_meta_box.template.php';
3125 3125
         foreach ($mt_boxes as $box => $label) {
3126 3126
             $callback_args = [
3127 3127
                 'template_path' => $mt_template_path,
3128
-                'template_args' => $mt_template_args[ $box ],
3128
+                'template_args' => $mt_template_args[$box],
3129 3129
             ];
3130
-            $mt            = str_replace('_i_box', '', $box);
3130
+            $mt = str_replace('_i_box', '', $box);
3131 3131
             $this->addMetaBox(
3132
-                'espresso_' . $mt . '_inactive_mts',
3132
+                'espresso_'.$mt.'_inactive_mts',
3133 3133
                 $label,
3134
-                function ($post, $metabox) {
3134
+                function($post, $metabox) {
3135 3135
                     EEH_Template::display_template(
3136 3136
                         $metabox['args']['template_path'],
3137 3137
                         $metabox['args']['template_args']
@@ -3279,7 +3279,7 @@  discard block
 block discarded – undo
3279 3279
                 $valid_data = $form->valid_data();
3280 3280
                 \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 3);
3281 3281
                 foreach ($valid_data as $property => $value) {
3282
-                    $setter = 'set_' . $property;
3282
+                    $setter = 'set_'.$property;
3283 3283
                     if (method_exists($network_config, $setter)) {
3284 3284
                         $network_config->{$setter}($value);
3285 3285
                     } elseif (
@@ -3315,7 +3315,7 @@  discard block
 block discarded – undo
3315 3315
     protected function _get_mt_tabs($tab_array)
3316 3316
     {
3317 3317
         $tab_array = (array) $tab_array;
3318
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3318
+        $template  = EE_MSG_TEMPLATE_PATH.'ee_msg_details_mt_settings_tab_item.template.php';
3319 3319
         $tabs      = '';
3320 3320
 
3321 3321
         foreach ($tab_array as $tab) {
@@ -3342,19 +3342,19 @@  discard block
 block discarded – undo
3342 3342
         $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3343 3343
 
3344 3344
 
3345
-        if (! empty($fields)) {
3345
+        if ( ! empty($fields)) {
3346 3346
             $existing_settings = $messenger->get_existing_admin_settings();
3347 3347
 
3348 3348
             foreach ($fields as $field_name => $field_props) {
3349
-                $field_id                         = $messenger->name . '-' . $field_name;
3350
-                $template_form_field[ $field_id ] = [
3351
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3349
+                $field_id                         = $messenger->name.'-'.$field_name;
3350
+                $template_form_field[$field_id] = [
3351
+                    'name'       => 'messenger_settings['.$field_id.']',
3352 3352
                     'label'      => $field_props['label'],
3353 3353
                     'input'      => $field_props['field_type'],
3354 3354
                     'type'       => $field_props['value_type'],
3355 3355
                     'required'   => $field_props['required'],
3356 3356
                     'validation' => $field_props['validation'],
3357
-                    'value'      => $existing_settings[ $field_id ] ?? $field_props['default'],
3357
+                    'value'      => $existing_settings[$field_id] ?? $field_props['default'],
3358 3358
                     'css_class'  => '',
3359 3359
                     'format'     => $field_props['format'],
3360 3360
                 ];
@@ -3367,20 +3367,20 @@  discard block
 block discarded – undo
3367 3367
 
3368 3368
         // we also need some hidden fields
3369 3369
         $settings_template_args['hidden_fields'] = [
3370
-            'messenger_settings[messenger]' . $messenger->name => [
3370
+            'messenger_settings[messenger]'.$messenger->name => [
3371 3371
                 'type'  => 'hidden',
3372 3372
                 'value' => $messenger->name,
3373 3373
             ],
3374
-            'type' . $messenger->name                          => [
3374
+            'type'.$messenger->name                          => [
3375 3375
                 'type'  => 'hidden',
3376 3376
                 'value' => 'messenger',
3377 3377
             ],
3378 3378
         ];
3379 3379
 
3380 3380
         // make sure any active message types that are existing are included in the hidden fields
3381
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3382
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3383
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3381
+        if (isset($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'])) {
3382
+            foreach ($this->_m_mt_settings['message_type_tabs'][$messenger->name]['active'] as $mt => $values) {
3383
+                $settings_template_args['hidden_fields']['messenger_settings[message_types]['.$mt.']'] = [
3384 3384
                     'type'  => 'hidden',
3385 3385
                     'value' => $mt,
3386 3386
                 ];
@@ -3390,7 +3390,7 @@  discard block
 block discarded – undo
3390 3390
             $settings_template_args['hidden_fields'],
3391 3391
             'array'
3392 3392
         );
3393
-        $active                                  =
3393
+        $active =
3394 3394
             $this->_message_resource_manager->is_messenger_active($messenger->name);
3395 3395
 
3396 3396
         $settings_template_args['messenger']           = $messenger->name;
@@ -3410,9 +3410,9 @@  discard block
 block discarded – undo
3410 3410
 
3411 3411
 
3412 3412
         $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3413
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3413
+        $settings_template_args['nonce']         = wp_create_nonce('activate_'.$messenger->name.'_toggle_nonce');
3414 3414
         $settings_template_args['on_off_status'] = $active;
3415
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3415
+        $template                                = EE_MSG_TEMPLATE_PATH.'ee_msg_m_settings_content.template.php';
3416 3416
         return EEH_Template::display_template(
3417 3417
             $template,
3418 3418
             $settings_template_args,
@@ -3437,7 +3437,7 @@  discard block
 block discarded – undo
3437 3437
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3438 3438
         // let's check that we have required data
3439 3439
 
3440
-        if (! $this->_active_messenger_name) {
3440
+        if ( ! $this->_active_messenger_name) {
3441 3441
             EE_Error::add_error(
3442 3442
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3443 3443
                 __FILE__,
@@ -3455,7 +3455,7 @@  discard block
 block discarded – undo
3455 3455
 
3456 3456
 
3457 3457
         $status = $this->request->getRequestParam('status');
3458
-        if (! $status) {
3458
+        if ( ! $status) {
3459 3459
             EE_Error::add_error(
3460 3460
                 esc_html__(
3461 3461
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3512,7 +3512,7 @@  discard block
 block discarded – undo
3512 3512
         $this->_prep_default_response_for_messenger_or_message_type_toggle();
3513 3513
 
3514 3514
         // let's make sure we have the necessary data
3515
-        if (! $this->_active_message_type_name) {
3515
+        if ( ! $this->_active_message_type_name) {
3516 3516
             EE_Error::add_error(
3517 3517
                 esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
3518 3518
                 __FILE__,
@@ -3522,7 +3522,7 @@  discard block
 block discarded – undo
3522 3522
             $success = false;
3523 3523
         }
3524 3524
 
3525
-        if (! $this->_active_messenger_name) {
3525
+        if ( ! $this->_active_messenger_name) {
3526 3526
             EE_Error::add_error(
3527 3527
                 esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3528 3528
                 __FILE__,
@@ -3533,7 +3533,7 @@  discard block
 block discarded – undo
3533 3533
         }
3534 3534
 
3535 3535
         $status = $this->request->getRequestParam('status');
3536
-        if (! $status) {
3536
+        if ( ! $status) {
3537 3537
             EE_Error::add_error(
3538 3538
                 esc_html__(
3539 3539
                     'Messenger status needed to know whether activation or deactivation is happening. No status is given',
@@ -3745,7 +3745,7 @@  discard block
 block discarded – undo
3745 3745
         EE_Message_Type $message_type = null
3746 3746
     ) {
3747 3747
         // if $messenger isn't a valid messenger object then get out.
3748
-        if (! $messenger instanceof EE_Messenger) {
3748
+        if ( ! $messenger instanceof EE_Messenger) {
3749 3749
             EE_Error::add_error(
3750 3750
                 esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
3751 3751
                 __FILE__,
@@ -3799,7 +3799,7 @@  discard block
 block discarded – undo
3799 3799
             // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
3800 3800
             // in which case we just give a success message for the messenger being successfully activated.
3801 3801
         } else {
3802
-            if (! $messenger->get_default_message_types()) {
3802
+            if ( ! $messenger->get_default_message_types()) {
3803 3803
                 // messenger doesn't have any default message types so still a success.
3804 3804
                 EE_Error::add_success(
3805 3805
                     sprintf(
@@ -3855,7 +3855,7 @@  discard block
 block discarded – undo
3855 3855
         EE_Error::overwrite_success();
3856 3856
 
3857 3857
         // if $messenger isn't a valid messenger object then get out.
3858
-        if (! $messenger instanceof EE_Messenger) {
3858
+        if ( ! $messenger instanceof EE_Messenger) {
3859 3859
             EE_Error::add_error(
3860 3860
                 esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
3861 3861
                 __FILE__,
@@ -3925,7 +3925,7 @@  discard block
 block discarded – undo
3925 3925
      */
3926 3926
     public function update_mt_form()
3927 3927
     {
3928
-        if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
3928
+        if ( ! $this->_active_messenger_name || ! $this->_active_message_type_name) {
3929 3929
             EE_Error::add_error(
3930 3930
                 esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
3931 3931
                 __FILE__,
@@ -3936,7 +3936,7 @@  discard block
 block discarded – undo
3936 3936
         }
3937 3937
 
3938 3938
         $message_types = $this->get_installed_message_types();
3939
-        $message_type  = $message_types[ $this->_active_message_type_name ];
3939
+        $message_type  = $message_types[$this->_active_message_type_name];
3940 3940
         $messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
3941 3941
         $content       = $this->_message_type_settings_content($message_type, $messenger, true);
3942 3942
 
@@ -3955,7 +3955,7 @@  discard block
 block discarded – undo
3955 3955
     public function save_settings()
3956 3956
     {
3957 3957
         $type = $this->request->getRequestParam('type');
3958
-        if (! $type) {
3958
+        if ( ! $type) {
3959 3959
             EE_Error::add_error(
3960 3960
                 esc_html__(
3961 3961
                     'Cannot save settings because type is unknown (messenger settings or message type settings?)',
Please login to merge, or discard this patch.
admin_pages/messages/Messages_Admin_Page_Init.core.php 2 patches
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -12,47 +12,47 @@
 block discarded – undo
12 12
  */
13 13
 class Messages_Admin_Page_Init extends EE_Admin_Page_Init
14 14
 {
15
-    /**
16
-     *constructor
17
-     *
18
-     * @Constructor
19
-     * @access public
20
-     * @return void
21
-     */
22
-    public function __construct()
23
-    {
24
-        if (! defined('EE_MSG_PG_SLUG')) {
25
-            define('EE_MSG_PG_SLUG', 'espresso_messages');
26
-            define('EE_MSG_PG_NAME', ucwords(str_replace('_', '', EE_MSG_PG_SLUG)));
27
-            define('EE_MSG_ADMIN', EE_ADMIN_PAGES . 'messages/');
28
-            define('EE_MSG_ADMIN_URL', admin_url('admin.php?page=' . EE_MSG_PG_SLUG));
29
-            define('EE_MSG_ASSETS_PATH', EE_MSG_ADMIN . 'assets/');
30
-            define('EE_MSG_ASSETS_URL', EE_ADMIN_PAGES_URL . 'messages/assets/');
31
-            define('EE_MSG_TEMPLATE_PATH', EE_MSG_ADMIN . 'templates/');
32
-            define('EE_MSG_TEMPLATE_URL', EE_ADMIN_PAGES_URL . 'messages/templates/');
33
-        }
15
+	/**
16
+	 *constructor
17
+	 *
18
+	 * @Constructor
19
+	 * @access public
20
+	 * @return void
21
+	 */
22
+	public function __construct()
23
+	{
24
+		if (! defined('EE_MSG_PG_SLUG')) {
25
+			define('EE_MSG_PG_SLUG', 'espresso_messages');
26
+			define('EE_MSG_PG_NAME', ucwords(str_replace('_', '', EE_MSG_PG_SLUG)));
27
+			define('EE_MSG_ADMIN', EE_ADMIN_PAGES . 'messages/');
28
+			define('EE_MSG_ADMIN_URL', admin_url('admin.php?page=' . EE_MSG_PG_SLUG));
29
+			define('EE_MSG_ASSETS_PATH', EE_MSG_ADMIN . 'assets/');
30
+			define('EE_MSG_ASSETS_URL', EE_ADMIN_PAGES_URL . 'messages/assets/');
31
+			define('EE_MSG_TEMPLATE_PATH', EE_MSG_ADMIN . 'templates/');
32
+			define('EE_MSG_TEMPLATE_URL', EE_ADMIN_PAGES_URL . 'messages/templates/');
33
+		}
34 34
 
35
-        parent::__construct();
36
-    }
35
+		parent::__construct();
36
+	}
37 37
 
38 38
 
39
-    protected function _set_init_properties()
40
-    {
41
-        $this->label = esc_html__('Messages System', 'event_espresso');
42
-    }
39
+	protected function _set_init_properties()
40
+	{
41
+		$this->label = esc_html__('Messages System', 'event_espresso');
42
+	}
43 43
 
44 44
 
45
-    public function getMenuProperties(): array
46
-    {
47
-        return [
48
-            'menu_type'    => AdminMenuItem::TYPE_MENU_SUB_ITEM,
49
-            'menu_group'   => 'management',
50
-            'menu_order'   => 10,
51
-            'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY,
52
-            'parent_slug'  => 'espresso_events',
53
-            'menu_slug'    => EE_MSG_PG_SLUG,
54
-            'menu_label'   => esc_html__('Messages', 'event_espresso'),
55
-            'capability'   => 'ee_read_global_messages',
56
-        ];
57
-    }
45
+	public function getMenuProperties(): array
46
+	{
47
+		return [
48
+			'menu_type'    => AdminMenuItem::TYPE_MENU_SUB_ITEM,
49
+			'menu_group'   => 'management',
50
+			'menu_order'   => 10,
51
+			'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY,
52
+			'parent_slug'  => 'espresso_events',
53
+			'menu_slug'    => EE_MSG_PG_SLUG,
54
+			'menu_label'   => esc_html__('Messages', 'event_espresso'),
55
+			'capability'   => 'ee_read_global_messages',
56
+		];
57
+	}
58 58
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -21,15 +21,15 @@
 block discarded – undo
21 21
      */
22 22
     public function __construct()
23 23
     {
24
-        if (! defined('EE_MSG_PG_SLUG')) {
24
+        if ( ! defined('EE_MSG_PG_SLUG')) {
25 25
             define('EE_MSG_PG_SLUG', 'espresso_messages');
26 26
             define('EE_MSG_PG_NAME', ucwords(str_replace('_', '', EE_MSG_PG_SLUG)));
27
-            define('EE_MSG_ADMIN', EE_ADMIN_PAGES . 'messages/');
28
-            define('EE_MSG_ADMIN_URL', admin_url('admin.php?page=' . EE_MSG_PG_SLUG));
29
-            define('EE_MSG_ASSETS_PATH', EE_MSG_ADMIN . 'assets/');
30
-            define('EE_MSG_ASSETS_URL', EE_ADMIN_PAGES_URL . 'messages/assets/');
31
-            define('EE_MSG_TEMPLATE_PATH', EE_MSG_ADMIN . 'templates/');
32
-            define('EE_MSG_TEMPLATE_URL', EE_ADMIN_PAGES_URL . 'messages/templates/');
27
+            define('EE_MSG_ADMIN', EE_ADMIN_PAGES.'messages/');
28
+            define('EE_MSG_ADMIN_URL', admin_url('admin.php?page='.EE_MSG_PG_SLUG));
29
+            define('EE_MSG_ASSETS_PATH', EE_MSG_ADMIN.'assets/');
30
+            define('EE_MSG_ASSETS_URL', EE_ADMIN_PAGES_URL.'messages/assets/');
31
+            define('EE_MSG_TEMPLATE_PATH', EE_MSG_ADMIN.'templates/');
32
+            define('EE_MSG_TEMPLATE_URL', EE_ADMIN_PAGES_URL.'messages/templates/');
33 33
         }
34 34
 
35 35
         parent::__construct();
Please login to merge, or discard this patch.
admin_pages/registrations/Registrations_Admin_Page.core.php 2 patches
Indentation   +3662 added lines, -3662 removed lines patch added patch discarded remove patch
@@ -21,2207 +21,2207 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class Registrations_Admin_Page extends EE_Admin_Page_CPT
23 23
 {
24
-    /**
25
-     * @var EE_Registration
26
-     */
27
-    private $_registration;
28
-
29
-    /**
30
-     * @var EE_Event
31
-     */
32
-    private $_reg_event;
33
-
34
-    /**
35
-     * @var EE_Session
36
-     */
37
-    private $_session;
38
-
39
-    /**
40
-     * @var array
41
-     */
42
-    private static $_reg_status;
43
-
44
-    /**
45
-     * Form for displaying the custom questions for this registration.
46
-     * This gets used a few times throughout the request so its best to cache it
47
-     *
48
-     * @var EE_Registration_Custom_Questions_Form
49
-     */
50
-    protected $_reg_custom_questions_form;
51
-
52
-    /**
53
-     * @var EEM_Registration $registration_model
54
-     */
55
-    private $registration_model;
56
-
57
-    /**
58
-     * @var EEM_Attendee $attendee_model
59
-     */
60
-    private $attendee_model;
61
-
62
-    /**
63
-     * @var EEM_Event $event_model
64
-     */
65
-    private $event_model;
66
-
67
-    /**
68
-     * @var EEM_Status $status_model
69
-     */
70
-    private $status_model;
71
-
72
-
73
-    /**
74
-     * @param bool $routing
75
-     * @throws InvalidArgumentException
76
-     * @throws InvalidDataTypeException
77
-     * @throws InvalidInterfaceException
78
-     * @throws ReflectionException
79
-     */
80
-    public function __construct($routing = true)
81
-    {
82
-        parent::__construct($routing);
83
-        $this->cpt_editpost_route = 'edit_attendee';
84
-        add_action('wp_loaded', [$this, 'wp_loaded']);
85
-    }
86
-
87
-
88
-    /**
89
-     * @return EEM_Registration
90
-     * @throws InvalidArgumentException
91
-     * @throws InvalidDataTypeException
92
-     * @throws InvalidInterfaceException
93
-     * @since 4.10.2.p
94
-     */
95
-    protected function getRegistrationModel()
96
-    {
97
-        if (! $this->registration_model instanceof EEM_Registration) {
98
-            $this->registration_model = $this->loader->getShared('EEM_Registration');
99
-        }
100
-        return $this->registration_model;
101
-    }
102
-
103
-
104
-    /**
105
-     * @return EEM_Attendee
106
-     * @throws InvalidArgumentException
107
-     * @throws InvalidDataTypeException
108
-     * @throws InvalidInterfaceException
109
-     * @since 4.10.2.p
110
-     */
111
-    protected function getAttendeeModel()
112
-    {
113
-        if (! $this->attendee_model instanceof EEM_Attendee) {
114
-            $this->attendee_model = $this->loader->getShared('EEM_Attendee');
115
-        }
116
-        return $this->attendee_model;
117
-    }
118
-
119
-
120
-    /**
121
-     * @return EEM_Event
122
-     * @throws InvalidArgumentException
123
-     * @throws InvalidDataTypeException
124
-     * @throws InvalidInterfaceException
125
-     * @since 4.10.2.p
126
-     */
127
-    protected function getEventModel()
128
-    {
129
-        if (! $this->event_model instanceof EEM_Event) {
130
-            $this->event_model = $this->loader->getShared('EEM_Event');
131
-        }
132
-        return $this->event_model;
133
-    }
134
-
135
-
136
-    /**
137
-     * @return EEM_Status
138
-     * @throws InvalidArgumentException
139
-     * @throws InvalidDataTypeException
140
-     * @throws InvalidInterfaceException
141
-     * @since 4.10.2.p
142
-     */
143
-    protected function getStatusModel()
144
-    {
145
-        if (! $this->status_model instanceof EEM_Status) {
146
-            $this->status_model = $this->loader->getShared('EEM_Status');
147
-        }
148
-        return $this->status_model;
149
-    }
150
-
151
-
152
-    public function wp_loaded()
153
-    {
154
-        // when adding a new registration...
155
-        $action = $this->request->getRequestParam('action');
156
-        if ($action === 'new_registration') {
157
-            EE_System::do_not_cache();
158
-            if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
159
-                // and it's NOT the attendee information reg step
160
-                // force cookie expiration by setting time to last week
161
-                setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
162
-                // and update the global
163
-                $_COOKIE['ee_registration_added'] = 0;
164
-            }
165
-        }
166
-    }
167
-
168
-
169
-    protected function _init_page_props()
170
-    {
171
-        $this->page_slug        = REG_PG_SLUG;
172
-        $this->_admin_base_url  = REG_ADMIN_URL;
173
-        $this->_admin_base_path = REG_ADMIN;
174
-        $this->page_label       = esc_html__('Registrations', 'event_espresso');
175
-        $this->_cpt_routes      = [
176
-            'add_new_attendee' => 'espresso_attendees',
177
-            'edit_attendee'    => 'espresso_attendees',
178
-            'insert_attendee'  => 'espresso_attendees',
179
-            'update_attendee'  => 'espresso_attendees',
180
-        ];
181
-        $this->_cpt_model_names = [
182
-            'add_new_attendee' => 'EEM_Attendee',
183
-            'edit_attendee'    => 'EEM_Attendee',
184
-        ];
185
-        $this->_cpt_edit_routes = [
186
-            'espresso_attendees' => 'edit_attendee',
187
-        ];
188
-        $this->_pagenow_map     = [
189
-            'add_new_attendee' => 'post-new.php',
190
-            'edit_attendee'    => 'post.php',
191
-            'trash'            => 'post.php',
192
-        ];
193
-        add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
194
-        // add filters so that the comment urls don't take users to a confusing 404 page
195
-        add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
196
-    }
197
-
198
-
199
-    /**
200
-     * @param string     $link    The comment permalink with '#comment-$id' appended.
201
-     * @param WP_Comment $comment The current comment object.
202
-     * @return string
203
-     */
204
-    public function clear_comment_link($link, WP_Comment $comment)
205
-    {
206
-        // gotta make sure this only happens on this route
207
-        $post_type = get_post_type($comment->comment_post_ID);
208
-        if ($post_type === 'espresso_attendees') {
209
-            return '#commentsdiv';
210
-        }
211
-        return $link;
212
-    }
213
-
214
-
215
-    protected function _ajax_hooks()
216
-    {
217
-        // todo: all hooks for registrations ajax goes in here
218
-        add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
219
-    }
220
-
221
-
222
-    protected function _define_page_props()
223
-    {
224
-        $this->_admin_page_title = $this->page_label;
225
-        $this->_labels           = [
226
-            'buttons'                      => [
227
-                'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
228
-                'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
229
-                'edit'                => esc_html__('Edit Contact', 'event_espresso'),
230
-                'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
231
-                'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
-                'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
-            ],
234
-            'publishbox'                   => [
235
-                'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
-                'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
-            ],
238
-            'hide_add_button_on_cpt_route' => [
239
-                'edit_attendee' => true,
240
-            ],
241
-        ];
242
-    }
243
-
244
-
245
-    /**
246
-     * grab url requests and route them
247
-     *
248
-     * @return void
249
-     * @throws EE_Error
250
-     */
251
-    public function _set_page_routes()
252
-    {
253
-        $this->_get_registration_status_array();
254
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
-        $REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
-        $ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
-        $this->_page_routes = [
259
-            'default'                             => [
260
-                'func'       => [$this, '_registrations_overview_list_table'],
261
-                'capability' => 'ee_read_registrations',
262
-            ],
263
-            'view_registration'                   => [
264
-                'func'       => [$this, '_registration_details'],
265
-                'capability' => 'ee_read_registration',
266
-                'obj_id'     => $REG_ID,
267
-            ],
268
-            'edit_registration'                   => [
269
-                'func'               => '_update_attendee_registration_form',
270
-                'noheader'           => true,
271
-                'headers_sent_route' => 'view_registration',
272
-                'capability'         => 'ee_edit_registration',
273
-                'obj_id'             => $REG_ID,
274
-                '_REG_ID'            => $REG_ID,
275
-            ],
276
-            'trash_registrations'                 => [
277
-                'func'       => '_trash_or_restore_registrations',
278
-                'args'       => ['trash' => true],
279
-                'noheader'   => true,
280
-                'capability' => 'ee_delete_registrations',
281
-            ],
282
-            'restore_registrations'               => [
283
-                'func'       => '_trash_or_restore_registrations',
284
-                'args'       => ['trash' => false],
285
-                'noheader'   => true,
286
-                'capability' => 'ee_delete_registrations',
287
-            ],
288
-            'delete_registrations'                => [
289
-                'func'       => '_delete_registrations',
290
-                'noheader'   => true,
291
-                'capability' => 'ee_delete_registrations',
292
-            ],
293
-            'new_registration'                    => [
294
-                'func'       => 'new_registration',
295
-                'capability' => 'ee_edit_registrations',
296
-            ],
297
-            'process_reg_step'                    => [
298
-                'func'       => 'process_reg_step',
299
-                'noheader'   => true,
300
-                'capability' => 'ee_edit_registrations',
301
-            ],
302
-            'redirect_to_txn'                     => [
303
-                'func'       => 'redirect_to_txn',
304
-                'noheader'   => true,
305
-                'capability' => 'ee_edit_registrations',
306
-            ],
307
-            'change_reg_status'                   => [
308
-                'func'       => '_change_reg_status',
309
-                'noheader'   => true,
310
-                'capability' => 'ee_edit_registration',
311
-                'obj_id'     => $REG_ID,
312
-            ],
313
-            'approve_registration'                => [
314
-                'func'       => 'approve_registration',
315
-                'noheader'   => true,
316
-                'capability' => 'ee_edit_registration',
317
-                'obj_id'     => $REG_ID,
318
-            ],
319
-            'approve_and_notify_registration'     => [
320
-                'func'       => 'approve_registration',
321
-                'noheader'   => true,
322
-                'args'       => [true],
323
-                'capability' => 'ee_edit_registration',
324
-                'obj_id'     => $REG_ID,
325
-            ],
326
-            'approve_registrations'               => [
327
-                'func'       => 'bulk_action_on_registrations',
328
-                'noheader'   => true,
329
-                'capability' => 'ee_edit_registrations',
330
-                'args'       => ['approve'],
331
-            ],
332
-            'approve_and_notify_registrations'    => [
333
-                'func'       => 'bulk_action_on_registrations',
334
-                'noheader'   => true,
335
-                'capability' => 'ee_edit_registrations',
336
-                'args'       => ['approve', true],
337
-            ],
338
-            'decline_registration'                => [
339
-                'func'       => 'decline_registration',
340
-                'noheader'   => true,
341
-                'capability' => 'ee_edit_registration',
342
-                'obj_id'     => $REG_ID,
343
-            ],
344
-            'decline_and_notify_registration'     => [
345
-                'func'       => 'decline_registration',
346
-                'noheader'   => true,
347
-                'args'       => [true],
348
-                'capability' => 'ee_edit_registration',
349
-                'obj_id'     => $REG_ID,
350
-            ],
351
-            'decline_registrations'               => [
352
-                'func'       => 'bulk_action_on_registrations',
353
-                'noheader'   => true,
354
-                'capability' => 'ee_edit_registrations',
355
-                'args'       => ['decline'],
356
-            ],
357
-            'decline_and_notify_registrations'    => [
358
-                'func'       => 'bulk_action_on_registrations',
359
-                'noheader'   => true,
360
-                'capability' => 'ee_edit_registrations',
361
-                'args'       => ['decline', true],
362
-            ],
363
-            'pending_registration'                => [
364
-                'func'       => 'pending_registration',
365
-                'noheader'   => true,
366
-                'capability' => 'ee_edit_registration',
367
-                'obj_id'     => $REG_ID,
368
-            ],
369
-            'pending_and_notify_registration'     => [
370
-                'func'       => 'pending_registration',
371
-                'noheader'   => true,
372
-                'args'       => [true],
373
-                'capability' => 'ee_edit_registration',
374
-                'obj_id'     => $REG_ID,
375
-            ],
376
-            'pending_registrations'               => [
377
-                'func'       => 'bulk_action_on_registrations',
378
-                'noheader'   => true,
379
-                'capability' => 'ee_edit_registrations',
380
-                'args'       => ['pending'],
381
-            ],
382
-            'pending_and_notify_registrations'    => [
383
-                'func'       => 'bulk_action_on_registrations',
384
-                'noheader'   => true,
385
-                'capability' => 'ee_edit_registrations',
386
-                'args'       => ['pending', true],
387
-            ],
388
-            'no_approve_registration'             => [
389
-                'func'       => 'not_approve_registration',
390
-                'noheader'   => true,
391
-                'capability' => 'ee_edit_registration',
392
-                'obj_id'     => $REG_ID,
393
-            ],
394
-            'no_approve_and_notify_registration'  => [
395
-                'func'       => 'not_approve_registration',
396
-                'noheader'   => true,
397
-                'args'       => [true],
398
-                'capability' => 'ee_edit_registration',
399
-                'obj_id'     => $REG_ID,
400
-            ],
401
-            'no_approve_registrations'            => [
402
-                'func'       => 'bulk_action_on_registrations',
403
-                'noheader'   => true,
404
-                'capability' => 'ee_edit_registrations',
405
-                'args'       => ['not_approve'],
406
-            ],
407
-            'no_approve_and_notify_registrations' => [
408
-                'func'       => 'bulk_action_on_registrations',
409
-                'noheader'   => true,
410
-                'capability' => 'ee_edit_registrations',
411
-                'args'       => ['not_approve', true],
412
-            ],
413
-            'cancel_registration'                 => [
414
-                'func'       => 'cancel_registration',
415
-                'noheader'   => true,
416
-                'capability' => 'ee_edit_registration',
417
-                'obj_id'     => $REG_ID,
418
-            ],
419
-            'cancel_and_notify_registration'      => [
420
-                'func'       => 'cancel_registration',
421
-                'noheader'   => true,
422
-                'args'       => [true],
423
-                'capability' => 'ee_edit_registration',
424
-                'obj_id'     => $REG_ID,
425
-            ],
426
-            'cancel_registrations'                => [
427
-                'func'       => 'bulk_action_on_registrations',
428
-                'noheader'   => true,
429
-                'capability' => 'ee_edit_registrations',
430
-                'args'       => ['cancel'],
431
-            ],
432
-            'cancel_and_notify_registrations'     => [
433
-                'func'       => 'bulk_action_on_registrations',
434
-                'noheader'   => true,
435
-                'capability' => 'ee_edit_registrations',
436
-                'args'       => ['cancel', true],
437
-            ],
438
-            'wait_list_registration'              => [
439
-                'func'       => 'wait_list_registration',
440
-                'noheader'   => true,
441
-                'capability' => 'ee_edit_registration',
442
-                'obj_id'     => $REG_ID,
443
-            ],
444
-            'wait_list_and_notify_registration'   => [
445
-                'func'       => 'wait_list_registration',
446
-                'noheader'   => true,
447
-                'args'       => [true],
448
-                'capability' => 'ee_edit_registration',
449
-                'obj_id'     => $REG_ID,
450
-            ],
451
-            'contact_list'                        => [
452
-                'func'       => '_attendee_contact_list_table',
453
-                'capability' => 'ee_read_contacts',
454
-            ],
455
-            'add_new_attendee'                    => [
456
-                'func' => '_create_new_cpt_item',
457
-                'args' => [
458
-                    'new_attendee' => true,
459
-                    'capability'   => 'ee_edit_contacts',
460
-                ],
461
-            ],
462
-            'edit_attendee'                       => [
463
-                'func'       => '_edit_cpt_item',
464
-                'capability' => 'ee_edit_contacts',
465
-                'obj_id'     => $ATT_ID,
466
-            ],
467
-            'duplicate_attendee'                  => [
468
-                'func'       => '_duplicate_attendee',
469
-                'noheader'   => true,
470
-                'capability' => 'ee_edit_contacts',
471
-                'obj_id'     => $ATT_ID,
472
-            ],
473
-            'insert_attendee'                     => [
474
-                'func'       => '_insert_or_update_attendee',
475
-                'args'       => [
476
-                    'new_attendee' => true,
477
-                ],
478
-                'noheader'   => true,
479
-                'capability' => 'ee_edit_contacts',
480
-            ],
481
-            'update_attendee'                     => [
482
-                'func'       => '_insert_or_update_attendee',
483
-                'args'       => [
484
-                    'new_attendee' => false,
485
-                ],
486
-                'noheader'   => true,
487
-                'capability' => 'ee_edit_contacts',
488
-                'obj_id'     => $ATT_ID,
489
-            ],
490
-            'trash_attendees'                     => [
491
-                'func'       => '_trash_or_restore_attendees',
492
-                'args'       => [
493
-                    'trash' => 'true',
494
-                ],
495
-                'noheader'   => true,
496
-                'capability' => 'ee_delete_contacts',
497
-            ],
498
-            'trash_attendee'                      => [
499
-                'func'       => '_trash_or_restore_attendees',
500
-                'args'       => [
501
-                    'trash' => true,
502
-                ],
503
-                'noheader'   => true,
504
-                'capability' => 'ee_delete_contacts',
505
-                'obj_id'     => $ATT_ID,
506
-            ],
507
-            'restore_attendees'                   => [
508
-                'func'       => '_trash_or_restore_attendees',
509
-                'args'       => [
510
-                    'trash' => false,
511
-                ],
512
-                'noheader'   => true,
513
-                'capability' => 'ee_delete_contacts',
514
-                'obj_id'     => $ATT_ID,
515
-            ],
516
-            'resend_registration'                 => [
517
-                'func'       => '_resend_registration',
518
-                'noheader'   => true,
519
-                'capability' => 'ee_send_message',
520
-            ],
521
-            'registrations_report'                => [
522
-                'func'       => [$this, '_registrations_report'],
523
-                'noheader'   => true,
524
-                'capability' => 'ee_read_registrations',
525
-            ],
526
-            'contact_list_export'                 => [
527
-                'func'       => '_contact_list_export',
528
-                'noheader'   => true,
529
-                'capability' => 'export',
530
-            ],
531
-            'contact_list_report'                 => [
532
-                'func'       => '_contact_list_report',
533
-                'noheader'   => true,
534
-                'capability' => 'ee_read_contacts',
535
-            ],
536
-        ];
537
-    }
538
-
539
-
540
-    protected function _set_page_config()
541
-    {
542
-        $REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
-        $ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
-        $this->_page_config = [
545
-            'default'           => [
546
-                'nav'           => [
547
-                    'label' => esc_html__('Overview', 'event_espresso'),
548
-                    'icon'  => 'dashicons-list-view',
549
-                    'order' => 5,
550
-                ],
551
-                'help_tabs'     => [
552
-                    'registrations_overview_help_tab'                       => [
553
-                        'title'    => esc_html__('Registrations Overview', 'event_espresso'),
554
-                        'filename' => 'registrations_overview',
555
-                    ],
556
-                    'registrations_overview_table_column_headings_help_tab' => [
557
-                        'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
558
-                        'filename' => 'registrations_overview_table_column_headings',
559
-                    ],
560
-                    'registrations_overview_filters_help_tab'               => [
561
-                        'title'    => esc_html__('Registration Filters', 'event_espresso'),
562
-                        'filename' => 'registrations_overview_filters',
563
-                    ],
564
-                    'registrations_overview_views_help_tab'                 => [
565
-                        'title'    => esc_html__('Registration Views', 'event_espresso'),
566
-                        'filename' => 'registrations_overview_views',
567
-                    ],
568
-                    'registrations_regoverview_other_help_tab'              => [
569
-                        'title'    => esc_html__('Registrations Other', 'event_espresso'),
570
-                        'filename' => 'registrations_overview_other',
571
-                    ],
572
-                ],
573
-                'list_table'    => 'EE_Registrations_List_Table',
574
-                'require_nonce' => false,
575
-            ],
576
-            'view_registration' => [
577
-                'nav'           => [
578
-                    'label'      => esc_html__('REG Details', 'event_espresso'),
579
-                    'icon'       => 'dashicons-clipboard',
580
-                    'order'      => 15,
581
-                    'url'        => $REG_ID
582
-                        ? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
583
-                        : $this->_admin_base_url,
584
-                    'persistent' => false,
585
-                ],
586
-                'help_tabs'     => [
587
-                    'registrations_details_help_tab'                    => [
588
-                        'title'    => esc_html__('Registration Details', 'event_espresso'),
589
-                        'filename' => 'registrations_details',
590
-                    ],
591
-                    'registrations_details_table_help_tab'              => [
592
-                        'title'    => esc_html__('Registration Details Table', 'event_espresso'),
593
-                        'filename' => 'registrations_details_table',
594
-                    ],
595
-                    'registrations_details_form_answers_help_tab'       => [
596
-                        'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
597
-                        'filename' => 'registrations_details_form_answers',
598
-                    ],
599
-                    'registrations_details_registrant_details_help_tab' => [
600
-                        'title'    => esc_html__('Contact Details', 'event_espresso'),
601
-                        'filename' => 'registrations_details_registrant_details',
602
-                    ],
603
-                ],
604
-                'metaboxes'     => array_merge(
605
-                    $this->_default_espresso_metaboxes,
606
-                    ['_registration_details_metaboxes']
607
-                ),
608
-                'require_nonce' => false,
609
-            ],
610
-            'new_registration'  => [
611
-                'nav'           => [
612
-                    'label'      => esc_html__('Add New Registration', 'event_espresso'),
613
-                    'icon'       => 'dashicons-plus-alt',
614
-                    'url'        => '#',
615
-                    'order'      => 15,
616
-                    'persistent' => false,
617
-                ],
618
-                'metaboxes'     => $this->_default_espresso_metaboxes,
619
-                'labels'        => [
620
-                    'publishbox' => esc_html__('Save Registration', 'event_espresso'),
621
-                ],
622
-                'require_nonce' => false,
623
-            ],
624
-            'add_new_attendee'  => [
625
-                'nav'           => [
626
-                    'label'      => esc_html__('Add Contact', 'event_espresso'),
627
-                    'icon'       => 'dashicons-plus-alt',
628
-                    'order'      => 15,
629
-                    'persistent' => false,
630
-                ],
631
-                'metaboxes'     => array_merge(
632
-                    $this->_default_espresso_metaboxes,
633
-                    ['_publish_post_box', 'attendee_editor_metaboxes']
634
-                ),
635
-                'require_nonce' => false,
636
-            ],
637
-            'edit_attendee'     => [
638
-                'nav'           => [
639
-                    'label'      => esc_html__('Edit Contact', 'event_espresso'),
640
-                    'icon'       => 'dashicons-edit-large',
641
-                    'order'      => 15,
642
-                    'persistent' => false,
643
-                    'url'        => $ATT_ID
644
-                        ? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
-                        : $this->_admin_base_url,
646
-                ],
647
-                'metaboxes'     => array_merge(
648
-                    $this->_default_espresso_metaboxes,
649
-                    ['attendee_editor_metaboxes']
650
-                ),
651
-                'require_nonce' => false,
652
-            ],
653
-            'contact_list'      => [
654
-                'nav'           => [
655
-                    'label' => esc_html__('Contact List', 'event_espresso'),
656
-                    'icon'  => 'dashicons-id-alt',
657
-                    'order' => 20,
658
-                ],
659
-                'list_table'    => 'EE_Attendee_Contact_List_Table',
660
-                'help_tabs'     => [
661
-                    'registrations_contact_list_help_tab'                       => [
662
-                        'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
663
-                        'filename' => 'registrations_contact_list',
664
-                    ],
665
-                    'registrations_contact-list_table_column_headings_help_tab' => [
666
-                        'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
667
-                        'filename' => 'registrations_contact_list_table_column_headings',
668
-                    ],
669
-                    'registrations_contact_list_views_help_tab'                 => [
670
-                        'title'    => esc_html__('Contact List Views', 'event_espresso'),
671
-                        'filename' => 'registrations_contact_list_views',
672
-                    ],
673
-                    'registrations_contact_list_other_help_tab'                 => [
674
-                        'title'    => esc_html__('Contact List Other', 'event_espresso'),
675
-                        'filename' => 'registrations_contact_list_other',
676
-                    ],
677
-                ],
678
-                'metaboxes'     => [],
679
-                'require_nonce' => false,
680
-            ],
681
-            // override default cpt routes
682
-            'create_new'        => '',
683
-            'edit'              => '',
684
-        ];
685
-    }
686
-
687
-
688
-    /**
689
-     * The below methods aren't used by this class currently
690
-     */
691
-    protected function _add_screen_options()
692
-    {
693
-    }
694
-
695
-
696
-    protected function _add_feature_pointers()
697
-    {
698
-    }
699
-
700
-
701
-    public function admin_init()
702
-    {
703
-        EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
704
-            'click "Update Registration Questions" to save your changes',
705
-            'event_espresso'
706
-        );
707
-    }
708
-
709
-
710
-    public function admin_notices()
711
-    {
712
-    }
713
-
714
-
715
-    public function admin_footer_scripts()
716
-    {
717
-    }
718
-
719
-
720
-    /**
721
-     * get list of registration statuses
722
-     *
723
-     * @return void
724
-     * @throws EE_Error
725
-     */
726
-    private function _get_registration_status_array()
727
-    {
728
-        self::$_reg_status = EEM_Registration::reg_status_array([], true);
729
-    }
730
-
731
-
732
-    /**
733
-     * @throws InvalidArgumentException
734
-     * @throws InvalidDataTypeException
735
-     * @throws InvalidInterfaceException
736
-     * @since 4.10.2.p
737
-     */
738
-    protected function _add_screen_options_default()
739
-    {
740
-        $this->_per_page_screen_option();
741
-    }
742
-
743
-
744
-    /**
745
-     * @throws InvalidArgumentException
746
-     * @throws InvalidDataTypeException
747
-     * @throws InvalidInterfaceException
748
-     * @since 4.10.2.p
749
-     */
750
-    protected function _add_screen_options_contact_list()
751
-    {
752
-        $page_title              = $this->_admin_page_title;
753
-        $this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
754
-        $this->_per_page_screen_option();
755
-        $this->_admin_page_title = $page_title;
756
-    }
757
-
758
-
759
-    public function load_scripts_styles()
760
-    {
761
-        // style
762
-        wp_register_style(
763
-            'espresso_reg',
764
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
765
-            ['ee-admin-css'],
766
-            EVENT_ESPRESSO_VERSION
767
-        );
768
-        wp_enqueue_style('espresso_reg');
769
-        // script
770
-        wp_register_script(
771
-            'espresso_reg',
772
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
773
-            ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774
-            EVENT_ESPRESSO_VERSION,
775
-            true
776
-        );
777
-        wp_enqueue_script('espresso_reg');
778
-    }
779
-
780
-
781
-    /**
782
-     * @throws EE_Error
783
-     * @throws InvalidArgumentException
784
-     * @throws InvalidDataTypeException
785
-     * @throws InvalidInterfaceException
786
-     * @throws ReflectionException
787
-     * @since 4.10.2.p
788
-     */
789
-    public function load_scripts_styles_edit_attendee()
790
-    {
791
-        // stuff to only show up on our attendee edit details page.
792
-        $attendee_details_translations = [
793
-            'att_publish_text' => sprintf(
794
-            /* translators: The date and time */
795
-                wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
797
-            ),
798
-        ];
799
-        wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
800
-        wp_enqueue_script('jquery-validate');
801
-    }
802
-
803
-
804
-    /**
805
-     * @throws EE_Error
806
-     * @throws InvalidArgumentException
807
-     * @throws InvalidDataTypeException
808
-     * @throws InvalidInterfaceException
809
-     * @throws ReflectionException
810
-     * @since 4.10.2.p
811
-     */
812
-    public function load_scripts_styles_view_registration()
813
-    {
814
-        $this->_set_registration_object();
815
-        // styles
816
-        wp_enqueue_style('espresso-ui-theme');
817
-        // scripts
818
-        $this->_get_reg_custom_questions_form($this->_registration->ID());
819
-        $this->_reg_custom_questions_form->wp_enqueue_scripts();
820
-    }
821
-
822
-
823
-    public function load_scripts_styles_contact_list()
824
-    {
825
-        wp_dequeue_style('espresso_reg');
826
-        wp_register_style(
827
-            'espresso_att',
828
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
829
-            ['ee-admin-css'],
830
-            EVENT_ESPRESSO_VERSION
831
-        );
832
-        wp_enqueue_style('espresso_att');
833
-    }
834
-
835
-
836
-    public function load_scripts_styles_new_registration()
837
-    {
838
-        wp_register_script(
839
-            'ee-spco-for-admin',
840
-            REG_ASSETS_URL . 'spco_for_admin.js',
841
-            ['underscore', 'jquery'],
842
-            EVENT_ESPRESSO_VERSION,
843
-            true
844
-        );
845
-        wp_enqueue_script('ee-spco-for-admin');
846
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
847
-        EE_Form_Section_Proper::wp_enqueue_scripts();
848
-        EED_Ticket_Selector::load_tckt_slctr_assets();
849
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
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 Not Approved',
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 Not Approved 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
-        $this->_views = [
942
-            'all'   => [
943
-                'slug'        => 'all',
944
-                'label'       => esc_html__('View All Registrations', 'event_espresso'),
945
-                'count'       => 0,
946
-                'bulk_action' => array_merge(
947
-                    $def_reg_status_actions,
948
-                    [
949
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
-                    ]
951
-                ),
952
-            ],
953
-            'month' => [
954
-                'slug'        => 'month',
955
-                'label'       => esc_html__('This Month', 'event_espresso'),
956
-                'count'       => 0,
957
-                'bulk_action' => array_merge(
958
-                    $def_reg_status_actions,
959
-                    [
960
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
961
-                    ]
962
-                ),
963
-            ],
964
-            'today' => [
965
-                'slug'        => 'today',
966
-                'label'       => sprintf(
967
-                    esc_html__('Today - %s', 'event_espresso'),
968
-                    date('M d, Y', current_time('timestamp'))
969
-                ),
970
-                'count'       => 0,
971
-                'bulk_action' => array_merge(
972
-                    $def_reg_status_actions,
973
-                    [
974
-                        'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
975
-                    ]
976
-                ),
977
-            ],
978
-        ];
979
-        if (
980
-            $this->capabilities->current_user_can(
981
-                'ee_delete_registrations',
982
-                'espresso_registrations_delete_registration'
983
-            )
984
-        ) {
985
-            $this->_views['incomplete'] = [
986
-                'slug'        => 'incomplete',
987
-                'label'       => esc_html__('Incomplete', 'event_espresso'),
988
-                'count'       => 0,
989
-                'bulk_action' => [
990
-                    'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
991
-                ],
992
-            ];
993
-            $this->_views['trash']      = [
994
-                'slug'        => 'trash',
995
-                'label'       => esc_html__('Trash', 'event_espresso'),
996
-                'count'       => 0,
997
-                'bulk_action' => [
998
-                    'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
999
-                    'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
1000
-                ],
1001
-            ];
1002
-        }
1003
-    }
1004
-
1005
-
1006
-    protected function _set_list_table_views_contact_list()
1007
-    {
1008
-        $this->_views = [
1009
-            'in_use' => [
1010
-                'slug'        => 'in_use',
1011
-                'label'       => esc_html__('In Use', 'event_espresso'),
1012
-                'count'       => 0,
1013
-                'bulk_action' => [
1014
-                    'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1015
-                ],
1016
-            ],
1017
-        ];
1018
-        if (
1019
-            $this->capabilities->current_user_can(
1020
-                'ee_delete_contacts',
1021
-                'espresso_registrations_trash_attendees'
1022
-            )
1023
-        ) {
1024
-            $this->_views['trash'] = [
1025
-                'slug'        => 'trash',
1026
-                'label'       => esc_html__('Trash', 'event_espresso'),
1027
-                'count'       => 0,
1028
-                'bulk_action' => [
1029
-                    'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1030
-                ],
1031
-            ];
1032
-        }
1033
-    }
1034
-
1035
-
1036
-    /**
1037
-     * @return array
1038
-     * @throws EE_Error
1039
-     */
1040
-    protected function _registration_legend_items()
1041
-    {
1042
-        $fc_items = [
1043
-            'star-icon'        => [
1044
-                'class' => 'dashicons dashicons-star-filled gold-icon',
1045
-                'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1046
-            ],
1047
-            'view_details'     => [
1048
-                'class' => 'dashicons dashicons-clipboard',
1049
-                'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1050
-            ],
1051
-            'edit_attendee'    => [
1052
-                'class' => 'dashicons dashicons-admin-users',
1053
-                'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1054
-            ],
1055
-            'view_transaction' => [
1056
-                'class' => 'dashicons dashicons-cart',
1057
-                'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1058
-            ],
1059
-            'view_invoice'     => [
1060
-                'class' => 'dashicons dashicons-media-spreadsheet',
1061
-                'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1062
-            ],
1063
-        ];
1064
-        if (
1065
-            $this->capabilities->current_user_can(
1066
-                'ee_send_message',
1067
-                'espresso_registrations_resend_registration'
1068
-            )
1069
-        ) {
1070
-            $fc_items['resend_registration'] = [
1071
-                'class' => 'dashicons dashicons-email-alt',
1072
-                'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1073
-            ];
1074
-        } else {
1075
-            $fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1076
-        }
1077
-        if (
1078
-            $this->capabilities->current_user_can(
1079
-                'ee_read_global_messages',
1080
-                'view_filtered_messages'
1081
-            )
1082
-        ) {
1083
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1084
-            if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1085
-                $fc_items['view_related_messages'] = [
1086
-                    'class' => $related_for_icon['css_class'],
1087
-                    'desc'  => $related_for_icon['label'],
1088
-                ];
1089
-            }
1090
-        }
1091
-        $sc_items = [
1092
-            'approved_status'   => [
1093
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1094
-                'desc'  => EEH_Template::pretty_status(
1095
-                    EEM_Registration::status_id_approved,
1096
-                    false,
1097
-                    'sentence'
1098
-                ),
1099
-            ],
1100
-            'pending_status'    => [
1101
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1102
-                'desc'  => EEH_Template::pretty_status(
1103
-                    EEM_Registration::status_id_pending_payment,
1104
-                    false,
1105
-                    'sentence'
1106
-                ),
1107
-            ],
1108
-            'wait_list'         => [
1109
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1110
-                'desc'  => EEH_Template::pretty_status(
1111
-                    EEM_Registration::status_id_wait_list,
1112
-                    false,
1113
-                    'sentence'
1114
-                ),
1115
-            ],
1116
-            'incomplete_status' => [
1117
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1118
-                'desc'  => EEH_Template::pretty_status(
1119
-                    EEM_Registration::status_id_incomplete,
1120
-                    false,
1121
-                    'sentence'
1122
-                ),
1123
-            ],
1124
-            'not_approved'      => [
1125
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1126
-                'desc'  => EEH_Template::pretty_status(
1127
-                    EEM_Registration::status_id_not_approved,
1128
-                    false,
1129
-                    'sentence'
1130
-                ),
1131
-            ],
1132
-            'declined_status'   => [
1133
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1134
-                'desc'  => EEH_Template::pretty_status(
1135
-                    EEM_Registration::status_id_declined,
1136
-                    false,
1137
-                    'sentence'
1138
-                ),
1139
-            ],
1140
-            'cancelled_status'  => [
1141
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1142
-                'desc'  => EEH_Template::pretty_status(
1143
-                    EEM_Registration::status_id_cancelled,
1144
-                    false,
1145
-                    'sentence'
1146
-                ),
1147
-            ],
1148
-        ];
1149
-        return array_merge($fc_items, $sc_items);
1150
-    }
1151
-
1152
-
1153
-
1154
-    /***************************************        REGISTRATION OVERVIEW        **************************************/
1155
-
1156
-
1157
-    /**
1158
-     * @throws DomainException
1159
-     * @throws EE_Error
1160
-     * @throws InvalidArgumentException
1161
-     * @throws InvalidDataTypeException
1162
-     * @throws InvalidInterfaceException
1163
-     */
1164
-    protected function _registrations_overview_list_table()
1165
-    {
1166
-        $this->appendAddNewRegistrationButtonToPageTitle();
1167
-        $header_text                  = '';
1168
-        $admin_page_header_decorators = [
1169
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1170
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1171
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1172
-            'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1173
-        ];
1174
-        foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1175
-            $filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1176
-            $header_text             = $filter_header_decorator->getHeaderText($header_text);
1177
-        }
1178
-        $this->_template_args['before_list_table'] = $header_text;
1179
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1180
-        $this->display_admin_list_table_page_with_no_sidebar();
1181
-    }
1182
-
1183
-
1184
-    /**
1185
-     * @throws EE_Error
1186
-     * @throws InvalidArgumentException
1187
-     * @throws InvalidDataTypeException
1188
-     * @throws InvalidInterfaceException
1189
-     */
1190
-    private function appendAddNewRegistrationButtonToPageTitle()
1191
-    {
1192
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1193
-        if (
1194
-            $EVT_ID
1195
-            && $this->capabilities->current_user_can(
1196
-                'ee_edit_registrations',
1197
-                'espresso_registrations_new_registration',
1198
-                $EVT_ID
1199
-            )
1200
-        ) {
1201
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1202
-                    'new_registration',
1203
-                    'add-registrant',
1204
-                    ['event_id' => $EVT_ID],
1205
-                    'add-new-h2'
1206
-                );
1207
-        }
1208
-    }
1209
-
1210
-
1211
-    /**
1212
-     * This sets the _registration property for the registration details screen
1213
-     *
1214
-     * @return void
1215
-     * @throws EE_Error
1216
-     * @throws InvalidArgumentException
1217
-     * @throws InvalidDataTypeException
1218
-     * @throws InvalidInterfaceException
1219
-     */
1220
-    private function _set_registration_object()
1221
-    {
1222
-        // get out if we've already set the object
1223
-        if ($this->_registration instanceof EE_Registration) {
1224
-            return;
1225
-        }
1226
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1227
-        if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1228
-            return;
1229
-        }
1230
-        $error_msg = sprintf(
1231
-            esc_html__(
1232
-                'An error occurred and the details for Registration ID #%s could not be retrieved.',
1233
-                'event_espresso'
1234
-            ),
1235
-            $REG_ID
1236
-        );
1237
-        EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1238
-        $this->_registration = null;
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * Used to retrieve registrations for the list table.
1244
-     *
1245
-     * @param int  $per_page
1246
-     * @param bool $count
1247
-     * @param bool $this_month
1248
-     * @param bool $today
1249
-     * @return EE_Registration[]|int
1250
-     * @throws EE_Error
1251
-     * @throws InvalidArgumentException
1252
-     * @throws InvalidDataTypeException
1253
-     * @throws InvalidInterfaceException
1254
-     */
1255
-    public function get_registrations(
1256
-        $per_page = 10,
1257
-        $count = false,
1258
-        $this_month = false,
1259
-        $today = false
1260
-    ) {
1261
-        if ($this_month) {
1262
-            $this->request->setRequestParam('status', 'month');
1263
-        }
1264
-        if ($today) {
1265
-            $this->request->setRequestParam('status', 'today');
1266
-        }
1267
-        $query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1268
-        /**
1269
-         * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1270
-         *
1271
-         * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1272
-         * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1273
-         *                      or if you have the development copy of EE you can view this at the path:
1274
-         *                      /docs/G--Model-System/model-query-params.md
1275
-         */
1276
-        $query_params['group_by'] = '';
1277
-
1278
-        return $count
1279
-            ? $this->getRegistrationModel()->count($query_params)
1280
-            /** @type EE_Registration[] */
1281
-            : $this->getRegistrationModel()->get_all($query_params);
1282
-    }
1283
-
1284
-
1285
-    /**
1286
-     * Retrieves the query parameters to be used by the Registration model for getting registrations.
1287
-     * Note: this listens to values on the request for some query parameters.
1288
-     *
1289
-     * @param array $request
1290
-     * @param int   $per_page
1291
-     * @param bool  $count
1292
-     * @return array
1293
-     * @throws EE_Error
1294
-     * @throws InvalidArgumentException
1295
-     * @throws InvalidDataTypeException
1296
-     * @throws InvalidInterfaceException
1297
-     */
1298
-    protected function _get_registration_query_parameters(
1299
-        array $request = [],
1300
-        int $per_page = 10,
1301
-        bool $count = false
1302
-    ): array {
1303
-        /** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1304
-        $list_table_query_builder = $this->loader->getNew(
1305
-            'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1306
-            [null, null, $request]
1307
-        );
1308
-        return $list_table_query_builder->getQueryParams($per_page, $count);
1309
-    }
1310
-
1311
-
1312
-    public function get_registration_status_array(): array
1313
-    {
1314
-        return self::$_reg_status;
1315
-    }
1316
-
1317
-
1318
-
1319
-
1320
-    /***************************************        REGISTRATION DETAILS        ***************************************/
1321
-    /**
1322
-     * generates HTML for the View Registration Details Admin page
1323
-     *
1324
-     * @return void
1325
-     * @throws DomainException
1326
-     * @throws EE_Error
1327
-     * @throws InvalidArgumentException
1328
-     * @throws InvalidDataTypeException
1329
-     * @throws InvalidInterfaceException
1330
-     * @throws EntityNotFoundException
1331
-     * @throws ReflectionException
1332
-     */
1333
-    protected function _registration_details()
1334
-    {
1335
-        $this->_template_args = [];
1336
-        $this->_set_registration_object();
1337
-        if (is_object($this->_registration)) {
1338
-            $transaction                                   = $this->_registration->transaction()
1339
-                ? $this->_registration->transaction()
1340
-                : EE_Transaction::new_instance();
1341
-            $this->_session                                = $transaction->session_data();
1342
-            $event_id                                      = $this->_registration->event_ID();
1343
-            $this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1344
-            $this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1345
-            $this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1346
-            $this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1347
-            $this->_template_args['grand_total']           = $transaction->total();
1348
-            $this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1349
-            // link back to overview
1350
-            $this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1351
-            $this->_template_args['registration']                = $this->_registration;
1352
-            $this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1353
-                [
1354
-                    'action'   => 'default',
1355
-                    'event_id' => $event_id,
1356
-                ],
1357
-                REG_ADMIN_URL
1358
-            );
1359
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1360
-                [
1361
-                    'action' => 'default',
1362
-                    'EVT_ID' => $event_id,
1363
-                    'page'   => 'espresso_transactions',
1364
-                ],
1365
-                admin_url('admin.php')
1366
-            );
1367
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1368
-                [
1369
-                    'page'   => 'espresso_events',
1370
-                    'action' => 'edit',
1371
-                    'post'   => $event_id,
1372
-                ],
1373
-                admin_url('admin.php')
1374
-            );
1375
-            // next and previous links
1376
-            $next_reg                                      = $this->_registration->next(
1377
-                null,
1378
-                [],
1379
-                'REG_ID'
1380
-            );
1381
-            $this->_template_args['next_registration']     = $next_reg
1382
-                ? $this->_next_link(
1383
-                    EE_Admin_Page::add_query_args_and_nonce(
1384
-                        [
1385
-                            'action'  => 'view_registration',
1386
-                            '_REG_ID' => $next_reg['REG_ID'],
1387
-                        ],
1388
-                        REG_ADMIN_URL
1389
-                    ),
1390
-                    'dashicons dashicons-arrow-right ee-icon-size-22'
1391
-                )
1392
-                : '';
1393
-            $previous_reg                                  = $this->_registration->previous(
1394
-                null,
1395
-                [],
1396
-                'REG_ID'
1397
-            );
1398
-            $this->_template_args['previous_registration'] = $previous_reg
1399
-                ? $this->_previous_link(
1400
-                    EE_Admin_Page::add_query_args_and_nonce(
1401
-                        [
1402
-                            'action'  => 'view_registration',
1403
-                            '_REG_ID' => $previous_reg['REG_ID'],
1404
-                        ],
1405
-                        REG_ADMIN_URL
1406
-                    ),
1407
-                    'dashicons dashicons-arrow-left ee-icon-size-22'
1408
-                )
1409
-                : '';
1410
-            // grab header
1411
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1412
-            $this->_template_args['REG_ID']            = $this->_registration->ID();
1413
-            $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1414
-                $template_path,
1415
-                $this->_template_args,
1416
-                true
1417
-            );
1418
-        } else {
1419
-            $this->_template_args['admin_page_header'] = '';
1420
-            $this->_display_espresso_notices();
1421
-        }
1422
-        // the details template wrapper
1423
-        $this->display_admin_page_with_sidebar();
1424
-    }
1425
-
1426
-
1427
-    /**
1428
-     * @throws EE_Error
1429
-     * @throws InvalidArgumentException
1430
-     * @throws InvalidDataTypeException
1431
-     * @throws InvalidInterfaceException
1432
-     * @throws ReflectionException
1433
-     * @since 4.10.2.p
1434
-     */
1435
-    protected function _registration_details_metaboxes()
1436
-    {
1437
-        do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1438
-        $this->_set_registration_object();
1439
-        $attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1440
-        $this->addMetaBox(
1441
-            'edit-reg-status-mbox',
1442
-            esc_html__('Registration Status', 'event_espresso'),
1443
-            [$this, 'set_reg_status_buttons_metabox'],
1444
-            $this->_wp_page_slug
1445
-        );
1446
-        $this->addMetaBox(
1447
-            'edit-reg-details-mbox',
1448
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1449
-            . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1450
-            [$this, '_reg_details_meta_box'],
1451
-            $this->_wp_page_slug
1452
-        );
1453
-        if (
1454
-            $attendee instanceof EE_Attendee
1455
-            && $this->capabilities->current_user_can(
1456
-                'ee_read_registration',
1457
-                'edit-reg-questions-mbox',
1458
-                $this->_registration->ID()
1459
-            )
1460
-        ) {
1461
-            $this->addMetaBox(
1462
-                'edit-reg-questions-mbox',
1463
-                esc_html__('Registration Form Answers', 'event_espresso'),
1464
-                [$this, '_reg_questions_meta_box'],
1465
-                $this->_wp_page_slug
1466
-            );
1467
-        }
1468
-        $this->addMetaBox(
1469
-            'edit-reg-registrant-mbox',
1470
-            esc_html__('Contact Details', 'event_espresso'),
1471
-            [$this, '_reg_registrant_side_meta_box'],
1472
-            $this->_wp_page_slug,
1473
-            'side'
1474
-        );
1475
-        if ($this->_registration->group_size() > 1) {
1476
-            $this->addMetaBox(
1477
-                'edit-reg-attendees-mbox',
1478
-                esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1479
-                [$this, '_reg_attendees_meta_box'],
1480
-                $this->_wp_page_slug
1481
-            );
1482
-        }
1483
-    }
1484
-
1485
-
1486
-    /**
1487
-     * set_reg_status_buttons_metabox
1488
-     *
1489
-     * @return void
1490
-     * @throws EE_Error
1491
-     * @throws EntityNotFoundException
1492
-     * @throws InvalidArgumentException
1493
-     * @throws InvalidDataTypeException
1494
-     * @throws InvalidInterfaceException
1495
-     * @throws ReflectionException
1496
-     */
1497
-    public function set_reg_status_buttons_metabox()
1498
-    {
1499
-        $this->_set_registration_object();
1500
-        $change_reg_status_form = $this->_generate_reg_status_change_form();
1501
-        $output                 = $change_reg_status_form->form_open(
1502
-            self::add_query_args_and_nonce(
1503
-                [
1504
-                    'action' => 'change_reg_status',
1505
-                ],
1506
-                REG_ADMIN_URL
1507
-            )
1508
-        );
1509
-        $output                 .= $change_reg_status_form->get_html();
1510
-        $output                 .= $change_reg_status_form->form_close();
1511
-        echo wp_kses($output, AllowedTags::getWithFormTags());
1512
-    }
1513
-
1514
-
1515
-    /**
1516
-     * @return EE_Form_Section_Proper
1517
-     * @throws EE_Error
1518
-     * @throws InvalidArgumentException
1519
-     * @throws InvalidDataTypeException
1520
-     * @throws InvalidInterfaceException
1521
-     * @throws EntityNotFoundException
1522
-     * @throws ReflectionException
1523
-     */
1524
-    protected function _generate_reg_status_change_form()
1525
-    {
1526
-        $reg_status_change_form_array = [
1527
-            'name'            => 'reg_status_change_form',
1528
-            'html_id'         => 'reg-status-change-form',
1529
-            'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1530
-            'subsections'     => [
1531
-                'return' => new EE_Hidden_Input(
1532
-                    [
1533
-                        'name'    => 'return',
1534
-                        'default' => 'view_registration',
1535
-                    ]
1536
-                ),
1537
-                'REG_ID' => new EE_Hidden_Input(
1538
-                    [
1539
-                        'name'    => 'REG_ID',
1540
-                        'default' => $this->_registration->ID(),
1541
-                    ]
1542
-                ),
1543
-            ],
1544
-        ];
1545
-        if (
1546
-            $this->capabilities->current_user_can(
1547
-                'ee_edit_registration',
1548
-                'toggle_registration_status',
1549
-                $this->_registration->ID()
1550
-            )
1551
-        ) {
1552
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1553
-                $this->_get_reg_statuses(),
1554
-                [
1555
-                    'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1556
-                    'default'         => $this->_registration->status_ID(),
1557
-                ]
1558
-            );
1559
-            $reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1560
-                [
1561
-                    'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1562
-                    'default'         => false,
1563
-                    'html_help_text'  => esc_html__(
1564
-                        'If set to "Yes", then the related messages will be sent to the registrant.',
1565
-                        'event_espresso'
1566
-                    ),
1567
-                ]
1568
-            );
1569
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1570
-                [
1571
-                    'html_class'      => 'button--primary',
1572
-                    'html_label_text' => '&nbsp;',
1573
-                    'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1574
-                ]
1575
-            );
1576
-        }
1577
-        return new EE_Form_Section_Proper($reg_status_change_form_array);
1578
-    }
1579
-
1580
-
1581
-    /**
1582
-     * Returns an array of all the buttons for the various statuses and switch status actions
1583
-     *
1584
-     * @return array
1585
-     * @throws EE_Error
1586
-     * @throws InvalidArgumentException
1587
-     * @throws InvalidDataTypeException
1588
-     * @throws InvalidInterfaceException
1589
-     * @throws EntityNotFoundException
1590
-     */
1591
-    protected function _get_reg_statuses()
1592
-    {
1593
-        $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1594
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1595
-        // get current reg status
1596
-        $current_status = $this->_registration->status_ID();
1597
-        // is registration for free event? This will determine whether to display the pending payment option
1598
-        if (
1599
-            $current_status !== EEM_Registration::status_id_pending_payment
1600
-            && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1601
-        ) {
1602
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1603
-        }
1604
-        return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1605
-    }
1606
-
1607
-
1608
-    /**
1609
-     * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1610
-     *
1611
-     * @param bool $status REG status given for changing registrations to.
1612
-     * @param bool $notify Whether to send messages notifications or not.
1613
-     * @return array (array with reg_id(s) updated and whether update was successful.
1614
-     * @throws DomainException
1615
-     * @throws EE_Error
1616
-     * @throws EntityNotFoundException
1617
-     * @throws InvalidArgumentException
1618
-     * @throws InvalidDataTypeException
1619
-     * @throws InvalidInterfaceException
1620
-     * @throws ReflectionException
1621
-     * @throws RuntimeException
1622
-     */
1623
-    protected function _set_registration_status_from_request($status = false, $notify = false)
1624
-    {
1625
-        $REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1626
-            ? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1627
-            : $this->request->getRequestParam('_REG_ID', [], 'int', true);
1628
-        // sanitize $REG_IDs
1629
-        $REG_IDs = array_map('absint', $REG_IDs);
1630
-        // and remove empty entries
1631
-        $REG_IDs = array_filter($REG_IDs);
1632
-
1633
-        $result = $this->_set_registration_status($REG_IDs, $status, $notify);
1634
-
1635
-        /**
1636
-         * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1637
-         * Currently this value is used downstream by the _process_resend_registration method.
1638
-         *
1639
-         * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1640
-         * @param bool                     $status           The status registrations were changed to.
1641
-         * @param bool                     $success          If the status was changed successfully for all registrations.
1642
-         * @param Registrations_Admin_Page $admin_page
1643
-         */
1644
-        $REG_ID = apply_filters(
1645
-            'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1646
-            $result['REG_ID'],
1647
-            $status,
1648
-            $result['success'],
1649
-            $this
1650
-        );
1651
-        $this->request->setRequestParam('_REG_ID', $REG_ID);
1652
-
1653
-        // notify?
1654
-        if (
1655
-            $notify
1656
-            && $result['success']
1657
-            && ! empty($REG_ID)
1658
-            && $this->capabilities->current_user_can(
1659
-                'ee_send_message',
1660
-                'espresso_registrations_resend_registration'
1661
-            )
1662
-        ) {
1663
-            $this->_process_resend_registration();
1664
-        }
1665
-        return $result;
1666
-    }
1667
-
1668
-
1669
-    /**
1670
-     * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1671
-     * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1672
-     *
1673
-     * @param array  $REG_IDs
1674
-     * @param string $status
1675
-     * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1676
-     *                       slug sent with setting the registration status.
1677
-     * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1678
-     * @throws EE_Error
1679
-     * @throws InvalidArgumentException
1680
-     * @throws InvalidDataTypeException
1681
-     * @throws InvalidInterfaceException
1682
-     * @throws ReflectionException
1683
-     * @throws RuntimeException
1684
-     * @throws EntityNotFoundException
1685
-     * @throws DomainException
1686
-     */
1687
-    protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1688
-    {
1689
-        $success = false;
1690
-        // typecast $REG_IDs
1691
-        $REG_IDs = (array) $REG_IDs;
1692
-        if (! empty($REG_IDs)) {
1693
-            $success = true;
1694
-            // set default status if none is passed
1695
-            $status         = $status ?: EEM_Registration::status_id_pending_payment;
1696
-            $status_context = $notify
1697
-                ? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1698
-                : Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1699
-            // loop through REG_ID's and change status
1700
-            foreach ($REG_IDs as $REG_ID) {
1701
-                $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1702
-                if ($registration instanceof EE_Registration) {
1703
-                    $registration->set_status(
1704
-                        $status,
1705
-                        false,
1706
-                        new Context(
1707
-                            $status_context,
1708
-                            esc_html__(
1709
-                                'Manually triggered status change on a Registration Admin Page route.',
1710
-                                'event_espresso'
1711
-                            )
1712
-                        )
1713
-                    );
1714
-                    $result = $registration->save();
1715
-                    // verifying explicit fails because update *may* just return 0 for 0 rows affected
1716
-                    $success = $result !== false ? $success : false;
1717
-                }
1718
-            }
1719
-        }
1720
-
1721
-        // return $success and processed registrations
1722
-        return ['REG_ID' => $REG_IDs, 'success' => $success];
1723
-    }
1724
-
1725
-
1726
-    /**
1727
-     * Common logic for setting up success message and redirecting to appropriate route
1728
-     *
1729
-     * @param string $STS_ID status id for the registration changed to
1730
-     * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1731
-     * @return void
1732
-     * @throws DomainException
1733
-     * @throws EE_Error
1734
-     * @throws EntityNotFoundException
1735
-     * @throws InvalidArgumentException
1736
-     * @throws InvalidDataTypeException
1737
-     * @throws InvalidInterfaceException
1738
-     * @throws ReflectionException
1739
-     * @throws RuntimeException
1740
-     */
1741
-    protected function _reg_status_change_return($STS_ID, $notify = false)
1742
-    {
1743
-        $result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1744
-            : ['success' => false];
1745
-        $success = isset($result['success']) && $result['success'];
1746
-        // setup success message
1747
-        if ($success) {
1748
-            if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1749
-                $msg = sprintf(
1750
-                    esc_html__('Registration status has been set to %s', 'event_espresso'),
1751
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1752
-                );
1753
-            } else {
1754
-                $msg = sprintf(
1755
-                    esc_html__('Registrations have been set to %s.', 'event_espresso'),
1756
-                    EEH_Template::pretty_status($STS_ID, false, 'lower')
1757
-                );
1758
-            }
1759
-            EE_Error::add_success($msg);
1760
-        } else {
1761
-            EE_Error::add_error(
1762
-                esc_html__(
1763
-                    'Something went wrong, and the status was not changed',
1764
-                    'event_espresso'
1765
-                ),
1766
-                __FILE__,
1767
-                __LINE__,
1768
-                __FUNCTION__
1769
-            );
1770
-        }
1771
-        $return = $this->request->getRequestParam('return');
1772
-        $route  = $return === 'view_registration'
1773
-            ? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1774
-            : ['action' => 'default'];
1775
-        $route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1776
-        $this->_redirect_after_action($success, '', '', $route, true);
1777
-    }
1778
-
1779
-
1780
-    /**
1781
-     * incoming reg status change from reg details page.
1782
-     *
1783
-     * @return void
1784
-     * @throws EE_Error
1785
-     * @throws EntityNotFoundException
1786
-     * @throws InvalidArgumentException
1787
-     * @throws InvalidDataTypeException
1788
-     * @throws InvalidInterfaceException
1789
-     * @throws ReflectionException
1790
-     * @throws RuntimeException
1791
-     * @throws DomainException
1792
-     */
1793
-    protected function _change_reg_status()
1794
-    {
1795
-        $this->request->setRequestParam('return', 'view_registration');
1796
-        // set notify based on whether the send notifications toggle is set or not
1797
-        $notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1798
-        $reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1799
-        $this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1800
-        switch ($reg_status) {
1801
-            case EEM_Registration::status_id_approved:
1802
-            case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1803
-                $this->approve_registration($notify);
1804
-                break;
1805
-            case EEM_Registration::status_id_pending_payment:
1806
-            case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1807
-                $this->pending_registration($notify);
1808
-                break;
1809
-            case EEM_Registration::status_id_not_approved:
1810
-            case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1811
-                $this->not_approve_registration($notify);
1812
-                break;
1813
-            case EEM_Registration::status_id_declined:
1814
-            case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1815
-                $this->decline_registration($notify);
1816
-                break;
1817
-            case EEM_Registration::status_id_cancelled:
1818
-            case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1819
-                $this->cancel_registration($notify);
1820
-                break;
1821
-            case EEM_Registration::status_id_wait_list:
1822
-            case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1823
-                $this->wait_list_registration($notify);
1824
-                break;
1825
-            case EEM_Registration::status_id_incomplete:
1826
-            default:
1827
-                $this->request->unSetRequestParam('return');
1828
-                $this->_reg_status_change_return('');
1829
-                break;
1830
-        }
1831
-    }
1832
-
1833
-
1834
-    /**
1835
-     * Callback for bulk action routes.
1836
-     * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1837
-     * method was chosen so there is one central place all the registration status bulk actions are going through.
1838
-     * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1839
-     * when an action is happening on just a single registration).
1840
-     *
1841
-     * @param      $action
1842
-     * @param bool $notify
1843
-     */
1844
-    protected function bulk_action_on_registrations($action, $notify = false)
1845
-    {
1846
-        do_action(
1847
-            'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1848
-            $this,
1849
-            $action,
1850
-            $notify
1851
-        );
1852
-        $method = $action . '_registration';
1853
-        if (method_exists($this, $method)) {
1854
-            $this->$method($notify);
1855
-        }
1856
-    }
1857
-
1858
-
1859
-    /**
1860
-     * approve_registration
1861
-     *
1862
-     * @param bool $notify whether or not to notify the registrant about their approval.
1863
-     * @return void
1864
-     * @throws EE_Error
1865
-     * @throws EntityNotFoundException
1866
-     * @throws InvalidArgumentException
1867
-     * @throws InvalidDataTypeException
1868
-     * @throws InvalidInterfaceException
1869
-     * @throws ReflectionException
1870
-     * @throws RuntimeException
1871
-     * @throws DomainException
1872
-     */
1873
-    protected function approve_registration($notify = false)
1874
-    {
1875
-        $this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1876
-    }
1877
-
1878
-
1879
-    /**
1880
-     * decline_registration
1881
-     *
1882
-     * @param bool $notify whether or not to notify the registrant about their status change.
1883
-     * @return void
1884
-     * @throws EE_Error
1885
-     * @throws EntityNotFoundException
1886
-     * @throws InvalidArgumentException
1887
-     * @throws InvalidDataTypeException
1888
-     * @throws InvalidInterfaceException
1889
-     * @throws ReflectionException
1890
-     * @throws RuntimeException
1891
-     * @throws DomainException
1892
-     */
1893
-    protected function decline_registration($notify = false)
1894
-    {
1895
-        $this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1896
-    }
1897
-
1898
-
1899
-    /**
1900
-     * cancel_registration
1901
-     *
1902
-     * @param bool $notify whether or not to notify the registrant about their status change.
1903
-     * @return void
1904
-     * @throws EE_Error
1905
-     * @throws EntityNotFoundException
1906
-     * @throws InvalidArgumentException
1907
-     * @throws InvalidDataTypeException
1908
-     * @throws InvalidInterfaceException
1909
-     * @throws ReflectionException
1910
-     * @throws RuntimeException
1911
-     * @throws DomainException
1912
-     */
1913
-    protected function cancel_registration($notify = false)
1914
-    {
1915
-        $this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1916
-    }
1917
-
1918
-
1919
-    /**
1920
-     * not_approve_registration
1921
-     *
1922
-     * @param bool $notify whether or not to notify the registrant about their status change.
1923
-     * @return void
1924
-     * @throws EE_Error
1925
-     * @throws EntityNotFoundException
1926
-     * @throws InvalidArgumentException
1927
-     * @throws InvalidDataTypeException
1928
-     * @throws InvalidInterfaceException
1929
-     * @throws ReflectionException
1930
-     * @throws RuntimeException
1931
-     * @throws DomainException
1932
-     */
1933
-    protected function not_approve_registration($notify = false)
1934
-    {
1935
-        $this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1936
-    }
1937
-
1938
-
1939
-    /**
1940
-     * decline_registration
1941
-     *
1942
-     * @param bool $notify whether or not to notify the registrant about their status change.
1943
-     * @return void
1944
-     * @throws EE_Error
1945
-     * @throws EntityNotFoundException
1946
-     * @throws InvalidArgumentException
1947
-     * @throws InvalidDataTypeException
1948
-     * @throws InvalidInterfaceException
1949
-     * @throws ReflectionException
1950
-     * @throws RuntimeException
1951
-     * @throws DomainException
1952
-     */
1953
-    protected function pending_registration($notify = false)
1954
-    {
1955
-        $this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1956
-    }
1957
-
1958
-
1959
-    /**
1960
-     * waitlist_registration
1961
-     *
1962
-     * @param bool $notify whether or not to notify the registrant about their status change.
1963
-     * @return void
1964
-     * @throws EE_Error
1965
-     * @throws EntityNotFoundException
1966
-     * @throws InvalidArgumentException
1967
-     * @throws InvalidDataTypeException
1968
-     * @throws InvalidInterfaceException
1969
-     * @throws ReflectionException
1970
-     * @throws RuntimeException
1971
-     * @throws DomainException
1972
-     */
1973
-    protected function wait_list_registration($notify = false)
1974
-    {
1975
-        $this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1976
-    }
1977
-
1978
-
1979
-    /**
1980
-     * generates HTML for the Registration main meta box
1981
-     *
1982
-     * @return void
1983
-     * @throws DomainException
1984
-     * @throws EE_Error
1985
-     * @throws InvalidArgumentException
1986
-     * @throws InvalidDataTypeException
1987
-     * @throws InvalidInterfaceException
1988
-     * @throws ReflectionException
1989
-     * @throws EntityNotFoundException
1990
-     */
1991
-    public function _reg_details_meta_box()
1992
-    {
1993
-        EEH_Autoloader::register_line_item_display_autoloaders();
1994
-        EEH_Autoloader::register_line_item_filter_autoloaders();
1995
-        EE_Registry::instance()->load_helper('Line_Item');
1996
-        $transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
1997
-            : EE_Transaction::new_instance();
1998
-        $this->_session = $transaction->session_data();
1999
-        $filters        = new EE_Line_Item_Filter_Collection();
2000
-        $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001
-        $filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2003
-            $filters,
2004
-            $transaction->total_line_item()
2005
-        );
2006
-        $filtered_line_item_tree                 = $line_item_filter_processor->process();
2007
-        $line_item_display                       = new EE_Line_Item_Display(
2008
-            'reg_admin_table',
2009
-            'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2010
-        );
2011
-        $this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2012
-            $filtered_line_item_tree,
2013
-            ['EE_Registration' => $this->_registration]
2014
-        );
2015
-        $attendee                                = $this->_registration->attendee();
2016
-        if (
2017
-            $this->capabilities->current_user_can(
2018
-                'ee_read_transaction',
2019
-                'espresso_transactions_view_transaction'
2020
-            )
2021
-        ) {
2022
-            $this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2023
-                EE_Admin_Page::add_query_args_and_nonce(
2024
-                    [
2025
-                        'action' => 'view_transaction',
2026
-                        'TXN_ID' => $transaction->ID(),
2027
-                    ],
2028
-                    TXN_ADMIN_URL
2029
-                ),
2030
-                esc_html__(' View Transaction', 'event_espresso'),
2031
-                'button button--secondary right',
2032
-                'dashicons dashicons-cart'
2033
-            );
2034
-        } else {
2035
-            $this->_template_args['view_transaction_button'] = '';
2036
-        }
2037
-        if (
2038
-            $attendee instanceof EE_Attendee
2039
-            && $this->capabilities->current_user_can(
2040
-                'ee_send_message',
2041
-                'espresso_registrations_resend_registration'
2042
-            )
2043
-        ) {
2044
-            $this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2045
-                EE_Admin_Page::add_query_args_and_nonce(
2046
-                    [
2047
-                        'action'      => 'resend_registration',
2048
-                        '_REG_ID'     => $this->_registration->ID(),
2049
-                        'redirect_to' => 'view_registration',
2050
-                    ],
2051
-                    REG_ADMIN_URL
2052
-                ),
2053
-                esc_html__(' Resend Registration', 'event_espresso'),
2054
-                'button button--secondary right',
2055
-                'dashicons dashicons-email-alt'
2056
-            );
2057
-        } else {
2058
-            $this->_template_args['resend_registration_button'] = '';
2059
-        }
2060
-        $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2061
-        $payment                               = $transaction->get_first_related('Payment');
2062
-        $payment                               = ! $payment instanceof EE_Payment
2063
-            ? EE_Payment::new_instance()
2064
-            : $payment;
2065
-        $payment_method                        = $payment->get_first_related('Payment_Method');
2066
-        $payment_method                        = ! $payment_method instanceof EE_Payment_Method
2067
-            ? EE_Payment_Method::new_instance()
2068
-            : $payment_method;
2069
-        $reg_details                           = [
2070
-            'payment_method'       => $payment_method->name(),
2071
-            'response_msg'         => $payment->gateway_response(),
2072
-            'registration_id'      => $this->_registration->get('REG_code'),
2073
-            'registration_session' => $this->_registration->session_ID(),
2074
-            'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2075
-            'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2076
-        ];
2077
-        if (isset($reg_details['registration_id'])) {
2078
-            $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2079
-            $this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2080
-                'Registration ID',
2081
-                'event_espresso'
2082
-            );
2083
-            $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2084
-        }
2085
-        if (isset($reg_details['payment_method'])) {
2086
-            $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2087
-            $this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2088
-                'Most Recent Payment Method',
2089
-                'event_espresso'
2090
-            );
2091
-            $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2092
-            $this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2093
-            $this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2094
-                'Payment method response',
2095
-                'event_espresso'
2096
-            );
2097
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2098
-        }
2099
-        $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100
-        $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2101
-            'Registration Session',
2102
-            'event_espresso'
2103
-        );
2104
-        $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2105
-        $this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2106
-        $this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2107
-            'Registration placed from IP',
2108
-            'event_espresso'
2109
-        );
2110
-        $this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2111
-        $this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2112
-        $this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2113
-            'Registrant User Agent',
2114
-            'event_espresso'
2115
-        );
2116
-        $this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2117
-        $this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2118
-            [
2119
-                'action'   => 'default',
2120
-                'event_id' => $this->_registration->event_ID(),
2121
-            ],
2122
-            REG_ADMIN_URL
2123
-        );
2124
-
2125
-        $this->_template_args['REG_ID']   = $this->_registration->ID();
2126
-        $this->_template_args['event_id'] = $this->_registration->event_ID();
2127
-
2128
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2129
-        EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130
-    }
2131
-
2132
-
2133
-    /**
2134
-     * generates HTML for the Registration Questions meta box.
2135
-     * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2136
-     * otherwise uses new forms system
2137
-     *
2138
-     * @return void
2139
-     * @throws DomainException
2140
-     * @throws EE_Error
2141
-     * @throws InvalidArgumentException
2142
-     * @throws InvalidDataTypeException
2143
-     * @throws InvalidInterfaceException
2144
-     * @throws ReflectionException
2145
-     */
2146
-    public function _reg_questions_meta_box()
2147
-    {
2148
-        // allow someone to override this method entirely
2149
-        if (
2150
-            apply_filters(
2151
-                'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2152
-                true,
2153
-                $this,
2154
-                $this->_registration
2155
-            )
2156
-        ) {
2157
-            $form = $this->_get_reg_custom_questions_form(
2158
-                $this->_registration->ID()
2159
-            );
2160
-
2161
-            $this->_template_args['att_questions'] = count($form->subforms()) > 0
2162
-                ? $form->get_html_and_js()
2163
-                : '';
2164
-
2165
-            $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166
-            $this->_template_args['REG_ID']                    = $this->_registration->ID();
2167
-            $template_path                                     =
2168
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2169
-            EEH_Template::display_template($template_path, $this->_template_args);
2170
-        }
2171
-    }
2172
-
2173
-
2174
-    /**
2175
-     * form_before_question_group
2176
-     *
2177
-     * @param string $output
2178
-     * @return        string
2179
-     * @deprecated    as of 4.8.32.rc.000
2180
-     */
2181
-    public function form_before_question_group($output)
2182
-    {
2183
-        EE_Error::doing_it_wrong(
2184
-            __CLASS__ . '::' . __FUNCTION__,
2185
-            esc_html__(
2186
-                '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.',
2187
-                'event_espresso'
2188
-            ),
2189
-            '4.8.32.rc.000'
2190
-        );
2191
-        return '
24
+	/**
25
+	 * @var EE_Registration
26
+	 */
27
+	private $_registration;
28
+
29
+	/**
30
+	 * @var EE_Event
31
+	 */
32
+	private $_reg_event;
33
+
34
+	/**
35
+	 * @var EE_Session
36
+	 */
37
+	private $_session;
38
+
39
+	/**
40
+	 * @var array
41
+	 */
42
+	private static $_reg_status;
43
+
44
+	/**
45
+	 * Form for displaying the custom questions for this registration.
46
+	 * This gets used a few times throughout the request so its best to cache it
47
+	 *
48
+	 * @var EE_Registration_Custom_Questions_Form
49
+	 */
50
+	protected $_reg_custom_questions_form;
51
+
52
+	/**
53
+	 * @var EEM_Registration $registration_model
54
+	 */
55
+	private $registration_model;
56
+
57
+	/**
58
+	 * @var EEM_Attendee $attendee_model
59
+	 */
60
+	private $attendee_model;
61
+
62
+	/**
63
+	 * @var EEM_Event $event_model
64
+	 */
65
+	private $event_model;
66
+
67
+	/**
68
+	 * @var EEM_Status $status_model
69
+	 */
70
+	private $status_model;
71
+
72
+
73
+	/**
74
+	 * @param bool $routing
75
+	 * @throws InvalidArgumentException
76
+	 * @throws InvalidDataTypeException
77
+	 * @throws InvalidInterfaceException
78
+	 * @throws ReflectionException
79
+	 */
80
+	public function __construct($routing = true)
81
+	{
82
+		parent::__construct($routing);
83
+		$this->cpt_editpost_route = 'edit_attendee';
84
+		add_action('wp_loaded', [$this, 'wp_loaded']);
85
+	}
86
+
87
+
88
+	/**
89
+	 * @return EEM_Registration
90
+	 * @throws InvalidArgumentException
91
+	 * @throws InvalidDataTypeException
92
+	 * @throws InvalidInterfaceException
93
+	 * @since 4.10.2.p
94
+	 */
95
+	protected function getRegistrationModel()
96
+	{
97
+		if (! $this->registration_model instanceof EEM_Registration) {
98
+			$this->registration_model = $this->loader->getShared('EEM_Registration');
99
+		}
100
+		return $this->registration_model;
101
+	}
102
+
103
+
104
+	/**
105
+	 * @return EEM_Attendee
106
+	 * @throws InvalidArgumentException
107
+	 * @throws InvalidDataTypeException
108
+	 * @throws InvalidInterfaceException
109
+	 * @since 4.10.2.p
110
+	 */
111
+	protected function getAttendeeModel()
112
+	{
113
+		if (! $this->attendee_model instanceof EEM_Attendee) {
114
+			$this->attendee_model = $this->loader->getShared('EEM_Attendee');
115
+		}
116
+		return $this->attendee_model;
117
+	}
118
+
119
+
120
+	/**
121
+	 * @return EEM_Event
122
+	 * @throws InvalidArgumentException
123
+	 * @throws InvalidDataTypeException
124
+	 * @throws InvalidInterfaceException
125
+	 * @since 4.10.2.p
126
+	 */
127
+	protected function getEventModel()
128
+	{
129
+		if (! $this->event_model instanceof EEM_Event) {
130
+			$this->event_model = $this->loader->getShared('EEM_Event');
131
+		}
132
+		return $this->event_model;
133
+	}
134
+
135
+
136
+	/**
137
+	 * @return EEM_Status
138
+	 * @throws InvalidArgumentException
139
+	 * @throws InvalidDataTypeException
140
+	 * @throws InvalidInterfaceException
141
+	 * @since 4.10.2.p
142
+	 */
143
+	protected function getStatusModel()
144
+	{
145
+		if (! $this->status_model instanceof EEM_Status) {
146
+			$this->status_model = $this->loader->getShared('EEM_Status');
147
+		}
148
+		return $this->status_model;
149
+	}
150
+
151
+
152
+	public function wp_loaded()
153
+	{
154
+		// when adding a new registration...
155
+		$action = $this->request->getRequestParam('action');
156
+		if ($action === 'new_registration') {
157
+			EE_System::do_not_cache();
158
+			if ($this->request->getRequestParam('processing_registration', 0, 'int') !== 1) {
159
+				// and it's NOT the attendee information reg step
160
+				// force cookie expiration by setting time to last week
161
+				setcookie('ee_registration_added', 0, time() - WEEK_IN_SECONDS, '/');
162
+				// and update the global
163
+				$_COOKIE['ee_registration_added'] = 0;
164
+			}
165
+		}
166
+	}
167
+
168
+
169
+	protected function _init_page_props()
170
+	{
171
+		$this->page_slug        = REG_PG_SLUG;
172
+		$this->_admin_base_url  = REG_ADMIN_URL;
173
+		$this->_admin_base_path = REG_ADMIN;
174
+		$this->page_label       = esc_html__('Registrations', 'event_espresso');
175
+		$this->_cpt_routes      = [
176
+			'add_new_attendee' => 'espresso_attendees',
177
+			'edit_attendee'    => 'espresso_attendees',
178
+			'insert_attendee'  => 'espresso_attendees',
179
+			'update_attendee'  => 'espresso_attendees',
180
+		];
181
+		$this->_cpt_model_names = [
182
+			'add_new_attendee' => 'EEM_Attendee',
183
+			'edit_attendee'    => 'EEM_Attendee',
184
+		];
185
+		$this->_cpt_edit_routes = [
186
+			'espresso_attendees' => 'edit_attendee',
187
+		];
188
+		$this->_pagenow_map     = [
189
+			'add_new_attendee' => 'post-new.php',
190
+			'edit_attendee'    => 'post.php',
191
+			'trash'            => 'post.php',
192
+		];
193
+		add_action('edit_form_after_title', [$this, 'after_title_form_fields'], 10);
194
+		// add filters so that the comment urls don't take users to a confusing 404 page
195
+		add_filter('get_comment_link', [$this, 'clear_comment_link'], 10, 2);
196
+	}
197
+
198
+
199
+	/**
200
+	 * @param string     $link    The comment permalink with '#comment-$id' appended.
201
+	 * @param WP_Comment $comment The current comment object.
202
+	 * @return string
203
+	 */
204
+	public function clear_comment_link($link, WP_Comment $comment)
205
+	{
206
+		// gotta make sure this only happens on this route
207
+		$post_type = get_post_type($comment->comment_post_ID);
208
+		if ($post_type === 'espresso_attendees') {
209
+			return '#commentsdiv';
210
+		}
211
+		return $link;
212
+	}
213
+
214
+
215
+	protected function _ajax_hooks()
216
+	{
217
+		// todo: all hooks for registrations ajax goes in here
218
+		add_action('wp_ajax_toggle_checkin_status', [$this, 'toggle_checkin_status']);
219
+	}
220
+
221
+
222
+	protected function _define_page_props()
223
+	{
224
+		$this->_admin_page_title = $this->page_label;
225
+		$this->_labels           = [
226
+			'buttons'                      => [
227
+				'add-registrant'      => esc_html__('Add New Registration', 'event_espresso'),
228
+				'add-attendee'        => esc_html__('Add Contact', 'event_espresso'),
229
+				'edit'                => esc_html__('Edit Contact', 'event_espresso'),
230
+				'csv_reg_report'      => esc_html__('Registrations CSV Report', 'event_espresso'),
231
+				'contact_list_report' => esc_html__('Contact List Report', 'event_espresso'),
232
+				'contact_list_export' => esc_html__('Export Data', 'event_espresso'),
233
+			],
234
+			'publishbox'                   => [
235
+				'add_new_attendee' => esc_html__('Add Contact Record', 'event_espresso'),
236
+				'edit_attendee'    => esc_html__('Update Contact Record', 'event_espresso'),
237
+			],
238
+			'hide_add_button_on_cpt_route' => [
239
+				'edit_attendee' => true,
240
+			],
241
+		];
242
+	}
243
+
244
+
245
+	/**
246
+	 * grab url requests and route them
247
+	 *
248
+	 * @return void
249
+	 * @throws EE_Error
250
+	 */
251
+	public function _set_page_routes()
252
+	{
253
+		$this->_get_registration_status_array();
254
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
255
+		$REG_ID             = $this->request->getRequestParam('reg_status_change_form[REG_ID]', $REG_ID, 'int');
256
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
257
+		$ATT_ID             = $this->request->getRequestParam('post', $ATT_ID, 'int');
258
+		$this->_page_routes = [
259
+			'default'                             => [
260
+				'func'       => [$this, '_registrations_overview_list_table'],
261
+				'capability' => 'ee_read_registrations',
262
+			],
263
+			'view_registration'                   => [
264
+				'func'       => [$this, '_registration_details'],
265
+				'capability' => 'ee_read_registration',
266
+				'obj_id'     => $REG_ID,
267
+			],
268
+			'edit_registration'                   => [
269
+				'func'               => '_update_attendee_registration_form',
270
+				'noheader'           => true,
271
+				'headers_sent_route' => 'view_registration',
272
+				'capability'         => 'ee_edit_registration',
273
+				'obj_id'             => $REG_ID,
274
+				'_REG_ID'            => $REG_ID,
275
+			],
276
+			'trash_registrations'                 => [
277
+				'func'       => '_trash_or_restore_registrations',
278
+				'args'       => ['trash' => true],
279
+				'noheader'   => true,
280
+				'capability' => 'ee_delete_registrations',
281
+			],
282
+			'restore_registrations'               => [
283
+				'func'       => '_trash_or_restore_registrations',
284
+				'args'       => ['trash' => false],
285
+				'noheader'   => true,
286
+				'capability' => 'ee_delete_registrations',
287
+			],
288
+			'delete_registrations'                => [
289
+				'func'       => '_delete_registrations',
290
+				'noheader'   => true,
291
+				'capability' => 'ee_delete_registrations',
292
+			],
293
+			'new_registration'                    => [
294
+				'func'       => 'new_registration',
295
+				'capability' => 'ee_edit_registrations',
296
+			],
297
+			'process_reg_step'                    => [
298
+				'func'       => 'process_reg_step',
299
+				'noheader'   => true,
300
+				'capability' => 'ee_edit_registrations',
301
+			],
302
+			'redirect_to_txn'                     => [
303
+				'func'       => 'redirect_to_txn',
304
+				'noheader'   => true,
305
+				'capability' => 'ee_edit_registrations',
306
+			],
307
+			'change_reg_status'                   => [
308
+				'func'       => '_change_reg_status',
309
+				'noheader'   => true,
310
+				'capability' => 'ee_edit_registration',
311
+				'obj_id'     => $REG_ID,
312
+			],
313
+			'approve_registration'                => [
314
+				'func'       => 'approve_registration',
315
+				'noheader'   => true,
316
+				'capability' => 'ee_edit_registration',
317
+				'obj_id'     => $REG_ID,
318
+			],
319
+			'approve_and_notify_registration'     => [
320
+				'func'       => 'approve_registration',
321
+				'noheader'   => true,
322
+				'args'       => [true],
323
+				'capability' => 'ee_edit_registration',
324
+				'obj_id'     => $REG_ID,
325
+			],
326
+			'approve_registrations'               => [
327
+				'func'       => 'bulk_action_on_registrations',
328
+				'noheader'   => true,
329
+				'capability' => 'ee_edit_registrations',
330
+				'args'       => ['approve'],
331
+			],
332
+			'approve_and_notify_registrations'    => [
333
+				'func'       => 'bulk_action_on_registrations',
334
+				'noheader'   => true,
335
+				'capability' => 'ee_edit_registrations',
336
+				'args'       => ['approve', true],
337
+			],
338
+			'decline_registration'                => [
339
+				'func'       => 'decline_registration',
340
+				'noheader'   => true,
341
+				'capability' => 'ee_edit_registration',
342
+				'obj_id'     => $REG_ID,
343
+			],
344
+			'decline_and_notify_registration'     => [
345
+				'func'       => 'decline_registration',
346
+				'noheader'   => true,
347
+				'args'       => [true],
348
+				'capability' => 'ee_edit_registration',
349
+				'obj_id'     => $REG_ID,
350
+			],
351
+			'decline_registrations'               => [
352
+				'func'       => 'bulk_action_on_registrations',
353
+				'noheader'   => true,
354
+				'capability' => 'ee_edit_registrations',
355
+				'args'       => ['decline'],
356
+			],
357
+			'decline_and_notify_registrations'    => [
358
+				'func'       => 'bulk_action_on_registrations',
359
+				'noheader'   => true,
360
+				'capability' => 'ee_edit_registrations',
361
+				'args'       => ['decline', true],
362
+			],
363
+			'pending_registration'                => [
364
+				'func'       => 'pending_registration',
365
+				'noheader'   => true,
366
+				'capability' => 'ee_edit_registration',
367
+				'obj_id'     => $REG_ID,
368
+			],
369
+			'pending_and_notify_registration'     => [
370
+				'func'       => 'pending_registration',
371
+				'noheader'   => true,
372
+				'args'       => [true],
373
+				'capability' => 'ee_edit_registration',
374
+				'obj_id'     => $REG_ID,
375
+			],
376
+			'pending_registrations'               => [
377
+				'func'       => 'bulk_action_on_registrations',
378
+				'noheader'   => true,
379
+				'capability' => 'ee_edit_registrations',
380
+				'args'       => ['pending'],
381
+			],
382
+			'pending_and_notify_registrations'    => [
383
+				'func'       => 'bulk_action_on_registrations',
384
+				'noheader'   => true,
385
+				'capability' => 'ee_edit_registrations',
386
+				'args'       => ['pending', true],
387
+			],
388
+			'no_approve_registration'             => [
389
+				'func'       => 'not_approve_registration',
390
+				'noheader'   => true,
391
+				'capability' => 'ee_edit_registration',
392
+				'obj_id'     => $REG_ID,
393
+			],
394
+			'no_approve_and_notify_registration'  => [
395
+				'func'       => 'not_approve_registration',
396
+				'noheader'   => true,
397
+				'args'       => [true],
398
+				'capability' => 'ee_edit_registration',
399
+				'obj_id'     => $REG_ID,
400
+			],
401
+			'no_approve_registrations'            => [
402
+				'func'       => 'bulk_action_on_registrations',
403
+				'noheader'   => true,
404
+				'capability' => 'ee_edit_registrations',
405
+				'args'       => ['not_approve'],
406
+			],
407
+			'no_approve_and_notify_registrations' => [
408
+				'func'       => 'bulk_action_on_registrations',
409
+				'noheader'   => true,
410
+				'capability' => 'ee_edit_registrations',
411
+				'args'       => ['not_approve', true],
412
+			],
413
+			'cancel_registration'                 => [
414
+				'func'       => 'cancel_registration',
415
+				'noheader'   => true,
416
+				'capability' => 'ee_edit_registration',
417
+				'obj_id'     => $REG_ID,
418
+			],
419
+			'cancel_and_notify_registration'      => [
420
+				'func'       => 'cancel_registration',
421
+				'noheader'   => true,
422
+				'args'       => [true],
423
+				'capability' => 'ee_edit_registration',
424
+				'obj_id'     => $REG_ID,
425
+			],
426
+			'cancel_registrations'                => [
427
+				'func'       => 'bulk_action_on_registrations',
428
+				'noheader'   => true,
429
+				'capability' => 'ee_edit_registrations',
430
+				'args'       => ['cancel'],
431
+			],
432
+			'cancel_and_notify_registrations'     => [
433
+				'func'       => 'bulk_action_on_registrations',
434
+				'noheader'   => true,
435
+				'capability' => 'ee_edit_registrations',
436
+				'args'       => ['cancel', true],
437
+			],
438
+			'wait_list_registration'              => [
439
+				'func'       => 'wait_list_registration',
440
+				'noheader'   => true,
441
+				'capability' => 'ee_edit_registration',
442
+				'obj_id'     => $REG_ID,
443
+			],
444
+			'wait_list_and_notify_registration'   => [
445
+				'func'       => 'wait_list_registration',
446
+				'noheader'   => true,
447
+				'args'       => [true],
448
+				'capability' => 'ee_edit_registration',
449
+				'obj_id'     => $REG_ID,
450
+			],
451
+			'contact_list'                        => [
452
+				'func'       => '_attendee_contact_list_table',
453
+				'capability' => 'ee_read_contacts',
454
+			],
455
+			'add_new_attendee'                    => [
456
+				'func' => '_create_new_cpt_item',
457
+				'args' => [
458
+					'new_attendee' => true,
459
+					'capability'   => 'ee_edit_contacts',
460
+				],
461
+			],
462
+			'edit_attendee'                       => [
463
+				'func'       => '_edit_cpt_item',
464
+				'capability' => 'ee_edit_contacts',
465
+				'obj_id'     => $ATT_ID,
466
+			],
467
+			'duplicate_attendee'                  => [
468
+				'func'       => '_duplicate_attendee',
469
+				'noheader'   => true,
470
+				'capability' => 'ee_edit_contacts',
471
+				'obj_id'     => $ATT_ID,
472
+			],
473
+			'insert_attendee'                     => [
474
+				'func'       => '_insert_or_update_attendee',
475
+				'args'       => [
476
+					'new_attendee' => true,
477
+				],
478
+				'noheader'   => true,
479
+				'capability' => 'ee_edit_contacts',
480
+			],
481
+			'update_attendee'                     => [
482
+				'func'       => '_insert_or_update_attendee',
483
+				'args'       => [
484
+					'new_attendee' => false,
485
+				],
486
+				'noheader'   => true,
487
+				'capability' => 'ee_edit_contacts',
488
+				'obj_id'     => $ATT_ID,
489
+			],
490
+			'trash_attendees'                     => [
491
+				'func'       => '_trash_or_restore_attendees',
492
+				'args'       => [
493
+					'trash' => 'true',
494
+				],
495
+				'noheader'   => true,
496
+				'capability' => 'ee_delete_contacts',
497
+			],
498
+			'trash_attendee'                      => [
499
+				'func'       => '_trash_or_restore_attendees',
500
+				'args'       => [
501
+					'trash' => true,
502
+				],
503
+				'noheader'   => true,
504
+				'capability' => 'ee_delete_contacts',
505
+				'obj_id'     => $ATT_ID,
506
+			],
507
+			'restore_attendees'                   => [
508
+				'func'       => '_trash_or_restore_attendees',
509
+				'args'       => [
510
+					'trash' => false,
511
+				],
512
+				'noheader'   => true,
513
+				'capability' => 'ee_delete_contacts',
514
+				'obj_id'     => $ATT_ID,
515
+			],
516
+			'resend_registration'                 => [
517
+				'func'       => '_resend_registration',
518
+				'noheader'   => true,
519
+				'capability' => 'ee_send_message',
520
+			],
521
+			'registrations_report'                => [
522
+				'func'       => [$this, '_registrations_report'],
523
+				'noheader'   => true,
524
+				'capability' => 'ee_read_registrations',
525
+			],
526
+			'contact_list_export'                 => [
527
+				'func'       => '_contact_list_export',
528
+				'noheader'   => true,
529
+				'capability' => 'export',
530
+			],
531
+			'contact_list_report'                 => [
532
+				'func'       => '_contact_list_report',
533
+				'noheader'   => true,
534
+				'capability' => 'ee_read_contacts',
535
+			],
536
+		];
537
+	}
538
+
539
+
540
+	protected function _set_page_config()
541
+	{
542
+		$REG_ID             = $this->request->getRequestParam('_REG_ID', 0, 'int');
543
+		$ATT_ID             = $this->request->getRequestParam('ATT_ID', 0, 'int');
544
+		$this->_page_config = [
545
+			'default'           => [
546
+				'nav'           => [
547
+					'label' => esc_html__('Overview', 'event_espresso'),
548
+					'icon'  => 'dashicons-list-view',
549
+					'order' => 5,
550
+				],
551
+				'help_tabs'     => [
552
+					'registrations_overview_help_tab'                       => [
553
+						'title'    => esc_html__('Registrations Overview', 'event_espresso'),
554
+						'filename' => 'registrations_overview',
555
+					],
556
+					'registrations_overview_table_column_headings_help_tab' => [
557
+						'title'    => esc_html__('Registrations Table Column Headings', 'event_espresso'),
558
+						'filename' => 'registrations_overview_table_column_headings',
559
+					],
560
+					'registrations_overview_filters_help_tab'               => [
561
+						'title'    => esc_html__('Registration Filters', 'event_espresso'),
562
+						'filename' => 'registrations_overview_filters',
563
+					],
564
+					'registrations_overview_views_help_tab'                 => [
565
+						'title'    => esc_html__('Registration Views', 'event_espresso'),
566
+						'filename' => 'registrations_overview_views',
567
+					],
568
+					'registrations_regoverview_other_help_tab'              => [
569
+						'title'    => esc_html__('Registrations Other', 'event_espresso'),
570
+						'filename' => 'registrations_overview_other',
571
+					],
572
+				],
573
+				'list_table'    => 'EE_Registrations_List_Table',
574
+				'require_nonce' => false,
575
+			],
576
+			'view_registration' => [
577
+				'nav'           => [
578
+					'label'      => esc_html__('REG Details', 'event_espresso'),
579
+					'icon'       => 'dashicons-clipboard',
580
+					'order'      => 15,
581
+					'url'        => $REG_ID
582
+						? add_query_arg(['_REG_ID' => $REG_ID], $this->_current_page_view_url)
583
+						: $this->_admin_base_url,
584
+					'persistent' => false,
585
+				],
586
+				'help_tabs'     => [
587
+					'registrations_details_help_tab'                    => [
588
+						'title'    => esc_html__('Registration Details', 'event_espresso'),
589
+						'filename' => 'registrations_details',
590
+					],
591
+					'registrations_details_table_help_tab'              => [
592
+						'title'    => esc_html__('Registration Details Table', 'event_espresso'),
593
+						'filename' => 'registrations_details_table',
594
+					],
595
+					'registrations_details_form_answers_help_tab'       => [
596
+						'title'    => esc_html__('Registration Form Answers', 'event_espresso'),
597
+						'filename' => 'registrations_details_form_answers',
598
+					],
599
+					'registrations_details_registrant_details_help_tab' => [
600
+						'title'    => esc_html__('Contact Details', 'event_espresso'),
601
+						'filename' => 'registrations_details_registrant_details',
602
+					],
603
+				],
604
+				'metaboxes'     => array_merge(
605
+					$this->_default_espresso_metaboxes,
606
+					['_registration_details_metaboxes']
607
+				),
608
+				'require_nonce' => false,
609
+			],
610
+			'new_registration'  => [
611
+				'nav'           => [
612
+					'label'      => esc_html__('Add New Registration', 'event_espresso'),
613
+					'icon'       => 'dashicons-plus-alt',
614
+					'url'        => '#',
615
+					'order'      => 15,
616
+					'persistent' => false,
617
+				],
618
+				'metaboxes'     => $this->_default_espresso_metaboxes,
619
+				'labels'        => [
620
+					'publishbox' => esc_html__('Save Registration', 'event_espresso'),
621
+				],
622
+				'require_nonce' => false,
623
+			],
624
+			'add_new_attendee'  => [
625
+				'nav'           => [
626
+					'label'      => esc_html__('Add Contact', 'event_espresso'),
627
+					'icon'       => 'dashicons-plus-alt',
628
+					'order'      => 15,
629
+					'persistent' => false,
630
+				],
631
+				'metaboxes'     => array_merge(
632
+					$this->_default_espresso_metaboxes,
633
+					['_publish_post_box', 'attendee_editor_metaboxes']
634
+				),
635
+				'require_nonce' => false,
636
+			],
637
+			'edit_attendee'     => [
638
+				'nav'           => [
639
+					'label'      => esc_html__('Edit Contact', 'event_espresso'),
640
+					'icon'       => 'dashicons-edit-large',
641
+					'order'      => 15,
642
+					'persistent' => false,
643
+					'url'        => $ATT_ID
644
+						? add_query_arg(['ATT_ID' => $ATT_ID], $this->_current_page_view_url)
645
+						: $this->_admin_base_url,
646
+				],
647
+				'metaboxes'     => array_merge(
648
+					$this->_default_espresso_metaboxes,
649
+					['attendee_editor_metaboxes']
650
+				),
651
+				'require_nonce' => false,
652
+			],
653
+			'contact_list'      => [
654
+				'nav'           => [
655
+					'label' => esc_html__('Contact List', 'event_espresso'),
656
+					'icon'  => 'dashicons-id-alt',
657
+					'order' => 20,
658
+				],
659
+				'list_table'    => 'EE_Attendee_Contact_List_Table',
660
+				'help_tabs'     => [
661
+					'registrations_contact_list_help_tab'                       => [
662
+						'title'    => esc_html__('Registrations Contact List', 'event_espresso'),
663
+						'filename' => 'registrations_contact_list',
664
+					],
665
+					'registrations_contact-list_table_column_headings_help_tab' => [
666
+						'title'    => esc_html__('Contact List Table Column Headings', 'event_espresso'),
667
+						'filename' => 'registrations_contact_list_table_column_headings',
668
+					],
669
+					'registrations_contact_list_views_help_tab'                 => [
670
+						'title'    => esc_html__('Contact List Views', 'event_espresso'),
671
+						'filename' => 'registrations_contact_list_views',
672
+					],
673
+					'registrations_contact_list_other_help_tab'                 => [
674
+						'title'    => esc_html__('Contact List Other', 'event_espresso'),
675
+						'filename' => 'registrations_contact_list_other',
676
+					],
677
+				],
678
+				'metaboxes'     => [],
679
+				'require_nonce' => false,
680
+			],
681
+			// override default cpt routes
682
+			'create_new'        => '',
683
+			'edit'              => '',
684
+		];
685
+	}
686
+
687
+
688
+	/**
689
+	 * The below methods aren't used by this class currently
690
+	 */
691
+	protected function _add_screen_options()
692
+	{
693
+	}
694
+
695
+
696
+	protected function _add_feature_pointers()
697
+	{
698
+	}
699
+
700
+
701
+	public function admin_init()
702
+	{
703
+		EE_Registry::$i18n_js_strings['update_att_qstns'] = esc_html__(
704
+			'click "Update Registration Questions" to save your changes',
705
+			'event_espresso'
706
+		);
707
+	}
708
+
709
+
710
+	public function admin_notices()
711
+	{
712
+	}
713
+
714
+
715
+	public function admin_footer_scripts()
716
+	{
717
+	}
718
+
719
+
720
+	/**
721
+	 * get list of registration statuses
722
+	 *
723
+	 * @return void
724
+	 * @throws EE_Error
725
+	 */
726
+	private function _get_registration_status_array()
727
+	{
728
+		self::$_reg_status = EEM_Registration::reg_status_array([], true);
729
+	}
730
+
731
+
732
+	/**
733
+	 * @throws InvalidArgumentException
734
+	 * @throws InvalidDataTypeException
735
+	 * @throws InvalidInterfaceException
736
+	 * @since 4.10.2.p
737
+	 */
738
+	protected function _add_screen_options_default()
739
+	{
740
+		$this->_per_page_screen_option();
741
+	}
742
+
743
+
744
+	/**
745
+	 * @throws InvalidArgumentException
746
+	 * @throws InvalidDataTypeException
747
+	 * @throws InvalidInterfaceException
748
+	 * @since 4.10.2.p
749
+	 */
750
+	protected function _add_screen_options_contact_list()
751
+	{
752
+		$page_title              = $this->_admin_page_title;
753
+		$this->_admin_page_title = esc_html__('Contacts', 'event_espresso');
754
+		$this->_per_page_screen_option();
755
+		$this->_admin_page_title = $page_title;
756
+	}
757
+
758
+
759
+	public function load_scripts_styles()
760
+	{
761
+		// style
762
+		wp_register_style(
763
+			'espresso_reg',
764
+			REG_ASSETS_URL . 'espresso_registrations_admin.css',
765
+			['ee-admin-css'],
766
+			EVENT_ESPRESSO_VERSION
767
+		);
768
+		wp_enqueue_style('espresso_reg');
769
+		// script
770
+		wp_register_script(
771
+			'espresso_reg',
772
+			REG_ASSETS_URL . 'espresso_registrations_admin.js',
773
+			['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774
+			EVENT_ESPRESSO_VERSION,
775
+			true
776
+		);
777
+		wp_enqueue_script('espresso_reg');
778
+	}
779
+
780
+
781
+	/**
782
+	 * @throws EE_Error
783
+	 * @throws InvalidArgumentException
784
+	 * @throws InvalidDataTypeException
785
+	 * @throws InvalidInterfaceException
786
+	 * @throws ReflectionException
787
+	 * @since 4.10.2.p
788
+	 */
789
+	public function load_scripts_styles_edit_attendee()
790
+	{
791
+		// stuff to only show up on our attendee edit details page.
792
+		$attendee_details_translations = [
793
+			'att_publish_text' => sprintf(
794
+			/* translators: The date and time */
795
+				wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
+				'<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
797
+			),
798
+		];
799
+		wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
800
+		wp_enqueue_script('jquery-validate');
801
+	}
802
+
803
+
804
+	/**
805
+	 * @throws EE_Error
806
+	 * @throws InvalidArgumentException
807
+	 * @throws InvalidDataTypeException
808
+	 * @throws InvalidInterfaceException
809
+	 * @throws ReflectionException
810
+	 * @since 4.10.2.p
811
+	 */
812
+	public function load_scripts_styles_view_registration()
813
+	{
814
+		$this->_set_registration_object();
815
+		// styles
816
+		wp_enqueue_style('espresso-ui-theme');
817
+		// scripts
818
+		$this->_get_reg_custom_questions_form($this->_registration->ID());
819
+		$this->_reg_custom_questions_form->wp_enqueue_scripts();
820
+	}
821
+
822
+
823
+	public function load_scripts_styles_contact_list()
824
+	{
825
+		wp_dequeue_style('espresso_reg');
826
+		wp_register_style(
827
+			'espresso_att',
828
+			REG_ASSETS_URL . 'espresso_attendees_admin.css',
829
+			['ee-admin-css'],
830
+			EVENT_ESPRESSO_VERSION
831
+		);
832
+		wp_enqueue_style('espresso_att');
833
+	}
834
+
835
+
836
+	public function load_scripts_styles_new_registration()
837
+	{
838
+		wp_register_script(
839
+			'ee-spco-for-admin',
840
+			REG_ASSETS_URL . 'spco_for_admin.js',
841
+			['underscore', 'jquery'],
842
+			EVENT_ESPRESSO_VERSION,
843
+			true
844
+		);
845
+		wp_enqueue_script('ee-spco-for-admin');
846
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
847
+		EE_Form_Section_Proper::wp_enqueue_scripts();
848
+		EED_Ticket_Selector::load_tckt_slctr_assets();
849
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
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 Not Approved',
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 Not Approved 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
+		$this->_views = [
942
+			'all'   => [
943
+				'slug'        => 'all',
944
+				'label'       => esc_html__('View All Registrations', 'event_espresso'),
945
+				'count'       => 0,
946
+				'bulk_action' => array_merge(
947
+					$def_reg_status_actions,
948
+					[
949
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
950
+					]
951
+				),
952
+			],
953
+			'month' => [
954
+				'slug'        => 'month',
955
+				'label'       => esc_html__('This Month', 'event_espresso'),
956
+				'count'       => 0,
957
+				'bulk_action' => array_merge(
958
+					$def_reg_status_actions,
959
+					[
960
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
961
+					]
962
+				),
963
+			],
964
+			'today' => [
965
+				'slug'        => 'today',
966
+				'label'       => sprintf(
967
+					esc_html__('Today - %s', 'event_espresso'),
968
+					date('M d, Y', current_time('timestamp'))
969
+				),
970
+				'count'       => 0,
971
+				'bulk_action' => array_merge(
972
+					$def_reg_status_actions,
973
+					[
974
+						'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
975
+					]
976
+				),
977
+			],
978
+		];
979
+		if (
980
+			$this->capabilities->current_user_can(
981
+				'ee_delete_registrations',
982
+				'espresso_registrations_delete_registration'
983
+			)
984
+		) {
985
+			$this->_views['incomplete'] = [
986
+				'slug'        => 'incomplete',
987
+				'label'       => esc_html__('Incomplete', 'event_espresso'),
988
+				'count'       => 0,
989
+				'bulk_action' => [
990
+					'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
991
+				],
992
+			];
993
+			$this->_views['trash']      = [
994
+				'slug'        => 'trash',
995
+				'label'       => esc_html__('Trash', 'event_espresso'),
996
+				'count'       => 0,
997
+				'bulk_action' => [
998
+					'restore_registrations' => esc_html__('Restore Registrations', 'event_espresso'),
999
+					'delete_registrations'  => esc_html__('Delete Registrations Permanently', 'event_espresso'),
1000
+				],
1001
+			];
1002
+		}
1003
+	}
1004
+
1005
+
1006
+	protected function _set_list_table_views_contact_list()
1007
+	{
1008
+		$this->_views = [
1009
+			'in_use' => [
1010
+				'slug'        => 'in_use',
1011
+				'label'       => esc_html__('In Use', 'event_espresso'),
1012
+				'count'       => 0,
1013
+				'bulk_action' => [
1014
+					'trash_attendees' => esc_html__('Move to Trash', 'event_espresso'),
1015
+				],
1016
+			],
1017
+		];
1018
+		if (
1019
+			$this->capabilities->current_user_can(
1020
+				'ee_delete_contacts',
1021
+				'espresso_registrations_trash_attendees'
1022
+			)
1023
+		) {
1024
+			$this->_views['trash'] = [
1025
+				'slug'        => 'trash',
1026
+				'label'       => esc_html__('Trash', 'event_espresso'),
1027
+				'count'       => 0,
1028
+				'bulk_action' => [
1029
+					'restore_attendees' => esc_html__('Restore from Trash', 'event_espresso'),
1030
+				],
1031
+			];
1032
+		}
1033
+	}
1034
+
1035
+
1036
+	/**
1037
+	 * @return array
1038
+	 * @throws EE_Error
1039
+	 */
1040
+	protected function _registration_legend_items()
1041
+	{
1042
+		$fc_items = [
1043
+			'star-icon'        => [
1044
+				'class' => 'dashicons dashicons-star-filled gold-icon',
1045
+				'desc'  => esc_html__('This is the Primary Registrant', 'event_espresso'),
1046
+			],
1047
+			'view_details'     => [
1048
+				'class' => 'dashicons dashicons-clipboard',
1049
+				'desc'  => esc_html__('View Registration Details', 'event_espresso'),
1050
+			],
1051
+			'edit_attendee'    => [
1052
+				'class' => 'dashicons dashicons-admin-users',
1053
+				'desc'  => esc_html__('Edit Contact Details', 'event_espresso'),
1054
+			],
1055
+			'view_transaction' => [
1056
+				'class' => 'dashicons dashicons-cart',
1057
+				'desc'  => esc_html__('View Transaction Details', 'event_espresso'),
1058
+			],
1059
+			'view_invoice'     => [
1060
+				'class' => 'dashicons dashicons-media-spreadsheet',
1061
+				'desc'  => esc_html__('View Transaction Invoice', 'event_espresso'),
1062
+			],
1063
+		];
1064
+		if (
1065
+			$this->capabilities->current_user_can(
1066
+				'ee_send_message',
1067
+				'espresso_registrations_resend_registration'
1068
+			)
1069
+		) {
1070
+			$fc_items['resend_registration'] = [
1071
+				'class' => 'dashicons dashicons-email-alt',
1072
+				'desc'  => esc_html__('Resend Registration Details', 'event_espresso'),
1073
+			];
1074
+		} else {
1075
+			$fc_items['blank'] = ['class' => 'blank', 'desc' => ''];
1076
+		}
1077
+		if (
1078
+			$this->capabilities->current_user_can(
1079
+				'ee_read_global_messages',
1080
+				'view_filtered_messages'
1081
+			)
1082
+		) {
1083
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
1084
+			if (is_array($related_for_icon) && isset($related_for_icon['css_class'], $related_for_icon['label'])) {
1085
+				$fc_items['view_related_messages'] = [
1086
+					'class' => $related_for_icon['css_class'],
1087
+					'desc'  => $related_for_icon['label'],
1088
+				];
1089
+			}
1090
+		}
1091
+		$sc_items = [
1092
+			'approved_status'   => [
1093
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1094
+				'desc'  => EEH_Template::pretty_status(
1095
+					EEM_Registration::status_id_approved,
1096
+					false,
1097
+					'sentence'
1098
+				),
1099
+			],
1100
+			'pending_status'    => [
1101
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1102
+				'desc'  => EEH_Template::pretty_status(
1103
+					EEM_Registration::status_id_pending_payment,
1104
+					false,
1105
+					'sentence'
1106
+				),
1107
+			],
1108
+			'wait_list'         => [
1109
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1110
+				'desc'  => EEH_Template::pretty_status(
1111
+					EEM_Registration::status_id_wait_list,
1112
+					false,
1113
+					'sentence'
1114
+				),
1115
+			],
1116
+			'incomplete_status' => [
1117
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1118
+				'desc'  => EEH_Template::pretty_status(
1119
+					EEM_Registration::status_id_incomplete,
1120
+					false,
1121
+					'sentence'
1122
+				),
1123
+			],
1124
+			'not_approved'      => [
1125
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1126
+				'desc'  => EEH_Template::pretty_status(
1127
+					EEM_Registration::status_id_not_approved,
1128
+					false,
1129
+					'sentence'
1130
+				),
1131
+			],
1132
+			'declined_status'   => [
1133
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1134
+				'desc'  => EEH_Template::pretty_status(
1135
+					EEM_Registration::status_id_declined,
1136
+					false,
1137
+					'sentence'
1138
+				),
1139
+			],
1140
+			'cancelled_status'  => [
1141
+				'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1142
+				'desc'  => EEH_Template::pretty_status(
1143
+					EEM_Registration::status_id_cancelled,
1144
+					false,
1145
+					'sentence'
1146
+				),
1147
+			],
1148
+		];
1149
+		return array_merge($fc_items, $sc_items);
1150
+	}
1151
+
1152
+
1153
+
1154
+	/***************************************        REGISTRATION OVERVIEW        **************************************/
1155
+
1156
+
1157
+	/**
1158
+	 * @throws DomainException
1159
+	 * @throws EE_Error
1160
+	 * @throws InvalidArgumentException
1161
+	 * @throws InvalidDataTypeException
1162
+	 * @throws InvalidInterfaceException
1163
+	 */
1164
+	protected function _registrations_overview_list_table()
1165
+	{
1166
+		$this->appendAddNewRegistrationButtonToPageTitle();
1167
+		$header_text                  = '';
1168
+		$admin_page_header_decorators = [
1169
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\AttendeeFilterHeader',
1170
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\EventFilterHeader',
1171
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\DateFilterHeader',
1172
+			'EventEspresso\core\domain\services\admin\registrations\list_table\page_header\TicketFilterHeader',
1173
+		];
1174
+		foreach ($admin_page_header_decorators as $admin_page_header_decorator) {
1175
+			$filter_header_decorator = $this->loader->getNew($admin_page_header_decorator);
1176
+			$header_text             = $filter_header_decorator->getHeaderText($header_text);
1177
+		}
1178
+		$this->_template_args['before_list_table'] = $header_text;
1179
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_registration_legend_items());
1180
+		$this->display_admin_list_table_page_with_no_sidebar();
1181
+	}
1182
+
1183
+
1184
+	/**
1185
+	 * @throws EE_Error
1186
+	 * @throws InvalidArgumentException
1187
+	 * @throws InvalidDataTypeException
1188
+	 * @throws InvalidInterfaceException
1189
+	 */
1190
+	private function appendAddNewRegistrationButtonToPageTitle()
1191
+	{
1192
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
1193
+		if (
1194
+			$EVT_ID
1195
+			&& $this->capabilities->current_user_can(
1196
+				'ee_edit_registrations',
1197
+				'espresso_registrations_new_registration',
1198
+				$EVT_ID
1199
+			)
1200
+		) {
1201
+			$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1202
+					'new_registration',
1203
+					'add-registrant',
1204
+					['event_id' => $EVT_ID],
1205
+					'add-new-h2'
1206
+				);
1207
+		}
1208
+	}
1209
+
1210
+
1211
+	/**
1212
+	 * This sets the _registration property for the registration details screen
1213
+	 *
1214
+	 * @return void
1215
+	 * @throws EE_Error
1216
+	 * @throws InvalidArgumentException
1217
+	 * @throws InvalidDataTypeException
1218
+	 * @throws InvalidInterfaceException
1219
+	 */
1220
+	private function _set_registration_object()
1221
+	{
1222
+		// get out if we've already set the object
1223
+		if ($this->_registration instanceof EE_Registration) {
1224
+			return;
1225
+		}
1226
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
1227
+		if ($this->_registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID)) {
1228
+			return;
1229
+		}
1230
+		$error_msg = sprintf(
1231
+			esc_html__(
1232
+				'An error occurred and the details for Registration ID #%s could not be retrieved.',
1233
+				'event_espresso'
1234
+			),
1235
+			$REG_ID
1236
+		);
1237
+		EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
1238
+		$this->_registration = null;
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * Used to retrieve registrations for the list table.
1244
+	 *
1245
+	 * @param int  $per_page
1246
+	 * @param bool $count
1247
+	 * @param bool $this_month
1248
+	 * @param bool $today
1249
+	 * @return EE_Registration[]|int
1250
+	 * @throws EE_Error
1251
+	 * @throws InvalidArgumentException
1252
+	 * @throws InvalidDataTypeException
1253
+	 * @throws InvalidInterfaceException
1254
+	 */
1255
+	public function get_registrations(
1256
+		$per_page = 10,
1257
+		$count = false,
1258
+		$this_month = false,
1259
+		$today = false
1260
+	) {
1261
+		if ($this_month) {
1262
+			$this->request->setRequestParam('status', 'month');
1263
+		}
1264
+		if ($today) {
1265
+			$this->request->setRequestParam('status', 'today');
1266
+		}
1267
+		$query_params = $this->_get_registration_query_parameters([], $per_page, $count);
1268
+		/**
1269
+		 * Override the default groupby added by EEM_Base so that sorts with multiple order bys work as expected
1270
+		 *
1271
+		 * @link https://events.codebasehq.com/projects/event-espresso/tickets/10093
1272
+		 * @see  https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
1273
+		 *                      or if you have the development copy of EE you can view this at the path:
1274
+		 *                      /docs/G--Model-System/model-query-params.md
1275
+		 */
1276
+		$query_params['group_by'] = '';
1277
+
1278
+		return $count
1279
+			? $this->getRegistrationModel()->count($query_params)
1280
+			/** @type EE_Registration[] */
1281
+			: $this->getRegistrationModel()->get_all($query_params);
1282
+	}
1283
+
1284
+
1285
+	/**
1286
+	 * Retrieves the query parameters to be used by the Registration model for getting registrations.
1287
+	 * Note: this listens to values on the request for some query parameters.
1288
+	 *
1289
+	 * @param array $request
1290
+	 * @param int   $per_page
1291
+	 * @param bool  $count
1292
+	 * @return array
1293
+	 * @throws EE_Error
1294
+	 * @throws InvalidArgumentException
1295
+	 * @throws InvalidDataTypeException
1296
+	 * @throws InvalidInterfaceException
1297
+	 */
1298
+	protected function _get_registration_query_parameters(
1299
+		array $request = [],
1300
+		int $per_page = 10,
1301
+		bool $count = false
1302
+	): array {
1303
+		/** @var EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder $list_table_query_builder */
1304
+		$list_table_query_builder = $this->loader->getNew(
1305
+			'EventEspresso\core\domain\services\admin\registrations\list_table\QueryBuilder',
1306
+			[null, null, $request]
1307
+		);
1308
+		return $list_table_query_builder->getQueryParams($per_page, $count);
1309
+	}
1310
+
1311
+
1312
+	public function get_registration_status_array(): array
1313
+	{
1314
+		return self::$_reg_status;
1315
+	}
1316
+
1317
+
1318
+
1319
+
1320
+	/***************************************        REGISTRATION DETAILS        ***************************************/
1321
+	/**
1322
+	 * generates HTML for the View Registration Details Admin page
1323
+	 *
1324
+	 * @return void
1325
+	 * @throws DomainException
1326
+	 * @throws EE_Error
1327
+	 * @throws InvalidArgumentException
1328
+	 * @throws InvalidDataTypeException
1329
+	 * @throws InvalidInterfaceException
1330
+	 * @throws EntityNotFoundException
1331
+	 * @throws ReflectionException
1332
+	 */
1333
+	protected function _registration_details()
1334
+	{
1335
+		$this->_template_args = [];
1336
+		$this->_set_registration_object();
1337
+		if (is_object($this->_registration)) {
1338
+			$transaction                                   = $this->_registration->transaction()
1339
+				? $this->_registration->transaction()
1340
+				: EE_Transaction::new_instance();
1341
+			$this->_session                                = $transaction->session_data();
1342
+			$event_id                                      = $this->_registration->event_ID();
1343
+			$this->_template_args['reg_nmbr']['value']     = $this->_registration->ID();
1344
+			$this->_template_args['reg_nmbr']['label']     = esc_html__('Registration Number', 'event_espresso');
1345
+			$this->_template_args['reg_datetime']['value'] = $this->_registration->get_i18n_datetime('REG_date');
1346
+			$this->_template_args['reg_datetime']['label'] = esc_html__('Date', 'event_espresso');
1347
+			$this->_template_args['grand_total']           = $transaction->total();
1348
+			$this->_template_args['currency_sign']         = EE_Registry::instance()->CFG->currency->sign;
1349
+			// link back to overview
1350
+			$this->_template_args['reg_overview_url']            = REG_ADMIN_URL;
1351
+			$this->_template_args['registration']                = $this->_registration;
1352
+			$this->_template_args['filtered_registrations_link'] = EE_Admin_Page::add_query_args_and_nonce(
1353
+				[
1354
+					'action'   => 'default',
1355
+					'event_id' => $event_id,
1356
+				],
1357
+				REG_ADMIN_URL
1358
+			);
1359
+			$this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1360
+				[
1361
+					'action' => 'default',
1362
+					'EVT_ID' => $event_id,
1363
+					'page'   => 'espresso_transactions',
1364
+				],
1365
+				admin_url('admin.php')
1366
+			);
1367
+			$this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1368
+				[
1369
+					'page'   => 'espresso_events',
1370
+					'action' => 'edit',
1371
+					'post'   => $event_id,
1372
+				],
1373
+				admin_url('admin.php')
1374
+			);
1375
+			// next and previous links
1376
+			$next_reg                                      = $this->_registration->next(
1377
+				null,
1378
+				[],
1379
+				'REG_ID'
1380
+			);
1381
+			$this->_template_args['next_registration']     = $next_reg
1382
+				? $this->_next_link(
1383
+					EE_Admin_Page::add_query_args_and_nonce(
1384
+						[
1385
+							'action'  => 'view_registration',
1386
+							'_REG_ID' => $next_reg['REG_ID'],
1387
+						],
1388
+						REG_ADMIN_URL
1389
+					),
1390
+					'dashicons dashicons-arrow-right ee-icon-size-22'
1391
+				)
1392
+				: '';
1393
+			$previous_reg                                  = $this->_registration->previous(
1394
+				null,
1395
+				[],
1396
+				'REG_ID'
1397
+			);
1398
+			$this->_template_args['previous_registration'] = $previous_reg
1399
+				? $this->_previous_link(
1400
+					EE_Admin_Page::add_query_args_and_nonce(
1401
+						[
1402
+							'action'  => 'view_registration',
1403
+							'_REG_ID' => $previous_reg['REG_ID'],
1404
+						],
1405
+						REG_ADMIN_URL
1406
+					),
1407
+					'dashicons dashicons-arrow-left ee-icon-size-22'
1408
+				)
1409
+				: '';
1410
+			// grab header
1411
+			$template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1412
+			$this->_template_args['REG_ID']            = $this->_registration->ID();
1413
+			$this->_template_args['admin_page_header'] = EEH_Template::display_template(
1414
+				$template_path,
1415
+				$this->_template_args,
1416
+				true
1417
+			);
1418
+		} else {
1419
+			$this->_template_args['admin_page_header'] = '';
1420
+			$this->_display_espresso_notices();
1421
+		}
1422
+		// the details template wrapper
1423
+		$this->display_admin_page_with_sidebar();
1424
+	}
1425
+
1426
+
1427
+	/**
1428
+	 * @throws EE_Error
1429
+	 * @throws InvalidArgumentException
1430
+	 * @throws InvalidDataTypeException
1431
+	 * @throws InvalidInterfaceException
1432
+	 * @throws ReflectionException
1433
+	 * @since 4.10.2.p
1434
+	 */
1435
+	protected function _registration_details_metaboxes()
1436
+	{
1437
+		do_action('AHEE__Registrations_Admin_Page___registration_details_metabox__start', $this);
1438
+		$this->_set_registration_object();
1439
+		$attendee = $this->_registration instanceof EE_Registration ? $this->_registration->attendee() : null;
1440
+		$this->addMetaBox(
1441
+			'edit-reg-status-mbox',
1442
+			esc_html__('Registration Status', 'event_espresso'),
1443
+			[$this, 'set_reg_status_buttons_metabox'],
1444
+			$this->_wp_page_slug
1445
+		);
1446
+		$this->addMetaBox(
1447
+			'edit-reg-details-mbox',
1448
+			'<span>' . esc_html__('Registration Details', 'event_espresso')
1449
+			. '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1450
+			[$this, '_reg_details_meta_box'],
1451
+			$this->_wp_page_slug
1452
+		);
1453
+		if (
1454
+			$attendee instanceof EE_Attendee
1455
+			&& $this->capabilities->current_user_can(
1456
+				'ee_read_registration',
1457
+				'edit-reg-questions-mbox',
1458
+				$this->_registration->ID()
1459
+			)
1460
+		) {
1461
+			$this->addMetaBox(
1462
+				'edit-reg-questions-mbox',
1463
+				esc_html__('Registration Form Answers', 'event_espresso'),
1464
+				[$this, '_reg_questions_meta_box'],
1465
+				$this->_wp_page_slug
1466
+			);
1467
+		}
1468
+		$this->addMetaBox(
1469
+			'edit-reg-registrant-mbox',
1470
+			esc_html__('Contact Details', 'event_espresso'),
1471
+			[$this, '_reg_registrant_side_meta_box'],
1472
+			$this->_wp_page_slug,
1473
+			'side'
1474
+		);
1475
+		if ($this->_registration->group_size() > 1) {
1476
+			$this->addMetaBox(
1477
+				'edit-reg-attendees-mbox',
1478
+				esc_html__('Other Registrations in this Transaction', 'event_espresso'),
1479
+				[$this, '_reg_attendees_meta_box'],
1480
+				$this->_wp_page_slug
1481
+			);
1482
+		}
1483
+	}
1484
+
1485
+
1486
+	/**
1487
+	 * set_reg_status_buttons_metabox
1488
+	 *
1489
+	 * @return void
1490
+	 * @throws EE_Error
1491
+	 * @throws EntityNotFoundException
1492
+	 * @throws InvalidArgumentException
1493
+	 * @throws InvalidDataTypeException
1494
+	 * @throws InvalidInterfaceException
1495
+	 * @throws ReflectionException
1496
+	 */
1497
+	public function set_reg_status_buttons_metabox()
1498
+	{
1499
+		$this->_set_registration_object();
1500
+		$change_reg_status_form = $this->_generate_reg_status_change_form();
1501
+		$output                 = $change_reg_status_form->form_open(
1502
+			self::add_query_args_and_nonce(
1503
+				[
1504
+					'action' => 'change_reg_status',
1505
+				],
1506
+				REG_ADMIN_URL
1507
+			)
1508
+		);
1509
+		$output                 .= $change_reg_status_form->get_html();
1510
+		$output                 .= $change_reg_status_form->form_close();
1511
+		echo wp_kses($output, AllowedTags::getWithFormTags());
1512
+	}
1513
+
1514
+
1515
+	/**
1516
+	 * @return EE_Form_Section_Proper
1517
+	 * @throws EE_Error
1518
+	 * @throws InvalidArgumentException
1519
+	 * @throws InvalidDataTypeException
1520
+	 * @throws InvalidInterfaceException
1521
+	 * @throws EntityNotFoundException
1522
+	 * @throws ReflectionException
1523
+	 */
1524
+	protected function _generate_reg_status_change_form()
1525
+	{
1526
+		$reg_status_change_form_array = [
1527
+			'name'            => 'reg_status_change_form',
1528
+			'html_id'         => 'reg-status-change-form',
1529
+			'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1530
+			'subsections'     => [
1531
+				'return' => new EE_Hidden_Input(
1532
+					[
1533
+						'name'    => 'return',
1534
+						'default' => 'view_registration',
1535
+					]
1536
+				),
1537
+				'REG_ID' => new EE_Hidden_Input(
1538
+					[
1539
+						'name'    => 'REG_ID',
1540
+						'default' => $this->_registration->ID(),
1541
+					]
1542
+				),
1543
+			],
1544
+		];
1545
+		if (
1546
+			$this->capabilities->current_user_can(
1547
+				'ee_edit_registration',
1548
+				'toggle_registration_status',
1549
+				$this->_registration->ID()
1550
+			)
1551
+		) {
1552
+			$reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1553
+				$this->_get_reg_statuses(),
1554
+				[
1555
+					'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
1556
+					'default'         => $this->_registration->status_ID(),
1557
+				]
1558
+			);
1559
+			$reg_status_change_form_array['subsections']['send_notifications'] = new EE_Yes_No_Input(
1560
+				[
1561
+					'html_label_text' => esc_html__('Send Related Messages', 'event_espresso'),
1562
+					'default'         => false,
1563
+					'html_help_text'  => esc_html__(
1564
+						'If set to "Yes", then the related messages will be sent to the registrant.',
1565
+						'event_espresso'
1566
+					),
1567
+				]
1568
+			);
1569
+			$reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1570
+				[
1571
+					'html_class'      => 'button--primary',
1572
+					'html_label_text' => '&nbsp;',
1573
+					'default'         => esc_html__('Update Registration Status', 'event_espresso'),
1574
+				]
1575
+			);
1576
+		}
1577
+		return new EE_Form_Section_Proper($reg_status_change_form_array);
1578
+	}
1579
+
1580
+
1581
+	/**
1582
+	 * Returns an array of all the buttons for the various statuses and switch status actions
1583
+	 *
1584
+	 * @return array
1585
+	 * @throws EE_Error
1586
+	 * @throws InvalidArgumentException
1587
+	 * @throws InvalidDataTypeException
1588
+	 * @throws InvalidInterfaceException
1589
+	 * @throws EntityNotFoundException
1590
+	 */
1591
+	protected function _get_reg_statuses()
1592
+	{
1593
+		$reg_status_array = $this->getRegistrationModel()->reg_status_array();
1594
+		unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1595
+		// get current reg status
1596
+		$current_status = $this->_registration->status_ID();
1597
+		// is registration for free event? This will determine whether to display the pending payment option
1598
+		if (
1599
+			$current_status !== EEM_Registration::status_id_pending_payment
1600
+			&& EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1601
+		) {
1602
+			unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1603
+		}
1604
+		return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1605
+	}
1606
+
1607
+
1608
+	/**
1609
+	 * This method is used when using _REG_ID from request which may or may not be an array of reg_ids.
1610
+	 *
1611
+	 * @param bool $status REG status given for changing registrations to.
1612
+	 * @param bool $notify Whether to send messages notifications or not.
1613
+	 * @return array (array with reg_id(s) updated and whether update was successful.
1614
+	 * @throws DomainException
1615
+	 * @throws EE_Error
1616
+	 * @throws EntityNotFoundException
1617
+	 * @throws InvalidArgumentException
1618
+	 * @throws InvalidDataTypeException
1619
+	 * @throws InvalidInterfaceException
1620
+	 * @throws ReflectionException
1621
+	 * @throws RuntimeException
1622
+	 */
1623
+	protected function _set_registration_status_from_request($status = false, $notify = false)
1624
+	{
1625
+		$REG_IDs = $this->request->requestParamIsSet('reg_status_change_form')
1626
+			? $this->request->getRequestParam('reg_status_change_form[REG_ID]', [], 'int', true)
1627
+			: $this->request->getRequestParam('_REG_ID', [], 'int', true);
1628
+		// sanitize $REG_IDs
1629
+		$REG_IDs = array_map('absint', $REG_IDs);
1630
+		// and remove empty entries
1631
+		$REG_IDs = array_filter($REG_IDs);
1632
+
1633
+		$result = $this->_set_registration_status($REG_IDs, $status, $notify);
1634
+
1635
+		/**
1636
+		 * Set and filter $_req_data['_REG_ID'] for any potential future messages notifications.
1637
+		 * Currently this value is used downstream by the _process_resend_registration method.
1638
+		 *
1639
+		 * @param int|array                $registration_ids The registration ids that have had their status changed successfully.
1640
+		 * @param bool                     $status           The status registrations were changed to.
1641
+		 * @param bool                     $success          If the status was changed successfully for all registrations.
1642
+		 * @param Registrations_Admin_Page $admin_page
1643
+		 */
1644
+		$REG_ID = apply_filters(
1645
+			'FHEE__Registrations_Admin_Page___set_registration_status_from_request__REG_IDs',
1646
+			$result['REG_ID'],
1647
+			$status,
1648
+			$result['success'],
1649
+			$this
1650
+		);
1651
+		$this->request->setRequestParam('_REG_ID', $REG_ID);
1652
+
1653
+		// notify?
1654
+		if (
1655
+			$notify
1656
+			&& $result['success']
1657
+			&& ! empty($REG_ID)
1658
+			&& $this->capabilities->current_user_can(
1659
+				'ee_send_message',
1660
+				'espresso_registrations_resend_registration'
1661
+			)
1662
+		) {
1663
+			$this->_process_resend_registration();
1664
+		}
1665
+		return $result;
1666
+	}
1667
+
1668
+
1669
+	/**
1670
+	 * Set the registration status for the given reg_id (which may or may not be an array, it gets typecast to an
1671
+	 * array). Note, this method does NOT take care of possible notifications.  That is required by calling code.
1672
+	 *
1673
+	 * @param array  $REG_IDs
1674
+	 * @param string $status
1675
+	 * @param bool   $notify Used to indicate whether notification was requested or not.  This determines the context
1676
+	 *                       slug sent with setting the registration status.
1677
+	 * @return array (an array with 'success' key representing whether status change was successful, and 'REG_ID' as
1678
+	 * @throws EE_Error
1679
+	 * @throws InvalidArgumentException
1680
+	 * @throws InvalidDataTypeException
1681
+	 * @throws InvalidInterfaceException
1682
+	 * @throws ReflectionException
1683
+	 * @throws RuntimeException
1684
+	 * @throws EntityNotFoundException
1685
+	 * @throws DomainException
1686
+	 */
1687
+	protected function _set_registration_status($REG_IDs = [], $status = '', $notify = false)
1688
+	{
1689
+		$success = false;
1690
+		// typecast $REG_IDs
1691
+		$REG_IDs = (array) $REG_IDs;
1692
+		if (! empty($REG_IDs)) {
1693
+			$success = true;
1694
+			// set default status if none is passed
1695
+			$status         = $status ?: EEM_Registration::status_id_pending_payment;
1696
+			$status_context = $notify
1697
+				? Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN_NOTIFY
1698
+				: Domain::CONTEXT_REGISTRATION_STATUS_CHANGE_REGISTRATION_ADMIN;
1699
+			// loop through REG_ID's and change status
1700
+			foreach ($REG_IDs as $REG_ID) {
1701
+				$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
1702
+				if ($registration instanceof EE_Registration) {
1703
+					$registration->set_status(
1704
+						$status,
1705
+						false,
1706
+						new Context(
1707
+							$status_context,
1708
+							esc_html__(
1709
+								'Manually triggered status change on a Registration Admin Page route.',
1710
+								'event_espresso'
1711
+							)
1712
+						)
1713
+					);
1714
+					$result = $registration->save();
1715
+					// verifying explicit fails because update *may* just return 0 for 0 rows affected
1716
+					$success = $result !== false ? $success : false;
1717
+				}
1718
+			}
1719
+		}
1720
+
1721
+		// return $success and processed registrations
1722
+		return ['REG_ID' => $REG_IDs, 'success' => $success];
1723
+	}
1724
+
1725
+
1726
+	/**
1727
+	 * Common logic for setting up success message and redirecting to appropriate route
1728
+	 *
1729
+	 * @param string $STS_ID status id for the registration changed to
1730
+	 * @param bool   $notify indicates whether the _set_registration_status_from_request does notifications or not.
1731
+	 * @return void
1732
+	 * @throws DomainException
1733
+	 * @throws EE_Error
1734
+	 * @throws EntityNotFoundException
1735
+	 * @throws InvalidArgumentException
1736
+	 * @throws InvalidDataTypeException
1737
+	 * @throws InvalidInterfaceException
1738
+	 * @throws ReflectionException
1739
+	 * @throws RuntimeException
1740
+	 */
1741
+	protected function _reg_status_change_return($STS_ID, $notify = false)
1742
+	{
1743
+		$result  = ! empty($STS_ID) ? $this->_set_registration_status_from_request($STS_ID, $notify)
1744
+			: ['success' => false];
1745
+		$success = isset($result['success']) && $result['success'];
1746
+		// setup success message
1747
+		if ($success) {
1748
+			if (is_array($result['REG_ID']) && count($result['REG_ID']) === 1) {
1749
+				$msg = sprintf(
1750
+					esc_html__('Registration status has been set to %s', 'event_espresso'),
1751
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1752
+				);
1753
+			} else {
1754
+				$msg = sprintf(
1755
+					esc_html__('Registrations have been set to %s.', 'event_espresso'),
1756
+					EEH_Template::pretty_status($STS_ID, false, 'lower')
1757
+				);
1758
+			}
1759
+			EE_Error::add_success($msg);
1760
+		} else {
1761
+			EE_Error::add_error(
1762
+				esc_html__(
1763
+					'Something went wrong, and the status was not changed',
1764
+					'event_espresso'
1765
+				),
1766
+				__FILE__,
1767
+				__LINE__,
1768
+				__FUNCTION__
1769
+			);
1770
+		}
1771
+		$return = $this->request->getRequestParam('return');
1772
+		$route  = $return === 'view_registration'
1773
+			? ['action' => 'view_registration', '_REG_ID' => reset($result['REG_ID'])]
1774
+			: ['action' => 'default'];
1775
+		$route  = $this->mergeExistingRequestParamsWithRedirectArgs($route);
1776
+		$this->_redirect_after_action($success, '', '', $route, true);
1777
+	}
1778
+
1779
+
1780
+	/**
1781
+	 * incoming reg status change from reg details page.
1782
+	 *
1783
+	 * @return void
1784
+	 * @throws EE_Error
1785
+	 * @throws EntityNotFoundException
1786
+	 * @throws InvalidArgumentException
1787
+	 * @throws InvalidDataTypeException
1788
+	 * @throws InvalidInterfaceException
1789
+	 * @throws ReflectionException
1790
+	 * @throws RuntimeException
1791
+	 * @throws DomainException
1792
+	 */
1793
+	protected function _change_reg_status()
1794
+	{
1795
+		$this->request->setRequestParam('return', 'view_registration');
1796
+		// set notify based on whether the send notifications toggle is set or not
1797
+		$notify     = $this->request->getRequestParam('reg_status_change_form[send_notifications]', false, 'bool');
1798
+		$reg_status = $this->request->getRequestParam('reg_status_change_form[reg_status]', '');
1799
+		$this->request->setRequestParam('reg_status_change_form[reg_status]', $reg_status);
1800
+		switch ($reg_status) {
1801
+			case EEM_Registration::status_id_approved:
1802
+			case EEH_Template::pretty_status(EEM_Registration::status_id_approved, false, 'sentence'):
1803
+				$this->approve_registration($notify);
1804
+				break;
1805
+			case EEM_Registration::status_id_pending_payment:
1806
+			case EEH_Template::pretty_status(EEM_Registration::status_id_pending_payment, false, 'sentence'):
1807
+				$this->pending_registration($notify);
1808
+				break;
1809
+			case EEM_Registration::status_id_not_approved:
1810
+			case EEH_Template::pretty_status(EEM_Registration::status_id_not_approved, false, 'sentence'):
1811
+				$this->not_approve_registration($notify);
1812
+				break;
1813
+			case EEM_Registration::status_id_declined:
1814
+			case EEH_Template::pretty_status(EEM_Registration::status_id_declined, false, 'sentence'):
1815
+				$this->decline_registration($notify);
1816
+				break;
1817
+			case EEM_Registration::status_id_cancelled:
1818
+			case EEH_Template::pretty_status(EEM_Registration::status_id_cancelled, false, 'sentence'):
1819
+				$this->cancel_registration($notify);
1820
+				break;
1821
+			case EEM_Registration::status_id_wait_list:
1822
+			case EEH_Template::pretty_status(EEM_Registration::status_id_wait_list, false, 'sentence'):
1823
+				$this->wait_list_registration($notify);
1824
+				break;
1825
+			case EEM_Registration::status_id_incomplete:
1826
+			default:
1827
+				$this->request->unSetRequestParam('return');
1828
+				$this->_reg_status_change_return('');
1829
+				break;
1830
+		}
1831
+	}
1832
+
1833
+
1834
+	/**
1835
+	 * Callback for bulk action routes.
1836
+	 * Note: although we could just register the singular route callbacks for each bulk action route as well, this
1837
+	 * method was chosen so there is one central place all the registration status bulk actions are going through.
1838
+	 * Potentially, this provides an easier place to locate logic that is specific to these bulk actions (as opposed to
1839
+	 * when an action is happening on just a single registration).
1840
+	 *
1841
+	 * @param      $action
1842
+	 * @param bool $notify
1843
+	 */
1844
+	protected function bulk_action_on_registrations($action, $notify = false)
1845
+	{
1846
+		do_action(
1847
+			'AHEE__Registrations_Admin_Page__bulk_action_on_registrations__before_execution',
1848
+			$this,
1849
+			$action,
1850
+			$notify
1851
+		);
1852
+		$method = $action . '_registration';
1853
+		if (method_exists($this, $method)) {
1854
+			$this->$method($notify);
1855
+		}
1856
+	}
1857
+
1858
+
1859
+	/**
1860
+	 * approve_registration
1861
+	 *
1862
+	 * @param bool $notify whether or not to notify the registrant about their approval.
1863
+	 * @return void
1864
+	 * @throws EE_Error
1865
+	 * @throws EntityNotFoundException
1866
+	 * @throws InvalidArgumentException
1867
+	 * @throws InvalidDataTypeException
1868
+	 * @throws InvalidInterfaceException
1869
+	 * @throws ReflectionException
1870
+	 * @throws RuntimeException
1871
+	 * @throws DomainException
1872
+	 */
1873
+	protected function approve_registration($notify = false)
1874
+	{
1875
+		$this->_reg_status_change_return(EEM_Registration::status_id_approved, $notify);
1876
+	}
1877
+
1878
+
1879
+	/**
1880
+	 * decline_registration
1881
+	 *
1882
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1883
+	 * @return void
1884
+	 * @throws EE_Error
1885
+	 * @throws EntityNotFoundException
1886
+	 * @throws InvalidArgumentException
1887
+	 * @throws InvalidDataTypeException
1888
+	 * @throws InvalidInterfaceException
1889
+	 * @throws ReflectionException
1890
+	 * @throws RuntimeException
1891
+	 * @throws DomainException
1892
+	 */
1893
+	protected function decline_registration($notify = false)
1894
+	{
1895
+		$this->_reg_status_change_return(EEM_Registration::status_id_declined, $notify);
1896
+	}
1897
+
1898
+
1899
+	/**
1900
+	 * cancel_registration
1901
+	 *
1902
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1903
+	 * @return void
1904
+	 * @throws EE_Error
1905
+	 * @throws EntityNotFoundException
1906
+	 * @throws InvalidArgumentException
1907
+	 * @throws InvalidDataTypeException
1908
+	 * @throws InvalidInterfaceException
1909
+	 * @throws ReflectionException
1910
+	 * @throws RuntimeException
1911
+	 * @throws DomainException
1912
+	 */
1913
+	protected function cancel_registration($notify = false)
1914
+	{
1915
+		$this->_reg_status_change_return(EEM_Registration::status_id_cancelled, $notify);
1916
+	}
1917
+
1918
+
1919
+	/**
1920
+	 * not_approve_registration
1921
+	 *
1922
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1923
+	 * @return void
1924
+	 * @throws EE_Error
1925
+	 * @throws EntityNotFoundException
1926
+	 * @throws InvalidArgumentException
1927
+	 * @throws InvalidDataTypeException
1928
+	 * @throws InvalidInterfaceException
1929
+	 * @throws ReflectionException
1930
+	 * @throws RuntimeException
1931
+	 * @throws DomainException
1932
+	 */
1933
+	protected function not_approve_registration($notify = false)
1934
+	{
1935
+		$this->_reg_status_change_return(EEM_Registration::status_id_not_approved, $notify);
1936
+	}
1937
+
1938
+
1939
+	/**
1940
+	 * decline_registration
1941
+	 *
1942
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1943
+	 * @return void
1944
+	 * @throws EE_Error
1945
+	 * @throws EntityNotFoundException
1946
+	 * @throws InvalidArgumentException
1947
+	 * @throws InvalidDataTypeException
1948
+	 * @throws InvalidInterfaceException
1949
+	 * @throws ReflectionException
1950
+	 * @throws RuntimeException
1951
+	 * @throws DomainException
1952
+	 */
1953
+	protected function pending_registration($notify = false)
1954
+	{
1955
+		$this->_reg_status_change_return(EEM_Registration::status_id_pending_payment, $notify);
1956
+	}
1957
+
1958
+
1959
+	/**
1960
+	 * waitlist_registration
1961
+	 *
1962
+	 * @param bool $notify whether or not to notify the registrant about their status change.
1963
+	 * @return void
1964
+	 * @throws EE_Error
1965
+	 * @throws EntityNotFoundException
1966
+	 * @throws InvalidArgumentException
1967
+	 * @throws InvalidDataTypeException
1968
+	 * @throws InvalidInterfaceException
1969
+	 * @throws ReflectionException
1970
+	 * @throws RuntimeException
1971
+	 * @throws DomainException
1972
+	 */
1973
+	protected function wait_list_registration($notify = false)
1974
+	{
1975
+		$this->_reg_status_change_return(EEM_Registration::status_id_wait_list, $notify);
1976
+	}
1977
+
1978
+
1979
+	/**
1980
+	 * generates HTML for the Registration main meta box
1981
+	 *
1982
+	 * @return void
1983
+	 * @throws DomainException
1984
+	 * @throws EE_Error
1985
+	 * @throws InvalidArgumentException
1986
+	 * @throws InvalidDataTypeException
1987
+	 * @throws InvalidInterfaceException
1988
+	 * @throws ReflectionException
1989
+	 * @throws EntityNotFoundException
1990
+	 */
1991
+	public function _reg_details_meta_box()
1992
+	{
1993
+		EEH_Autoloader::register_line_item_display_autoloaders();
1994
+		EEH_Autoloader::register_line_item_filter_autoloaders();
1995
+		EE_Registry::instance()->load_helper('Line_Item');
1996
+		$transaction    = $this->_registration->transaction() ? $this->_registration->transaction()
1997
+			: EE_Transaction::new_instance();
1998
+		$this->_session = $transaction->session_data();
1999
+		$filters        = new EE_Line_Item_Filter_Collection();
2000
+		$filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001
+		$filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
+		$line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2003
+			$filters,
2004
+			$transaction->total_line_item()
2005
+		);
2006
+		$filtered_line_item_tree                 = $line_item_filter_processor->process();
2007
+		$line_item_display                       = new EE_Line_Item_Display(
2008
+			'reg_admin_table',
2009
+			'EE_Admin_Table_Registration_Line_Item_Display_Strategy'
2010
+		);
2011
+		$this->_template_args['line_item_table'] = $line_item_display->display_line_item(
2012
+			$filtered_line_item_tree,
2013
+			['EE_Registration' => $this->_registration]
2014
+		);
2015
+		$attendee                                = $this->_registration->attendee();
2016
+		if (
2017
+			$this->capabilities->current_user_can(
2018
+				'ee_read_transaction',
2019
+				'espresso_transactions_view_transaction'
2020
+			)
2021
+		) {
2022
+			$this->_template_args['view_transaction_button'] = EEH_Template::get_button_or_link(
2023
+				EE_Admin_Page::add_query_args_and_nonce(
2024
+					[
2025
+						'action' => 'view_transaction',
2026
+						'TXN_ID' => $transaction->ID(),
2027
+					],
2028
+					TXN_ADMIN_URL
2029
+				),
2030
+				esc_html__(' View Transaction', 'event_espresso'),
2031
+				'button button--secondary right',
2032
+				'dashicons dashicons-cart'
2033
+			);
2034
+		} else {
2035
+			$this->_template_args['view_transaction_button'] = '';
2036
+		}
2037
+		if (
2038
+			$attendee instanceof EE_Attendee
2039
+			&& $this->capabilities->current_user_can(
2040
+				'ee_send_message',
2041
+				'espresso_registrations_resend_registration'
2042
+			)
2043
+		) {
2044
+			$this->_template_args['resend_registration_button'] = EEH_Template::get_button_or_link(
2045
+				EE_Admin_Page::add_query_args_and_nonce(
2046
+					[
2047
+						'action'      => 'resend_registration',
2048
+						'_REG_ID'     => $this->_registration->ID(),
2049
+						'redirect_to' => 'view_registration',
2050
+					],
2051
+					REG_ADMIN_URL
2052
+				),
2053
+				esc_html__(' Resend Registration', 'event_espresso'),
2054
+				'button button--secondary right',
2055
+				'dashicons dashicons-email-alt'
2056
+			);
2057
+		} else {
2058
+			$this->_template_args['resend_registration_button'] = '';
2059
+		}
2060
+		$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2061
+		$payment                               = $transaction->get_first_related('Payment');
2062
+		$payment                               = ! $payment instanceof EE_Payment
2063
+			? EE_Payment::new_instance()
2064
+			: $payment;
2065
+		$payment_method                        = $payment->get_first_related('Payment_Method');
2066
+		$payment_method                        = ! $payment_method instanceof EE_Payment_Method
2067
+			? EE_Payment_Method::new_instance()
2068
+			: $payment_method;
2069
+		$reg_details                           = [
2070
+			'payment_method'       => $payment_method->name(),
2071
+			'response_msg'         => $payment->gateway_response(),
2072
+			'registration_id'      => $this->_registration->get('REG_code'),
2073
+			'registration_session' => $this->_registration->session_ID(),
2074
+			'ip_address'           => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '',
2075
+			'user_agent'           => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '',
2076
+		];
2077
+		if (isset($reg_details['registration_id'])) {
2078
+			$this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
2079
+			$this->_template_args['reg_details']['registration_id']['label'] = esc_html__(
2080
+				'Registration ID',
2081
+				'event_espresso'
2082
+			);
2083
+			$this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
2084
+		}
2085
+		if (isset($reg_details['payment_method'])) {
2086
+			$this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
2087
+			$this->_template_args['reg_details']['payment_method']['label'] = esc_html__(
2088
+				'Most Recent Payment Method',
2089
+				'event_espresso'
2090
+			);
2091
+			$this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
2092
+			$this->_template_args['reg_details']['response_msg']['value']   = $reg_details['response_msg'];
2093
+			$this->_template_args['reg_details']['response_msg']['label']   = esc_html__(
2094
+				'Payment method response',
2095
+				'event_espresso'
2096
+			);
2097
+			$this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2098
+		}
2099
+		$this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100
+		$this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
2101
+			'Registration Session',
2102
+			'event_espresso'
2103
+		);
2104
+		$this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
2105
+		$this->_template_args['reg_details']['ip_address']['value']           = $reg_details['ip_address'];
2106
+		$this->_template_args['reg_details']['ip_address']['label']           = esc_html__(
2107
+			'Registration placed from IP',
2108
+			'event_espresso'
2109
+		);
2110
+		$this->_template_args['reg_details']['ip_address']['class']           = 'regular-text';
2111
+		$this->_template_args['reg_details']['user_agent']['value']           = $reg_details['user_agent'];
2112
+		$this->_template_args['reg_details']['user_agent']['label']           = esc_html__(
2113
+			'Registrant User Agent',
2114
+			'event_espresso'
2115
+		);
2116
+		$this->_template_args['reg_details']['user_agent']['class']           = 'large-text';
2117
+		$this->_template_args['event_link']                                   = EE_Admin_Page::add_query_args_and_nonce(
2118
+			[
2119
+				'action'   => 'default',
2120
+				'event_id' => $this->_registration->event_ID(),
2121
+			],
2122
+			REG_ADMIN_URL
2123
+		);
2124
+
2125
+		$this->_template_args['REG_ID']   = $this->_registration->ID();
2126
+		$this->_template_args['event_id'] = $this->_registration->event_ID();
2127
+
2128
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2129
+		EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130
+	}
2131
+
2132
+
2133
+	/**
2134
+	 * generates HTML for the Registration Questions meta box.
2135
+	 * If pre-4.8.32.rc.000 hooks are used, uses old methods (with its filters),
2136
+	 * otherwise uses new forms system
2137
+	 *
2138
+	 * @return void
2139
+	 * @throws DomainException
2140
+	 * @throws EE_Error
2141
+	 * @throws InvalidArgumentException
2142
+	 * @throws InvalidDataTypeException
2143
+	 * @throws InvalidInterfaceException
2144
+	 * @throws ReflectionException
2145
+	 */
2146
+	public function _reg_questions_meta_box()
2147
+	{
2148
+		// allow someone to override this method entirely
2149
+		if (
2150
+			apply_filters(
2151
+				'FHEE__Registrations_Admin_Page___reg_questions_meta_box__do_default',
2152
+				true,
2153
+				$this,
2154
+				$this->_registration
2155
+			)
2156
+		) {
2157
+			$form = $this->_get_reg_custom_questions_form(
2158
+				$this->_registration->ID()
2159
+			);
2160
+
2161
+			$this->_template_args['att_questions'] = count($form->subforms()) > 0
2162
+				? $form->get_html_and_js()
2163
+				: '';
2164
+
2165
+			$this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166
+			$this->_template_args['REG_ID']                    = $this->_registration->ID();
2167
+			$template_path                                     =
2168
+				REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2169
+			EEH_Template::display_template($template_path, $this->_template_args);
2170
+		}
2171
+	}
2172
+
2173
+
2174
+	/**
2175
+	 * form_before_question_group
2176
+	 *
2177
+	 * @param string $output
2178
+	 * @return        string
2179
+	 * @deprecated    as of 4.8.32.rc.000
2180
+	 */
2181
+	public function form_before_question_group($output)
2182
+	{
2183
+		EE_Error::doing_it_wrong(
2184
+			__CLASS__ . '::' . __FUNCTION__,
2185
+			esc_html__(
2186
+				'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.',
2187
+				'event_espresso'
2188
+			),
2189
+			'4.8.32.rc.000'
2190
+		);
2191
+		return '
2192 2192
 	<table class="form-table ee-width-100">
2193 2193
 		<tbody>
2194 2194
 			';
2195
-    }
2196
-
2197
-
2198
-    /**
2199
-     * form_after_question_group
2200
-     *
2201
-     * @param string $output
2202
-     * @return        string
2203
-     * @deprecated    as of 4.8.32.rc.000
2204
-     */
2205
-    public function form_after_question_group($output)
2206
-    {
2207
-        EE_Error::doing_it_wrong(
2208
-            __CLASS__ . '::' . __FUNCTION__,
2209
-            esc_html__(
2210
-                '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.',
2211
-                'event_espresso'
2212
-            ),
2213
-            '4.8.32.rc.000'
2214
-        );
2215
-        return '
2195
+	}
2196
+
2197
+
2198
+	/**
2199
+	 * form_after_question_group
2200
+	 *
2201
+	 * @param string $output
2202
+	 * @return        string
2203
+	 * @deprecated    as of 4.8.32.rc.000
2204
+	 */
2205
+	public function form_after_question_group($output)
2206
+	{
2207
+		EE_Error::doing_it_wrong(
2208
+			__CLASS__ . '::' . __FUNCTION__,
2209
+			esc_html__(
2210
+				'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.',
2211
+				'event_espresso'
2212
+			),
2213
+			'4.8.32.rc.000'
2214
+		);
2215
+		return '
2216 2216
 			<tr class="hide-if-no-js">
2217 2217
 				<th> </th>
2218 2218
 				<td class="reg-admin-edit-attendee-question-td">
2219 2219
 					<a class="reg-admin-edit-attendee-question-lnk" href="#" aria-label="'
2220
-               . esc_attr__('click to edit question', 'event_espresso')
2221
-               . '">
2220
+			   . esc_attr__('click to edit question', 'event_espresso')
2221
+			   . '">
2222 2222
 						<span class="reg-admin-edit-question-group-spn lt-grey-txt">'
2223
-               . esc_html__('edit the above question group', 'event_espresso')
2224
-               . '</span>
2223
+			   . esc_html__('edit the above question group', 'event_espresso')
2224
+			   . '</span>
2225 2225
 						<div class="dashicons dashicons-edit"></div>
2226 2226
 					</a>
2227 2227
 				</td>
@@ -2229,642 +2229,642 @@  discard block
 block discarded – undo
2229 2229
 		</tbody>
2230 2230
 	</table>
2231 2231
 ';
2232
-    }
2233
-
2234
-
2235
-    /**
2236
-     * form_form_field_label_wrap
2237
-     *
2238
-     * @param string $label
2239
-     * @return        string
2240
-     * @deprecated    as of 4.8.32.rc.000
2241
-     */
2242
-    public function form_form_field_label_wrap($label)
2243
-    {
2244
-        EE_Error::doing_it_wrong(
2245
-            __CLASS__ . '::' . __FUNCTION__,
2246
-            esc_html__(
2247
-                '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.',
2248
-                'event_espresso'
2249
-            ),
2250
-            '4.8.32.rc.000'
2251
-        );
2252
-        return '
2232
+	}
2233
+
2234
+
2235
+	/**
2236
+	 * form_form_field_label_wrap
2237
+	 *
2238
+	 * @param string $label
2239
+	 * @return        string
2240
+	 * @deprecated    as of 4.8.32.rc.000
2241
+	 */
2242
+	public function form_form_field_label_wrap($label)
2243
+	{
2244
+		EE_Error::doing_it_wrong(
2245
+			__CLASS__ . '::' . __FUNCTION__,
2246
+			esc_html__(
2247
+				'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.',
2248
+				'event_espresso'
2249
+			),
2250
+			'4.8.32.rc.000'
2251
+		);
2252
+		return '
2253 2253
 			<tr>
2254 2254
 				<th>
2255 2255
 					' . $label . '
2256 2256
 				</th>';
2257
-    }
2258
-
2259
-
2260
-    /**
2261
-     * form_form_field_input__wrap
2262
-     *
2263
-     * @param string $input
2264
-     * @return        string
2265
-     * @deprecated    as of 4.8.32.rc.000
2266
-     */
2267
-    public function form_form_field_input__wrap($input)
2268
-    {
2269
-        EE_Error::doing_it_wrong(
2270
-            __CLASS__ . '::' . __FUNCTION__,
2271
-            esc_html__(
2272
-                '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.',
2273
-                'event_espresso'
2274
-            ),
2275
-            '4.8.32.rc.000'
2276
-        );
2277
-        return '
2257
+	}
2258
+
2259
+
2260
+	/**
2261
+	 * form_form_field_input__wrap
2262
+	 *
2263
+	 * @param string $input
2264
+	 * @return        string
2265
+	 * @deprecated    as of 4.8.32.rc.000
2266
+	 */
2267
+	public function form_form_field_input__wrap($input)
2268
+	{
2269
+		EE_Error::doing_it_wrong(
2270
+			__CLASS__ . '::' . __FUNCTION__,
2271
+			esc_html__(
2272
+				'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.',
2273
+				'event_espresso'
2274
+			),
2275
+			'4.8.32.rc.000'
2276
+		);
2277
+		return '
2278 2278
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2279 2279
 					' . $input . '
2280 2280
 				</td>
2281 2281
 			</tr>';
2282
-    }
2283
-
2284
-
2285
-    /**
2286
-     * Updates the registration's custom questions according to the form info, if the form is submitted.
2287
-     * If it's not a post, the "view_registrations" route will be called next on the SAME request
2288
-     * to display the page
2289
-     *
2290
-     * @return void
2291
-     * @throws EE_Error
2292
-     * @throws InvalidArgumentException
2293
-     * @throws InvalidDataTypeException
2294
-     * @throws InvalidInterfaceException
2295
-     * @throws ReflectionException
2296
-     */
2297
-    protected function _update_attendee_registration_form()
2298
-    {
2299
-        do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2300
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2301
-            $REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2302
-            $success = $this->_save_reg_custom_questions_form($REG_ID);
2303
-            if ($success) {
2304
-                $what  = esc_html__('Registration Form', 'event_espresso');
2305
-                $route = $REG_ID
2306
-                    ? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2307
-                    : ['action' => 'default'];
2308
-                $this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2309
-            }
2310
-        }
2311
-    }
2312
-
2313
-
2314
-    /**
2315
-     * Gets the form for saving registrations custom questions (if done
2316
-     * previously retrieves the cached form object, which may have validation errors in it)
2317
-     *
2318
-     * @param int $REG_ID
2319
-     * @return EE_Registration_Custom_Questions_Form
2320
-     * @throws EE_Error
2321
-     * @throws InvalidArgumentException
2322
-     * @throws InvalidDataTypeException
2323
-     * @throws InvalidInterfaceException
2324
-     * @throws ReflectionException
2325
-     */
2326
-    protected function _get_reg_custom_questions_form($REG_ID)
2327
-    {
2328
-        if (! $this->_reg_custom_questions_form) {
2329
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2330
-            $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2331
-                $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2332
-            );
2333
-            $this->_reg_custom_questions_form->_construct_finalize(null, null);
2334
-        }
2335
-        return $this->_reg_custom_questions_form;
2336
-    }
2337
-
2338
-
2339
-    /**
2340
-     * Saves
2341
-     *
2342
-     * @param bool $REG_ID
2343
-     * @return bool
2344
-     * @throws EE_Error
2345
-     * @throws InvalidArgumentException
2346
-     * @throws InvalidDataTypeException
2347
-     * @throws InvalidInterfaceException
2348
-     * @throws ReflectionException
2349
-     */
2350
-    private function _save_reg_custom_questions_form($REG_ID = 0)
2351
-    {
2352
-        if (! $REG_ID) {
2353
-            EE_Error::add_error(
2354
-                esc_html__(
2355
-                    'An error occurred. No registration ID was received.',
2356
-                    'event_espresso'
2357
-                ),
2358
-                __FILE__,
2359
-                __FUNCTION__,
2360
-                __LINE__
2361
-            );
2362
-        }
2363
-        $form = $this->_get_reg_custom_questions_form($REG_ID);
2364
-        $form->receive_form_submission($this->request->requestParams());
2365
-        $success = false;
2366
-        if ($form->is_valid()) {
2367
-            foreach ($form->subforms() as $question_group_form) {
2368
-                foreach ($question_group_form->inputs() as $question_id => $input) {
2369
-                    $where_conditions    = [
2370
-                        'QST_ID' => $question_id,
2371
-                        'REG_ID' => $REG_ID,
2372
-                    ];
2373
-                    $possibly_new_values = [
2374
-                        'ANS_value' => $input->normalized_value(),
2375
-                    ];
2376
-                    $answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2377
-                    if ($answer instanceof EE_Answer) {
2378
-                        $success = $answer->save($possibly_new_values);
2379
-                    } else {
2380
-                        // insert it then
2381
-                        $cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2382
-                        $answer      = EE_Answer::new_instance($cols_n_vals);
2383
-                        $success     = $answer->save();
2384
-                    }
2385
-                }
2386
-            }
2387
-        } else {
2388
-            EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2389
-        }
2390
-        return $success;
2391
-    }
2392
-
2393
-
2394
-    /**
2395
-     * generates HTML for the Registration main meta box
2396
-     *
2397
-     * @return void
2398
-     * @throws DomainException
2399
-     * @throws EE_Error
2400
-     * @throws InvalidArgumentException
2401
-     * @throws InvalidDataTypeException
2402
-     * @throws InvalidInterfaceException
2403
-     * @throws ReflectionException
2404
-     */
2405
-    public function _reg_attendees_meta_box()
2406
-    {
2407
-        $REG = $this->getRegistrationModel();
2408
-        // get all other registrations on this transaction, and cache
2409
-        // the attendees for them so we don't have to run another query using force_join
2410
-        $registrations                           = $REG->get_all(
2411
-            [
2412
-                [
2413
-                    'TXN_ID' => $this->_registration->transaction_ID(),
2414
-                    'REG_ID' => ['!=', $this->_registration->ID()],
2415
-                ],
2416
-                'force_join'               => ['Attendee'],
2417
-                'default_where_conditions' => 'other_models_only',
2418
-            ]
2419
-        );
2420
-        $this->_template_args['attendees']       = [];
2421
-        $this->_template_args['attendee_notice'] = '';
2422
-        if (
2423
-            empty($registrations)
2424
-            || (is_array($registrations)
2425
-                && ! EEH_Array::get_one_item_from_array($registrations))
2426
-        ) {
2427
-            EE_Error::add_error(
2428
-                esc_html__(
2429
-                    'There are no records attached to this registration. Something may have gone wrong with the registration',
2430
-                    'event_espresso'
2431
-                ),
2432
-                __FILE__,
2433
-                __FUNCTION__,
2434
-                __LINE__
2435
-            );
2436
-            $this->_template_args['attendee_notice'] = EE_Error::get_notices();
2437
-        } else {
2438
-            $att_nmbr = 1;
2439
-            foreach ($registrations as $registration) {
2440
-                /* @var $registration EE_Registration */
2441
-                $attendee                                                      = $registration->attendee()
2442
-                    ? $registration->attendee()
2443
-                    : $this->getAttendeeModel()->create_default_object();
2444
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2445
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2446
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2447
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2448
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2449
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2450
-                    ', ',
2451
-                    $attendee->full_address_as_array()
2452
-                );
2453
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2454
-                    [
2455
-                        'action' => 'edit_attendee',
2456
-                        'post'   => $attendee->ID(),
2457
-                    ],
2458
-                    REG_ADMIN_URL
2459
-                );
2460
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2461
-                    $registration->event_obj() instanceof EE_Event
2462
-                        ? $registration->event_obj()->name()
2463
-                        : '';
2464
-                $att_nmbr++;
2465
-            }
2466
-            $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2467
-        }
2468
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2469
-        EEH_Template::display_template($template_path, $this->_template_args);
2470
-    }
2471
-
2472
-
2473
-    /**
2474
-     * generates HTML for the Edit Registration side meta box
2475
-     *
2476
-     * @return void
2477
-     * @throws DomainException
2478
-     * @throws EE_Error
2479
-     * @throws InvalidArgumentException
2480
-     * @throws InvalidDataTypeException
2481
-     * @throws InvalidInterfaceException
2482
-     * @throws ReflectionException
2483
-     */
2484
-    public function _reg_registrant_side_meta_box()
2485
-    {
2486
-        /*@var $attendee EE_Attendee */
2487
-        $att_check = $this->_registration->attendee();
2488
-        $attendee  = $att_check instanceof EE_Attendee
2489
-            ? $att_check
2490
-            : $this->getAttendeeModel()->create_default_object();
2491
-        // now let's determine if this is not the primary registration.  If it isn't then we set the
2492
-        // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2493
-        // primary registration object (that way we know if we need to show create button or not)
2494
-        if (! $this->_registration->is_primary_registrant()) {
2495
-            $primary_registration = $this->_registration->get_primary_registration();
2496
-            $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2497
-                : null;
2498
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2499
-                // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2500
-                // custom attendee object so let's not worry about the primary reg.
2501
-                $primary_registration = null;
2502
-            }
2503
-        } else {
2504
-            $primary_registration = null;
2505
-        }
2506
-        $this->_template_args['ATT_ID']            = $attendee->ID();
2507
-        $this->_template_args['fname']             = $attendee->fname();
2508
-        $this->_template_args['lname']             = $attendee->lname();
2509
-        $this->_template_args['email']             = $attendee->email();
2510
-        $this->_template_args['phone']             = $attendee->phone();
2511
-        $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2512
-        // edit link
2513
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2514
-            [
2515
-                'action' => 'edit_attendee',
2516
-                'post'   => $attendee->ID(),
2517
-            ],
2518
-            REG_ADMIN_URL
2519
-        );
2520
-        $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2521
-        $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2522
-        // create link
2523
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2524
-            ? EE_Admin_Page::add_query_args_and_nonce(
2525
-                [
2526
-                    'action'  => 'duplicate_attendee',
2527
-                    '_REG_ID' => $this->_registration->ID(),
2528
-                ],
2529
-                REG_ADMIN_URL
2530
-            ) : '';
2531
-        $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2532
-        $this->_template_args['att_check']    = $att_check;
2533
-        $template_path                        =
2534
-            REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2535
-        EEH_Template::display_template($template_path, $this->_template_args);
2536
-    }
2537
-
2538
-
2539
-    /**
2540
-     * trash or restore registrations
2541
-     *
2542
-     * @param boolean $trash whether to archive or restore
2543
-     * @return void
2544
-     * @throws DomainException
2545
-     * @throws EE_Error
2546
-     * @throws EntityNotFoundException
2547
-     * @throws InvalidArgumentException
2548
-     * @throws InvalidDataTypeException
2549
-     * @throws InvalidInterfaceException
2550
-     * @throws ReflectionException
2551
-     * @throws RuntimeException
2552
-     * @throws UnexpectedEntityException
2553
-     */
2554
-    protected function _trash_or_restore_registrations($trash = true)
2555
-    {
2556
-        // if empty _REG_ID then get out because there's nothing to do
2557
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2558
-        if (empty($REG_IDs)) {
2559
-            EE_Error::add_error(
2560
-                sprintf(
2561
-                    esc_html__(
2562
-                        'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2563
-                        'event_espresso'
2564
-                    ),
2565
-                    $trash ? 'trash' : 'restore'
2566
-                ),
2567
-                __FILE__,
2568
-                __LINE__,
2569
-                __FUNCTION__
2570
-            );
2571
-            $this->_redirect_after_action(false, '', '', [], true);
2572
-        }
2573
-        $success        = 0;
2574
-        $overwrite_msgs = false;
2575
-        // Checkboxes
2576
-        $reg_count = count($REG_IDs);
2577
-        // cycle thru checkboxes
2578
-        foreach ($REG_IDs as $REG_ID) {
2579
-            /** @var EE_Registration $REG */
2580
-            $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2581
-            $payments = $REG->registration_payments();
2582
-            if (! empty($payments)) {
2583
-                $name           = $REG->attendee() instanceof EE_Attendee
2584
-                    ? $REG->attendee()->full_name()
2585
-                    : esc_html__('Unknown Attendee', 'event_espresso');
2586
-                $overwrite_msgs = true;
2587
-                EE_Error::add_error(
2588
-                    sprintf(
2589
-                        esc_html__(
2590
-                            '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.',
2591
-                            'event_espresso'
2592
-                        ),
2593
-                        $name
2594
-                    ),
2595
-                    __FILE__,
2596
-                    __FUNCTION__,
2597
-                    __LINE__
2598
-                );
2599
-                // can't trash this registration because it has payments.
2600
-                continue;
2601
-            }
2602
-            $updated = $trash ? $REG->delete() : $REG->restore();
2603
-            if ($updated) {
2604
-                $success++;
2605
-            }
2606
-        }
2607
-        $this->_redirect_after_action(
2608
-            $success === $reg_count, // were ALL registrations affected?
2609
-            $success > 1
2610
-                ? esc_html__('Registrations', 'event_espresso')
2611
-                : esc_html__('Registration', 'event_espresso'),
2612
-            $trash
2613
-                ? esc_html__('moved to the trash', 'event_espresso')
2614
-                : esc_html__('restored', 'event_espresso'),
2615
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2616
-            $overwrite_msgs
2617
-        );
2618
-    }
2619
-
2620
-
2621
-    /**
2622
-     * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2623
-     * registration but also.
2624
-     * 1. Removing relations to EE_Attendee
2625
-     * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2626
-     * ALSO trashed.
2627
-     * 3. Deleting permanently any related Line items but only if the above conditions are met.
2628
-     * 4. Removing relationships between all tickets and the related registrations
2629
-     * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2630
-     * 6. Deleting permanently any related Checkins.
2631
-     *
2632
-     * @return void
2633
-     * @throws EE_Error
2634
-     * @throws InvalidArgumentException
2635
-     * @throws InvalidDataTypeException
2636
-     * @throws InvalidInterfaceException
2637
-     * @throws ReflectionException
2638
-     */
2639
-    protected function _delete_registrations()
2640
-    {
2641
-        $REG_MDL = $this->getRegistrationModel();
2642
-        $success = 0;
2643
-        // Checkboxes
2644
-        $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2645
-
2646
-        if (! empty($REG_IDs)) {
2647
-            // if array has more than one element than success message should be plural
2648
-            $success = count($REG_IDs) > 1 ? 2 : 1;
2649
-            // cycle thru checkboxes
2650
-            foreach ($REG_IDs as $REG_ID) {
2651
-                $REG = $REG_MDL->get_one_by_ID($REG_ID);
2652
-                if (! $REG instanceof EE_Registration) {
2653
-                    continue;
2654
-                }
2655
-                $deleted = $this->_delete_registration($REG);
2656
-                if (! $deleted) {
2657
-                    $success = 0;
2658
-                }
2659
-            }
2660
-        }
2661
-
2662
-        $what        = $success > 1
2663
-            ? esc_html__('Registrations', 'event_espresso')
2664
-            : esc_html__('Registration', 'event_espresso');
2665
-        $action_desc = esc_html__('permanently deleted.', 'event_espresso');
2666
-        $this->_redirect_after_action(
2667
-            $success,
2668
-            $what,
2669
-            $action_desc,
2670
-            $this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2671
-            true
2672
-        );
2673
-    }
2674
-
2675
-
2676
-    /**
2677
-     * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2678
-     * models get affected.
2679
-     *
2680
-     * @param EE_Registration $REG registration to be deleted permanently
2681
-     * @return bool true = successful deletion, false = fail.
2682
-     * @throws EE_Error
2683
-     * @throws InvalidArgumentException
2684
-     * @throws InvalidDataTypeException
2685
-     * @throws InvalidInterfaceException
2686
-     * @throws ReflectionException
2687
-     */
2688
-    protected function _delete_registration(EE_Registration $REG)
2689
-    {
2690
-        // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2691
-        // registrations on the transaction that are NOT trashed.
2692
-        $TXN = $REG->get_first_related('Transaction');
2693
-        if (! $TXN instanceof EE_Transaction) {
2694
-            EE_Error::add_error(
2695
-                sprintf(
2696
-                    esc_html__(
2697
-                        'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2698
-                        'event_espresso'
2699
-                    ),
2700
-                    $REG->id()
2701
-                ),
2702
-                __FILE__,
2703
-                __FUNCTION__,
2704
-                __LINE__
2705
-            );
2706
-            return false;
2707
-        }
2708
-        $REGS        = $TXN->get_many_related('Registration');
2709
-        $all_trashed = true;
2710
-        foreach ($REGS as $registration) {
2711
-            if (! $registration->get('REG_deleted')) {
2712
-                $all_trashed = false;
2713
-            }
2714
-        }
2715
-        if (! $all_trashed) {
2716
-            EE_Error::add_error(
2717
-                esc_html__(
2718
-                    '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.',
2719
-                    'event_espresso'
2720
-                ),
2721
-                __FILE__,
2722
-                __FUNCTION__,
2723
-                __LINE__
2724
-            );
2725
-            return false;
2726
-        }
2727
-        // k made it here so that means we can delete all the related transactions and their answers (but let's do them
2728
-        // separately from THIS one).
2729
-        foreach ($REGS as $registration) {
2730
-            // delete related answers
2731
-            $registration->delete_related_permanently('Answer');
2732
-            // remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2733
-            $attendee = $registration->get_first_related('Attendee');
2734
-            if ($attendee instanceof EE_Attendee) {
2735
-                $registration->_remove_relation_to($attendee, 'Attendee');
2736
-            }
2737
-            // now remove relationships to tickets on this registration.
2738
-            $registration->_remove_relations('Ticket');
2739
-            // now delete permanently the checkins related to this registration.
2740
-            $registration->delete_related_permanently('Checkin');
2741
-            if ($registration->ID() === $REG->ID()) {
2742
-                continue;
2743
-            } //we don't want to delete permanently the existing registration just yet.
2744
-            // remove relation to transaction for these registrations if NOT the existing registrations
2745
-            $registration->_remove_relations('Transaction');
2746
-            // delete permanently any related messages.
2747
-            $registration->delete_related_permanently('Message');
2748
-            // now delete this registration permanently
2749
-            $registration->delete_permanently();
2750
-        }
2751
-        // now all related registrations on the transaction are handled.  So let's just handle this registration itself
2752
-        // (the transaction and line items should be all that's left).
2753
-        // delete the line items related to the transaction for this registration.
2754
-        $TXN->delete_related_permanently('Line_Item');
2755
-        // we need to remove all the relationships on the transaction
2756
-        $TXN->delete_related_permanently('Payment');
2757
-        $TXN->delete_related_permanently('Extra_Meta');
2758
-        $TXN->delete_related_permanently('Message');
2759
-        // now we can delete this REG permanently (and the transaction of course)
2760
-        $REG->delete_related_permanently('Transaction');
2761
-        return $REG->delete_permanently();
2762
-    }
2763
-
2764
-
2765
-    /**
2766
-     *    generates HTML for the Register New Attendee Admin page
2767
-     *
2768
-     * @throws DomainException
2769
-     * @throws EE_Error
2770
-     * @throws InvalidArgumentException
2771
-     * @throws InvalidDataTypeException
2772
-     * @throws InvalidInterfaceException
2773
-     * @throws ReflectionException
2774
-     */
2775
-    public function new_registration()
2776
-    {
2777
-        if (! $this->_set_reg_event()) {
2778
-            throw new EE_Error(
2779
-                esc_html__(
2780
-                    'Unable to continue with registering because there is no Event ID in the request',
2781
-                    'event_espresso'
2782
-                )
2783
-            );
2784
-        }
2785
-        /** @var CurrentPage $current_page */
2786
-        $current_page = $this->loader->getShared(CurrentPage::class);
2787
-        $current_page->setEspressoPage(true);
2788
-        // gotta start with a clean slate if we're not coming here via ajax
2789
-        if (
2790
-            ! $this->request->isAjax()
2791
-            && (
2792
-                ! $this->request->requestParamIsSet('processing_registration')
2793
-                || $this->request->requestParamIsSet('step_error')
2794
-            )
2795
-        ) {
2796
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2797
-        }
2798
-        $this->_template_args['event_name'] = '';
2799
-        // event name
2800
-        if ($this->_reg_event) {
2801
-            $this->_template_args['event_name'] = $this->_reg_event->name();
2802
-            $edit_event_url                     = self::add_query_args_and_nonce(
2803
-                [
2804
-                    'action' => 'edit',
2805
-                    'post'   => $this->_reg_event->ID(),
2806
-                ],
2807
-                EVENTS_ADMIN_URL
2808
-            );
2809
-            $edit_event_lnk                     = '<a href="'
2810
-                                                  . $edit_event_url
2811
-                                                  . '" aria-label="'
2812
-                                                  . esc_attr__('Edit ', 'event_espresso')
2813
-                                                  . $this->_reg_event->name()
2814
-                                                  . '">'
2815
-                                                  . esc_html__('Edit Event', 'event_espresso')
2816
-                                                  . '</a>';
2817
-            $this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2818
-                                                   . $edit_event_lnk
2819
-                                                   . '</span>';
2820
-        }
2821
-        $this->_template_args['step_content'] = $this->_get_registration_step_content();
2822
-        if ($this->request->isAjax()) {
2823
-            $this->_return_json();
2824
-        }
2825
-        // grab header
2826
-        $template_path                              =
2827
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2828
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2829
-            $template_path,
2830
-            $this->_template_args,
2831
-            true
2832
-        );
2833
-        // $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2834
-        // the details template wrapper
2835
-        $this->display_admin_page_with_sidebar();
2836
-    }
2837
-
2838
-
2839
-    /**
2840
-     * This returns the content for a registration step
2841
-     *
2842
-     * @return string html
2843
-     * @throws DomainException
2844
-     * @throws EE_Error
2845
-     * @throws InvalidArgumentException
2846
-     * @throws InvalidDataTypeException
2847
-     * @throws InvalidInterfaceException
2848
-     * @throws ReflectionException
2849
-     */
2850
-    protected function _get_registration_step_content()
2851
-    {
2852
-        if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2853
-            $warning_msg = sprintf(
2854
-                esc_html__(
2855
-                    '%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',
2856
-                    'event_espresso'
2857
-                ),
2858
-                '<br />',
2859
-                '<h3 class="important-notice">',
2860
-                '</h3>',
2861
-                '<div class="float-right">',
2862
-                '<span id="redirect_timer" class="important-notice">30</span>',
2863
-                '</div>',
2864
-                '<b>',
2865
-                '</b>'
2866
-            );
2867
-            return '
2282
+	}
2283
+
2284
+
2285
+	/**
2286
+	 * Updates the registration's custom questions according to the form info, if the form is submitted.
2287
+	 * If it's not a post, the "view_registrations" route will be called next on the SAME request
2288
+	 * to display the page
2289
+	 *
2290
+	 * @return void
2291
+	 * @throws EE_Error
2292
+	 * @throws InvalidArgumentException
2293
+	 * @throws InvalidDataTypeException
2294
+	 * @throws InvalidInterfaceException
2295
+	 * @throws ReflectionException
2296
+	 */
2297
+	protected function _update_attendee_registration_form()
2298
+	{
2299
+		do_action('AHEE__Registrations_Admin_Page___update_attendee_registration_form__start', $this);
2300
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
2301
+			$REG_ID  = $this->request->getRequestParam('_REG_ID', 0, 'int');
2302
+			$success = $this->_save_reg_custom_questions_form($REG_ID);
2303
+			if ($success) {
2304
+				$what  = esc_html__('Registration Form', 'event_espresso');
2305
+				$route = $REG_ID
2306
+					? ['action' => 'view_registration', '_REG_ID' => $REG_ID]
2307
+					: ['action' => 'default'];
2308
+				$this->_redirect_after_action(true, $what, esc_html__('updated', 'event_espresso'), $route);
2309
+			}
2310
+		}
2311
+	}
2312
+
2313
+
2314
+	/**
2315
+	 * Gets the form for saving registrations custom questions (if done
2316
+	 * previously retrieves the cached form object, which may have validation errors in it)
2317
+	 *
2318
+	 * @param int $REG_ID
2319
+	 * @return EE_Registration_Custom_Questions_Form
2320
+	 * @throws EE_Error
2321
+	 * @throws InvalidArgumentException
2322
+	 * @throws InvalidDataTypeException
2323
+	 * @throws InvalidInterfaceException
2324
+	 * @throws ReflectionException
2325
+	 */
2326
+	protected function _get_reg_custom_questions_form($REG_ID)
2327
+	{
2328
+		if (! $this->_reg_custom_questions_form) {
2329
+			require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2330
+			$this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2331
+				$this->getRegistrationModel()->get_one_by_ID($REG_ID)
2332
+			);
2333
+			$this->_reg_custom_questions_form->_construct_finalize(null, null);
2334
+		}
2335
+		return $this->_reg_custom_questions_form;
2336
+	}
2337
+
2338
+
2339
+	/**
2340
+	 * Saves
2341
+	 *
2342
+	 * @param bool $REG_ID
2343
+	 * @return bool
2344
+	 * @throws EE_Error
2345
+	 * @throws InvalidArgumentException
2346
+	 * @throws InvalidDataTypeException
2347
+	 * @throws InvalidInterfaceException
2348
+	 * @throws ReflectionException
2349
+	 */
2350
+	private function _save_reg_custom_questions_form($REG_ID = 0)
2351
+	{
2352
+		if (! $REG_ID) {
2353
+			EE_Error::add_error(
2354
+				esc_html__(
2355
+					'An error occurred. No registration ID was received.',
2356
+					'event_espresso'
2357
+				),
2358
+				__FILE__,
2359
+				__FUNCTION__,
2360
+				__LINE__
2361
+			);
2362
+		}
2363
+		$form = $this->_get_reg_custom_questions_form($REG_ID);
2364
+		$form->receive_form_submission($this->request->requestParams());
2365
+		$success = false;
2366
+		if ($form->is_valid()) {
2367
+			foreach ($form->subforms() as $question_group_form) {
2368
+				foreach ($question_group_form->inputs() as $question_id => $input) {
2369
+					$where_conditions    = [
2370
+						'QST_ID' => $question_id,
2371
+						'REG_ID' => $REG_ID,
2372
+					];
2373
+					$possibly_new_values = [
2374
+						'ANS_value' => $input->normalized_value(),
2375
+					];
2376
+					$answer              = EEM_Answer::instance()->get_one([$where_conditions]);
2377
+					if ($answer instanceof EE_Answer) {
2378
+						$success = $answer->save($possibly_new_values);
2379
+					} else {
2380
+						// insert it then
2381
+						$cols_n_vals = array_merge($where_conditions, $possibly_new_values);
2382
+						$answer      = EE_Answer::new_instance($cols_n_vals);
2383
+						$success     = $answer->save();
2384
+					}
2385
+				}
2386
+			}
2387
+		} else {
2388
+			EE_Error::add_error($form->get_validation_error_string(), __FILE__, __FUNCTION__, __LINE__);
2389
+		}
2390
+		return $success;
2391
+	}
2392
+
2393
+
2394
+	/**
2395
+	 * generates HTML for the Registration main meta box
2396
+	 *
2397
+	 * @return void
2398
+	 * @throws DomainException
2399
+	 * @throws EE_Error
2400
+	 * @throws InvalidArgumentException
2401
+	 * @throws InvalidDataTypeException
2402
+	 * @throws InvalidInterfaceException
2403
+	 * @throws ReflectionException
2404
+	 */
2405
+	public function _reg_attendees_meta_box()
2406
+	{
2407
+		$REG = $this->getRegistrationModel();
2408
+		// get all other registrations on this transaction, and cache
2409
+		// the attendees for them so we don't have to run another query using force_join
2410
+		$registrations                           = $REG->get_all(
2411
+			[
2412
+				[
2413
+					'TXN_ID' => $this->_registration->transaction_ID(),
2414
+					'REG_ID' => ['!=', $this->_registration->ID()],
2415
+				],
2416
+				'force_join'               => ['Attendee'],
2417
+				'default_where_conditions' => 'other_models_only',
2418
+			]
2419
+		);
2420
+		$this->_template_args['attendees']       = [];
2421
+		$this->_template_args['attendee_notice'] = '';
2422
+		if (
2423
+			empty($registrations)
2424
+			|| (is_array($registrations)
2425
+				&& ! EEH_Array::get_one_item_from_array($registrations))
2426
+		) {
2427
+			EE_Error::add_error(
2428
+				esc_html__(
2429
+					'There are no records attached to this registration. Something may have gone wrong with the registration',
2430
+					'event_espresso'
2431
+				),
2432
+				__FILE__,
2433
+				__FUNCTION__,
2434
+				__LINE__
2435
+			);
2436
+			$this->_template_args['attendee_notice'] = EE_Error::get_notices();
2437
+		} else {
2438
+			$att_nmbr = 1;
2439
+			foreach ($registrations as $registration) {
2440
+				/* @var $registration EE_Registration */
2441
+				$attendee                                                      = $registration->attendee()
2442
+					? $registration->attendee()
2443
+					: $this->getAttendeeModel()->create_default_object();
2444
+				$this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2445
+				$this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2446
+				$this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2447
+				$this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2448
+				$this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2449
+				$this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2450
+					', ',
2451
+					$attendee->full_address_as_array()
2452
+				);
2453
+				$this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2454
+					[
2455
+						'action' => 'edit_attendee',
2456
+						'post'   => $attendee->ID(),
2457
+					],
2458
+					REG_ADMIN_URL
2459
+				);
2460
+				$this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2461
+					$registration->event_obj() instanceof EE_Event
2462
+						? $registration->event_obj()->name()
2463
+						: '';
2464
+				$att_nmbr++;
2465
+			}
2466
+			$this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2467
+		}
2468
+		$template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2469
+		EEH_Template::display_template($template_path, $this->_template_args);
2470
+	}
2471
+
2472
+
2473
+	/**
2474
+	 * generates HTML for the Edit Registration side meta box
2475
+	 *
2476
+	 * @return void
2477
+	 * @throws DomainException
2478
+	 * @throws EE_Error
2479
+	 * @throws InvalidArgumentException
2480
+	 * @throws InvalidDataTypeException
2481
+	 * @throws InvalidInterfaceException
2482
+	 * @throws ReflectionException
2483
+	 */
2484
+	public function _reg_registrant_side_meta_box()
2485
+	{
2486
+		/*@var $attendee EE_Attendee */
2487
+		$att_check = $this->_registration->attendee();
2488
+		$attendee  = $att_check instanceof EE_Attendee
2489
+			? $att_check
2490
+			: $this->getAttendeeModel()->create_default_object();
2491
+		// now let's determine if this is not the primary registration.  If it isn't then we set the
2492
+		// primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2493
+		// primary registration object (that way we know if we need to show create button or not)
2494
+		if (! $this->_registration->is_primary_registrant()) {
2495
+			$primary_registration = $this->_registration->get_primary_registration();
2496
+			$primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2497
+				: null;
2498
+			if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2499
+				// in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2500
+				// custom attendee object so let's not worry about the primary reg.
2501
+				$primary_registration = null;
2502
+			}
2503
+		} else {
2504
+			$primary_registration = null;
2505
+		}
2506
+		$this->_template_args['ATT_ID']            = $attendee->ID();
2507
+		$this->_template_args['fname']             = $attendee->fname();
2508
+		$this->_template_args['lname']             = $attendee->lname();
2509
+		$this->_template_args['email']             = $attendee->email();
2510
+		$this->_template_args['phone']             = $attendee->phone();
2511
+		$this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2512
+		// edit link
2513
+		$this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2514
+			[
2515
+				'action' => 'edit_attendee',
2516
+				'post'   => $attendee->ID(),
2517
+			],
2518
+			REG_ADMIN_URL
2519
+		);
2520
+		$this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2521
+		$this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2522
+		// create link
2523
+		$this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2524
+			? EE_Admin_Page::add_query_args_and_nonce(
2525
+				[
2526
+					'action'  => 'duplicate_attendee',
2527
+					'_REG_ID' => $this->_registration->ID(),
2528
+				],
2529
+				REG_ADMIN_URL
2530
+			) : '';
2531
+		$this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2532
+		$this->_template_args['att_check']    = $att_check;
2533
+		$template_path                        =
2534
+			REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2535
+		EEH_Template::display_template($template_path, $this->_template_args);
2536
+	}
2537
+
2538
+
2539
+	/**
2540
+	 * trash or restore registrations
2541
+	 *
2542
+	 * @param boolean $trash whether to archive or restore
2543
+	 * @return void
2544
+	 * @throws DomainException
2545
+	 * @throws EE_Error
2546
+	 * @throws EntityNotFoundException
2547
+	 * @throws InvalidArgumentException
2548
+	 * @throws InvalidDataTypeException
2549
+	 * @throws InvalidInterfaceException
2550
+	 * @throws ReflectionException
2551
+	 * @throws RuntimeException
2552
+	 * @throws UnexpectedEntityException
2553
+	 */
2554
+	protected function _trash_or_restore_registrations($trash = true)
2555
+	{
2556
+		// if empty _REG_ID then get out because there's nothing to do
2557
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2558
+		if (empty($REG_IDs)) {
2559
+			EE_Error::add_error(
2560
+				sprintf(
2561
+					esc_html__(
2562
+						'In order to %1$s registrations you must select which ones you wish to %1$s by clicking the checkboxes.',
2563
+						'event_espresso'
2564
+					),
2565
+					$trash ? 'trash' : 'restore'
2566
+				),
2567
+				__FILE__,
2568
+				__LINE__,
2569
+				__FUNCTION__
2570
+			);
2571
+			$this->_redirect_after_action(false, '', '', [], true);
2572
+		}
2573
+		$success        = 0;
2574
+		$overwrite_msgs = false;
2575
+		// Checkboxes
2576
+		$reg_count = count($REG_IDs);
2577
+		// cycle thru checkboxes
2578
+		foreach ($REG_IDs as $REG_ID) {
2579
+			/** @var EE_Registration $REG */
2580
+			$REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2581
+			$payments = $REG->registration_payments();
2582
+			if (! empty($payments)) {
2583
+				$name           = $REG->attendee() instanceof EE_Attendee
2584
+					? $REG->attendee()->full_name()
2585
+					: esc_html__('Unknown Attendee', 'event_espresso');
2586
+				$overwrite_msgs = true;
2587
+				EE_Error::add_error(
2588
+					sprintf(
2589
+						esc_html__(
2590
+							'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.',
2591
+							'event_espresso'
2592
+						),
2593
+						$name
2594
+					),
2595
+					__FILE__,
2596
+					__FUNCTION__,
2597
+					__LINE__
2598
+				);
2599
+				// can't trash this registration because it has payments.
2600
+				continue;
2601
+			}
2602
+			$updated = $trash ? $REG->delete() : $REG->restore();
2603
+			if ($updated) {
2604
+				$success++;
2605
+			}
2606
+		}
2607
+		$this->_redirect_after_action(
2608
+			$success === $reg_count, // were ALL registrations affected?
2609
+			$success > 1
2610
+				? esc_html__('Registrations', 'event_espresso')
2611
+				: esc_html__('Registration', 'event_espresso'),
2612
+			$trash
2613
+				? esc_html__('moved to the trash', 'event_espresso')
2614
+				: esc_html__('restored', 'event_espresso'),
2615
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2616
+			$overwrite_msgs
2617
+		);
2618
+	}
2619
+
2620
+
2621
+	/**
2622
+	 * This is used to permanently delete registrations.  Note, this will handle not only deleting permanently the
2623
+	 * registration but also.
2624
+	 * 1. Removing relations to EE_Attendee
2625
+	 * 2. Deleting permanently the related transaction, but ONLY if all related registrations to the transaction are
2626
+	 * ALSO trashed.
2627
+	 * 3. Deleting permanently any related Line items but only if the above conditions are met.
2628
+	 * 4. Removing relationships between all tickets and the related registrations
2629
+	 * 5. Deleting permanently any related Answers (and the answers for other related registrations that were deleted.)
2630
+	 * 6. Deleting permanently any related Checkins.
2631
+	 *
2632
+	 * @return void
2633
+	 * @throws EE_Error
2634
+	 * @throws InvalidArgumentException
2635
+	 * @throws InvalidDataTypeException
2636
+	 * @throws InvalidInterfaceException
2637
+	 * @throws ReflectionException
2638
+	 */
2639
+	protected function _delete_registrations()
2640
+	{
2641
+		$REG_MDL = $this->getRegistrationModel();
2642
+		$success = 0;
2643
+		// Checkboxes
2644
+		$REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2645
+
2646
+		if (! empty($REG_IDs)) {
2647
+			// if array has more than one element than success message should be plural
2648
+			$success = count($REG_IDs) > 1 ? 2 : 1;
2649
+			// cycle thru checkboxes
2650
+			foreach ($REG_IDs as $REG_ID) {
2651
+				$REG = $REG_MDL->get_one_by_ID($REG_ID);
2652
+				if (! $REG instanceof EE_Registration) {
2653
+					continue;
2654
+				}
2655
+				$deleted = $this->_delete_registration($REG);
2656
+				if (! $deleted) {
2657
+					$success = 0;
2658
+				}
2659
+			}
2660
+		}
2661
+
2662
+		$what        = $success > 1
2663
+			? esc_html__('Registrations', 'event_espresso')
2664
+			: esc_html__('Registration', 'event_espresso');
2665
+		$action_desc = esc_html__('permanently deleted.', 'event_espresso');
2666
+		$this->_redirect_after_action(
2667
+			$success,
2668
+			$what,
2669
+			$action_desc,
2670
+			$this->mergeExistingRequestParamsWithRedirectArgs(['action' => 'default']),
2671
+			true
2672
+		);
2673
+	}
2674
+
2675
+
2676
+	/**
2677
+	 * handles the permanent deletion of a registration.  See comments with _delete_registrations() for details on what
2678
+	 * models get affected.
2679
+	 *
2680
+	 * @param EE_Registration $REG registration to be deleted permanently
2681
+	 * @return bool true = successful deletion, false = fail.
2682
+	 * @throws EE_Error
2683
+	 * @throws InvalidArgumentException
2684
+	 * @throws InvalidDataTypeException
2685
+	 * @throws InvalidInterfaceException
2686
+	 * @throws ReflectionException
2687
+	 */
2688
+	protected function _delete_registration(EE_Registration $REG)
2689
+	{
2690
+		// first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2691
+		// registrations on the transaction that are NOT trashed.
2692
+		$TXN = $REG->get_first_related('Transaction');
2693
+		if (! $TXN instanceof EE_Transaction) {
2694
+			EE_Error::add_error(
2695
+				sprintf(
2696
+					esc_html__(
2697
+						'Unable to permanently delete registration %d because its related transaction has already been deleted. If you can restore the related transaction to the database then this registration can be deleted.',
2698
+						'event_espresso'
2699
+					),
2700
+					$REG->id()
2701
+				),
2702
+				__FILE__,
2703
+				__FUNCTION__,
2704
+				__LINE__
2705
+			);
2706
+			return false;
2707
+		}
2708
+		$REGS        = $TXN->get_many_related('Registration');
2709
+		$all_trashed = true;
2710
+		foreach ($REGS as $registration) {
2711
+			if (! $registration->get('REG_deleted')) {
2712
+				$all_trashed = false;
2713
+			}
2714
+		}
2715
+		if (! $all_trashed) {
2716
+			EE_Error::add_error(
2717
+				esc_html__(
2718
+					'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.',
2719
+					'event_espresso'
2720
+				),
2721
+				__FILE__,
2722
+				__FUNCTION__,
2723
+				__LINE__
2724
+			);
2725
+			return false;
2726
+		}
2727
+		// k made it here so that means we can delete all the related transactions and their answers (but let's do them
2728
+		// separately from THIS one).
2729
+		foreach ($REGS as $registration) {
2730
+			// delete related answers
2731
+			$registration->delete_related_permanently('Answer');
2732
+			// remove relationship to EE_Attendee (but we ALWAYS leave the contact record intact)
2733
+			$attendee = $registration->get_first_related('Attendee');
2734
+			if ($attendee instanceof EE_Attendee) {
2735
+				$registration->_remove_relation_to($attendee, 'Attendee');
2736
+			}
2737
+			// now remove relationships to tickets on this registration.
2738
+			$registration->_remove_relations('Ticket');
2739
+			// now delete permanently the checkins related to this registration.
2740
+			$registration->delete_related_permanently('Checkin');
2741
+			if ($registration->ID() === $REG->ID()) {
2742
+				continue;
2743
+			} //we don't want to delete permanently the existing registration just yet.
2744
+			// remove relation to transaction for these registrations if NOT the existing registrations
2745
+			$registration->_remove_relations('Transaction');
2746
+			// delete permanently any related messages.
2747
+			$registration->delete_related_permanently('Message');
2748
+			// now delete this registration permanently
2749
+			$registration->delete_permanently();
2750
+		}
2751
+		// now all related registrations on the transaction are handled.  So let's just handle this registration itself
2752
+		// (the transaction and line items should be all that's left).
2753
+		// delete the line items related to the transaction for this registration.
2754
+		$TXN->delete_related_permanently('Line_Item');
2755
+		// we need to remove all the relationships on the transaction
2756
+		$TXN->delete_related_permanently('Payment');
2757
+		$TXN->delete_related_permanently('Extra_Meta');
2758
+		$TXN->delete_related_permanently('Message');
2759
+		// now we can delete this REG permanently (and the transaction of course)
2760
+		$REG->delete_related_permanently('Transaction');
2761
+		return $REG->delete_permanently();
2762
+	}
2763
+
2764
+
2765
+	/**
2766
+	 *    generates HTML for the Register New Attendee Admin page
2767
+	 *
2768
+	 * @throws DomainException
2769
+	 * @throws EE_Error
2770
+	 * @throws InvalidArgumentException
2771
+	 * @throws InvalidDataTypeException
2772
+	 * @throws InvalidInterfaceException
2773
+	 * @throws ReflectionException
2774
+	 */
2775
+	public function new_registration()
2776
+	{
2777
+		if (! $this->_set_reg_event()) {
2778
+			throw new EE_Error(
2779
+				esc_html__(
2780
+					'Unable to continue with registering because there is no Event ID in the request',
2781
+					'event_espresso'
2782
+				)
2783
+			);
2784
+		}
2785
+		/** @var CurrentPage $current_page */
2786
+		$current_page = $this->loader->getShared(CurrentPage::class);
2787
+		$current_page->setEspressoPage(true);
2788
+		// gotta start with a clean slate if we're not coming here via ajax
2789
+		if (
2790
+			! $this->request->isAjax()
2791
+			&& (
2792
+				! $this->request->requestParamIsSet('processing_registration')
2793
+				|| $this->request->requestParamIsSet('step_error')
2794
+			)
2795
+		) {
2796
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
2797
+		}
2798
+		$this->_template_args['event_name'] = '';
2799
+		// event name
2800
+		if ($this->_reg_event) {
2801
+			$this->_template_args['event_name'] = $this->_reg_event->name();
2802
+			$edit_event_url                     = self::add_query_args_and_nonce(
2803
+				[
2804
+					'action' => 'edit',
2805
+					'post'   => $this->_reg_event->ID(),
2806
+				],
2807
+				EVENTS_ADMIN_URL
2808
+			);
2809
+			$edit_event_lnk                     = '<a href="'
2810
+												  . $edit_event_url
2811
+												  . '" aria-label="'
2812
+												  . esc_attr__('Edit ', 'event_espresso')
2813
+												  . $this->_reg_event->name()
2814
+												  . '">'
2815
+												  . esc_html__('Edit Event', 'event_espresso')
2816
+												  . '</a>';
2817
+			$this->_template_args['event_name'] .= ' <span class="admin-page-header-edit-lnk not-bold">'
2818
+												   . $edit_event_lnk
2819
+												   . '</span>';
2820
+		}
2821
+		$this->_template_args['step_content'] = $this->_get_registration_step_content();
2822
+		if ($this->request->isAjax()) {
2823
+			$this->_return_json();
2824
+		}
2825
+		// grab header
2826
+		$template_path                              =
2827
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2828
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
2829
+			$template_path,
2830
+			$this->_template_args,
2831
+			true
2832
+		);
2833
+		// $this->_set_publish_post_box_vars( NULL, FALSE, FALSE, NULL, FALSE );
2834
+		// the details template wrapper
2835
+		$this->display_admin_page_with_sidebar();
2836
+	}
2837
+
2838
+
2839
+	/**
2840
+	 * This returns the content for a registration step
2841
+	 *
2842
+	 * @return string html
2843
+	 * @throws DomainException
2844
+	 * @throws EE_Error
2845
+	 * @throws InvalidArgumentException
2846
+	 * @throws InvalidDataTypeException
2847
+	 * @throws InvalidInterfaceException
2848
+	 * @throws ReflectionException
2849
+	 */
2850
+	protected function _get_registration_step_content()
2851
+	{
2852
+		if (isset($_COOKIE['ee_registration_added']) && $_COOKIE['ee_registration_added']) {
2853
+			$warning_msg = sprintf(
2854
+				esc_html__(
2855
+					'%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',
2856
+					'event_espresso'
2857
+				),
2858
+				'<br />',
2859
+				'<h3 class="important-notice">',
2860
+				'</h3>',
2861
+				'<div class="float-right">',
2862
+				'<span id="redirect_timer" class="important-notice">30</span>',
2863
+				'</div>',
2864
+				'<b>',
2865
+				'</b>'
2866
+			);
2867
+			return '
2868 2868
 	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2869 2869
 	<script >
2870 2870
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
@@ -2877,845 +2877,845 @@  discard block
 block discarded – undo
2877 2877
 	        }
2878 2878
 	    }, 800 );
2879 2879
 	</script >';
2880
-        }
2881
-        $template_args = [
2882
-            'title'                    => '',
2883
-            'content'                  => '',
2884
-            'step_button_text'         => '',
2885
-            'show_notification_toggle' => false,
2886
-        ];
2887
-        // to indicate we're processing a new registration
2888
-        $hidden_fields = [
2889
-            'processing_registration' => [
2890
-                'type'  => 'hidden',
2891
-                'value' => 0,
2892
-            ],
2893
-            'event_id'                => [
2894
-                'type'  => 'hidden',
2895
-                'value' => $this->_reg_event->ID(),
2896
-            ],
2897
-        ];
2898
-        // if the cart is empty then we know we're at step one, so we'll display the ticket selector
2899
-        $cart = EE_Registry::instance()->SSN->cart();
2900
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2901
-        switch ($step) {
2902
-            case 'ticket':
2903
-                $hidden_fields['processing_registration']['value'] = 1;
2904
-                $template_args['title']                            = esc_html__(
2905
-                    'Step One: Select the Ticket for this registration',
2906
-                    'event_espresso'
2907
-                );
2908
-                $template_args['content']                          =
2909
-                    EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2910
-                $template_args['content']                          .= '</div>';
2911
-                $template_args['step_button_text']                 = esc_html__(
2912
-                    'Add Tickets and Continue to Registrant Details',
2913
-                    'event_espresso'
2914
-                );
2915
-                $template_args['show_notification_toggle']         = false;
2916
-                break;
2917
-            case 'questions':
2918
-                $hidden_fields['processing_registration']['value'] = 2;
2919
-                $template_args['title']                            = esc_html__(
2920
-                    'Step Two: Add Registrant Details for this Registration',
2921
-                    'event_espresso'
2922
-                );
2923
-                // in theory, we should be able to run EED_SPCO at this point
2924
-                // because the cart should have been set up properly by the first process_reg_step run.
2925
-                $template_args['content']                  =
2926
-                    EED_Single_Page_Checkout::registration_checkout_for_admin();
2927
-                $template_args['step_button_text']         = esc_html__(
2928
-                    'Save Registration and Continue to Details',
2929
-                    'event_espresso'
2930
-                );
2931
-                $template_args['show_notification_toggle'] = true;
2932
-                break;
2933
-        }
2934
-        // we come back to the process_registration_step route.
2935
-        $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2936
-        return EEH_Template::display_template(
2937
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2938
-            $template_args,
2939
-            true
2940
-        );
2941
-    }
2942
-
2943
-
2944
-    /**
2945
-     * set_reg_event
2946
-     *
2947
-     * @return bool
2948
-     * @throws EE_Error
2949
-     * @throws InvalidArgumentException
2950
-     * @throws InvalidDataTypeException
2951
-     * @throws InvalidInterfaceException
2952
-     */
2953
-    private function _set_reg_event()
2954
-    {
2955
-        if (is_object($this->_reg_event)) {
2956
-            return true;
2957
-        }
2958
-
2959
-        $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2960
-        if (! $EVT_ID) {
2961
-            return false;
2962
-        }
2963
-        $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2964
-        return true;
2965
-    }
2966
-
2967
-
2968
-    /**
2969
-     * process_reg_step
2970
-     *
2971
-     * @return void
2972
-     * @throws DomainException
2973
-     * @throws EE_Error
2974
-     * @throws InvalidArgumentException
2975
-     * @throws InvalidDataTypeException
2976
-     * @throws InvalidInterfaceException
2977
-     * @throws ReflectionException
2978
-     * @throws RuntimeException
2979
-     */
2980
-    public function process_reg_step()
2981
-    {
2982
-        EE_System::do_not_cache();
2983
-        $this->_set_reg_event();
2984
-        /** @var CurrentPage $current_page */
2985
-        $current_page = $this->loader->getShared(CurrentPage::class);
2986
-        $current_page->setEspressoPage(true);
2987
-        $this->request->setRequestParam('uts', time());
2988
-        // what step are we on?
2989
-        $cart = EE_Registry::instance()->SSN->cart();
2990
-        $step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2991
-        // if doing ajax then we need to verify the nonce
2992
-        if ($this->request->isAjax()) {
2993
-            $nonce = $this->request->getRequestParam($this->_req_nonce, '');
2994
-            $this->_verify_nonce($nonce, $this->_req_nonce);
2995
-        }
2996
-        switch ($step) {
2997
-            case 'ticket':
2998
-                // process ticket selection
2999
-                $success = EED_Ticket_Selector::instance()->process_ticket_selections();
3000
-                if ($success) {
3001
-                    EE_Error::add_success(
3002
-                        esc_html__(
3003
-                            'Tickets Selected. Now complete the registration.',
3004
-                            'event_espresso'
3005
-                        )
3006
-                    );
3007
-                } else {
3008
-                    $this->request->setRequestParam('step_error', true);
3009
-                    $query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3010
-                }
3011
-                if ($this->request->isAjax()) {
3012
-                    $this->new_registration(); // display next step
3013
-                } else {
3014
-                    $query_args = [
3015
-                        'action'                  => 'new_registration',
3016
-                        'processing_registration' => 1,
3017
-                        'event_id'                => $this->_reg_event->ID(),
3018
-                        'uts'                     => time(),
3019
-                    ];
3020
-                    $this->_redirect_after_action(
3021
-                        false,
3022
-                        '',
3023
-                        '',
3024
-                        $query_args,
3025
-                        true
3026
-                    );
3027
-                }
3028
-                break;
3029
-            case 'questions':
3030
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3031
-                    add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3032
-                }
3033
-                // process registration
3034
-                $transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3035
-                if ($cart instanceof EE_Cart) {
3036
-                    $grand_total = $cart->get_grand_total();
3037
-                    if ($grand_total instanceof EE_Line_Item) {
3038
-                        $grand_total->save_this_and_descendants_to_txn();
3039
-                    }
3040
-                }
3041
-                if (! $transaction instanceof EE_Transaction) {
3042
-                    $query_args = [
3043
-                        'action'                  => 'new_registration',
3044
-                        'processing_registration' => 2,
3045
-                        'event_id'                => $this->_reg_event->ID(),
3046
-                        'uts'                     => time(),
3047
-                    ];
3048
-                    if ($this->request->isAjax()) {
3049
-                        // display registration form again because there are errors (maybe validation?)
3050
-                        $this->new_registration();
3051
-                        return;
3052
-                    }
3053
-                    $this->_redirect_after_action(
3054
-                        false,
3055
-                        '',
3056
-                        '',
3057
-                        $query_args,
3058
-                        true
3059
-                    );
3060
-                    return;
3061
-                }
3062
-                // maybe update status, and make sure to save transaction if not done already
3063
-                if (! $transaction->update_status_based_on_total_paid()) {
3064
-                    $transaction->save();
3065
-                }
3066
-                EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3067
-                $query_args = [
3068
-                    'action'        => 'redirect_to_txn',
3069
-                    'TXN_ID'        => $transaction->ID(),
3070
-                    'EVT_ID'        => $this->_reg_event->ID(),
3071
-                    'event_name'    => urlencode($this->_reg_event->name()),
3072
-                    'redirect_from' => 'new_registration',
3073
-                ];
3074
-                $this->_redirect_after_action(false, '', '', $query_args, true);
3075
-                break;
3076
-        }
3077
-        // what are you looking here for?  Should be nothing to do at this point.
3078
-    }
3079
-
3080
-
3081
-    /**
3082
-     * redirect_to_txn
3083
-     *
3084
-     * @return void
3085
-     * @throws EE_Error
3086
-     * @throws InvalidArgumentException
3087
-     * @throws InvalidDataTypeException
3088
-     * @throws InvalidInterfaceException
3089
-     * @throws ReflectionException
3090
-     */
3091
-    public function redirect_to_txn()
3092
-    {
3093
-        EE_System::do_not_cache();
3094
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3095
-        $query_args = [
3096
-            'action' => 'view_transaction',
3097
-            'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3098
-            'page'   => 'espresso_transactions',
3099
-        ];
3100
-        if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3101
-            $query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3102
-            $query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3103
-            $query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3104
-        }
3105
-        EE_Error::add_success(
3106
-            esc_html__(
3107
-                'Registration Created.  Please review the transaction and add any payments as necessary',
3108
-                'event_espresso'
3109
-            )
3110
-        );
3111
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3112
-    }
3113
-
3114
-
3115
-    /**
3116
-     * generates HTML for the Attendee Contact List
3117
-     *
3118
-     * @return void
3119
-     * @throws DomainException
3120
-     * @throws EE_Error
3121
-     */
3122
-    protected function _attendee_contact_list_table()
3123
-    {
3124
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3125
-        $this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3126
-        $this->display_admin_list_table_page_with_no_sidebar();
3127
-    }
3128
-
3129
-
3130
-    /**
3131
-     * get_attendees
3132
-     *
3133
-     * @param      $per_page
3134
-     * @param bool $count whether to return count or data.
3135
-     * @param bool $trash
3136
-     * @return array|int
3137
-     * @throws EE_Error
3138
-     * @throws InvalidArgumentException
3139
-     * @throws InvalidDataTypeException
3140
-     * @throws InvalidInterfaceException
3141
-     */
3142
-    public function get_attendees($per_page, $count = false, $trash = false)
3143
-    {
3144
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3145
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3146
-        $orderby = $this->request->getRequestParam('orderby');
3147
-        switch ($orderby) {
3148
-            case 'ATT_ID':
3149
-            case 'ATT_fname':
3150
-            case 'ATT_email':
3151
-            case 'ATT_city':
3152
-            case 'STA_ID':
3153
-            case 'CNT_ID':
3154
-                break;
3155
-            case 'Registration_Count':
3156
-                $orderby = 'Registration_Count';
3157
-                break;
3158
-            default:
3159
-                $orderby = 'ATT_lname';
3160
-        }
3161
-        $sort         = $this->request->getRequestParam('order', 'ASC');
3162
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
3163
-        $per_page     = absint($per_page) ? $per_page : 10;
3164
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3165
-        $_where       = [];
3166
-        $search_term  = $this->request->getRequestParam('s');
3167
-        if ($search_term) {
3168
-            $search_term  = '%' . $search_term . '%';
3169
-            $_where['OR'] = [
3170
-                'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3171
-                'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3172
-                'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3173
-                'ATT_fname'                         => ['LIKE', $search_term],
3174
-                'ATT_lname'                         => ['LIKE', $search_term],
3175
-                'ATT_short_bio'                     => ['LIKE', $search_term],
3176
-                'ATT_email'                         => ['LIKE', $search_term],
3177
-                'ATT_address'                       => ['LIKE', $search_term],
3178
-                'ATT_address2'                      => ['LIKE', $search_term],
3179
-                'ATT_city'                          => ['LIKE', $search_term],
3180
-                'Country.CNT_name'                  => ['LIKE', $search_term],
3181
-                'State.STA_name'                    => ['LIKE', $search_term],
3182
-                'ATT_phone'                         => ['LIKE', $search_term],
3183
-                'Registration.REG_final_price'      => ['LIKE', $search_term],
3184
-                'Registration.REG_code'             => ['LIKE', $search_term],
3185
-                'Registration.REG_group_size'       => ['LIKE', $search_term],
3186
-            ];
3187
-        }
3188
-        $offset     = ($current_page - 1) * $per_page;
3189
-        $limit      = $count ? null : [$offset, $per_page];
3190
-        $query_args = [
3191
-            $_where,
3192
-            'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3193
-            'limit'         => $limit,
3194
-        ];
3195
-        if (! $count) {
3196
-            $query_args['order_by'] = [$orderby => $sort];
3197
-        }
3198
-        $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3199
-        return $count
3200
-            ? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3201
-            : $this->getAttendeeModel()->get_all($query_args);
3202
-    }
3203
-
3204
-
3205
-    /**
3206
-     * This is just taking care of resending the registration confirmation
3207
-     *
3208
-     * @return void
3209
-     * @throws EE_Error
3210
-     * @throws InvalidArgumentException
3211
-     * @throws InvalidDataTypeException
3212
-     * @throws InvalidInterfaceException
3213
-     * @throws ReflectionException
3214
-     */
3215
-    protected function _resend_registration()
3216
-    {
3217
-        $this->_process_resend_registration();
3218
-        $REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3219
-        $redirect_to = $this->request->getRequestParam('redirect_to');
3220
-        $query_args  = $redirect_to
3221
-            ? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3222
-            : ['action' => 'default'];
3223
-        $this->_redirect_after_action(false, '', '', $query_args, true);
3224
-    }
3225
-
3226
-
3227
-    /**
3228
-     * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3229
-     * to use when selecting registrations
3230
-     *
3231
-     * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3232
-     *                                                     the query parameters from the request
3233
-     * @return void ends the request with a redirect or download
3234
-     */
3235
-    public function _registrations_report_base($method_name_for_getting_query_params)
3236
-    {
3237
-        $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3238
-            ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3239
-            : null;
3240
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3241
-            $return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3242
-            $filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3243
-            $report_params = $this->$method_name_for_getting_query_params($filters);
3244
-            $use_filters   = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3245
-            wp_redirect(
3246
-                EE_Admin_Page::add_query_args_and_nonce(
3247
-                    [
3248
-                        'page'        => EED_Batch::PAGE_SLUG,
3249
-                        'batch'       => EED_Batch::batch_file_job,
3250
-                        'EVT_ID'      => $EVT_ID,
3251
-                        'filters'     => urlencode(serialize($report_params)),
3252
-                        'use_filters' => urlencode($use_filters),
3253
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3254
-                        'return_url'  => urlencode($return_url),
3255
-                    ]
3256
-                )
3257
-            );
3258
-        } else {
3259
-            // Pull the current request params
3260
-            $request_args = $this->request->requestParams();
3261
-            // Set the required request_args to be passed to the export
3262
-            $required_request_args = [
3263
-                'export' => 'report',
3264
-                'action' => 'registrations_report_for_event',
3265
-                'EVT_ID' => $EVT_ID,
3266
-            ];
3267
-            // Merge required request args, overriding any currently set
3268
-            $request_args = array_merge($request_args, $required_request_args);
3269
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3270
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3271
-                $EE_Export = EE_Export::instance($request_args);
3272
-                $EE_Export->export();
3273
-            }
3274
-        }
3275
-    }
3276
-
3277
-
3278
-    /**
3279
-     * Creates a registration report using only query parameters in the request
3280
-     *
3281
-     * @return void
3282
-     */
3283
-    public function _registrations_report()
3284
-    {
3285
-        $this->_registrations_report_base('_get_registration_query_parameters');
3286
-    }
3287
-
3288
-
3289
-    public function _contact_list_export()
3290
-    {
3291
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3292
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3293
-            $EE_Export = EE_Export::instance($this->request->requestParams());
3294
-            $EE_Export->export_attendees();
3295
-        }
3296
-    }
3297
-
3298
-
3299
-    public function _contact_list_report()
3300
-    {
3301
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3302
-            wp_redirect(
3303
-                EE_Admin_Page::add_query_args_and_nonce(
3304
-                    [
3305
-                        'page'        => EED_Batch::PAGE_SLUG,
3306
-                        'batch'       => EED_Batch::batch_file_job,
3307
-                        'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3308
-                        'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3309
-                    ]
3310
-                )
3311
-            );
3312
-        } else {
3313
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3314
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3315
-                $EE_Export = EE_Export::instance($this->request->requestParams());
3316
-                $EE_Export->report_attendees();
3317
-            }
3318
-        }
3319
-    }
3320
-
3321
-
3322
-
3323
-
3324
-
3325
-    /***************************************        ATTENDEE DETAILS        ***************************************/
3326
-    /**
3327
-     * This duplicates the attendee object for the given incoming registration id and attendee_id.
3328
-     *
3329
-     * @return void
3330
-     * @throws EE_Error
3331
-     * @throws InvalidArgumentException
3332
-     * @throws InvalidDataTypeException
3333
-     * @throws InvalidInterfaceException
3334
-     * @throws ReflectionException
3335
-     */
3336
-    protected function _duplicate_attendee()
3337
-    {
3338
-        $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3339
-        $action = $this->request->getRequestParam('return', 'default');
3340
-        // verify we have necessary info
3341
-        if (! $REG_ID) {
3342
-            EE_Error::add_error(
3343
-                esc_html__(
3344
-                    'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3345
-                    'event_espresso'
3346
-                ),
3347
-                __FILE__,
3348
-                __LINE__,
3349
-                __FUNCTION__
3350
-            );
3351
-            $query_args = ['action' => $action];
3352
-            $this->_redirect_after_action('', '', '', $query_args, true);
3353
-        }
3354
-        // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3355
-        $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3356
-        if (! $registration instanceof EE_Registration) {
3357
-            throw new RuntimeException(
3358
-                sprintf(
3359
-                    esc_html__(
3360
-                        'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3361
-                        'event_espresso'
3362
-                    ),
3363
-                    $REG_ID
3364
-                )
3365
-            );
3366
-        }
3367
-        $attendee = $registration->attendee();
3368
-        // remove relation of existing attendee on registration
3369
-        $registration->_remove_relation_to($attendee, 'Attendee');
3370
-        // new attendee
3371
-        $new_attendee = clone $attendee;
3372
-        $new_attendee->set('ATT_ID', 0);
3373
-        $new_attendee->save();
3374
-        // add new attendee to reg
3375
-        $registration->_add_relation_to($new_attendee, 'Attendee');
3376
-        EE_Error::add_success(
3377
-            esc_html__(
3378
-                'New Contact record created.  Now make any edits you wish to make for this contact.',
3379
-                'event_espresso'
3380
-            )
3381
-        );
3382
-        // redirect to edit page for attendee
3383
-        $query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3384
-        $this->_redirect_after_action('', '', '', $query_args, true);
3385
-    }
3386
-
3387
-
3388
-    /**
3389
-     * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3390
-     *
3391
-     * @param int     $post_id
3392
-     * @param WP_Post $post
3393
-     * @throws DomainException
3394
-     * @throws EE_Error
3395
-     * @throws InvalidArgumentException
3396
-     * @throws InvalidDataTypeException
3397
-     * @throws InvalidInterfaceException
3398
-     * @throws LogicException
3399
-     * @throws InvalidFormSubmissionException
3400
-     * @throws ReflectionException
3401
-     */
3402
-    protected function _insert_update_cpt_item($post_id, $post)
3403
-    {
3404
-        $success  = true;
3405
-        $attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3406
-            ? $this->getAttendeeModel()->get_one_by_ID($post_id)
3407
-            : null;
3408
-        // for attendee updates
3409
-        if ($attendee instanceof EE_Attendee) {
3410
-            // note we should only be UPDATING attendees at this point.
3411
-            $fname          = $this->request->getRequestParam('ATT_fname', '');
3412
-            $lname          = $this->request->getRequestParam('ATT_lname', '');
3413
-            $updated_fields = [
3414
-                'ATT_fname'     => $fname,
3415
-                'ATT_lname'     => $lname,
3416
-                'ATT_full_name' => "{$fname} {$lname}",
3417
-                'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3418
-                'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3419
-                'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3420
-                'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3421
-                'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3422
-                'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3423
-            ];
3424
-            foreach ($updated_fields as $field => $value) {
3425
-                $attendee->set($field, $value);
3426
-            }
3427
-
3428
-            // process contact details metabox form handler (which will also save the attendee)
3429
-            $contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3430
-            $success              = $contact_details_form->process($this->request->requestParams());
3431
-
3432
-            $attendee_update_callbacks = apply_filters(
3433
-                'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3434
-                []
3435
-            );
3436
-            foreach ($attendee_update_callbacks as $a_callback) {
3437
-                if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3438
-                    throw new EE_Error(
3439
-                        sprintf(
3440
-                            esc_html__(
3441
-                                '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.',
3442
-                                'event_espresso'
3443
-                            ),
3444
-                            $a_callback
3445
-                        )
3446
-                    );
3447
-                }
3448
-            }
3449
-        }
3450
-
3451
-        if ($success === false) {
3452
-            EE_Error::add_error(
3453
-                esc_html__(
3454
-                    'Something went wrong with updating the meta table data for the registration.',
3455
-                    'event_espresso'
3456
-                ),
3457
-                __FILE__,
3458
-                __FUNCTION__,
3459
-                __LINE__
3460
-            );
3461
-        }
3462
-    }
3463
-
3464
-
3465
-    public function trash_cpt_item($post_id)
3466
-    {
3467
-    }
3468
-
3469
-
3470
-    public function delete_cpt_item($post_id)
3471
-    {
3472
-    }
3473
-
3474
-
3475
-    public function restore_cpt_item($post_id)
3476
-    {
3477
-    }
3478
-
3479
-
3480
-    protected function _restore_cpt_item($post_id, $revision_id)
3481
-    {
3482
-    }
3483
-
3484
-
3485
-    /**
3486
-     * @throws EE_Error
3487
-     * @throws ReflectionException
3488
-     * @since 4.10.2.p
3489
-     */
3490
-    public function attendee_editor_metaboxes()
3491
-    {
3492
-        $this->verify_cpt_object();
3493
-        remove_meta_box(
3494
-            'postexcerpt',
3495
-            $this->_cpt_routes[ $this->_req_action ],
3496
-            'normal'
3497
-        );
3498
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3499
-        if (post_type_supports('espresso_attendees', 'excerpt')) {
3500
-            $this->addMetaBox(
3501
-                'postexcerpt',
3502
-                esc_html__('Short Biography', 'event_espresso'),
3503
-                'post_excerpt_meta_box',
3504
-                $this->_cpt_routes[ $this->_req_action ]
3505
-            );
3506
-        }
3507
-        if (post_type_supports('espresso_attendees', 'comments')) {
3508
-            $this->addMetaBox(
3509
-                'commentsdiv',
3510
-                esc_html__('Notes on the Contact', 'event_espresso'),
3511
-                'post_comment_meta_box',
3512
-                $this->_cpt_routes[ $this->_req_action ],
3513
-                'normal',
3514
-                'core'
3515
-            );
3516
-        }
3517
-        $this->addMetaBox(
3518
-            'attendee_contact_info',
3519
-            esc_html__('Contact Info', 'event_espresso'),
3520
-            [$this, 'attendee_contact_info'],
3521
-            $this->_cpt_routes[ $this->_req_action ],
3522
-            'side',
3523
-            'core'
3524
-        );
3525
-        $this->addMetaBox(
3526
-            'attendee_details_address',
3527
-            esc_html__('Address Details', 'event_espresso'),
3528
-            [$this, 'attendee_address_details'],
3529
-            $this->_cpt_routes[ $this->_req_action ],
3530
-            'normal',
3531
-            'core'
3532
-        );
3533
-        $this->addMetaBox(
3534
-            'attendee_registrations',
3535
-            esc_html__('Registrations for this Contact', 'event_espresso'),
3536
-            [$this, 'attendee_registrations_meta_box'],
3537
-            $this->_cpt_routes[ $this->_req_action ]
3538
-        );
3539
-    }
3540
-
3541
-
3542
-    /**
3543
-     * Metabox for attendee contact info
3544
-     *
3545
-     * @param WP_Post $post wp post object
3546
-     * @return void attendee contact info ( and form )
3547
-     * @throws EE_Error
3548
-     * @throws InvalidArgumentException
3549
-     * @throws InvalidDataTypeException
3550
-     * @throws InvalidInterfaceException
3551
-     * @throws LogicException
3552
-     * @throws DomainException
3553
-     */
3554
-    public function attendee_contact_info($post)
3555
-    {
3556
-        // get attendee object ( should already have it )
3557
-        $form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3558
-        $form->enqueueStylesAndScripts();
3559
-        echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3560
-    }
3561
-
3562
-
3563
-    /**
3564
-     * Return form handler for the contact details metabox
3565
-     *
3566
-     * @param EE_Attendee $attendee
3567
-     * @return AttendeeContactDetailsMetaboxFormHandler
3568
-     * @throws DomainException
3569
-     * @throws InvalidArgumentException
3570
-     * @throws InvalidDataTypeException
3571
-     * @throws InvalidInterfaceException
3572
-     */
3573
-    protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3574
-    {
3575
-        return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3576
-    }
3577
-
3578
-
3579
-    /**
3580
-     * Metabox for attendee details
3581
-     *
3582
-     * @param WP_Post $post wp post object
3583
-     * @throws EE_Error
3584
-     * @throws ReflectionException
3585
-     */
3586
-    public function attendee_address_details($post)
3587
-    {
3588
-        // get attendee object (should already have it)
3589
-        $this->_template_args['attendee']     = $this->_cpt_model_obj;
3590
-        $this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3591
-            new EE_Question_Form_Input(
3592
-                EE_Question::new_instance(
3593
-                    [
3594
-                        'QST_ID'           => 0,
3595
-                        'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3596
-                        'QST_system'       => 'admin-state',
3597
-                    ]
3598
-                ),
3599
-                EE_Answer::new_instance(
3600
-                    [
3601
-                        'ANS_ID'    => 0,
3602
-                        'ANS_value' => $this->_cpt_model_obj->state_ID(),
3603
-                    ]
3604
-                ),
3605
-                [
3606
-                    'input_id'       => 'STA_ID',
3607
-                    'input_name'     => 'STA_ID',
3608
-                    'input_prefix'   => '',
3609
-                    'append_qstn_id' => false,
3610
-                ]
3611
-            )
3612
-        );
3613
-        $this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3614
-            new EE_Question_Form_Input(
3615
-                EE_Question::new_instance(
3616
-                    [
3617
-                        'QST_ID'           => 0,
3618
-                        'QST_display_text' => esc_html__('Country', 'event_espresso'),
3619
-                        'QST_system'       => 'admin-country',
3620
-                    ]
3621
-                ),
3622
-                EE_Answer::new_instance(
3623
-                    [
3624
-                        'ANS_ID'    => 0,
3625
-                        'ANS_value' => $this->_cpt_model_obj->country_ID(),
3626
-                    ]
3627
-                ),
3628
-                [
3629
-                    'input_id'       => 'CNT_ISO',
3630
-                    'input_name'     => 'CNT_ISO',
3631
-                    'input_prefix'   => '',
3632
-                    'append_qstn_id' => false,
3633
-                ]
3634
-            )
3635
-        );
3636
-        $template                             =
3637
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3638
-        EEH_Template::display_template($template, $this->_template_args);
3639
-    }
3640
-
3641
-
3642
-    /**
3643
-     * _attendee_details
3644
-     *
3645
-     * @param $post
3646
-     * @return void
3647
-     * @throws DomainException
3648
-     * @throws EE_Error
3649
-     * @throws InvalidArgumentException
3650
-     * @throws InvalidDataTypeException
3651
-     * @throws InvalidInterfaceException
3652
-     * @throws ReflectionException
3653
-     */
3654
-    public function attendee_registrations_meta_box($post)
3655
-    {
3656
-        $this->_template_args['attendee']      = $this->_cpt_model_obj;
3657
-        $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3658
-        $template                              =
3659
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3660
-        EEH_Template::display_template($template, $this->_template_args);
3661
-    }
3662
-
3663
-
3664
-    /**
3665
-     * add in the form fields for the attendee edit
3666
-     *
3667
-     * @param WP_Post $post wp post object
3668
-     * @return void echos html for new form.
3669
-     * @throws DomainException
3670
-     */
3671
-    public function after_title_form_fields($post)
3672
-    {
3673
-        if ($post->post_type === 'espresso_attendees') {
3674
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3675
-            $template_args['attendee'] = $this->_cpt_model_obj;
3676
-            EEH_Template::display_template($template, $template_args);
3677
-        }
3678
-    }
3679
-
3680
-
3681
-    /**
3682
-     * _trash_or_restore_attendee
3683
-     *
3684
-     * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3685
-     * @return void
3686
-     * @throws EE_Error
3687
-     * @throws InvalidArgumentException
3688
-     * @throws InvalidDataTypeException
3689
-     * @throws InvalidInterfaceException
3690
-     */
3691
-    protected function _trash_or_restore_attendees($trash = true)
3692
-    {
3693
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3694
-        $status = $trash ? 'trash' : 'publish';
3695
-        // Checkboxes
3696
-        if ($this->request->requestParamIsSet('checkbox')) {
3697
-            $ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3698
-            // if array has more than one element than success message should be plural
3699
-            $success = count($ATT_IDs) > 1 ? 2 : 1;
3700
-            // cycle thru checkboxes
3701
-            foreach ($ATT_IDs as $ATT_ID) {
3702
-                $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3703
-                if (! $updated) {
3704
-                    $success = 0;
3705
-                }
3706
-            }
3707
-        } else {
3708
-            // grab single id and delete
3709
-            $ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3710
-            // update attendee
3711
-            $success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3712
-        }
3713
-        $what        = $success > 1
3714
-            ? esc_html__('Contacts', 'event_espresso')
3715
-            : esc_html__('Contact', 'event_espresso');
3716
-        $action_desc = $trash
3717
-            ? esc_html__('moved to the trash', 'event_espresso')
3718
-            : esc_html__('restored', 'event_espresso');
3719
-        $this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3720
-    }
2880
+		}
2881
+		$template_args = [
2882
+			'title'                    => '',
2883
+			'content'                  => '',
2884
+			'step_button_text'         => '',
2885
+			'show_notification_toggle' => false,
2886
+		];
2887
+		// to indicate we're processing a new registration
2888
+		$hidden_fields = [
2889
+			'processing_registration' => [
2890
+				'type'  => 'hidden',
2891
+				'value' => 0,
2892
+			],
2893
+			'event_id'                => [
2894
+				'type'  => 'hidden',
2895
+				'value' => $this->_reg_event->ID(),
2896
+			],
2897
+		];
2898
+		// if the cart is empty then we know we're at step one, so we'll display the ticket selector
2899
+		$cart = EE_Registry::instance()->SSN->cart();
2900
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2901
+		switch ($step) {
2902
+			case 'ticket':
2903
+				$hidden_fields['processing_registration']['value'] = 1;
2904
+				$template_args['title']                            = esc_html__(
2905
+					'Step One: Select the Ticket for this registration',
2906
+					'event_espresso'
2907
+				);
2908
+				$template_args['content']                          =
2909
+					EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2910
+				$template_args['content']                          .= '</div>';
2911
+				$template_args['step_button_text']                 = esc_html__(
2912
+					'Add Tickets and Continue to Registrant Details',
2913
+					'event_espresso'
2914
+				);
2915
+				$template_args['show_notification_toggle']         = false;
2916
+				break;
2917
+			case 'questions':
2918
+				$hidden_fields['processing_registration']['value'] = 2;
2919
+				$template_args['title']                            = esc_html__(
2920
+					'Step Two: Add Registrant Details for this Registration',
2921
+					'event_espresso'
2922
+				);
2923
+				// in theory, we should be able to run EED_SPCO at this point
2924
+				// because the cart should have been set up properly by the first process_reg_step run.
2925
+				$template_args['content']                  =
2926
+					EED_Single_Page_Checkout::registration_checkout_for_admin();
2927
+				$template_args['step_button_text']         = esc_html__(
2928
+					'Save Registration and Continue to Details',
2929
+					'event_espresso'
2930
+				);
2931
+				$template_args['show_notification_toggle'] = true;
2932
+				break;
2933
+		}
2934
+		// we come back to the process_registration_step route.
2935
+		$this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2936
+		return EEH_Template::display_template(
2937
+			REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2938
+			$template_args,
2939
+			true
2940
+		);
2941
+	}
2942
+
2943
+
2944
+	/**
2945
+	 * set_reg_event
2946
+	 *
2947
+	 * @return bool
2948
+	 * @throws EE_Error
2949
+	 * @throws InvalidArgumentException
2950
+	 * @throws InvalidDataTypeException
2951
+	 * @throws InvalidInterfaceException
2952
+	 */
2953
+	private function _set_reg_event()
2954
+	{
2955
+		if (is_object($this->_reg_event)) {
2956
+			return true;
2957
+		}
2958
+
2959
+		$EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2960
+		if (! $EVT_ID) {
2961
+			return false;
2962
+		}
2963
+		$this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
2964
+		return true;
2965
+	}
2966
+
2967
+
2968
+	/**
2969
+	 * process_reg_step
2970
+	 *
2971
+	 * @return void
2972
+	 * @throws DomainException
2973
+	 * @throws EE_Error
2974
+	 * @throws InvalidArgumentException
2975
+	 * @throws InvalidDataTypeException
2976
+	 * @throws InvalidInterfaceException
2977
+	 * @throws ReflectionException
2978
+	 * @throws RuntimeException
2979
+	 */
2980
+	public function process_reg_step()
2981
+	{
2982
+		EE_System::do_not_cache();
2983
+		$this->_set_reg_event();
2984
+		/** @var CurrentPage $current_page */
2985
+		$current_page = $this->loader->getShared(CurrentPage::class);
2986
+		$current_page->setEspressoPage(true);
2987
+		$this->request->setRequestParam('uts', time());
2988
+		// what step are we on?
2989
+		$cart = EE_Registry::instance()->SSN->cart();
2990
+		$step = ! $cart instanceof EE_Cart ? 'ticket' : 'questions';
2991
+		// if doing ajax then we need to verify the nonce
2992
+		if ($this->request->isAjax()) {
2993
+			$nonce = $this->request->getRequestParam($this->_req_nonce, '');
2994
+			$this->_verify_nonce($nonce, $this->_req_nonce);
2995
+		}
2996
+		switch ($step) {
2997
+			case 'ticket':
2998
+				// process ticket selection
2999
+				$success = EED_Ticket_Selector::instance()->process_ticket_selections();
3000
+				if ($success) {
3001
+					EE_Error::add_success(
3002
+						esc_html__(
3003
+							'Tickets Selected. Now complete the registration.',
3004
+							'event_espresso'
3005
+						)
3006
+					);
3007
+				} else {
3008
+					$this->request->setRequestParam('step_error', true);
3009
+					$query_args['step_error'] = $this->request->getRequestParam('step_error', true, 'bool');
3010
+				}
3011
+				if ($this->request->isAjax()) {
3012
+					$this->new_registration(); // display next step
3013
+				} else {
3014
+					$query_args = [
3015
+						'action'                  => 'new_registration',
3016
+						'processing_registration' => 1,
3017
+						'event_id'                => $this->_reg_event->ID(),
3018
+						'uts'                     => time(),
3019
+					];
3020
+					$this->_redirect_after_action(
3021
+						false,
3022
+						'',
3023
+						'',
3024
+						$query_args,
3025
+						true
3026
+					);
3027
+				}
3028
+				break;
3029
+			case 'questions':
3030
+				if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3031
+					add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3032
+				}
3033
+				// process registration
3034
+				$transaction = EED_Single_Page_Checkout::instance()->process_registration_from_admin();
3035
+				if ($cart instanceof EE_Cart) {
3036
+					$grand_total = $cart->get_grand_total();
3037
+					if ($grand_total instanceof EE_Line_Item) {
3038
+						$grand_total->save_this_and_descendants_to_txn();
3039
+					}
3040
+				}
3041
+				if (! $transaction instanceof EE_Transaction) {
3042
+					$query_args = [
3043
+						'action'                  => 'new_registration',
3044
+						'processing_registration' => 2,
3045
+						'event_id'                => $this->_reg_event->ID(),
3046
+						'uts'                     => time(),
3047
+					];
3048
+					if ($this->request->isAjax()) {
3049
+						// display registration form again because there are errors (maybe validation?)
3050
+						$this->new_registration();
3051
+						return;
3052
+					}
3053
+					$this->_redirect_after_action(
3054
+						false,
3055
+						'',
3056
+						'',
3057
+						$query_args,
3058
+						true
3059
+					);
3060
+					return;
3061
+				}
3062
+				// maybe update status, and make sure to save transaction if not done already
3063
+				if (! $transaction->update_status_based_on_total_paid()) {
3064
+					$transaction->save();
3065
+				}
3066
+				EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3067
+				$query_args = [
3068
+					'action'        => 'redirect_to_txn',
3069
+					'TXN_ID'        => $transaction->ID(),
3070
+					'EVT_ID'        => $this->_reg_event->ID(),
3071
+					'event_name'    => urlencode($this->_reg_event->name()),
3072
+					'redirect_from' => 'new_registration',
3073
+				];
3074
+				$this->_redirect_after_action(false, '', '', $query_args, true);
3075
+				break;
3076
+		}
3077
+		// what are you looking here for?  Should be nothing to do at this point.
3078
+	}
3079
+
3080
+
3081
+	/**
3082
+	 * redirect_to_txn
3083
+	 *
3084
+	 * @return void
3085
+	 * @throws EE_Error
3086
+	 * @throws InvalidArgumentException
3087
+	 * @throws InvalidDataTypeException
3088
+	 * @throws InvalidInterfaceException
3089
+	 * @throws ReflectionException
3090
+	 */
3091
+	public function redirect_to_txn()
3092
+	{
3093
+		EE_System::do_not_cache();
3094
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
3095
+		$query_args = [
3096
+			'action' => 'view_transaction',
3097
+			'TXN_ID' => $this->request->getRequestParam('TXN_ID', 0, 'int'),
3098
+			'page'   => 'espresso_transactions',
3099
+		];
3100
+		if ($this->request->requestParamIsSet('EVT_ID') && $this->request->requestParamIsSet('redirect_from')) {
3101
+			$query_args['EVT_ID']        = $this->request->getRequestParam('EVT_ID', 0, 'int');
3102
+			$query_args['event_name']    = urlencode($this->request->getRequestParam('event_name'));
3103
+			$query_args['redirect_from'] = $this->request->getRequestParam('redirect_from');
3104
+		}
3105
+		EE_Error::add_success(
3106
+			esc_html__(
3107
+				'Registration Created.  Please review the transaction and add any payments as necessary',
3108
+				'event_espresso'
3109
+			)
3110
+		);
3111
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3112
+	}
3113
+
3114
+
3115
+	/**
3116
+	 * generates HTML for the Attendee Contact List
3117
+	 *
3118
+	 * @return void
3119
+	 * @throws DomainException
3120
+	 * @throws EE_Error
3121
+	 */
3122
+	protected function _attendee_contact_list_table()
3123
+	{
3124
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3125
+		$this->_search_btn_label = esc_html__('Contacts', 'event_espresso');
3126
+		$this->display_admin_list_table_page_with_no_sidebar();
3127
+	}
3128
+
3129
+
3130
+	/**
3131
+	 * get_attendees
3132
+	 *
3133
+	 * @param      $per_page
3134
+	 * @param bool $count whether to return count or data.
3135
+	 * @param bool $trash
3136
+	 * @return array|int
3137
+	 * @throws EE_Error
3138
+	 * @throws InvalidArgumentException
3139
+	 * @throws InvalidDataTypeException
3140
+	 * @throws InvalidInterfaceException
3141
+	 */
3142
+	public function get_attendees($per_page, $count = false, $trash = false)
3143
+	{
3144
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3145
+		require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3146
+		$orderby = $this->request->getRequestParam('orderby');
3147
+		switch ($orderby) {
3148
+			case 'ATT_ID':
3149
+			case 'ATT_fname':
3150
+			case 'ATT_email':
3151
+			case 'ATT_city':
3152
+			case 'STA_ID':
3153
+			case 'CNT_ID':
3154
+				break;
3155
+			case 'Registration_Count':
3156
+				$orderby = 'Registration_Count';
3157
+				break;
3158
+			default:
3159
+				$orderby = 'ATT_lname';
3160
+		}
3161
+		$sort         = $this->request->getRequestParam('order', 'ASC');
3162
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
3163
+		$per_page     = absint($per_page) ? $per_page : 10;
3164
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
3165
+		$_where       = [];
3166
+		$search_term  = $this->request->getRequestParam('s');
3167
+		if ($search_term) {
3168
+			$search_term  = '%' . $search_term . '%';
3169
+			$_where['OR'] = [
3170
+				'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3171
+				'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
3172
+				'Registration.Event.EVT_short_desc' => ['LIKE', $search_term],
3173
+				'ATT_fname'                         => ['LIKE', $search_term],
3174
+				'ATT_lname'                         => ['LIKE', $search_term],
3175
+				'ATT_short_bio'                     => ['LIKE', $search_term],
3176
+				'ATT_email'                         => ['LIKE', $search_term],
3177
+				'ATT_address'                       => ['LIKE', $search_term],
3178
+				'ATT_address2'                      => ['LIKE', $search_term],
3179
+				'ATT_city'                          => ['LIKE', $search_term],
3180
+				'Country.CNT_name'                  => ['LIKE', $search_term],
3181
+				'State.STA_name'                    => ['LIKE', $search_term],
3182
+				'ATT_phone'                         => ['LIKE', $search_term],
3183
+				'Registration.REG_final_price'      => ['LIKE', $search_term],
3184
+				'Registration.REG_code'             => ['LIKE', $search_term],
3185
+				'Registration.REG_group_size'       => ['LIKE', $search_term],
3186
+			];
3187
+		}
3188
+		$offset     = ($current_page - 1) * $per_page;
3189
+		$limit      = $count ? null : [$offset, $per_page];
3190
+		$query_args = [
3191
+			$_where,
3192
+			'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3193
+			'limit'         => $limit,
3194
+		];
3195
+		if (! $count) {
3196
+			$query_args['order_by'] = [$orderby => $sort];
3197
+		}
3198
+		$query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
3199
+		return $count
3200
+			? $this->getAttendeeModel()->count($query_args, 'ATT_ID', true)
3201
+			: $this->getAttendeeModel()->get_all($query_args);
3202
+	}
3203
+
3204
+
3205
+	/**
3206
+	 * This is just taking care of resending the registration confirmation
3207
+	 *
3208
+	 * @return void
3209
+	 * @throws EE_Error
3210
+	 * @throws InvalidArgumentException
3211
+	 * @throws InvalidDataTypeException
3212
+	 * @throws InvalidInterfaceException
3213
+	 * @throws ReflectionException
3214
+	 */
3215
+	protected function _resend_registration()
3216
+	{
3217
+		$this->_process_resend_registration();
3218
+		$REG_ID      = $this->request->getRequestParam('_REG_ID', 0, 'int');
3219
+		$redirect_to = $this->request->getRequestParam('redirect_to');
3220
+		$query_args  = $redirect_to
3221
+			? ['action' => $redirect_to, '_REG_ID' => $REG_ID]
3222
+			: ['action' => 'default'];
3223
+		$this->_redirect_after_action(false, '', '', $query_args, true);
3224
+	}
3225
+
3226
+
3227
+	/**
3228
+	 * Creates a registration report, but accepts the name of a method to use for preparing the query parameters
3229
+	 * to use when selecting registrations
3230
+	 *
3231
+	 * @param string $method_name_for_getting_query_params the name of the method (on this class) to use for preparing
3232
+	 *                                                     the query parameters from the request
3233
+	 * @return void ends the request with a redirect or download
3234
+	 */
3235
+	public function _registrations_report_base($method_name_for_getting_query_params)
3236
+	{
3237
+		$EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3238
+			? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3239
+			: null;
3240
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3241
+			$return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3242
+			$filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3243
+			$report_params = $this->$method_name_for_getting_query_params($filters);
3244
+			$use_filters   = $this->request->getRequestParam('use_filters', false, DataType::BOOL);
3245
+			wp_redirect(
3246
+				EE_Admin_Page::add_query_args_and_nonce(
3247
+					[
3248
+						'page'        => EED_Batch::PAGE_SLUG,
3249
+						'batch'       => EED_Batch::batch_file_job,
3250
+						'EVT_ID'      => $EVT_ID,
3251
+						'filters'     => urlencode(serialize($report_params)),
3252
+						'use_filters' => urlencode($use_filters),
3253
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\RegistrationsReport'),
3254
+						'return_url'  => urlencode($return_url),
3255
+					]
3256
+				)
3257
+			);
3258
+		} else {
3259
+			// Pull the current request params
3260
+			$request_args = $this->request->requestParams();
3261
+			// Set the required request_args to be passed to the export
3262
+			$required_request_args = [
3263
+				'export' => 'report',
3264
+				'action' => 'registrations_report_for_event',
3265
+				'EVT_ID' => $EVT_ID,
3266
+			];
3267
+			// Merge required request args, overriding any currently set
3268
+			$request_args = array_merge($request_args, $required_request_args);
3269
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3270
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3271
+				$EE_Export = EE_Export::instance($request_args);
3272
+				$EE_Export->export();
3273
+			}
3274
+		}
3275
+	}
3276
+
3277
+
3278
+	/**
3279
+	 * Creates a registration report using only query parameters in the request
3280
+	 *
3281
+	 * @return void
3282
+	 */
3283
+	public function _registrations_report()
3284
+	{
3285
+		$this->_registrations_report_base('_get_registration_query_parameters');
3286
+	}
3287
+
3288
+
3289
+	public function _contact_list_export()
3290
+	{
3291
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3292
+			require_once(EE_CLASSES . 'EE_Export.class.php');
3293
+			$EE_Export = EE_Export::instance($this->request->requestParams());
3294
+			$EE_Export->export_attendees();
3295
+		}
3296
+	}
3297
+
3298
+
3299
+	public function _contact_list_report()
3300
+	{
3301
+		if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3302
+			wp_redirect(
3303
+				EE_Admin_Page::add_query_args_and_nonce(
3304
+					[
3305
+						'page'        => EED_Batch::PAGE_SLUG,
3306
+						'batch'       => EED_Batch::batch_file_job,
3307
+						'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\AttendeesReport'),
3308
+						'return_url'  => urlencode($this->request->getRequestParam('return_url', '', DataType::URL)),
3309
+					]
3310
+				)
3311
+			);
3312
+		} else {
3313
+			if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3314
+				require_once(EE_CLASSES . 'EE_Export.class.php');
3315
+				$EE_Export = EE_Export::instance($this->request->requestParams());
3316
+				$EE_Export->report_attendees();
3317
+			}
3318
+		}
3319
+	}
3320
+
3321
+
3322
+
3323
+
3324
+
3325
+	/***************************************        ATTENDEE DETAILS        ***************************************/
3326
+	/**
3327
+	 * This duplicates the attendee object for the given incoming registration id and attendee_id.
3328
+	 *
3329
+	 * @return void
3330
+	 * @throws EE_Error
3331
+	 * @throws InvalidArgumentException
3332
+	 * @throws InvalidDataTypeException
3333
+	 * @throws InvalidInterfaceException
3334
+	 * @throws ReflectionException
3335
+	 */
3336
+	protected function _duplicate_attendee()
3337
+	{
3338
+		$REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3339
+		$action = $this->request->getRequestParam('return', 'default');
3340
+		// verify we have necessary info
3341
+		if (! $REG_ID) {
3342
+			EE_Error::add_error(
3343
+				esc_html__(
3344
+					'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
3345
+					'event_espresso'
3346
+				),
3347
+				__FILE__,
3348
+				__LINE__,
3349
+				__FUNCTION__
3350
+			);
3351
+			$query_args = ['action' => $action];
3352
+			$this->_redirect_after_action('', '', '', $query_args, true);
3353
+		}
3354
+		// okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3355
+		$registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3356
+		if (! $registration instanceof EE_Registration) {
3357
+			throw new RuntimeException(
3358
+				sprintf(
3359
+					esc_html__(
3360
+						'Unable to create the contact because a valid registration could not be retrieved for REG ID: %1$d',
3361
+						'event_espresso'
3362
+					),
3363
+					$REG_ID
3364
+				)
3365
+			);
3366
+		}
3367
+		$attendee = $registration->attendee();
3368
+		// remove relation of existing attendee on registration
3369
+		$registration->_remove_relation_to($attendee, 'Attendee');
3370
+		// new attendee
3371
+		$new_attendee = clone $attendee;
3372
+		$new_attendee->set('ATT_ID', 0);
3373
+		$new_attendee->save();
3374
+		// add new attendee to reg
3375
+		$registration->_add_relation_to($new_attendee, 'Attendee');
3376
+		EE_Error::add_success(
3377
+			esc_html__(
3378
+				'New Contact record created.  Now make any edits you wish to make for this contact.',
3379
+				'event_espresso'
3380
+			)
3381
+		);
3382
+		// redirect to edit page for attendee
3383
+		$query_args = ['post' => $new_attendee->ID(), 'action' => 'edit_attendee'];
3384
+		$this->_redirect_after_action('', '', '', $query_args, true);
3385
+	}
3386
+
3387
+
3388
+	/**
3389
+	 * Callback invoked by parent EE_Admin_CPT class hooked in on `save_post` wp hook.
3390
+	 *
3391
+	 * @param int     $post_id
3392
+	 * @param WP_Post $post
3393
+	 * @throws DomainException
3394
+	 * @throws EE_Error
3395
+	 * @throws InvalidArgumentException
3396
+	 * @throws InvalidDataTypeException
3397
+	 * @throws InvalidInterfaceException
3398
+	 * @throws LogicException
3399
+	 * @throws InvalidFormSubmissionException
3400
+	 * @throws ReflectionException
3401
+	 */
3402
+	protected function _insert_update_cpt_item($post_id, $post)
3403
+	{
3404
+		$success  = true;
3405
+		$attendee = $post instanceof WP_Post && $post->post_type === 'espresso_attendees'
3406
+			? $this->getAttendeeModel()->get_one_by_ID($post_id)
3407
+			: null;
3408
+		// for attendee updates
3409
+		if ($attendee instanceof EE_Attendee) {
3410
+			// note we should only be UPDATING attendees at this point.
3411
+			$fname          = $this->request->getRequestParam('ATT_fname', '');
3412
+			$lname          = $this->request->getRequestParam('ATT_lname', '');
3413
+			$updated_fields = [
3414
+				'ATT_fname'     => $fname,
3415
+				'ATT_lname'     => $lname,
3416
+				'ATT_full_name' => "{$fname} {$lname}",
3417
+				'ATT_address'   => $this->request->getRequestParam('ATT_address', ''),
3418
+				'ATT_address2'  => $this->request->getRequestParam('ATT_address2', ''),
3419
+				'ATT_city'      => $this->request->getRequestParam('ATT_city', ''),
3420
+				'STA_ID'        => $this->request->getRequestParam('STA_ID', ''),
3421
+				'CNT_ISO'       => $this->request->getRequestParam('CNT_ISO', ''),
3422
+				'ATT_zip'       => $this->request->getRequestParam('ATT_zip', ''),
3423
+			];
3424
+			foreach ($updated_fields as $field => $value) {
3425
+				$attendee->set($field, $value);
3426
+			}
3427
+
3428
+			// process contact details metabox form handler (which will also save the attendee)
3429
+			$contact_details_form = $this->getAttendeeContactDetailsMetaboxFormHandler($attendee);
3430
+			$success              = $contact_details_form->process($this->request->requestParams());
3431
+
3432
+			$attendee_update_callbacks = apply_filters(
3433
+				'FHEE__Registrations_Admin_Page__insert_update_cpt_item__attendee_update',
3434
+				[]
3435
+			);
3436
+			foreach ($attendee_update_callbacks as $a_callback) {
3437
+				if (false === call_user_func_array($a_callback, [$attendee, $this->request->requestParams()])) {
3438
+					throw new EE_Error(
3439
+						sprintf(
3440
+							esc_html__(
3441
+								'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.',
3442
+								'event_espresso'
3443
+							),
3444
+							$a_callback
3445
+						)
3446
+					);
3447
+				}
3448
+			}
3449
+		}
3450
+
3451
+		if ($success === false) {
3452
+			EE_Error::add_error(
3453
+				esc_html__(
3454
+					'Something went wrong with updating the meta table data for the registration.',
3455
+					'event_espresso'
3456
+				),
3457
+				__FILE__,
3458
+				__FUNCTION__,
3459
+				__LINE__
3460
+			);
3461
+		}
3462
+	}
3463
+
3464
+
3465
+	public function trash_cpt_item($post_id)
3466
+	{
3467
+	}
3468
+
3469
+
3470
+	public function delete_cpt_item($post_id)
3471
+	{
3472
+	}
3473
+
3474
+
3475
+	public function restore_cpt_item($post_id)
3476
+	{
3477
+	}
3478
+
3479
+
3480
+	protected function _restore_cpt_item($post_id, $revision_id)
3481
+	{
3482
+	}
3483
+
3484
+
3485
+	/**
3486
+	 * @throws EE_Error
3487
+	 * @throws ReflectionException
3488
+	 * @since 4.10.2.p
3489
+	 */
3490
+	public function attendee_editor_metaboxes()
3491
+	{
3492
+		$this->verify_cpt_object();
3493
+		remove_meta_box(
3494
+			'postexcerpt',
3495
+			$this->_cpt_routes[ $this->_req_action ],
3496
+			'normal'
3497
+		);
3498
+		remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3499
+		if (post_type_supports('espresso_attendees', 'excerpt')) {
3500
+			$this->addMetaBox(
3501
+				'postexcerpt',
3502
+				esc_html__('Short Biography', 'event_espresso'),
3503
+				'post_excerpt_meta_box',
3504
+				$this->_cpt_routes[ $this->_req_action ]
3505
+			);
3506
+		}
3507
+		if (post_type_supports('espresso_attendees', 'comments')) {
3508
+			$this->addMetaBox(
3509
+				'commentsdiv',
3510
+				esc_html__('Notes on the Contact', 'event_espresso'),
3511
+				'post_comment_meta_box',
3512
+				$this->_cpt_routes[ $this->_req_action ],
3513
+				'normal',
3514
+				'core'
3515
+			);
3516
+		}
3517
+		$this->addMetaBox(
3518
+			'attendee_contact_info',
3519
+			esc_html__('Contact Info', 'event_espresso'),
3520
+			[$this, 'attendee_contact_info'],
3521
+			$this->_cpt_routes[ $this->_req_action ],
3522
+			'side',
3523
+			'core'
3524
+		);
3525
+		$this->addMetaBox(
3526
+			'attendee_details_address',
3527
+			esc_html__('Address Details', 'event_espresso'),
3528
+			[$this, 'attendee_address_details'],
3529
+			$this->_cpt_routes[ $this->_req_action ],
3530
+			'normal',
3531
+			'core'
3532
+		);
3533
+		$this->addMetaBox(
3534
+			'attendee_registrations',
3535
+			esc_html__('Registrations for this Contact', 'event_espresso'),
3536
+			[$this, 'attendee_registrations_meta_box'],
3537
+			$this->_cpt_routes[ $this->_req_action ]
3538
+		);
3539
+	}
3540
+
3541
+
3542
+	/**
3543
+	 * Metabox for attendee contact info
3544
+	 *
3545
+	 * @param WP_Post $post wp post object
3546
+	 * @return void attendee contact info ( and form )
3547
+	 * @throws EE_Error
3548
+	 * @throws InvalidArgumentException
3549
+	 * @throws InvalidDataTypeException
3550
+	 * @throws InvalidInterfaceException
3551
+	 * @throws LogicException
3552
+	 * @throws DomainException
3553
+	 */
3554
+	public function attendee_contact_info($post)
3555
+	{
3556
+		// get attendee object ( should already have it )
3557
+		$form = $this->getAttendeeContactDetailsMetaboxFormHandler($this->_cpt_model_obj);
3558
+		$form->enqueueStylesAndScripts();
3559
+		echo wp_kses($form->display(), AllowedTags::getWithFormTags());
3560
+	}
3561
+
3562
+
3563
+	/**
3564
+	 * Return form handler for the contact details metabox
3565
+	 *
3566
+	 * @param EE_Attendee $attendee
3567
+	 * @return AttendeeContactDetailsMetaboxFormHandler
3568
+	 * @throws DomainException
3569
+	 * @throws InvalidArgumentException
3570
+	 * @throws InvalidDataTypeException
3571
+	 * @throws InvalidInterfaceException
3572
+	 */
3573
+	protected function getAttendeeContactDetailsMetaboxFormHandler(EE_Attendee $attendee)
3574
+	{
3575
+		return new AttendeeContactDetailsMetaboxFormHandler($attendee, EE_Registry::instance());
3576
+	}
3577
+
3578
+
3579
+	/**
3580
+	 * Metabox for attendee details
3581
+	 *
3582
+	 * @param WP_Post $post wp post object
3583
+	 * @throws EE_Error
3584
+	 * @throws ReflectionException
3585
+	 */
3586
+	public function attendee_address_details($post)
3587
+	{
3588
+		// get attendee object (should already have it)
3589
+		$this->_template_args['attendee']     = $this->_cpt_model_obj;
3590
+		$this->_template_args['state_html']   = EEH_Form_Fields::generate_form_input(
3591
+			new EE_Question_Form_Input(
3592
+				EE_Question::new_instance(
3593
+					[
3594
+						'QST_ID'           => 0,
3595
+						'QST_display_text' => esc_html__('State/Province', 'event_espresso'),
3596
+						'QST_system'       => 'admin-state',
3597
+					]
3598
+				),
3599
+				EE_Answer::new_instance(
3600
+					[
3601
+						'ANS_ID'    => 0,
3602
+						'ANS_value' => $this->_cpt_model_obj->state_ID(),
3603
+					]
3604
+				),
3605
+				[
3606
+					'input_id'       => 'STA_ID',
3607
+					'input_name'     => 'STA_ID',
3608
+					'input_prefix'   => '',
3609
+					'append_qstn_id' => false,
3610
+				]
3611
+			)
3612
+		);
3613
+		$this->_template_args['country_html'] = EEH_Form_Fields::generate_form_input(
3614
+			new EE_Question_Form_Input(
3615
+				EE_Question::new_instance(
3616
+					[
3617
+						'QST_ID'           => 0,
3618
+						'QST_display_text' => esc_html__('Country', 'event_espresso'),
3619
+						'QST_system'       => 'admin-country',
3620
+					]
3621
+				),
3622
+				EE_Answer::new_instance(
3623
+					[
3624
+						'ANS_ID'    => 0,
3625
+						'ANS_value' => $this->_cpt_model_obj->country_ID(),
3626
+					]
3627
+				),
3628
+				[
3629
+					'input_id'       => 'CNT_ISO',
3630
+					'input_name'     => 'CNT_ISO',
3631
+					'input_prefix'   => '',
3632
+					'append_qstn_id' => false,
3633
+				]
3634
+			)
3635
+		);
3636
+		$template                             =
3637
+			REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3638
+		EEH_Template::display_template($template, $this->_template_args);
3639
+	}
3640
+
3641
+
3642
+	/**
3643
+	 * _attendee_details
3644
+	 *
3645
+	 * @param $post
3646
+	 * @return void
3647
+	 * @throws DomainException
3648
+	 * @throws EE_Error
3649
+	 * @throws InvalidArgumentException
3650
+	 * @throws InvalidDataTypeException
3651
+	 * @throws InvalidInterfaceException
3652
+	 * @throws ReflectionException
3653
+	 */
3654
+	public function attendee_registrations_meta_box($post)
3655
+	{
3656
+		$this->_template_args['attendee']      = $this->_cpt_model_obj;
3657
+		$this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3658
+		$template                              =
3659
+			REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3660
+		EEH_Template::display_template($template, $this->_template_args);
3661
+	}
3662
+
3663
+
3664
+	/**
3665
+	 * add in the form fields for the attendee edit
3666
+	 *
3667
+	 * @param WP_Post $post wp post object
3668
+	 * @return void echos html for new form.
3669
+	 * @throws DomainException
3670
+	 */
3671
+	public function after_title_form_fields($post)
3672
+	{
3673
+		if ($post->post_type === 'espresso_attendees') {
3674
+			$template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3675
+			$template_args['attendee'] = $this->_cpt_model_obj;
3676
+			EEH_Template::display_template($template, $template_args);
3677
+		}
3678
+	}
3679
+
3680
+
3681
+	/**
3682
+	 * _trash_or_restore_attendee
3683
+	 *
3684
+	 * @param boolean $trash - whether to move item to trash (TRUE) or restore it (FALSE)
3685
+	 * @return void
3686
+	 * @throws EE_Error
3687
+	 * @throws InvalidArgumentException
3688
+	 * @throws InvalidDataTypeException
3689
+	 * @throws InvalidInterfaceException
3690
+	 */
3691
+	protected function _trash_or_restore_attendees($trash = true)
3692
+	{
3693
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3694
+		$status = $trash ? 'trash' : 'publish';
3695
+		// Checkboxes
3696
+		if ($this->request->requestParamIsSet('checkbox')) {
3697
+			$ATT_IDs = $this->request->getRequestParam('checkbox', [], 'int', true);
3698
+			// if array has more than one element than success message should be plural
3699
+			$success = count($ATT_IDs) > 1 ? 2 : 1;
3700
+			// cycle thru checkboxes
3701
+			foreach ($ATT_IDs as $ATT_ID) {
3702
+				$updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3703
+				if (! $updated) {
3704
+					$success = 0;
3705
+				}
3706
+			}
3707
+		} else {
3708
+			// grab single id and delete
3709
+			$ATT_ID = $this->request->getRequestParam('ATT_ID', 0, 'int');
3710
+			// update attendee
3711
+			$success = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID) ? 1 : 0;
3712
+		}
3713
+		$what        = $success > 1
3714
+			? esc_html__('Contacts', 'event_espresso')
3715
+			: esc_html__('Contact', 'event_espresso');
3716
+		$action_desc = $trash
3717
+			? esc_html__('moved to the trash', 'event_espresso')
3718
+			: esc_html__('restored', 'event_espresso');
3719
+		$this->_redirect_after_action($success, $what, $action_desc, ['action' => 'contact_list']);
3720
+	}
3721 3721
 }
Please login to merge, or discard this patch.
Spacing   +104 added lines, -104 removed lines patch added patch discarded remove patch
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
      */
95 95
     protected function getRegistrationModel()
96 96
     {
97
-        if (! $this->registration_model instanceof EEM_Registration) {
97
+        if ( ! $this->registration_model instanceof EEM_Registration) {
98 98
             $this->registration_model = $this->loader->getShared('EEM_Registration');
99 99
         }
100 100
         return $this->registration_model;
@@ -110,7 +110,7 @@  discard block
 block discarded – undo
110 110
      */
111 111
     protected function getAttendeeModel()
112 112
     {
113
-        if (! $this->attendee_model instanceof EEM_Attendee) {
113
+        if ( ! $this->attendee_model instanceof EEM_Attendee) {
114 114
             $this->attendee_model = $this->loader->getShared('EEM_Attendee');
115 115
         }
116 116
         return $this->attendee_model;
@@ -126,7 +126,7 @@  discard block
 block discarded – undo
126 126
      */
127 127
     protected function getEventModel()
128 128
     {
129
-        if (! $this->event_model instanceof EEM_Event) {
129
+        if ( ! $this->event_model instanceof EEM_Event) {
130 130
             $this->event_model = $this->loader->getShared('EEM_Event');
131 131
         }
132 132
         return $this->event_model;
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
      */
143 143
     protected function getStatusModel()
144 144
     {
145
-        if (! $this->status_model instanceof EEM_Status) {
145
+        if ( ! $this->status_model instanceof EEM_Status) {
146 146
             $this->status_model = $this->loader->getShared('EEM_Status');
147 147
         }
148 148
         return $this->status_model;
@@ -761,7 +761,7 @@  discard block
 block discarded – undo
761 761
         // style
762 762
         wp_register_style(
763 763
             'espresso_reg',
764
-            REG_ASSETS_URL . 'espresso_registrations_admin.css',
764
+            REG_ASSETS_URL.'espresso_registrations_admin.css',
765 765
             ['ee-admin-css'],
766 766
             EVENT_ESPRESSO_VERSION
767 767
         );
@@ -769,7 +769,7 @@  discard block
 block discarded – undo
769 769
         // script
770 770
         wp_register_script(
771 771
             'espresso_reg',
772
-            REG_ASSETS_URL . 'espresso_registrations_admin.js',
772
+            REG_ASSETS_URL.'espresso_registrations_admin.js',
773 773
             ['jquery-ui-datepicker', 'jquery-ui-draggable', 'ee_admin_js'],
774 774
             EVENT_ESPRESSO_VERSION,
775 775
             true
@@ -793,7 +793,7 @@  discard block
 block discarded – undo
793 793
             'att_publish_text' => sprintf(
794 794
             /* translators: The date and time */
795 795
                 wp_strip_all_tags(__('Created on: %s', 'event_espresso')),
796
-                '<b>' . $this->_cpt_model_obj->get_datetime('ATT_created') . '</b>'
796
+                '<b>'.$this->_cpt_model_obj->get_datetime('ATT_created').'</b>'
797 797
             ),
798 798
         ];
799 799
         wp_localize_script('espresso_reg', 'ATTENDEE_DETAILS', $attendee_details_translations);
@@ -825,7 +825,7 @@  discard block
 block discarded – undo
825 825
         wp_dequeue_style('espresso_reg');
826 826
         wp_register_style(
827 827
             'espresso_att',
828
-            REG_ASSETS_URL . 'espresso_attendees_admin.css',
828
+            REG_ASSETS_URL.'espresso_attendees_admin.css',
829 829
             ['ee-admin-css'],
830 830
             EVENT_ESPRESSO_VERSION
831 831
         );
@@ -837,7 +837,7 @@  discard block
 block discarded – undo
837 837
     {
838 838
         wp_register_script(
839 839
             'ee-spco-for-admin',
840
-            REG_ASSETS_URL . 'spco_for_admin.js',
840
+            REG_ASSETS_URL.'spco_for_admin.js',
841 841
             ['underscore', 'jquery'],
842 842
             EVENT_ESPRESSO_VERSION,
843 843
             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
         );
@@ -990,7 +990,7 @@  discard block
 block discarded – undo
990 990
                     'trash_registrations' => esc_html__('Trash Registrations', 'event_espresso'),
991 991
                 ],
992 992
             ];
993
-            $this->_views['trash']      = [
993
+            $this->_views['trash'] = [
994 994
                 'slug'        => 'trash',
995 995
                 'label'       => esc_html__('Trash', 'event_espresso'),
996 996
                 'count'       => 0,
@@ -1090,7 +1090,7 @@  discard block
 block discarded – undo
1090 1090
         }
1091 1091
         $sc_items = [
1092 1092
             'approved_status'   => [
1093
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_approved,
1093
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_approved,
1094 1094
                 'desc'  => EEH_Template::pretty_status(
1095 1095
                     EEM_Registration::status_id_approved,
1096 1096
                     false,
@@ -1098,7 +1098,7 @@  discard block
 block discarded – undo
1098 1098
                 ),
1099 1099
             ],
1100 1100
             'pending_status'    => [
1101
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_pending_payment,
1101
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_pending_payment,
1102 1102
                 'desc'  => EEH_Template::pretty_status(
1103 1103
                     EEM_Registration::status_id_pending_payment,
1104 1104
                     false,
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
                 ),
1107 1107
             ],
1108 1108
             'wait_list'         => [
1109
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_wait_list,
1109
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_wait_list,
1110 1110
                 'desc'  => EEH_Template::pretty_status(
1111 1111
                     EEM_Registration::status_id_wait_list,
1112 1112
                     false,
@@ -1114,7 +1114,7 @@  discard block
 block discarded – undo
1114 1114
                 ),
1115 1115
             ],
1116 1116
             'incomplete_status' => [
1117
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_incomplete,
1117
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_incomplete,
1118 1118
                 'desc'  => EEH_Template::pretty_status(
1119 1119
                     EEM_Registration::status_id_incomplete,
1120 1120
                     false,
@@ -1122,7 +1122,7 @@  discard block
 block discarded – undo
1122 1122
                 ),
1123 1123
             ],
1124 1124
             'not_approved'      => [
1125
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_not_approved,
1125
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_not_approved,
1126 1126
                 'desc'  => EEH_Template::pretty_status(
1127 1127
                     EEM_Registration::status_id_not_approved,
1128 1128
                     false,
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
                 ),
1131 1131
             ],
1132 1132
             'declined_status'   => [
1133
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_declined,
1133
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_declined,
1134 1134
                 'desc'  => EEH_Template::pretty_status(
1135 1135
                     EEM_Registration::status_id_declined,
1136 1136
                     false,
@@ -1138,7 +1138,7 @@  discard block
 block discarded – undo
1138 1138
                 ),
1139 1139
             ],
1140 1140
             'cancelled_status'  => [
1141
-                'class' => 'ee-status-legend ee-status-bg--' . EEM_Registration::status_id_cancelled,
1141
+                'class' => 'ee-status-legend ee-status-bg--'.EEM_Registration::status_id_cancelled,
1142 1142
                 'desc'  => EEH_Template::pretty_status(
1143 1143
                     EEM_Registration::status_id_cancelled,
1144 1144
                     false,
@@ -1198,7 +1198,7 @@  discard block
 block discarded – undo
1198 1198
                 $EVT_ID
1199 1199
             )
1200 1200
         ) {
1201
-            $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1201
+            $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1202 1202
                     'new_registration',
1203 1203
                     'add-registrant',
1204 1204
                     ['event_id' => $EVT_ID],
@@ -1356,7 +1356,7 @@  discard block
 block discarded – undo
1356 1356
                 ],
1357 1357
                 REG_ADMIN_URL
1358 1358
             );
1359
-            $this->_template_args['filtered_transactions_link']  = EE_Admin_Page::add_query_args_and_nonce(
1359
+            $this->_template_args['filtered_transactions_link'] = EE_Admin_Page::add_query_args_and_nonce(
1360 1360
                 [
1361 1361
                     'action' => 'default',
1362 1362
                     'EVT_ID' => $event_id,
@@ -1364,7 +1364,7 @@  discard block
 block discarded – undo
1364 1364
                 ],
1365 1365
                 admin_url('admin.php')
1366 1366
             );
1367
-            $this->_template_args['event_link']                  = EE_Admin_Page::add_query_args_and_nonce(
1367
+            $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(
1368 1368
                 [
1369 1369
                     'page'   => 'espresso_events',
1370 1370
                     'action' => 'edit',
@@ -1373,12 +1373,12 @@  discard block
 block discarded – undo
1373 1373
                 admin_url('admin.php')
1374 1374
             );
1375 1375
             // next and previous links
1376
-            $next_reg                                      = $this->_registration->next(
1376
+            $next_reg = $this->_registration->next(
1377 1377
                 null,
1378 1378
                 [],
1379 1379
                 'REG_ID'
1380 1380
             );
1381
-            $this->_template_args['next_registration']     = $next_reg
1381
+            $this->_template_args['next_registration'] = $next_reg
1382 1382
                 ? $this->_next_link(
1383 1383
                     EE_Admin_Page::add_query_args_and_nonce(
1384 1384
                         [
@@ -1390,7 +1390,7 @@  discard block
 block discarded – undo
1390 1390
                     'dashicons dashicons-arrow-right ee-icon-size-22'
1391 1391
                 )
1392 1392
                 : '';
1393
-            $previous_reg                                  = $this->_registration->previous(
1393
+            $previous_reg = $this->_registration->previous(
1394 1394
                 null,
1395 1395
                 [],
1396 1396
                 'REG_ID'
@@ -1408,7 +1408,7 @@  discard block
 block discarded – undo
1408 1408
                 )
1409 1409
                 : '';
1410 1410
             // grab header
1411
-            $template_path                             = REG_TEMPLATE_PATH . 'reg_admin_details_header.template.php';
1411
+            $template_path                             = REG_TEMPLATE_PATH.'reg_admin_details_header.template.php';
1412 1412
             $this->_template_args['REG_ID']            = $this->_registration->ID();
1413 1413
             $this->_template_args['admin_page_header'] = EEH_Template::display_template(
1414 1414
                 $template_path,
@@ -1445,7 +1445,7 @@  discard block
 block discarded – undo
1445 1445
         );
1446 1446
         $this->addMetaBox(
1447 1447
             'edit-reg-details-mbox',
1448
-            '<span>' . esc_html__('Registration Details', 'event_espresso')
1448
+            '<span>'.esc_html__('Registration Details', 'event_espresso')
1449 1449
             . '&nbsp;<span class="dashicons dashicons-clipboard"></span></span>',
1450 1450
             [$this, '_reg_details_meta_box'],
1451 1451
             $this->_wp_page_slug
@@ -1549,7 +1549,7 @@  discard block
 block discarded – undo
1549 1549
                 $this->_registration->ID()
1550 1550
             )
1551 1551
         ) {
1552
-            $reg_status_change_form_array['subsections']['reg_status']         = new EE_Select_Input(
1552
+            $reg_status_change_form_array['subsections']['reg_status'] = new EE_Select_Input(
1553 1553
                 $this->_get_reg_statuses(),
1554 1554
                 [
1555 1555
                     'html_label_text' => esc_html__('Change Registration Status to', 'event_espresso'),
@@ -1566,7 +1566,7 @@  discard block
 block discarded – undo
1566 1566
                     ),
1567 1567
                 ]
1568 1568
             );
1569
-            $reg_status_change_form_array['subsections']['submit']             = new EE_Submit_Input(
1569
+            $reg_status_change_form_array['subsections']['submit'] = new EE_Submit_Input(
1570 1570
                 [
1571 1571
                     'html_class'      => 'button--primary',
1572 1572
                     'html_label_text' => '&nbsp;',
@@ -1591,7 +1591,7 @@  discard block
 block discarded – undo
1591 1591
     protected function _get_reg_statuses()
1592 1592
     {
1593 1593
         $reg_status_array = $this->getRegistrationModel()->reg_status_array();
1594
-        unset($reg_status_array[ EEM_Registration::status_id_incomplete ]);
1594
+        unset($reg_status_array[EEM_Registration::status_id_incomplete]);
1595 1595
         // get current reg status
1596 1596
         $current_status = $this->_registration->status_ID();
1597 1597
         // is registration for free event? This will determine whether to display the pending payment option
@@ -1599,7 +1599,7 @@  discard block
 block discarded – undo
1599 1599
             $current_status !== EEM_Registration::status_id_pending_payment
1600 1600
             && EEH_Money::compare_floats($this->_registration->ticket()->price(), 0.00)
1601 1601
         ) {
1602
-            unset($reg_status_array[ EEM_Registration::status_id_pending_payment ]);
1602
+            unset($reg_status_array[EEM_Registration::status_id_pending_payment]);
1603 1603
         }
1604 1604
         return $this->getStatusModel()->localized_status($reg_status_array, false, 'sentence');
1605 1605
     }
@@ -1689,7 +1689,7 @@  discard block
 block discarded – undo
1689 1689
         $success = false;
1690 1690
         // typecast $REG_IDs
1691 1691
         $REG_IDs = (array) $REG_IDs;
1692
-        if (! empty($REG_IDs)) {
1692
+        if ( ! empty($REG_IDs)) {
1693 1693
             $success = true;
1694 1694
             // set default status if none is passed
1695 1695
             $status         = $status ?: EEM_Registration::status_id_pending_payment;
@@ -1849,7 +1849,7 @@  discard block
 block discarded – undo
1849 1849
             $action,
1850 1850
             $notify
1851 1851
         );
1852
-        $method = $action . '_registration';
1852
+        $method = $action.'_registration';
1853 1853
         if (method_exists($this, $method)) {
1854 1854
             $this->$method($notify);
1855 1855
         }
@@ -1999,7 +1999,7 @@  discard block
 block discarded – undo
1999 1999
         $filters        = new EE_Line_Item_Filter_Collection();
2000 2000
         $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
2001 2001
         $filters->add(new EE_Non_Zero_Line_Item_Filter());
2002
-        $line_item_filter_processor              = new EE_Line_Item_Filter_Processor(
2002
+        $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
2003 2003
             $filters,
2004 2004
             $transaction->total_line_item()
2005 2005
         );
@@ -2012,7 +2012,7 @@  discard block
 block discarded – undo
2012 2012
             $filtered_line_item_tree,
2013 2013
             ['EE_Registration' => $this->_registration]
2014 2014
         );
2015
-        $attendee                                = $this->_registration->attendee();
2015
+        $attendee = $this->_registration->attendee();
2016 2016
         if (
2017 2017
             $this->capabilities->current_user_can(
2018 2018
                 'ee_read_transaction',
@@ -2094,7 +2094,7 @@  discard block
 block discarded – undo
2094 2094
                 'Payment method response',
2095 2095
                 'event_espresso'
2096 2096
             );
2097
-            $this->_template_args['reg_details']['response_msg']['class']   = 'regular-text';
2097
+            $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
2098 2098
         }
2099 2099
         $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
2100 2100
         $this->_template_args['reg_details']['registration_session']['label'] = esc_html__(
@@ -2125,7 +2125,7 @@  discard block
 block discarded – undo
2125 2125
         $this->_template_args['REG_ID']   = $this->_registration->ID();
2126 2126
         $this->_template_args['event_id'] = $this->_registration->event_ID();
2127 2127
 
2128
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
2128
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_details.template.php';
2129 2129
         EEH_Template::display_template($template_path, $this->_template_args); // already escaped
2130 2130
     }
2131 2131
 
@@ -2165,7 +2165,7 @@  discard block
 block discarded – undo
2165 2165
             $this->_template_args['reg_questions_form_action'] = 'edit_registration';
2166 2166
             $this->_template_args['REG_ID']                    = $this->_registration->ID();
2167 2167
             $template_path                                     =
2168
-                REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_questions.template.php';
2168
+                REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_reg_questions.template.php';
2169 2169
             EEH_Template::display_template($template_path, $this->_template_args);
2170 2170
         }
2171 2171
     }
@@ -2181,7 +2181,7 @@  discard block
 block discarded – undo
2181 2181
     public function form_before_question_group($output)
2182 2182
     {
2183 2183
         EE_Error::doing_it_wrong(
2184
-            __CLASS__ . '::' . __FUNCTION__,
2184
+            __CLASS__.'::'.__FUNCTION__,
2185 2185
             esc_html__(
2186 2186
                 '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.',
2187 2187
                 'event_espresso'
@@ -2205,7 +2205,7 @@  discard block
 block discarded – undo
2205 2205
     public function form_after_question_group($output)
2206 2206
     {
2207 2207
         EE_Error::doing_it_wrong(
2208
-            __CLASS__ . '::' . __FUNCTION__,
2208
+            __CLASS__.'::'.__FUNCTION__,
2209 2209
             esc_html__(
2210 2210
                 '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.',
2211 2211
                 'event_espresso'
@@ -2242,7 +2242,7 @@  discard block
 block discarded – undo
2242 2242
     public function form_form_field_label_wrap($label)
2243 2243
     {
2244 2244
         EE_Error::doing_it_wrong(
2245
-            __CLASS__ . '::' . __FUNCTION__,
2245
+            __CLASS__.'::'.__FUNCTION__,
2246 2246
             esc_html__(
2247 2247
                 '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.',
2248 2248
                 'event_espresso'
@@ -2252,7 +2252,7 @@  discard block
 block discarded – undo
2252 2252
         return '
2253 2253
 			<tr>
2254 2254
 				<th>
2255
-					' . $label . '
2255
+					' . $label.'
2256 2256
 				</th>';
2257 2257
     }
2258 2258
 
@@ -2267,7 +2267,7 @@  discard block
 block discarded – undo
2267 2267
     public function form_form_field_input__wrap($input)
2268 2268
     {
2269 2269
         EE_Error::doing_it_wrong(
2270
-            __CLASS__ . '::' . __FUNCTION__,
2270
+            __CLASS__.'::'.__FUNCTION__,
2271 2271
             esc_html__(
2272 2272
                 '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.',
2273 2273
                 'event_espresso'
@@ -2276,7 +2276,7 @@  discard block
 block discarded – undo
2276 2276
         );
2277 2277
         return '
2278 2278
 				<td class="reg-admin-attendee-questions-input-td disabled-input">
2279
-					' . $input . '
2279
+					' . $input.'
2280 2280
 				</td>
2281 2281
 			</tr>';
2282 2282
     }
@@ -2325,8 +2325,8 @@  discard block
 block discarded – undo
2325 2325
      */
2326 2326
     protected function _get_reg_custom_questions_form($REG_ID)
2327 2327
     {
2328
-        if (! $this->_reg_custom_questions_form) {
2329
-            require_once(REG_ADMIN . 'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2328
+        if ( ! $this->_reg_custom_questions_form) {
2329
+            require_once(REG_ADMIN.'form_sections/EE_Registration_Custom_Questions_Form.form.php');
2330 2330
             $this->_reg_custom_questions_form = new EE_Registration_Custom_Questions_Form(
2331 2331
                 $this->getRegistrationModel()->get_one_by_ID($REG_ID)
2332 2332
             );
@@ -2349,7 +2349,7 @@  discard block
 block discarded – undo
2349 2349
      */
2350 2350
     private function _save_reg_custom_questions_form($REG_ID = 0)
2351 2351
     {
2352
-        if (! $REG_ID) {
2352
+        if ( ! $REG_ID) {
2353 2353
             EE_Error::add_error(
2354 2354
                 esc_html__(
2355 2355
                     'An error occurred. No registration ID was received.',
@@ -2366,7 +2366,7 @@  discard block
 block discarded – undo
2366 2366
         if ($form->is_valid()) {
2367 2367
             foreach ($form->subforms() as $question_group_form) {
2368 2368
                 foreach ($question_group_form->inputs() as $question_id => $input) {
2369
-                    $where_conditions    = [
2369
+                    $where_conditions = [
2370 2370
                         'QST_ID' => $question_id,
2371 2371
                         'REG_ID' => $REG_ID,
2372 2372
                     ];
@@ -2407,7 +2407,7 @@  discard block
 block discarded – undo
2407 2407
         $REG = $this->getRegistrationModel();
2408 2408
         // get all other registrations on this transaction, and cache
2409 2409
         // the attendees for them so we don't have to run another query using force_join
2410
-        $registrations                           = $REG->get_all(
2410
+        $registrations = $REG->get_all(
2411 2411
             [
2412 2412
                 [
2413 2413
                     'TXN_ID' => $this->_registration->transaction_ID(),
@@ -2441,23 +2441,23 @@  discard block
 block discarded – undo
2441 2441
                 $attendee                                                      = $registration->attendee()
2442 2442
                     ? $registration->attendee()
2443 2443
                     : $this->getAttendeeModel()->create_default_object();
2444
-                $this->_template_args['attendees'][ $att_nmbr ]['STS_ID']      = $registration->status_ID();
2445
-                $this->_template_args['attendees'][ $att_nmbr ]['fname']       = $attendee->fname();
2446
-                $this->_template_args['attendees'][ $att_nmbr ]['lname']       = $attendee->lname();
2447
-                $this->_template_args['attendees'][ $att_nmbr ]['email']       = $attendee->email();
2448
-                $this->_template_args['attendees'][ $att_nmbr ]['final_price'] = $registration->final_price();
2449
-                $this->_template_args['attendees'][ $att_nmbr ]['address']     = implode(
2444
+                $this->_template_args['attendees'][$att_nmbr]['STS_ID']      = $registration->status_ID();
2445
+                $this->_template_args['attendees'][$att_nmbr]['fname']       = $attendee->fname();
2446
+                $this->_template_args['attendees'][$att_nmbr]['lname']       = $attendee->lname();
2447
+                $this->_template_args['attendees'][$att_nmbr]['email']       = $attendee->email();
2448
+                $this->_template_args['attendees'][$att_nmbr]['final_price'] = $registration->final_price();
2449
+                $this->_template_args['attendees'][$att_nmbr]['address']     = implode(
2450 2450
                     ', ',
2451 2451
                     $attendee->full_address_as_array()
2452 2452
                 );
2453
-                $this->_template_args['attendees'][ $att_nmbr ]['att_link']    = self::add_query_args_and_nonce(
2453
+                $this->_template_args['attendees'][$att_nmbr]['att_link'] = self::add_query_args_and_nonce(
2454 2454
                     [
2455 2455
                         'action' => 'edit_attendee',
2456 2456
                         'post'   => $attendee->ID(),
2457 2457
                     ],
2458 2458
                     REG_ADMIN_URL
2459 2459
                 );
2460
-                $this->_template_args['attendees'][ $att_nmbr ]['event_name']  =
2460
+                $this->_template_args['attendees'][$att_nmbr]['event_name'] =
2461 2461
                     $registration->event_obj() instanceof EE_Event
2462 2462
                         ? $registration->event_obj()->name()
2463 2463
                         : '';
@@ -2465,7 +2465,7 @@  discard block
 block discarded – undo
2465 2465
             }
2466 2466
             $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
2467 2467
         }
2468
-        $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_attendees.template.php';
2468
+        $template_path = REG_TEMPLATE_PATH.'reg_admin_details_main_meta_box_attendees.template.php';
2469 2469
         EEH_Template::display_template($template_path, $this->_template_args);
2470 2470
     }
2471 2471
 
@@ -2491,11 +2491,11 @@  discard block
 block discarded – undo
2491 2491
         // now let's determine if this is not the primary registration.  If it isn't then we set the
2492 2492
         // primary_registration object for reference BUT ONLY if the Attendee object loaded is not the same as the
2493 2493
         // primary registration object (that way we know if we need to show create button or not)
2494
-        if (! $this->_registration->is_primary_registrant()) {
2494
+        if ( ! $this->_registration->is_primary_registrant()) {
2495 2495
             $primary_registration = $this->_registration->get_primary_registration();
2496 2496
             $primary_attendee     = $primary_registration instanceof EE_Registration ? $primary_registration->attendee()
2497 2497
                 : null;
2498
-            if (! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2498
+            if ( ! $primary_attendee instanceof EE_Attendee || $attendee->ID() !== $primary_attendee->ID()) {
2499 2499
                 // in here?  This means the displayed registration is not the primary registrant but ALREADY HAS its own
2500 2500
                 // custom attendee object so let's not worry about the primary reg.
2501 2501
                 $primary_registration = null;
@@ -2510,7 +2510,7 @@  discard block
 block discarded – undo
2510 2510
         $this->_template_args['phone']             = $attendee->phone();
2511 2511
         $this->_template_args['formatted_address'] = EEH_Address::format($attendee);
2512 2512
         // edit link
2513
-        $this->_template_args['att_edit_link']  = EE_Admin_Page::add_query_args_and_nonce(
2513
+        $this->_template_args['att_edit_link'] = EE_Admin_Page::add_query_args_and_nonce(
2514 2514
             [
2515 2515
                 'action' => 'edit_attendee',
2516 2516
                 'post'   => $attendee->ID(),
@@ -2520,7 +2520,7 @@  discard block
 block discarded – undo
2520 2520
         $this->_template_args['att_edit_title'] = esc_html__('View details for this contact.', 'event_espresso');
2521 2521
         $this->_template_args['att_edit_label'] = esc_html__('View/Edit Contact', 'event_espresso');
2522 2522
         // create link
2523
-        $this->_template_args['create_link']  = $primary_registration instanceof EE_Registration
2523
+        $this->_template_args['create_link'] = $primary_registration instanceof EE_Registration
2524 2524
             ? EE_Admin_Page::add_query_args_and_nonce(
2525 2525
                 [
2526 2526
                     'action'  => 'duplicate_attendee',
@@ -2531,7 +2531,7 @@  discard block
 block discarded – undo
2531 2531
         $this->_template_args['create_label'] = esc_html__('Create Contact', 'event_espresso');
2532 2532
         $this->_template_args['att_check']    = $att_check;
2533 2533
         $template_path                        =
2534
-            REG_TEMPLATE_PATH . 'reg_admin_details_side_meta_box_registrant.template.php';
2534
+            REG_TEMPLATE_PATH.'reg_admin_details_side_meta_box_registrant.template.php';
2535 2535
         EEH_Template::display_template($template_path, $this->_template_args);
2536 2536
     }
2537 2537
 
@@ -2579,7 +2579,7 @@  discard block
 block discarded – undo
2579 2579
             /** @var EE_Registration $REG */
2580 2580
             $REG      = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
2581 2581
             $payments = $REG->registration_payments();
2582
-            if (! empty($payments)) {
2582
+            if ( ! empty($payments)) {
2583 2583
                 $name           = $REG->attendee() instanceof EE_Attendee
2584 2584
                     ? $REG->attendee()->full_name()
2585 2585
                     : esc_html__('Unknown Attendee', 'event_espresso');
@@ -2643,17 +2643,17 @@  discard block
 block discarded – undo
2643 2643
         // Checkboxes
2644 2644
         $REG_IDs = $this->request->getRequestParam('_REG_ID', [], 'int', true);
2645 2645
 
2646
-        if (! empty($REG_IDs)) {
2646
+        if ( ! empty($REG_IDs)) {
2647 2647
             // if array has more than one element than success message should be plural
2648 2648
             $success = count($REG_IDs) > 1 ? 2 : 1;
2649 2649
             // cycle thru checkboxes
2650 2650
             foreach ($REG_IDs as $REG_ID) {
2651 2651
                 $REG = $REG_MDL->get_one_by_ID($REG_ID);
2652
-                if (! $REG instanceof EE_Registration) {
2652
+                if ( ! $REG instanceof EE_Registration) {
2653 2653
                     continue;
2654 2654
                 }
2655 2655
                 $deleted = $this->_delete_registration($REG);
2656
-                if (! $deleted) {
2656
+                if ( ! $deleted) {
2657 2657
                     $success = 0;
2658 2658
                 }
2659 2659
             }
@@ -2690,7 +2690,7 @@  discard block
 block discarded – undo
2690 2690
         // first we start with the transaction... ultimately, we WILL not delete permanently if there are any related
2691 2691
         // registrations on the transaction that are NOT trashed.
2692 2692
         $TXN = $REG->get_first_related('Transaction');
2693
-        if (! $TXN instanceof EE_Transaction) {
2693
+        if ( ! $TXN instanceof EE_Transaction) {
2694 2694
             EE_Error::add_error(
2695 2695
                 sprintf(
2696 2696
                     esc_html__(
@@ -2708,11 +2708,11 @@  discard block
 block discarded – undo
2708 2708
         $REGS        = $TXN->get_many_related('Registration');
2709 2709
         $all_trashed = true;
2710 2710
         foreach ($REGS as $registration) {
2711
-            if (! $registration->get('REG_deleted')) {
2711
+            if ( ! $registration->get('REG_deleted')) {
2712 2712
                 $all_trashed = false;
2713 2713
             }
2714 2714
         }
2715
-        if (! $all_trashed) {
2715
+        if ( ! $all_trashed) {
2716 2716
             EE_Error::add_error(
2717 2717
                 esc_html__(
2718 2718
                     '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.',
@@ -2774,7 +2774,7 @@  discard block
 block discarded – undo
2774 2774
      */
2775 2775
     public function new_registration()
2776 2776
     {
2777
-        if (! $this->_set_reg_event()) {
2777
+        if ( ! $this->_set_reg_event()) {
2778 2778
             throw new EE_Error(
2779 2779
                 esc_html__(
2780 2780
                     'Unable to continue with registering because there is no Event ID in the request',
@@ -2806,7 +2806,7 @@  discard block
 block discarded – undo
2806 2806
                 ],
2807 2807
                 EVENTS_ADMIN_URL
2808 2808
             );
2809
-            $edit_event_lnk                     = '<a href="'
2809
+            $edit_event_lnk = '<a href="'
2810 2810
                                                   . $edit_event_url
2811 2811
                                                   . '" aria-label="'
2812 2812
                                                   . esc_attr__('Edit ', 'event_espresso')
@@ -2824,7 +2824,7 @@  discard block
 block discarded – undo
2824 2824
         }
2825 2825
         // grab header
2826 2826
         $template_path                              =
2827
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee.template.php';
2827
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee.template.php';
2828 2828
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
2829 2829
             $template_path,
2830 2830
             $this->_template_args,
@@ -2865,7 +2865,7 @@  discard block
 block discarded – undo
2865 2865
                 '</b>'
2866 2866
             );
2867 2867
             return '
2868
-	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg . '</p></div>
2868
+	<div id="ee-add-reg-back-button-dv"><p>' . $warning_msg.'</p></div>
2869 2869
 	<script >
2870 2870
 		// WHOAH !!! it appears that someone is using the back button from the Transaction admin page
2871 2871
 		// after just adding a new registration... we gotta try to put a stop to that !!!
@@ -2907,7 +2907,7 @@  discard block
 block discarded – undo
2907 2907
                 );
2908 2908
                 $template_args['content']                          =
2909 2909
                     EED_Ticket_Selector::instance()->display_ticket_selector($this->_reg_event);
2910
-                $template_args['content']                          .= '</div>';
2910
+                $template_args['content'] .= '</div>';
2911 2911
                 $template_args['step_button_text']                 = esc_html__(
2912 2912
                     'Add Tickets and Continue to Registrant Details',
2913 2913
                     'event_espresso'
@@ -2934,7 +2934,7 @@  discard block
 block discarded – undo
2934 2934
         // we come back to the process_registration_step route.
2935 2935
         $this->_set_add_edit_form_tags('process_reg_step', $hidden_fields);
2936 2936
         return EEH_Template::display_template(
2937
-            REG_TEMPLATE_PATH . 'reg_admin_register_new_attendee_step_content.template.php',
2937
+            REG_TEMPLATE_PATH.'reg_admin_register_new_attendee_step_content.template.php',
2938 2938
             $template_args,
2939 2939
             true
2940 2940
         );
@@ -2957,7 +2957,7 @@  discard block
 block discarded – undo
2957 2957
         }
2958 2958
 
2959 2959
         $EVT_ID = $this->request->getRequestParam('event_id', 0, 'int');
2960
-        if (! $EVT_ID) {
2960
+        if ( ! $EVT_ID) {
2961 2961
             return false;
2962 2962
         }
2963 2963
         $this->_reg_event = $this->getEventModel()->get_one_by_ID($EVT_ID);
@@ -3027,7 +3027,7 @@  discard block
 block discarded – undo
3027 3027
                 }
3028 3028
                 break;
3029 3029
             case 'questions':
3030
-                if (! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3030
+                if ( ! $this->request->requestParamIsSet('txn_reg_status_change[send_notifications]')) {
3031 3031
                     add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_false', 15);
3032 3032
                 }
3033 3033
                 // process registration
@@ -3038,7 +3038,7 @@  discard block
 block discarded – undo
3038 3038
                         $grand_total->save_this_and_descendants_to_txn();
3039 3039
                     }
3040 3040
                 }
3041
-                if (! $transaction instanceof EE_Transaction) {
3041
+                if ( ! $transaction instanceof EE_Transaction) {
3042 3042
                     $query_args = [
3043 3043
                         'action'                  => 'new_registration',
3044 3044
                         'processing_registration' => 2,
@@ -3060,7 +3060,7 @@  discard block
 block discarded – undo
3060 3060
                     return;
3061 3061
                 }
3062 3062
                 // maybe update status, and make sure to save transaction if not done already
3063
-                if (! $transaction->update_status_based_on_total_paid()) {
3063
+                if ( ! $transaction->update_status_based_on_total_paid()) {
3064 3064
                     $transaction->save();
3065 3065
                 }
3066 3066
                 EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
@@ -3142,7 +3142,7 @@  discard block
 block discarded – undo
3142 3142
     public function get_attendees($per_page, $count = false, $trash = false)
3143 3143
     {
3144 3144
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3145
-        require_once(REG_ADMIN . 'EE_Attendee_Contact_List_Table.class.php');
3145
+        require_once(REG_ADMIN.'EE_Attendee_Contact_List_Table.class.php');
3146 3146
         $orderby = $this->request->getRequestParam('orderby');
3147 3147
         switch ($orderby) {
3148 3148
             case 'ATT_ID':
@@ -3165,7 +3165,7 @@  discard block
 block discarded – undo
3165 3165
         $_where       = [];
3166 3166
         $search_term  = $this->request->getRequestParam('s');
3167 3167
         if ($search_term) {
3168
-            $search_term  = '%' . $search_term . '%';
3168
+            $search_term  = '%'.$search_term.'%';
3169 3169
             $_where['OR'] = [
3170 3170
                 'Registration.Event.EVT_name'       => ['LIKE', $search_term],
3171 3171
                 'Registration.Event.EVT_desc'       => ['LIKE', $search_term],
@@ -3192,7 +3192,7 @@  discard block
 block discarded – undo
3192 3192
             'extra_selects' => ['Registration_Count' => ['Registration.REG_ID', 'count', '%d']],
3193 3193
             'limit'         => $limit,
3194 3194
         ];
3195
-        if (! $count) {
3195
+        if ( ! $count) {
3196 3196
             $query_args['order_by'] = [$orderby => $sort];
3197 3197
         }
3198 3198
         $query_args[0]['status'] = $trash ? ['!=', 'publish'] : ['IN', ['publish']];
@@ -3237,7 +3237,7 @@  discard block
 block discarded – undo
3237 3237
         $EVT_ID = $this->request->requestParamIsSet('EVT_ID')
3238 3238
             ? $this->request->getRequestParam('EVT_ID', 0, DataType::INT)
3239 3239
             : null;
3240
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3240
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3241 3241
             $return_url    = $this->request->getRequestParam('return_url', '', DataType::URL);
3242 3242
             $filters       = $this->request->getRequestParam('filters', [], DataType::STRING, true);
3243 3243
             $report_params = $this->$method_name_for_getting_query_params($filters);
@@ -3266,8 +3266,8 @@  discard block
 block discarded – undo
3266 3266
             ];
3267 3267
             // Merge required request args, overriding any currently set
3268 3268
             $request_args = array_merge($request_args, $required_request_args);
3269
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3270
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3269
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3270
+                require_once(EE_CLASSES.'EE_Export.class.php');
3271 3271
                 $EE_Export = EE_Export::instance($request_args);
3272 3272
                 $EE_Export->export();
3273 3273
             }
@@ -3288,8 +3288,8 @@  discard block
 block discarded – undo
3288 3288
 
3289 3289
     public function _contact_list_export()
3290 3290
     {
3291
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3292
-            require_once(EE_CLASSES . 'EE_Export.class.php');
3291
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3292
+            require_once(EE_CLASSES.'EE_Export.class.php');
3293 3293
             $EE_Export = EE_Export::instance($this->request->requestParams());
3294 3294
             $EE_Export->export_attendees();
3295 3295
         }
@@ -3298,7 +3298,7 @@  discard block
 block discarded – undo
3298 3298
 
3299 3299
     public function _contact_list_report()
3300 3300
     {
3301
-        if (! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3301
+        if ( ! defined('EE_USE_OLD_CSV_REPORT_CLASS')) {
3302 3302
             wp_redirect(
3303 3303
                 EE_Admin_Page::add_query_args_and_nonce(
3304 3304
                     [
@@ -3310,8 +3310,8 @@  discard block
 block discarded – undo
3310 3310
                 )
3311 3311
             );
3312 3312
         } else {
3313
-            if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
3314
-                require_once(EE_CLASSES . 'EE_Export.class.php');
3313
+            if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
3314
+                require_once(EE_CLASSES.'EE_Export.class.php');
3315 3315
                 $EE_Export = EE_Export::instance($this->request->requestParams());
3316 3316
                 $EE_Export->report_attendees();
3317 3317
             }
@@ -3338,7 +3338,7 @@  discard block
 block discarded – undo
3338 3338
         $REG_ID = $this->request->getRequestParam('_REG_ID', 0, 'int');
3339 3339
         $action = $this->request->getRequestParam('return', 'default');
3340 3340
         // verify we have necessary info
3341
-        if (! $REG_ID) {
3341
+        if ( ! $REG_ID) {
3342 3342
             EE_Error::add_error(
3343 3343
                 esc_html__(
3344 3344
                     'Unable to create the contact for the registration because the required parameters are not present (_REG_ID )',
@@ -3353,7 +3353,7 @@  discard block
 block discarded – undo
3353 3353
         }
3354 3354
         // okay necessary deets present... let's dupe the incoming attendee and attach to incoming registration.
3355 3355
         $registration = $this->getRegistrationModel()->get_one_by_ID($REG_ID);
3356
-        if (! $registration instanceof EE_Registration) {
3356
+        if ( ! $registration instanceof EE_Registration) {
3357 3357
             throw new RuntimeException(
3358 3358
                 sprintf(
3359 3359
                     esc_html__(
@@ -3492,16 +3492,16 @@  discard block
 block discarded – undo
3492 3492
         $this->verify_cpt_object();
3493 3493
         remove_meta_box(
3494 3494
             'postexcerpt',
3495
-            $this->_cpt_routes[ $this->_req_action ],
3495
+            $this->_cpt_routes[$this->_req_action],
3496 3496
             'normal'
3497 3497
         );
3498
-        remove_meta_box('commentstatusdiv', $this->_cpt_routes[ $this->_req_action ], 'normal');
3498
+        remove_meta_box('commentstatusdiv', $this->_cpt_routes[$this->_req_action], 'normal');
3499 3499
         if (post_type_supports('espresso_attendees', 'excerpt')) {
3500 3500
             $this->addMetaBox(
3501 3501
                 'postexcerpt',
3502 3502
                 esc_html__('Short Biography', 'event_espresso'),
3503 3503
                 'post_excerpt_meta_box',
3504
-                $this->_cpt_routes[ $this->_req_action ]
3504
+                $this->_cpt_routes[$this->_req_action]
3505 3505
             );
3506 3506
         }
3507 3507
         if (post_type_supports('espresso_attendees', 'comments')) {
@@ -3509,7 +3509,7 @@  discard block
 block discarded – undo
3509 3509
                 'commentsdiv',
3510 3510
                 esc_html__('Notes on the Contact', 'event_espresso'),
3511 3511
                 'post_comment_meta_box',
3512
-                $this->_cpt_routes[ $this->_req_action ],
3512
+                $this->_cpt_routes[$this->_req_action],
3513 3513
                 'normal',
3514 3514
                 'core'
3515 3515
             );
@@ -3518,7 +3518,7 @@  discard block
 block discarded – undo
3518 3518
             'attendee_contact_info',
3519 3519
             esc_html__('Contact Info', 'event_espresso'),
3520 3520
             [$this, 'attendee_contact_info'],
3521
-            $this->_cpt_routes[ $this->_req_action ],
3521
+            $this->_cpt_routes[$this->_req_action],
3522 3522
             'side',
3523 3523
             'core'
3524 3524
         );
@@ -3526,7 +3526,7 @@  discard block
 block discarded – undo
3526 3526
             'attendee_details_address',
3527 3527
             esc_html__('Address Details', 'event_espresso'),
3528 3528
             [$this, 'attendee_address_details'],
3529
-            $this->_cpt_routes[ $this->_req_action ],
3529
+            $this->_cpt_routes[$this->_req_action],
3530 3530
             'normal',
3531 3531
             'core'
3532 3532
         );
@@ -3534,7 +3534,7 @@  discard block
 block discarded – undo
3534 3534
             'attendee_registrations',
3535 3535
             esc_html__('Registrations for this Contact', 'event_espresso'),
3536 3536
             [$this, 'attendee_registrations_meta_box'],
3537
-            $this->_cpt_routes[ $this->_req_action ]
3537
+            $this->_cpt_routes[$this->_req_action]
3538 3538
         );
3539 3539
     }
3540 3540
 
@@ -3633,8 +3633,8 @@  discard block
 block discarded – undo
3633 3633
                 ]
3634 3634
             )
3635 3635
         );
3636
-        $template                             =
3637
-            REG_TEMPLATE_PATH . 'attendee_address_details_metabox_content.template.php';
3636
+        $template =
3637
+            REG_TEMPLATE_PATH.'attendee_address_details_metabox_content.template.php';
3638 3638
         EEH_Template::display_template($template, $this->_template_args);
3639 3639
     }
3640 3640
 
@@ -3656,7 +3656,7 @@  discard block
 block discarded – undo
3656 3656
         $this->_template_args['attendee']      = $this->_cpt_model_obj;
3657 3657
         $this->_template_args['registrations'] = $this->_cpt_model_obj->get_many_related('Registration');
3658 3658
         $template                              =
3659
-            REG_TEMPLATE_PATH . 'attendee_registrations_main_meta_box.template.php';
3659
+            REG_TEMPLATE_PATH.'attendee_registrations_main_meta_box.template.php';
3660 3660
         EEH_Template::display_template($template, $this->_template_args);
3661 3661
     }
3662 3662
 
@@ -3671,7 +3671,7 @@  discard block
 block discarded – undo
3671 3671
     public function after_title_form_fields($post)
3672 3672
     {
3673 3673
         if ($post->post_type === 'espresso_attendees') {
3674
-            $template                  = REG_TEMPLATE_PATH . 'attendee_details_after_title_form_fields.template.php';
3674
+            $template                  = REG_TEMPLATE_PATH.'attendee_details_after_title_form_fields.template.php';
3675 3675
             $template_args['attendee'] = $this->_cpt_model_obj;
3676 3676
             EEH_Template::display_template($template, $template_args);
3677 3677
         }
@@ -3700,7 +3700,7 @@  discard block
 block discarded – undo
3700 3700
             // cycle thru checkboxes
3701 3701
             foreach ($ATT_IDs as $ATT_ID) {
3702 3702
                 $updated = $this->getAttendeeModel()->update_by_ID(['status' => $status], $ATT_ID);
3703
-                if (! $updated) {
3703
+                if ( ! $updated) {
3704 3704
                     $success = 0;
3705 3705
                 }
3706 3706
             }
Please login to merge, or discard this patch.
admin_pages/payments/Payments_Admin_Page.core.php 2 patches
Indentation   +1294 added lines, -1294 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'       => '_payment_methods_list',
92
-                'capability' => 'ee_edit_payment_methods',
93
-            ],
94
-            'payment_settings'          => [
95
-                'func'       => '_payment_settings',
96
-                'capability' => 'ee_manage_gateways',
97
-            ],
98
-            'activate_payment_method'   => [
99
-                'func'       => '_activate_payment_method',
100
-                'noheader'   => true,
101
-                'capability' => 'ee_edit_payment_methods',
102
-            ],
103
-            'deactivate_payment_method' => [
104
-                'func'       => '_deactivate_payment_method',
105
-                'noheader'   => true,
106
-                'capability' => 'ee_delete_payment_methods',
107
-            ],
108
-            'update_payment_method'     => [
109
-                'func'               => '_update_payment_method',
110
-                'noheader'           => true,
111
-                'headers_sent_route' => 'default',
112
-                'capability'         => 'ee_edit_payment_methods',
113
-            ],
114
-            'update_payment_settings'   => [
115
-                'func'       => '_update_payment_settings',
116
-                'noheader'   => true,
117
-                'capability' => 'ee_manage_gateways',
118
-            ],
119
-            'payment_log'               => [
120
-                'func'       => '_payment_log_overview_list_table',
121
-                'capability' => 'ee_read_payment_methods',
122
-            ],
123
-            'payment_log_details'       => [
124
-                'func'       => '_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'       => '_payment_methods_list',
92
+				'capability' => 'ee_edit_payment_methods',
93
+			],
94
+			'payment_settings'          => [
95
+				'func'       => '_payment_settings',
96
+				'capability' => 'ee_manage_gateways',
97
+			],
98
+			'activate_payment_method'   => [
99
+				'func'       => '_activate_payment_method',
100
+				'noheader'   => true,
101
+				'capability' => 'ee_edit_payment_methods',
102
+			],
103
+			'deactivate_payment_method' => [
104
+				'func'       => '_deactivate_payment_method',
105
+				'noheader'   => true,
106
+				'capability' => 'ee_delete_payment_methods',
107
+			],
108
+			'update_payment_method'     => [
109
+				'func'               => '_update_payment_method',
110
+				'noheader'           => true,
111
+				'headers_sent_route' => 'default',
112
+				'capability'         => 'ee_edit_payment_methods',
113
+			],
114
+			'update_payment_settings'   => [
115
+				'func'       => '_update_payment_settings',
116
+				'noheader'   => true,
117
+				'capability' => 'ee_manage_gateways',
118
+			],
119
+			'payment_log'               => [
120
+				'func'       => '_payment_log_overview_list_table',
121
+				'capability' => 'ee_read_payment_methods',
122
+			],
123
+			'payment_log_details'       => [
124
+				'func'       => '_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,1022 +313,1022 @@  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
-        /** @var EE_Payment_Method $payment_method */
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('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::td(
876
-                    EEH_HTML::p(
877
-                        esc_html__('All fields marked with a * are required fields', 'event_espresso'),
878
-                        '',
879
-                        'grey-text'
880
-                    )
881
-                )
882
-            )
883
-        );
884
-    }
885
-
886
-
887
-    /**
888
-     * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
889
-     *
890
-     * @throws EE_Error
891
-     * @throws ReflectionException
892
-     * @global WP_User $current_user
893
-     */
894
-    protected function _activate_payment_method()
895
-    {
896
-        if (isset($this->_req_data['payment_method_type'])) {
897
-            $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
898
-            // see if one exists
899
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
900
-            $payment_method = EE_Payment_Method_Manager::instance()
901
-                                                       ->activate_a_payment_method_of_type($payment_method_type);
902
-            $this->_redirect_after_action(
903
-                1,
904
-                'Payment Method',
905
-                'activated',
906
-                ['action' => 'default', 'payment_method' => $payment_method->slug()]
907
-            );
908
-        } else {
909
-            $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
910
-        }
911
-    }
912
-
913
-
914
-    /**
915
-     * @throws EE_Error
916
-     * @throws ReflectionException
917
-     */
918
-    protected function _deactivate_payment_method()
919
-    {
920
-        if (isset($this->_req_data['payment_method'])) {
921
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
922
-            // deactivate it
923
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
924
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
925
-            $this->_redirect_after_action(
926
-                $count_updated,
927
-                'Payment Method',
928
-                'deactivated',
929
-                ['action' => 'default', 'payment_method' => $payment_method_slug]
930
-            );
931
-        } else {
932
-            $this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
933
-        }
934
-    }
935
-
936
-
937
-    /**
938
-     * Processes the payment method form that was submitted. This is slightly trickier than usual form
939
-     * processing because we first need to identify WHICH form was processed and which payment method
940
-     * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
941
-     * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
942
-     * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
943
-     * subsequently called 'headers_sent_func' which is _payment_methods_list)
944
-     *
945
-     * @return void
946
-     * @throws EE_Error
947
-     * @throws ReflectionException
948
-     */
949
-    protected function _update_payment_method()
950
-    {
951
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
952
-            // ok let's find which gateway form to use based on the form input
953
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
954
-            /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
955
-            $correct_pmt_form_to_use = null;
956
-            $payment_method          = null;
957
-            foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
958
-                if ($payment_method instanceof EE_Payment_Method) {
959
-                    // get the form and simplify it, like what we do when we display it
960
-                    $pmt_form = $this->_generate_payment_method_settings_form($payment_method);
961
-                    if ($pmt_form->form_data_present_in($this->_req_data)) {
962
-                        $correct_pmt_form_to_use = $pmt_form;
963
-                        break;
964
-                    }
965
-                }
966
-            }
967
-            // if we couldn't find the correct payment method type...
968
-            if (! $correct_pmt_form_to_use) {
969
-                EE_Error::add_error(
970
-                    esc_html__(
971
-                        "We could not find which payment method type your form submission related to. Please contact support",
972
-                        'event_espresso'
973
-                    ),
974
-                    __FILE__,
975
-                    __FUNCTION__,
976
-                    __LINE__
977
-                );
978
-                $this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
979
-            }
980
-            $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
981
-            if ($correct_pmt_form_to_use->is_valid()) {
982
-                $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
983
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
984
-                    throw new EE_Error(
985
-                        sprintf(
986
-                            esc_html__(
987
-                                'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
988
-                                'event_espresso'
989
-                            ),
990
-                            'payment_method_settings'
991
-                        )
992
-                    );
993
-                }
994
-                $payment_settings_subform->save();
995
-                /** @var $pm EE_Payment_Method */
996
-                $this->_redirect_after_action(
997
-                    true,
998
-                    'Payment Method',
999
-                    'updated',
1000
-                    ['action' => 'default', 'payment_method' => $payment_method->slug()]
1001
-                );
1002
-            } else {
1003
-                EE_Error::add_error(
1004
-                    sprintf(
1005
-                        esc_html__(
1006
-                            'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1007
-                            'event_espresso'
1008
-                        ),
1009
-                        $payment_method instanceof EE_Payment_Method
1010
-                            ? $payment_method->type_obj()->pretty_name()
1011
-                            : esc_html__('"(unknown)"', 'event_espresso')
1012
-                    ),
1013
-                    __FILE__,
1014
-                    __FUNCTION__,
1015
-                    __LINE__
1016
-                );
1017
-            }
1018
-        }
1019
-    }
1020
-
1021
-
1022
-    /**
1023
-     * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1024
-     *
1025
-     * @throws DomainException
1026
-     * @throws EE_Error
1027
-     * @throws InvalidArgumentException
1028
-     * @throws InvalidDataTypeException
1029
-     * @throws InvalidInterfaceException
1030
-     */
1031
-    protected function _payment_settings()
1032
-    {
1033
-        $form = $this->getPaymentSettingsForm();
1034
-        $this->_set_add_edit_form_tags('update_payment_settings');
1035
-        $this->_set_publish_post_box_vars();
1036
-        $this->_template_args['admin_page_content'] = EEH_HTML::div(
1037
-            $form->get_html_and_js(),
1038
-            '',
1039
-            'padding'
1040
-        );
1041
-        $this->display_admin_page_with_sidebar();
1042
-    }
1043
-
1044
-
1045
-    /**
1046
-     *        _update_payment_settings
1047
-     *
1048
-     * @access protected
1049
-     * @return void
1050
-     * @throws EE_Error
1051
-     * @throws InvalidArgumentException
1052
-     * @throws InvalidDataTypeException
1053
-     * @throws InvalidInterfaceException
1054
-     */
1055
-    protected function _update_payment_settings()
1056
-    {
1057
-        $form = $this->getPaymentSettingsForm();
1058
-        if ($form->was_submitted($this->_req_data)) {
1059
-            $form->receive_form_submission($this->_req_data);
1060
-            if ($form->is_valid()) {
1061
-                /**
1062
-                 * @var $reg_config EE_Registration_Config
1063
-                 */
1064
-                $loader                                   = LoaderFactory::getLoader();
1065
-                $reg_config                               = $loader->getShared('EE_Registration_Config');
1066
-                $valid_data                               = $form->valid_data();
1067
-                $show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1068
-                $reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1069
-                $reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1070
-            }
1071
-        }
1072
-        EE_Registry::instance()->CFG = apply_filters(
1073
-            'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1074
-            EE_Registry::instance()->CFG
1075
-        );
1076
-
1077
-        $what    = esc_html__('Payment Settings', 'event_espresso');
1078
-        $success = $this->_update_espresso_configuration(
1079
-            $what,
1080
-            EE_Registry::instance()->CFG,
1081
-            __FILE__,
1082
-            __FUNCTION__,
1083
-            __LINE__
1084
-        );
1085
-        $this->_redirect_after_action(
1086
-            $success,
1087
-            $what,
1088
-            esc_html__('updated', 'event_espresso'),
1089
-            ['action' => 'payment_settings']
1090
-        );
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     * Gets the form used for updating payment settings
1096
-     *
1097
-     * @return EE_Form_Section_Proper
1098
-     * @throws EE_Error
1099
-     * @throws InvalidArgumentException
1100
-     * @throws InvalidDataTypeException
1101
-     * @throws InvalidInterfaceException
1102
-     */
1103
-    protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1104
-    {
1105
-        /**
1106
-         * @var $reg_config EE_Registration_Config
1107
-         */
1108
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1109
-        return new EE_Form_Section_Proper(
1110
-            [
1111
-                'name'            => 'payment-settings',
1112
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1113
-                'subsections'     => [
1114
-                    'show_pending_payment_options' => new EE_Switch_Input(
1115
-                        [
1116
-                            'default'        => $reg_config->show_pending_payment_options
1117
-                                ? EE_Switch_Input::OPTION_ON
1118
-                                : EE_Switch_Input::OPTION_OFF,
1119
-                            'html_name'      => 'show_pending_payment_options',
1120
-                            'html_help_text' => esc_html__(
1121
-                                "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. ",
1122
-                                'event_espresso'
1123
-                            ),
1124
-                        ],
1125
-                        [
1126
-                            EE_Switch_Input::OPTION_OFF => esc_html__(
1127
-                                'pending payment options are NOT displayed',
1128
-                                'event_espresso'
1129
-                            ),
1130
-                            EE_Switch_Input::OPTION_ON  => esc_html__(
1131
-                                'pending payment options are displayed',
1132
-                                'event_espresso'
1133
-                            ),
1134
-                        ]
1135
-                    ),
1136
-                    'gateway_log_lifespan'         => new EE_Select_Input(
1137
-                        $reg_config->gatewayLogLifespanOptions(),
1138
-                        [
1139
-                            'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1140
-                            'html_help_text'  => esc_html__(
1141
-                                '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.',
1142
-                                'event_espresso'
1143
-                            ),
1144
-                            'default'         => $reg_config->gateway_log_lifespan,
1145
-                        ]
1146
-                    ),
1147
-                ],
1148
-            ]
1149
-        );
1150
-    }
1151
-
1152
-
1153
-    /**
1154
-     * @throws EE_Error
1155
-     */
1156
-    protected function _payment_log_overview_list_table()
1157
-    {
1158
-        $this->display_admin_list_table_page_with_sidebar();
1159
-    }
1160
-
1161
-
1162
-    protected function _set_list_table_views_payment_log()
1163
-    {
1164
-        $this->_views = [
1165
-            'all' => [
1166
-                'slug'  => 'all',
1167
-                'label' => esc_html__('View All Logs', 'event_espresso'),
1168
-                'count' => 0,
1169
-            ],
1170
-        ];
1171
-    }
1172
-
1173
-
1174
-    /**
1175
-     * @param int  $per_page
1176
-     * @param int  $current_page
1177
-     * @param bool $count
1178
-     * @return array|int
1179
-     * @throws EE_Error
1180
-     * @throws ReflectionException
1181
-     */
1182
-    public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1183
-    {
1184
-        EE_Registry::instance()->load_model('Change_Log');
1185
-        // we may need to do multiple queries (joining differently), so we actually want an array of query params
1186
-        $query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1187
-        // check if they've selected a specific payment method
1188
-        if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1189
-            $query_params[0]['OR*pm_or_pay_pm'] = [
1190
-                'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1191
-                'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1192
-            ];
1193
-        }
1194
-        // take into account search
1195
-        if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1196
-            $similarity_string                                                              =
1197
-                ['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1198
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1199
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1200
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1201
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1202
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1203
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1204
-            $query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1205
-            $query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1206
-            $query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1207
-            $query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1208
-        }
1209
-        if (
1210
-            isset($this->_req_data['payment-filter-start-date'])
1211
-            && isset($this->_req_data['payment-filter-end-date'])
1212
-        ) {
1213
-            // add date
1214
-            $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1215
-            $end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1216
-            // make sure our timestamps start and end right at the boundaries for each day
1217
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1218
-            $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1219
-            // convert to timestamps
1220
-            $start_date = strtotime($start_date);
1221
-            $end_date   = strtotime($end_date);
1222
-            // makes sure start date is the lowest value and vice versa
1223
-            $start_date = min($start_date, $end_date);
1224
-            $end_date   = max($start_date, $end_date);
1225
-            // convert for query
1226
-            $start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1227
-                'LOG_time',
1228
-                date('Y-m-d H:i:s', $start_date),
1229
-                'Y-m-d H:i:s'
1230
-            );
1231
-            $end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1232
-                'LOG_time',
1233
-                date('Y-m-d H:i:s', $end_date),
1234
-                'Y-m-d H:i:s'
1235
-            );
1236
-            $query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1237
-        }
1238
-        if ($count) {
1239
-            return EEM_Change_Log::instance()->count($query_params);
1240
-        }
1241
-        if (isset($this->_req_data['order'])) {
1242
-            $sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1243
-                ? $this->_req_data['order']
1244
-                : 'DESC';
1245
-            $query_params['order_by'] = ['LOG_time' => $sort];
1246
-        } else {
1247
-            $query_params['order_by'] = ['LOG_time' => 'DESC'];
1248
-        }
1249
-        $offset = ($current_page - 1) * $per_page;
1250
-        if (! isset($this->_req_data['download_results'])) {
1251
-            $query_params['limit'] = [$offset, $per_page];
1252
-        }
1253
-        // now they've requested to instead just download the file instead of viewing it.
1254
-        if (isset($this->_req_data['download_results'])) {
1255
-            $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1256
-            header('Content-Disposition: attachment');
1257
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1258
-            echo '<h1> '
1259
-                 . sprintf(
1260
-                     esc_html__('Payment Logs for %1$s', 'event_espresso'),
1261
-                     esc_url_raw(site_url())
1262
-                 )
1263
-                 . '</h1 >';
1264
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1265
-            echo esc_html(var_export($query_params, true));
1266
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1267
-            echo esc_html(var_export($wpdb_results, true));
1268
-            die;
1269
-        }
1270
-        return EEM_Change_Log::instance()->get_all($query_params);
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * Used by usort to RE-sort log query results, because we lose the ordering
1276
-     * because we're possibly combining the results from two queries
1277
-     *
1278
-     * @param EE_Change_Log $logA
1279
-     * @param EE_Change_Log $logB
1280
-     * @return int
1281
-     * @throws EE_Error
1282
-     * @throws ReflectionException
1283
-     */
1284
-    protected function _sort_logs_again($logA, $logB)
1285
-    {
1286
-        $timeA = $logA->get_raw('LOG_time');
1287
-        $timeB = $logB->get_raw('LOG_time');
1288
-        if ($timeA == $timeB) {
1289
-            return 0;
1290
-        }
1291
-        $comparison = $timeA < $timeB
1292
-            ? -1
1293
-            : 1;
1294
-        if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1295
-            return $comparison * -1;
1296
-        }
1297
-        return $comparison;
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     * @throws EE_Error
1303
-     * @throws ReflectionException
1304
-     */
1305
-    protected function _payment_log_details()
1306
-    {
1307
-        EE_Registry::instance()->load_model('Change_Log');
1308
-        /** @var $payment_log EE_Change_Log */
1309
-        $payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1310
-        $payment_method = null;
1311
-        $transaction    = null;
1312
-        if ($payment_log instanceof EE_Change_Log) {
1313
-            if ($payment_log->object() instanceof EE_Payment) {
1314
-                $payment_method = $payment_log->object()->payment_method();
1315
-                $transaction    = $payment_log->object()->transaction();
1316
-            } elseif ($payment_log->object() instanceof EE_Payment_Method) {
1317
-                $payment_method = $payment_log->object();
1318
-            } elseif ($payment_log->object() instanceof EE_Transaction) {
1319
-                $transaction    = $payment_log->object();
1320
-                $payment_method = $transaction->payment_method();
1321
-            }
1322
-        }
1323
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1324
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1325
-            [
1326
-                'payment_log'    => $payment_log,
1327
-                'payment_method' => $payment_method,
1328
-                'transaction'    => $transaction,
1329
-            ],
1330
-            true
1331
-        );
1332
-        $this->display_admin_page_with_no_sidebar();
1333
-    }
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
+		/** @var EE_Payment_Method $payment_method */
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('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::td(
876
+					EEH_HTML::p(
877
+						esc_html__('All fields marked with a * are required fields', 'event_espresso'),
878
+						'',
879
+						'grey-text'
880
+					)
881
+				)
882
+			)
883
+		);
884
+	}
885
+
886
+
887
+	/**
888
+	 * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
889
+	 *
890
+	 * @throws EE_Error
891
+	 * @throws ReflectionException
892
+	 * @global WP_User $current_user
893
+	 */
894
+	protected function _activate_payment_method()
895
+	{
896
+		if (isset($this->_req_data['payment_method_type'])) {
897
+			$payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
898
+			// see if one exists
899
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
900
+			$payment_method = EE_Payment_Method_Manager::instance()
901
+													   ->activate_a_payment_method_of_type($payment_method_type);
902
+			$this->_redirect_after_action(
903
+				1,
904
+				'Payment Method',
905
+				'activated',
906
+				['action' => 'default', 'payment_method' => $payment_method->slug()]
907
+			);
908
+		} else {
909
+			$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
910
+		}
911
+	}
912
+
913
+
914
+	/**
915
+	 * @throws EE_Error
916
+	 * @throws ReflectionException
917
+	 */
918
+	protected function _deactivate_payment_method()
919
+	{
920
+		if (isset($this->_req_data['payment_method'])) {
921
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
922
+			// deactivate it
923
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
924
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
925
+			$this->_redirect_after_action(
926
+				$count_updated,
927
+				'Payment Method',
928
+				'deactivated',
929
+				['action' => 'default', 'payment_method' => $payment_method_slug]
930
+			);
931
+		} else {
932
+			$this->_redirect_after_action(false, 'Payment Method', 'deactivated', ['action' => 'default']);
933
+		}
934
+	}
935
+
936
+
937
+	/**
938
+	 * Processes the payment method form that was submitted. This is slightly trickier than usual form
939
+	 * processing because we first need to identify WHICH form was processed and which payment method
940
+	 * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
941
+	 * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
942
+	 * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
943
+	 * subsequently called 'headers_sent_func' which is _payment_methods_list)
944
+	 *
945
+	 * @return void
946
+	 * @throws EE_Error
947
+	 * @throws ReflectionException
948
+	 */
949
+	protected function _update_payment_method()
950
+	{
951
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
952
+			// ok let's find which gateway form to use based on the form input
953
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
954
+			/** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
955
+			$correct_pmt_form_to_use = null;
956
+			$payment_method          = null;
957
+			foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
958
+				if ($payment_method instanceof EE_Payment_Method) {
959
+					// get the form and simplify it, like what we do when we display it
960
+					$pmt_form = $this->_generate_payment_method_settings_form($payment_method);
961
+					if ($pmt_form->form_data_present_in($this->_req_data)) {
962
+						$correct_pmt_form_to_use = $pmt_form;
963
+						break;
964
+					}
965
+				}
966
+			}
967
+			// if we couldn't find the correct payment method type...
968
+			if (! $correct_pmt_form_to_use) {
969
+				EE_Error::add_error(
970
+					esc_html__(
971
+						"We could not find which payment method type your form submission related to. Please contact support",
972
+						'event_espresso'
973
+					),
974
+					__FILE__,
975
+					__FUNCTION__,
976
+					__LINE__
977
+				);
978
+				$this->_redirect_after_action(false, 'Payment Method', 'activated', ['action' => 'default']);
979
+			}
980
+			$correct_pmt_form_to_use->receive_form_submission($this->_req_data);
981
+			if ($correct_pmt_form_to_use->is_valid()) {
982
+				$payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
983
+				if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
984
+					throw new EE_Error(
985
+						sprintf(
986
+							esc_html__(
987
+								'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
988
+								'event_espresso'
989
+							),
990
+							'payment_method_settings'
991
+						)
992
+					);
993
+				}
994
+				$payment_settings_subform->save();
995
+				/** @var $pm EE_Payment_Method */
996
+				$this->_redirect_after_action(
997
+					true,
998
+					'Payment Method',
999
+					'updated',
1000
+					['action' => 'default', 'payment_method' => $payment_method->slug()]
1001
+				);
1002
+			} else {
1003
+				EE_Error::add_error(
1004
+					sprintf(
1005
+						esc_html__(
1006
+							'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
1007
+							'event_espresso'
1008
+						),
1009
+						$payment_method instanceof EE_Payment_Method
1010
+							? $payment_method->type_obj()->pretty_name()
1011
+							: esc_html__('"(unknown)"', 'event_espresso')
1012
+					),
1013
+					__FILE__,
1014
+					__FUNCTION__,
1015
+					__LINE__
1016
+				);
1017
+			}
1018
+		}
1019
+	}
1020
+
1021
+
1022
+	/**
1023
+	 * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
1024
+	 *
1025
+	 * @throws DomainException
1026
+	 * @throws EE_Error
1027
+	 * @throws InvalidArgumentException
1028
+	 * @throws InvalidDataTypeException
1029
+	 * @throws InvalidInterfaceException
1030
+	 */
1031
+	protected function _payment_settings()
1032
+	{
1033
+		$form = $this->getPaymentSettingsForm();
1034
+		$this->_set_add_edit_form_tags('update_payment_settings');
1035
+		$this->_set_publish_post_box_vars();
1036
+		$this->_template_args['admin_page_content'] = EEH_HTML::div(
1037
+			$form->get_html_and_js(),
1038
+			'',
1039
+			'padding'
1040
+		);
1041
+		$this->display_admin_page_with_sidebar();
1042
+	}
1043
+
1044
+
1045
+	/**
1046
+	 *        _update_payment_settings
1047
+	 *
1048
+	 * @access protected
1049
+	 * @return void
1050
+	 * @throws EE_Error
1051
+	 * @throws InvalidArgumentException
1052
+	 * @throws InvalidDataTypeException
1053
+	 * @throws InvalidInterfaceException
1054
+	 */
1055
+	protected function _update_payment_settings()
1056
+	{
1057
+		$form = $this->getPaymentSettingsForm();
1058
+		if ($form->was_submitted($this->_req_data)) {
1059
+			$form->receive_form_submission($this->_req_data);
1060
+			if ($form->is_valid()) {
1061
+				/**
1062
+				 * @var $reg_config EE_Registration_Config
1063
+				 */
1064
+				$loader                                   = LoaderFactory::getLoader();
1065
+				$reg_config                               = $loader->getShared('EE_Registration_Config');
1066
+				$valid_data                               = $form->valid_data();
1067
+				$show_pending_payment_options             = $valid_data['show_pending_payment_options'] ?? null;
1068
+				$reg_config->show_pending_payment_options = $show_pending_payment_options === 'ON';
1069
+				$reg_config->gateway_log_lifespan         = $valid_data['gateway_log_lifespan'];
1070
+			}
1071
+		}
1072
+		EE_Registry::instance()->CFG = apply_filters(
1073
+			'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
1074
+			EE_Registry::instance()->CFG
1075
+		);
1076
+
1077
+		$what    = esc_html__('Payment Settings', 'event_espresso');
1078
+		$success = $this->_update_espresso_configuration(
1079
+			$what,
1080
+			EE_Registry::instance()->CFG,
1081
+			__FILE__,
1082
+			__FUNCTION__,
1083
+			__LINE__
1084
+		);
1085
+		$this->_redirect_after_action(
1086
+			$success,
1087
+			$what,
1088
+			esc_html__('updated', 'event_espresso'),
1089
+			['action' => 'payment_settings']
1090
+		);
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 * Gets the form used for updating payment settings
1096
+	 *
1097
+	 * @return EE_Form_Section_Proper
1098
+	 * @throws EE_Error
1099
+	 * @throws InvalidArgumentException
1100
+	 * @throws InvalidDataTypeException
1101
+	 * @throws InvalidInterfaceException
1102
+	 */
1103
+	protected function getPaymentSettingsForm(): EE_Form_Section_Proper
1104
+	{
1105
+		/**
1106
+		 * @var $reg_config EE_Registration_Config
1107
+		 */
1108
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1109
+		return new EE_Form_Section_Proper(
1110
+			[
1111
+				'name'            => 'payment-settings',
1112
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1113
+				'subsections'     => [
1114
+					'show_pending_payment_options' => new EE_Switch_Input(
1115
+						[
1116
+							'default'        => $reg_config->show_pending_payment_options
1117
+								? EE_Switch_Input::OPTION_ON
1118
+								: EE_Switch_Input::OPTION_OFF,
1119
+							'html_name'      => 'show_pending_payment_options',
1120
+							'html_help_text' => esc_html__(
1121
+								"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. ",
1122
+								'event_espresso'
1123
+							),
1124
+						],
1125
+						[
1126
+							EE_Switch_Input::OPTION_OFF => esc_html__(
1127
+								'pending payment options are NOT displayed',
1128
+								'event_espresso'
1129
+							),
1130
+							EE_Switch_Input::OPTION_ON  => esc_html__(
1131
+								'pending payment options are displayed',
1132
+								'event_espresso'
1133
+							),
1134
+						]
1135
+					),
1136
+					'gateway_log_lifespan'         => new EE_Select_Input(
1137
+						$reg_config->gatewayLogLifespanOptions(),
1138
+						[
1139
+							'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1140
+							'html_help_text'  => esc_html__(
1141
+								'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.',
1142
+								'event_espresso'
1143
+							),
1144
+							'default'         => $reg_config->gateway_log_lifespan,
1145
+						]
1146
+					),
1147
+				],
1148
+			]
1149
+		);
1150
+	}
1151
+
1152
+
1153
+	/**
1154
+	 * @throws EE_Error
1155
+	 */
1156
+	protected function _payment_log_overview_list_table()
1157
+	{
1158
+		$this->display_admin_list_table_page_with_sidebar();
1159
+	}
1160
+
1161
+
1162
+	protected function _set_list_table_views_payment_log()
1163
+	{
1164
+		$this->_views = [
1165
+			'all' => [
1166
+				'slug'  => 'all',
1167
+				'label' => esc_html__('View All Logs', 'event_espresso'),
1168
+				'count' => 0,
1169
+			],
1170
+		];
1171
+	}
1172
+
1173
+
1174
+	/**
1175
+	 * @param int  $per_page
1176
+	 * @param int  $current_page
1177
+	 * @param bool $count
1178
+	 * @return array|int
1179
+	 * @throws EE_Error
1180
+	 * @throws ReflectionException
1181
+	 */
1182
+	public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1183
+	{
1184
+		EE_Registry::instance()->load_model('Change_Log');
1185
+		// we may need to do multiple queries (joining differently), so we actually want an array of query params
1186
+		$query_params = [['LOG_type' => EEM_Change_Log::type_gateway]];
1187
+		// check if they've selected a specific payment method
1188
+		if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1189
+			$query_params[0]['OR*pm_or_pay_pm'] = [
1190
+				'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1191
+				'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1192
+			];
1193
+		}
1194
+		// take into account search
1195
+		if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1196
+			$similarity_string                                                              =
1197
+				['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1198
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1199
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1200
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1201
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_name']                     = $similarity_string;
1202
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name']               = $similarity_string;
1203
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_type']                     = $similarity_string;
1204
+			$query_params[0]['OR*s']['Payment_Method.PMD_name']                             = $similarity_string;
1205
+			$query_params[0]['OR*s']['Payment_Method.PMD_admin_name']                       = $similarity_string;
1206
+			$query_params[0]['OR*s']['Payment_Method.PMD_type']                             = $similarity_string;
1207
+			$query_params[0]['OR*s']['LOG_message']                                         = $similarity_string;
1208
+		}
1209
+		if (
1210
+			isset($this->_req_data['payment-filter-start-date'])
1211
+			&& isset($this->_req_data['payment-filter-end-date'])
1212
+		) {
1213
+			// add date
1214
+			$start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1215
+			$end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1216
+			// make sure our timestamps start and end right at the boundaries for each day
1217
+			$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1218
+			$end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1219
+			// convert to timestamps
1220
+			$start_date = strtotime($start_date);
1221
+			$end_date   = strtotime($end_date);
1222
+			// makes sure start date is the lowest value and vice versa
1223
+			$start_date = min($start_date, $end_date);
1224
+			$end_date   = max($start_date, $end_date);
1225
+			// convert for query
1226
+			$start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1227
+				'LOG_time',
1228
+				date('Y-m-d H:i:s', $start_date),
1229
+				'Y-m-d H:i:s'
1230
+			);
1231
+			$end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1232
+				'LOG_time',
1233
+				date('Y-m-d H:i:s', $end_date),
1234
+				'Y-m-d H:i:s'
1235
+			);
1236
+			$query_params[0]['LOG_time'] = ['BETWEEN', [$start_date, $end_date]];
1237
+		}
1238
+		if ($count) {
1239
+			return EEM_Change_Log::instance()->count($query_params);
1240
+		}
1241
+		if (isset($this->_req_data['order'])) {
1242
+			$sort                     = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1243
+				? $this->_req_data['order']
1244
+				: 'DESC';
1245
+			$query_params['order_by'] = ['LOG_time' => $sort];
1246
+		} else {
1247
+			$query_params['order_by'] = ['LOG_time' => 'DESC'];
1248
+		}
1249
+		$offset = ($current_page - 1) * $per_page;
1250
+		if (! isset($this->_req_data['download_results'])) {
1251
+			$query_params['limit'] = [$offset, $per_page];
1252
+		}
1253
+		// now they've requested to instead just download the file instead of viewing it.
1254
+		if (isset($this->_req_data['download_results'])) {
1255
+			$wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1256
+			header('Content-Disposition: attachment');
1257
+			header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1258
+			echo '<h1> '
1259
+				 . sprintf(
1260
+					 esc_html__('Payment Logs for %1$s', 'event_espresso'),
1261
+					 esc_url_raw(site_url())
1262
+				 )
1263
+				 . '</h1 >';
1264
+			echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1265
+			echo esc_html(var_export($query_params, true));
1266
+			echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1267
+			echo esc_html(var_export($wpdb_results, true));
1268
+			die;
1269
+		}
1270
+		return EEM_Change_Log::instance()->get_all($query_params);
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * Used by usort to RE-sort log query results, because we lose the ordering
1276
+	 * because we're possibly combining the results from two queries
1277
+	 *
1278
+	 * @param EE_Change_Log $logA
1279
+	 * @param EE_Change_Log $logB
1280
+	 * @return int
1281
+	 * @throws EE_Error
1282
+	 * @throws ReflectionException
1283
+	 */
1284
+	protected function _sort_logs_again($logA, $logB)
1285
+	{
1286
+		$timeA = $logA->get_raw('LOG_time');
1287
+		$timeB = $logB->get_raw('LOG_time');
1288
+		if ($timeA == $timeB) {
1289
+			return 0;
1290
+		}
1291
+		$comparison = $timeA < $timeB
1292
+			? -1
1293
+			: 1;
1294
+		if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1295
+			return $comparison * -1;
1296
+		}
1297
+		return $comparison;
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 * @throws EE_Error
1303
+	 * @throws ReflectionException
1304
+	 */
1305
+	protected function _payment_log_details()
1306
+	{
1307
+		EE_Registry::instance()->load_model('Change_Log');
1308
+		/** @var $payment_log EE_Change_Log */
1309
+		$payment_log    = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1310
+		$payment_method = null;
1311
+		$transaction    = null;
1312
+		if ($payment_log instanceof EE_Change_Log) {
1313
+			if ($payment_log->object() instanceof EE_Payment) {
1314
+				$payment_method = $payment_log->object()->payment_method();
1315
+				$transaction    = $payment_log->object()->transaction();
1316
+			} elseif ($payment_log->object() instanceof EE_Payment_Method) {
1317
+				$payment_method = $payment_log->object();
1318
+			} elseif ($payment_log->object() instanceof EE_Transaction) {
1319
+				$transaction    = $payment_log->object();
1320
+				$payment_method = $transaction->payment_method();
1321
+			}
1322
+		}
1323
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1324
+			EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1325
+			[
1326
+				'payment_log'    => $payment_log,
1327
+				'payment_method' => $payment_method,
1328
+				'transaction'    => $transaction,
1329
+			],
1330
+			true
1331
+		);
1332
+		$this->display_admin_page_with_no_sidebar();
1333
+	}
1334 1334
 }
Please login to merge, or discard this patch.
Spacing   +49 added lines, -49 removed lines patch added patch discarded remove patch
@@ -152,7 +152,7 @@  discard block
 block discarded – undo
152 152
             ),
153 153
             'require_nonce' => false,
154 154
         ];
155
-        $this->_page_config         = [
155
+        $this->_page_config = [
156 156
             'default'          => $payment_method_list_config,
157 157
             'payment_settings' => [
158 158
                 'nav'           => [
@@ -209,10 +209,10 @@  discard block
 block discarded – undo
209 209
             foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
210 210
                 $template_args                              = $config['template_args'] ?? [];
211 211
                 $template_args['admin_page_obj']            = $this;
212
-                $all_pmt_help_tabs_config[ $help_tab_name ] = [
212
+                $all_pmt_help_tabs_config[$help_tab_name] = [
213 213
                     'title'   => $config['title'],
214 214
                     'content' => EEH_Template::display_template(
215
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
215
+                        $payment_method_type->file_folder().'help_tabs/'.$config['filename'].'.help_tab.php',
216 216
                         $template_args,
217 217
                         true
218 218
                     ),
@@ -255,7 +255,7 @@  discard block
 block discarded – undo
255 255
         wp_enqueue_style('espresso-ui-theme');
256 256
         wp_register_style(
257 257
             'espresso_payments',
258
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
258
+            EE_PAYMENTS_ASSETS_URL.'ee-payments.css',
259 259
             [],
260 260
             EVENT_ESPRESSO_VERSION
261 261
         );
@@ -264,7 +264,7 @@  discard block
 block discarded – undo
264 264
         wp_enqueue_script('ee-text-links');
265 265
         wp_enqueue_script(
266 266
             'espresso_payments',
267
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
267
+            EE_PAYMENTS_ASSETS_URL.'espresso_payments_admin.js',
268 268
             ['ee-datepicker'],
269 269
             EVENT_ESPRESSO_VERSION,
270 270
             true
@@ -294,7 +294,7 @@  discard block
 block discarded – undo
294 294
         $table_analysis = LoaderFactory::getShared(TableAnalysis::class);
295 295
         /** @var TableManager $table_manager */
296 296
         $table_manager = LoaderFactory::getShared(TableManager::class);
297
-        if (! $table_analysis->tableExists('esp_payment_method')) {
297
+        if ( ! $table_analysis->tableExists('esp_payment_method')) {
298 298
             $table_manager->createTable(
299 299
                 'esp_payment_method',
300 300
                 "PMD_ID int(11) NOT NULL AUTO_INCREMENT,
@@ -316,7 +316,7 @@  discard block
 block discarded – undo
316 316
                 'InnoDB'
317 317
             );
318 318
         }
319
-        if (! $table_analysis->tableExists('esp_currency_payment_method')) {
319
+        if ( ! $table_analysis->tableExists('esp_currency_payment_method')) {
320 320
             $table_manager->createTable(
321 321
                 'esp_currency_payment_method',
322 322
                 "CPM_ID int(11) NOT NULL AUTO_INCREMENT,
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
             }
366 366
             // check for any active pms of that type
367 367
             $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
368
-            if (! $payment_method instanceof EE_Payment_Method) {
368
+            if ( ! $payment_method instanceof EE_Payment_Method) {
369 369
                 $payment_method = EE_Payment_Method::new_instance(
370 370
                     [
371 371
                         'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
                     ]
376 376
                 );
377 377
             }
378
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
378
+            $payment_methods[$payment_method->slug()] = $payment_method;
379 379
         }
380 380
         $payment_methods = apply_filters(
381 381
             'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
@@ -385,7 +385,7 @@  discard block
 block discarded – undo
385 385
             if ($payment_method instanceof EE_Payment_Method) {
386 386
                 $this->addMetaBox(
387 387
                 // html id
388
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
388
+                    'espresso_'.$payment_method->slug().'_payment_settings',
389 389
                     // title
390 390
                     sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
391 391
                     // callback
@@ -400,12 +400,12 @@  discard block
 block discarded – undo
400 400
                     ['payment_method' => $payment_method]
401 401
                 );
402 402
                 // setup for tabbed content
403
-                $tabs[ $payment_method->slug() ] = [
403
+                $tabs[$payment_method->slug()] = [
404 404
                     'label' => $payment_method->admin_name(),
405 405
                     'class' => $payment_method->active()
406 406
                         ? 'gateway-active'
407 407
                         : '',
408
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
408
+                    'href'  => 'espresso_'.$payment_method->slug().'_payment_settings',
409 409
                     'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
410 410
                     'slug'  => $payment_method->slug(),
411 411
                     'icon'  => $payment_method->active()
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
         /** @var EE_Payment_Method $payment_method */
443 443
         $payment_method = EEM_Payment_Method::instance()->get_one([['PMD_slug' => $payment_method_slug]]);
444 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)) {
445
+        if ( ! $this->_verify_payment_method($payment_method)) {
446 446
             // like, looking for an active one
447 447
             $payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
448 448
             // test that one as well
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
         $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
492 492
             ? $metabox['args']['payment_method']
493 493
             : null;
494
-        if (! $payment_method instanceof EE_Payment_Method) {
494
+        if ( ! $payment_method instanceof EE_Payment_Method) {
495 495
             throw new EE_Error(
496 496
                 esc_html__(
497 497
                     'Payment method metabox setup incorrectly. No Payment method object was supplied',
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
                 $form->receive_form_submission($this->_req_data);
508 508
             }
509 509
             echo wp_kses(
510
-                $form->form_open() . $form->get_html_and_js() . $form->form_close(),
510
+                $form->form_open().$form->get_html_and_js().$form->form_close(),
511 511
                 AllowedTags::getWithFormTags()
512 512
             );
513 513
         } else {
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
     protected function _generate_payment_method_settings_form(
532 532
         ?EE_Payment_Method $payment_method
533 533
     ): EE_Form_Section_Proper {
534
-        if (! $payment_method instanceof EE_Payment_Method) {
534
+        if ( ! $payment_method instanceof EE_Payment_Method) {
535 535
             return new EE_Form_Section_Proper();
536 536
         }
537 537
         $subsections = apply_filters(
@@ -548,8 +548,8 @@  discard block
 block discarded – undo
548 548
         );
549 549
         return new EE_Form_Section_Proper(
550 550
             [
551
-                'name'            => $payment_method->slug() . '_settings_form',
552
-                'html_id'         => $payment_method->slug() . '_settings_form',
551
+                'name'            => $payment_method->slug().'_settings_form',
552
+                'html_id'         => $payment_method->slug().'_settings_form',
553 553
                 'action'          => EE_Admin_Page::add_query_args_and_nonce(
554 554
                     [
555 555
                         'action'         => 'update_payment_method',
@@ -574,7 +574,7 @@  discard block
 block discarded – undo
574 574
      */
575 575
     protected function _pci_dss_compliance(EE_Payment_Method $payment_method): ?EE_Form_Section_HTML
576 576
     {
577
-        if (! $payment_method->type_obj()->requires_https()) {
577
+        if ( ! $payment_method->type_obj()->requires_https()) {
578 578
             return null;
579 579
         }
580 580
         return new EE_Form_Section_HTML(
@@ -587,7 +587,7 @@  discard block
 block discarded – undo
587 587
                             'important-notice'
588 588
                         )
589 589
                     )
590
-                ) .
590
+                ).
591 591
                 EEH_HTML::td(
592 592
                     EEH_HTML::div(
593 593
                         EEH_HTML::strong(
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
                             'important-notice'
640 640
                         )
641 641
                     )
642
-                ) .
642
+                ).
643 643
                 EEH_HTML::td(
644 644
                     EEH_HTML::div(
645 645
                         EEH_HTML::strong(
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
         $update_button = new EE_Submit_Input(
725 725
             [
726 726
                 'name'       => 'submit',
727
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
727
+                'html_id'    => 'save_'.$payment_method->slug().'_settings',
728 728
                 'default'    => sprintf(
729 729
                     esc_html__('Update %s Payment Settings', 'event_espresso'),
730 730
                     $payment_method->admin_name()
@@ -738,15 +738,15 @@  discard block
 block discarded – undo
738 738
                 // esc_html__('Update Settings', 'event_espresso'),
739 739
                     '&nbsp;',
740 740
                     '',
741
-                    'ee-update-' . $payment_method->slug() . '-settings__label'
742
-                ) .
741
+                    'ee-update-'.$payment_method->slug().'-settings__label'
742
+                ).
743 743
                 EEH_HTML::td(
744 744
                     $update_button->get_html_for_input(),
745 745
                     '',
746
-                    'ee-update-' . $payment_method->slug() . '-settings__input'
746
+                    'ee-update-'.$payment_method->slug().'-settings__input'
747 747
                 ),
748 748
                 '',
749
-                'ee-update-' . $payment_method->slug() . '-settings'
749
+                'ee-update-'.$payment_method->slug().'-settings'
750 750
             )
751 751
         );
752 752
     }
@@ -771,8 +771,8 @@  discard block
 block discarded – undo
771 771
                 // esc_html__('Deactivate Payment Method', 'event_espresso'),
772 772
                     '&nbsp;',
773 773
                     '',
774
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__label'
775
-                ) .
774
+                    'ee-deactivate-'.$payment_method->slug().'-settings__label'
775
+                ).
776 776
                 EEH_HTML::td(
777 777
                     EEH_HTML::link(
778 778
                         EE_Admin_Page::add_query_args_and_nonce(
@@ -784,14 +784,14 @@  discard block
 block discarded – undo
784 784
                         ),
785 785
                         $link_text_and_title,
786 786
                         $link_text_and_title,
787
-                        'deactivate_' . $payment_method->slug(),
787
+                        'deactivate_'.$payment_method->slug(),
788 788
                         'button button--secondary'
789 789
                     ),
790 790
                     '',
791
-                    'ee-deactivate-' . $payment_method->slug() . '-settings__input'
791
+                    'ee-deactivate-'.$payment_method->slug().'-settings__input'
792 792
                 ),
793 793
                 '',
794
-                'ee-deactivate-' . $payment_method->slug() . '-settings'
794
+                'ee-deactivate-'.$payment_method->slug().'-settings'
795 795
             )
796 796
         );
797 797
     }
@@ -813,8 +813,8 @@  discard block
 block discarded – undo
813 813
         );
814 814
         return new EE_Form_Section_Proper(
815 815
             [
816
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
817
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
816
+                'name'            => 'activate_'.$payment_method->slug().'_settings_form',
817
+                'html_id'         => 'activate_'.$payment_method->slug().'_settings_form',
818 818
                 'action'          => '#',
819 819
                 'layout_strategy' => new EE_Admin_Two_Column_Layout(),
820 820
                 'subsections'     => apply_filters(
@@ -830,11 +830,11 @@  discard block
 block discarded – undo
830 830
                                         '',
831 831
                                         'colspan="2"'
832 832
                                     )
833
-                                ) .
833
+                                ).
834 834
                                 EEH_HTML::tr(
835 835
                                     EEH_HTML::th(
836 836
                                         EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
837
-                                    ) .
837
+                                    ).
838 838
                                     EEH_HTML::td(
839 839
                                         EEH_HTML::link(
840 840
                                             EE_Admin_Page::add_query_args_and_nonce(
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
                                             ),
847 847
                                             $link_text_and_title,
848 848
                                             $link_text_and_title,
849
-                                            'activate_' . $payment_method->slug(),
849
+                                            'activate_'.$payment_method->slug(),
850 850
                                             'button button--primary-alt'
851 851
                                         )
852 852
                                     )
@@ -871,7 +871,7 @@  discard block
 block discarded – undo
871 871
     {
872 872
         return new EE_Form_Section_HTML(
873 873
             EEH_HTML::tr(
874
-                EEH_HTML::th() .
874
+                EEH_HTML::th().
875 875
                 EEH_HTML::td(
876 876
                     EEH_HTML::p(
877 877
                         esc_html__('All fields marked with a * are required fields', 'event_espresso'),
@@ -965,7 +965,7 @@  discard block
 block discarded – undo
965 965
                 }
966 966
             }
967 967
             // if we couldn't find the correct payment method type...
968
-            if (! $correct_pmt_form_to_use) {
968
+            if ( ! $correct_pmt_form_to_use) {
969 969
                 EE_Error::add_error(
970 970
                     esc_html__(
971 971
                         "We could not find which payment method type your form submission related to. Please contact support",
@@ -980,7 +980,7 @@  discard block
 block discarded – undo
980 980
             $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
981 981
             if ($correct_pmt_form_to_use->is_valid()) {
982 982
                 $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
983
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
983
+                if ( ! $payment_settings_subform instanceof EE_Payment_Method_Form) {
984 984
                     throw new EE_Error(
985 985
                         sprintf(
986 986
                             esc_html__(
@@ -1194,7 +1194,7 @@  discard block
 block discarded – undo
1194 1194
         // take into account search
1195 1195
         if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1196 1196
             $similarity_string                                                              =
1197
-                ['LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%'];
1197
+                ['LIKE', '%'.str_replace("", "%", $this->_req_data['s']).'%'];
1198 1198
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1199 1199
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1200 1200
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
@@ -1214,8 +1214,8 @@  discard block
 block discarded – undo
1214 1214
             $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1215 1215
             $end_date   = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1216 1216
             // make sure our timestamps start and end right at the boundaries for each day
1217
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1218
-            $end_date   = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1217
+            $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
1218
+            $end_date   = date('Y-m-d', strtotime($end_date)).' 23:59:59';
1219 1219
             // convert to timestamps
1220 1220
             $start_date = strtotime($start_date);
1221 1221
             $end_date   = strtotime($end_date);
@@ -1223,12 +1223,12 @@  discard block
 block discarded – undo
1223 1223
             $start_date = min($start_date, $end_date);
1224 1224
             $end_date   = max($start_date, $end_date);
1225 1225
             // convert for query
1226
-            $start_date                  = EEM_Change_Log::instance()->convert_datetime_for_query(
1226
+            $start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1227 1227
                 'LOG_time',
1228 1228
                 date('Y-m-d H:i:s', $start_date),
1229 1229
                 'Y-m-d H:i:s'
1230 1230
             );
1231
-            $end_date                    = EEM_Change_Log::instance()->convert_datetime_for_query(
1231
+            $end_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1232 1232
                 'LOG_time',
1233 1233
                 date('Y-m-d H:i:s', $end_date),
1234 1234
                 'Y-m-d H:i:s'
@@ -1247,23 +1247,23 @@  discard block
 block discarded – undo
1247 1247
             $query_params['order_by'] = ['LOG_time' => 'DESC'];
1248 1248
         }
1249 1249
         $offset = ($current_page - 1) * $per_page;
1250
-        if (! isset($this->_req_data['download_results'])) {
1250
+        if ( ! isset($this->_req_data['download_results'])) {
1251 1251
             $query_params['limit'] = [$offset, $per_page];
1252 1252
         }
1253 1253
         // now they've requested to instead just download the file instead of viewing it.
1254 1254
         if (isset($this->_req_data['download_results'])) {
1255 1255
             $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1256 1256
             header('Content-Disposition: attachment');
1257
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1257
+            header("Content-Disposition: attachment; filename=ee_payment_logs_for_".sanitize_key(site_url()));
1258 1258
             echo '<h1> '
1259 1259
                  . sprintf(
1260 1260
                      esc_html__('Payment Logs for %1$s', 'event_espresso'),
1261 1261
                      esc_url_raw(site_url())
1262 1262
                  )
1263 1263
                  . '</h1 >';
1264
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1264
+            echo '<h3>'.esc_html__('Query:', 'event_espresso').'</h3>';
1265 1265
             echo esc_html(var_export($query_params, true));
1266
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1266
+            echo '<h3>'.esc_html__('Results:', 'event_espresso').'</h3>';
1267 1267
             echo esc_html(var_export($wpdb_results, true));
1268 1268
             die;
1269 1269
         }
@@ -1321,7 +1321,7 @@  discard block
 block discarded – undo
1321 1321
             }
1322 1322
         }
1323 1323
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1324
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1324
+            EE_PAYMENTS_TEMPLATE_PATH.'payment_log_details.template.php',
1325 1325
             [
1326 1326
                 'payment_log'    => $payment_log,
1327 1327
                 'payment_method' => $payment_method,
Please login to merge, or discard this patch.
admin_pages/maintenance/Maintenance_Admin_Page.core.php 2 patches
Indentation   +955 added lines, -955 removed lines patch added patch discarded remove patch
@@ -14,959 +14,959 @@
 block discarded – undo
14 14
  */
15 15
 class Maintenance_Admin_Page extends EE_Admin_Page
16 16
 {
17
-    /**
18
-     * @var EE_Data_Migration_Manager
19
-     */
20
-    protected $migration_manager;
21
-
22
-    /**
23
-     * @var EE_Maintenance_Mode
24
-     */
25
-    protected $maintenance_mode;
26
-
27
-    /**
28
-     * @var EE_Form_Section_Proper
29
-     */
30
-    protected $datetime_fix_offset_form;
31
-
32
-
33
-    /**
34
-     * @param bool $routing
35
-     * @throws EE_Error
36
-     * @throws ReflectionException
37
-     */
38
-    public function __construct($routing = true)
39
-    {
40
-        $this->migration_manager = EE_Data_Migration_Manager::instance();
41
-        $this->maintenance_mode  = EE_Maintenance_Mode::instance();
42
-        parent::__construct($routing);
43
-    }
44
-
45
-
46
-    protected function _init_page_props()
47
-    {
48
-        $this->page_slug        = EE_MAINTENANCE_PG_SLUG;
49
-        $this->page_label       = EE_MAINTENANCE_LABEL;
50
-        $this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
51
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
52
-    }
53
-
54
-
55
-    protected function _ajax_hooks()
56
-    {
57
-        add_action('wp_ajax_migration_step', [$this, 'migration_step']);
58
-        add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
59
-    }
60
-
61
-
62
-    protected function _define_page_props()
63
-    {
64
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
65
-        $this->_labels           = [
66
-            'buttons' => [
67
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
68
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
69
-            ],
70
-        ];
71
-    }
72
-
73
-
74
-    protected function _set_page_routes()
75
-    {
76
-        $this->_page_routes = [
77
-            'default'                             => [
78
-                'func'       => '_maintenance',
79
-                'capability' => 'manage_options',
80
-            ],
81
-            'change_maintenance_level'            => [
82
-                'func'       => '_change_maintenance_level',
83
-                'capability' => 'manage_options',
84
-                'noheader'   => true,
85
-            ],
86
-            'system_status'                       => [
87
-                'func'       => '_system_status',
88
-                'capability' => 'manage_options',
89
-            ],
90
-            'download_system_status'              => [
91
-                'func'       => '_download_system_status',
92
-                'capability' => 'manage_options',
93
-                'noheader'   => true,
94
-            ],
95
-            'send_migration_crash_report'         => [
96
-                'func'       => '_send_migration_crash_report',
97
-                'capability' => 'manage_options',
98
-                'noheader'   => true,
99
-            ],
100
-            'confirm_migration_crash_report_sent' => [
101
-                'func'       => '_confirm_migration_crash_report_sent',
102
-                'capability' => 'manage_options',
103
-            ],
104
-            'data_reset'                          => [
105
-                'func'       => '_data_reset_and_delete',
106
-                'capability' => 'manage_options',
107
-            ],
108
-            'reset_db'                            => [
109
-                'func'       => '_reset_db',
110
-                'capability' => 'manage_options',
111
-                'noheader'   => true,
112
-                'args'       => ['nuke_old_ee4_data' => true],
113
-            ],
114
-            'start_with_fresh_ee4_db'             => [
115
-                'func'       => '_reset_db',
116
-                'capability' => 'manage_options',
117
-                'noheader'   => true,
118
-                'args'       => ['nuke_old_ee4_data' => false],
119
-            ],
120
-            'delete_db'                           => [
121
-                'func'       => '_delete_db',
122
-                'capability' => 'manage_options',
123
-                'noheader'   => true,
124
-            ],
125
-            'rerun_migration_from_ee3'            => [
126
-                'func'       => '_rerun_migration_from_ee3',
127
-                'capability' => 'manage_options',
128
-                'noheader'   => true,
129
-            ],
130
-            'reset_reservations'                  => [
131
-                'func'       => '_reset_reservations',
132
-                'capability' => 'manage_options',
133
-                'noheader'   => true,
134
-            ],
135
-            'reset_capabilities'                  => [
136
-                'func'       => '_reset_capabilities',
137
-                'capability' => 'manage_options',
138
-                'noheader'   => true,
139
-            ],
140
-            'reattempt_migration'                 => [
141
-                'func'       => '_reattempt_migration',
142
-                'capability' => 'manage_options',
143
-                'noheader'   => true,
144
-            ],
145
-            'datetime_tools'                      => [
146
-                'func'       => '_datetime_tools',
147
-                'capability' => 'manage_options',
148
-            ],
149
-            'run_datetime_offset_fix'             => [
150
-                'func'               => '_apply_datetime_offset',
151
-                'noheader'           => true,
152
-                'headers_sent_route' => 'datetime_tools',
153
-                'capability'         => 'manage_options',
154
-            ],
155
-        ];
156
-    }
157
-
158
-
159
-    protected function _set_page_config()
160
-    {
161
-        $this->_page_config = [
162
-            'default'        => [
163
-                'nav'           => [
164
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
165
-                    'icon'  => 'dashicons-admin-tools',
166
-                    'order' => 10,
167
-                ],
168
-                'require_nonce' => false,
169
-            ],
170
-            'data_reset'     => [
171
-                'nav'           => [
172
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
173
-                    'icon'  => 'dashicons-trash',
174
-                    'order' => 20,
175
-                ],
176
-                'require_nonce' => false,
177
-            ],
178
-            'datetime_tools' => [
179
-                'nav'           => [
180
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
181
-                    'icon'  => 'dashicons-calendar-alt',
182
-                    'order' => 25,
183
-                ],
184
-                'require_nonce' => false,
185
-            ],
186
-            'system_status'  => [
187
-                'nav'           => [
188
-                    'label' => esc_html__("System Information", "event_espresso"),
189
-                    'icon'  => 'dashicons-info',
190
-                    'order' => 30,
191
-                ],
192
-                'require_nonce' => false,
193
-            ],
194
-        ];
195
-    }
196
-
197
-
198
-    /**
199
-     * default maintenance page.
200
-     * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
201
-     *
202
-     * @throws EE_Error
203
-     */
204
-    public function _maintenance()
205
-    {
206
-        $show_maintenance_switch         = true;
207
-        $show_backup_db_text             = false;
208
-        $show_migration_progress         = false;
209
-        $script_names                    = [];
210
-        $addons_should_be_upgraded_first = false;
211
-        // it all depends on if we're in maintenance model level 1 (frontend-only) or
212
-        // level 2 (everything except maintenance page)
213
-        try {
214
-            // get the current maintenance level and check if
215
-            // we are removed
216
-            $mMode_level  = $this->maintenance_mode->level();
217
-            $placed_in_mm = $this->maintenance_mode->set_maintenance_mode_if_db_old();
218
-            if ($mMode_level == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
219
-                // we just took the site out of maintenance mode, so notify the user.
220
-                // unfortunately this message appears to be echoed on the NEXT page load...
221
-                // oh well, we should really be checking for this on addon deactivation anyways
222
-                EE_Error::add_attention(
223
-                    esc_html__(
224
-                        'Site taken out of maintenance mode because no data migration scripts are required',
225
-                        'event_espresso'
226
-                    )
227
-                );
228
-                $this->_process_notices(['page' => 'espresso_maintenance_settings']);
229
-            }
230
-            // in case an exception is thrown while trying to handle migrations
231
-            if ($mMode_level === EE_Maintenance_Mode::level_2_complete_maintenance) {
232
-                $show_maintenance_switch = false;
233
-                $show_migration_progress = true;
234
-                if (isset($this->_req_data['continue_migration'])) {
235
-                    $show_backup_db_text = false;
236
-                } else {
237
-                    $show_backup_db_text = true;
238
-                }
239
-                $scripts_needing_to_run          =
240
-                    $this->migration_manager->check_for_applicable_data_migration_scripts();
241
-                $addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
242
-                $script_names                    = [];
243
-                $current_script                  = null;
244
-                foreach ($scripts_needing_to_run as $script) {
245
-                    if ($script instanceof EE_Data_Migration_Script_Base) {
246
-                        if (! $current_script) {
247
-                            $current_script = $script;
248
-                            $current_script->migration_page_hooks();
249
-                        }
250
-                        $script_names[] = $script->pretty_name();
251
-                    }
252
-                }
253
-            }
254
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
255
-            $exception_thrown      = false;
256
-        } catch (EE_Error $e) {
257
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
258
-            // now, just so we can display the page correctly, make an error migration script stage object
259
-            // and also put the error on it. It only persists for the duration of this request
260
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
261
-            $most_recent_migration->add_error($e->getMessage());
262
-            $exception_thrown = true;
263
-        }
264
-        $current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
265
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
266
-        if (
267
-            $exception_thrown
268
-            || (
269
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
270
-                && $most_recent_migration->is_broken()
271
-            )
272
-        ) {
273
-            $this->_template_path                =
274
-                EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
-            $this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
276
-            $this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
277
-                [
278
-                    'action'  => 'confirm_migration_crash_report_sent',
279
-                    'success' => '0',
280
-                ],
281
-                EE_MAINTENANCE_ADMIN_URL
282
-            );
283
-        } elseif ($addons_should_be_upgraded_first) {
284
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
285
-        } else {
286
-            if (
287
-                $most_recent_migration instanceof EE_Data_Migration_Script_Base
288
-                && $most_recent_migration->can_continue()
289
-            ) {
290
-                $show_backup_db_text                    = false;
291
-                $show_continue_current_migration_script = true;
292
-                $show_most_recent_migration             = true;
293
-            } elseif (isset($this->_req_data['continue_migration'])) {
294
-                $show_most_recent_migration             = true;
295
-                $show_continue_current_migration_script = false;
296
-            } else {
297
-                $show_most_recent_migration             = false;
298
-                $show_continue_current_migration_script = false;
299
-            }
300
-            if (isset($current_script)) {
301
-                $migrates_to          = $current_script->migrates_to_version();
302
-                $plugin_slug          = $migrates_to['slug'];
303
-                $new_version          = $migrates_to['version'];
304
-                $this->_template_args = array_merge(
305
-                    $this->_template_args,
306
-                    [
307
-                        'current_db_state' => sprintf(
308
-                            esc_html__("EE%s (%s)", "event_espresso"),
309
-                            isset($current_db_state[ $plugin_slug ]) ? $current_db_state[ $plugin_slug ] : 3,
310
-                            $plugin_slug
311
-                        ),
312
-                        'next_db_state'    => sprintf(
313
-                            esc_html__("EE%s (%s)", 'event_espresso'),
314
-                            $new_version,
315
-                            $plugin_slug
316
-                        ),
317
-                    ]
318
-                );
319
-            } else {
320
-                $this->_template_args['current_db_state'] = null;
321
-                $this->_template_args['next_db_state']    = null;
322
-            }
323
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
324
-            $this->_template_args = array_merge(
325
-                $this->_template_args,
326
-                [
327
-                    'show_most_recent_migration'             => $show_most_recent_migration,
328
-                    // flag for showing the most recent migration's status and/or errors
329
-                    'show_migration_progress'                => $show_migration_progress,
330
-                    // flag for showing the option to run migrations and see their progress
331
-                    'show_backup_db_text'                    => $show_backup_db_text,
332
-                    // flag for showing text telling the user to back up their DB
333
-                    'show_maintenance_switch'                => $show_maintenance_switch,
334
-                    // flag for showing the option to change maintenance mode between levels 0 and 1
335
-                    'script_names'                           => $script_names,
336
-                    // array of names of scripts that have run
337
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
338
-                    // flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
339
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
340
-                        ['action' => 'reset_db'],
341
-                        EE_MAINTENANCE_ADMIN_URL
342
-                    ),
343
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
344
-                        ['action' => 'data_reset'],
345
-                        EE_MAINTENANCE_ADMIN_URL
346
-                    ),
347
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
348
-                        ['action' => 'change_maintenance_level'],
349
-                        EE_MAINTENANCE_ADMIN_URL
350
-                    ),
351
-                    'ultimate_db_state'                      => sprintf(
352
-                        esc_html__("EE%s", 'event_espresso'),
353
-                        espresso_version()
354
-                    ),
355
-                ]
356
-            );
357
-        }
358
-        $this->_template_args['most_recent_migration'] =
359
-            $most_recent_migration;// the actual most recently ran migration
360
-        // now render the migration options part, and put it in a variable
361
-        $migration_options_template_file                = apply_filters(
362
-            'FHEE__ee_migration_page__migration_options_template',
363
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
364
-        );
365
-        $migration_options_html                         = EEH_Template::display_template(
366
-            $migration_options_template_file,
367
-            $this->_template_args,
368
-            true
369
-        );
370
-        $this->_template_args['migration_options_html'] = $migration_options_html;
371
-        $this->_template_args['admin_page_content']     = EEH_Template::display_template(
372
-            $this->_template_path,
373
-            $this->_template_args,
374
-            true
375
-        );
376
-        $this->display_admin_page_with_sidebar();
377
-    }
378
-
379
-
380
-    /**
381
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
382
-     *
383
-     * @throws EE_Error
384
-     */
385
-    public function migration_step()
386
-    {
387
-        $this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
388
-        $this->_return_json();
389
-    }
390
-
391
-
392
-    /**
393
-     * Can be used by js when it notices a response with HTML in it in order
394
-     * to log the malformed response
395
-     *
396
-     * @throws EE_Error
397
-     */
398
-    public function add_error_to_migrations_ran()
399
-    {
400
-        $this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
401
-        $this->_template_args['data'] = ['ok' => true];
402
-        $this->_return_json();
403
-    }
404
-
405
-
406
-    /**
407
-     * changes the maintenance level, provided there are still no migration scripts that should run
408
-     *
409
-     * @throws EE_Error
410
-     */
411
-    public function _change_maintenance_level()
412
-    {
413
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
414
-        if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
415
-            $this->maintenance_mode->set_maintenance_level($new_level);
416
-            $success = true;
417
-        } else {
418
-            $this->maintenance_mode->set_maintenance_mode_if_db_old();
419
-            $success = false;
420
-        }
421
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
422
-    }
423
-
424
-
425
-    /**
426
-     * a tab with options for resetting and/or deleting EE data
427
-     *
428
-     * @throws EE_Error
429
-     * @throws DomainException
430
-     */
431
-    public function _data_reset_and_delete()
432
-    {
433
-        $this->_template_path                              =
434
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
435
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
436
-            'reset_reservations',
437
-            'reset_reservations',
438
-            [],
439
-            'button button--caution ee-confirm'
440
-        );
441
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
442
-            'reset_capabilities',
443
-            'reset_capabilities',
444
-            [],
445
-            'button button--caution ee-confirm'
446
-        );
447
-        $this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
448
-            ['action' => 'delete_db'],
449
-            EE_MAINTENANCE_ADMIN_URL
450
-        );
451
-        $this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
452
-            ['action' => 'reset_db'],
453
-            EE_MAINTENANCE_ADMIN_URL
454
-        );
455
-        $this->_template_args['admin_page_content']        = EEH_Template::display_template(
456
-            $this->_template_path,
457
-            $this->_template_args,
458
-            true
459
-        );
460
-        $this->display_admin_page_with_no_sidebar();
461
-    }
462
-
463
-
464
-    /**
465
-     * @throws EE_Error
466
-     * @throws ReflectionException
467
-     */
468
-    protected function _reset_reservations()
469
-    {
470
-        if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
471
-            EE_Error::add_success(
472
-                esc_html__(
473
-                    'Ticket and datetime reserved counts have been successfully reset.',
474
-                    'event_espresso'
475
-                )
476
-            );
477
-        } else {
478
-            EE_Error::add_success(
479
-                esc_html__(
480
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
481
-                    'event_espresso'
482
-                )
483
-            );
484
-        }
485
-        $this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
486
-    }
487
-
488
-
489
-    /**
490
-     * @throws EE_Error
491
-     */
492
-    protected function _reset_capabilities()
493
-    {
494
-        $this->capabilities->init_caps(true);
495
-        EE_Error::add_success(
496
-            esc_html__(
497
-                'Default Event Espresso capabilities have been restored for all current roles.',
498
-                'event_espresso'
499
-            )
500
-        );
501
-        $this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
502
-    }
503
-
504
-
505
-    /**
506
-     * resets the DMSs, so we can attempt to continue migrating after a fatal error
507
-     * (only a good idea when someone has somehow tried ot fix whatever caused
508
-     * the fatal error in teh first place)
509
-     *
510
-     * @throws EE_Error
511
-     */
512
-    protected function _reattempt_migration()
513
-    {
514
-        $this->migration_manager->reattempt();
515
-        $this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
516
-    }
517
-
518
-
519
-    /**
520
-     * shows the big ol' System Information page
521
-     *
522
-     * @throws EE_Error
523
-     */
524
-    public function _system_status()
525
-    {
526
-        $this->_template_path                               =
527
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
528
-        $this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
529
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
530
-            [
531
-                'action' => 'download_system_status',
532
-            ],
533
-            EE_MAINTENANCE_ADMIN_URL
534
-        );
535
-        $this->_template_args['admin_page_content']         = EEH_Template::display_template(
536
-            $this->_template_path,
537
-            $this->_template_args,
538
-            true
539
-        );
540
-        $this->display_admin_page_with_no_sidebar();
541
-    }
542
-
543
-
544
-    /**
545
-     * Downloads an HTML file of the system status that can be easily stored or emailed
546
-     */
547
-    public function _download_system_status()
548
-    {
549
-        $status_info = EEM_System_Status::instance()->get_system_stati();
550
-        header('Content-Disposition: attachment');
551
-        header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
552
-        $output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
553
-        $output .= '<h1>' . sprintf(
554
-                __('System Information for %1$s', 'event_espresso'),
555
-                esc_url_raw(site_url())
556
-            ) . '</h1>';
557
-        $output .= EEH_Template::layout_array_as_table($status_info);
558
-        echo esc_html($output);
559
-        die;
560
-    }
561
-
562
-
563
-    /**
564
-     * @throws EE_Error
565
-     */
566
-    public function _send_migration_crash_report()
567
-    {
568
-        $from      = $this->_req_data['from'];
569
-        $from_name = $this->_req_data['from_name'];
570
-        $body      = $this->_req_data['body'];
571
-        try {
572
-            $success = wp_mail(
573
-                EE_SUPPORT_EMAIL,
574
-                'Migration Crash Report',
575
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
576
-                [
577
-                    "from:$from_name<$from>",
578
-                ]
579
-            );
580
-        } catch (Exception $e) {
581
-            $success = false;
582
-        }
583
-        $this->_redirect_after_action(
584
-            $success,
585
-            esc_html__("Migration Crash Report", "event_espresso"),
586
-            esc_html__("sent", "event_espresso"),
587
-            ['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
588
-        );
589
-    }
590
-
591
-
592
-    /**
593
-     * @throws EE_Error
594
-     */
595
-    public function _confirm_migration_crash_report_sent()
596
-    {
597
-        try {
598
-            $most_recent_migration = $this->migration_manager->get_last_ran_script(true);
599
-        } catch (EE_Error $e) {
600
-            $this->migration_manager->add_error_to_migrations_ran($e->getMessage());
601
-            // now, just so we can display the page correctly, make an error migration script stage object
602
-            // and also put the error on it. It only persists for the duration of this request
603
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
604
-            $most_recent_migration->add_error($e->getMessage());
605
-        }
606
-        $success                                       = $this->_req_data['success'] === '1';
607
-        $this->_template_args['success']               = $success;
608
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
609
-        $this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
610
-            ['action' => 'reset_db'],
611
-            EE_MAINTENANCE_ADMIN_URL
612
-        );
613
-        $this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
614
-            ['action' => 'data_reset'],
615
-            EE_MAINTENANCE_ADMIN_URL
616
-        );
617
-        $this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
618
-            ['action' => 'reattempt_migration'],
619
-            EE_MAINTENANCE_ADMIN_URL
620
-        );
621
-        $this->_template_path                          =
622
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
623
-        $this->_template_args['admin_page_content']    = EEH_Template::display_template(
624
-            $this->_template_path,
625
-            $this->_template_args,
626
-            true
627
-        );
628
-        $this->display_admin_page_with_sidebar();
629
-    }
630
-
631
-
632
-    /**
633
-     * Resets the entire EE4 database.
634
-     * only sets up ee4 database for a fresh install-
635
-     * doesn't actually clean out the old wp options, or cpts
636
-     * (although it does erase old ee table data)
637
-     *
638
-     * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
639
-     *                                   or just try initializing ee4 default data
640
-     * @throws EE_Error
641
-     * @throws ReflectionException
642
-     */
643
-    public function _reset_db($nuke_old_ee4_data = true)
644
-    {
645
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
646
-        if ($nuke_old_ee4_data) {
647
-            EEH_Activation::delete_all_espresso_cpt_data();
648
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
649
-            EEH_Activation::remove_cron_tasks();
650
-        }
651
-        // make sure when we reset the registry's config that it
652
-        // switches to using the new singleton
653
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
654
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
655
-        EE_System::instance()->redirect_to_about_ee();
656
-    }
657
-
658
-
659
-    /**
660
-     * Deletes ALL EE tables, Records, and Options from the database.
661
-     *
662
-     * @throws EE_Error
663
-     * @throws ReflectionException
664
-     */
665
-    public function _delete_db()
666
-    {
667
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
668
-        EEH_Activation::delete_all_espresso_cpt_data();
669
-        EEH_Activation::delete_all_espresso_tables_and_data();
670
-        EEH_Activation::remove_cron_tasks();
671
-        EEH_Activation::deactivate_event_espresso();
672
-        wp_safe_redirect(admin_url('plugins.php'));
673
-        exit;
674
-    }
675
-
676
-
677
-    /**
678
-     * sets up EE4 to rerun the migrations from ee3 to ee4
679
-     *
680
-     * @throws EE_Error
681
-     * @throws ReflectionException
682
-     */
683
-    public function _rerun_migration_from_ee3()
684
-    {
685
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
686
-        EEH_Activation::delete_all_espresso_cpt_data();
687
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
688
-        // set the db state to something that will require migrations
689
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
690
-        $this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
691
-        $this->_redirect_after_action(
692
-            true,
693
-            esc_html__("Database", 'event_espresso'),
694
-            esc_html__("reset", 'event_espresso')
695
-        );
696
-    }
697
-
698
-
699
-    // none of the below group are currently used for Gateway Settings
700
-    protected function _add_screen_options()
701
-    {
702
-    }
703
-
704
-
705
-    protected function _add_feature_pointers()
706
-    {
707
-    }
708
-
709
-
710
-    public function admin_init()
711
-    {
712
-    }
713
-
714
-
715
-    public function admin_notices()
716
-    {
717
-    }
718
-
719
-
720
-    public function admin_footer_scripts()
721
-    {
722
-    }
723
-
724
-
725
-    public function load_scripts_styles()
726
-    {
727
-        wp_enqueue_script('ee_admin_js');
728
-        wp_enqueue_script(
729
-            'ee-maintenance',
730
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
731
-            ['jquery'],
732
-            EVENT_ESPRESSO_VERSION,
733
-            true
734
-        );
735
-        wp_register_style(
736
-            'espresso_maintenance',
737
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
738
-            [],
739
-            EVENT_ESPRESSO_VERSION
740
-        );
741
-        wp_enqueue_style('espresso_maintenance');
742
-        // localize script stuff
743
-        wp_localize_script(
744
-            'ee-maintenance',
745
-            'ee_maintenance',
746
-            [
747
-                'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
748
-                'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
749
-                'fatal_error'                      => wp_strip_all_tags(
750
-                    __(
751
-                        "A Fatal Error Has Occurred",
752
-                        "event_espresso"
753
-                    )
754
-                ),
755
-                'click_next_when_ready'            => wp_strip_all_tags(
756
-                    __(
757
-                        "The current Database Update has ended. Click 'next' when ready to proceed",
758
-                        "event_espresso"
759
-                    )
760
-                ),
761
-                'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
762
-                'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
763
-                'status_completed'                 => EE_Data_Migration_Manager::status_completed,
764
-                'confirm'                          => wp_strip_all_tags(
765
-                    __(
766
-                        'Are you sure you want to do this? It CANNOT be undone!',
767
-                        'event_espresso'
768
-                    )
769
-                ),
770
-                'confirm_skip_migration'           => wp_strip_all_tags(
771
-                    __(
772
-                        'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
773
-                        'event_espresso'
774
-                    )
775
-                ),
776
-            ]
777
-        );
778
-    }
779
-
780
-
781
-    public function load_scripts_styles_default()
782
-    {
783
-    }
784
-
785
-
786
-    /**
787
-     * Enqueue scripts and styles for the datetime tools page.
788
-     */
789
-    public function load_scripts_styles_datetime_tools()
790
-    {
791
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
792
-    }
793
-
794
-
795
-    /**
796
-     * @throws EE_Error
797
-     */
798
-    protected function _datetime_tools()
799
-    {
800
-        $form_action                                = EE_Admin_Page::add_query_args_and_nonce(
801
-            [
802
-                'action'        => 'run_datetime_offset_fix',
803
-                'return_action' => $this->_req_action,
804
-            ],
805
-            EE_MAINTENANCE_ADMIN_URL
806
-        );
807
-        $form                                       = $this->_get_datetime_offset_fix_form();
808
-        $this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
809
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
810
-                                                      . $form->get_html_and_js()
811
-                                                      . $form->form_close();
812
-        $this->display_admin_page_with_sidebar();
813
-    }
814
-
815
-
816
-    /**
817
-     * @throws EE_Error
818
-     */
819
-    protected function _get_datetime_offset_fix_form()
820
-    {
821
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
822
-            $this->datetime_fix_offset_form = new EE_Form_Section_Proper(
823
-                [
824
-                    'name'            => 'datetime_offset_fix_option',
825
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
826
-                    'subsections'     => [
827
-                        'title'                  => new EE_Form_Section_HTML(
828
-                            EEH_HTML::h2(
829
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
830
-                            )
831
-                        ),
832
-                        'explanation'            => new EE_Form_Section_HTML(
833
-                            EEH_HTML::p(
834
-                                esc_html__(
835
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
836
-                                    'event_espresso'
837
-                                )
838
-                            )
839
-                            . EEH_HTML::p(
840
-                                esc_html__(
841
-                                    '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.',
842
-                                    'event_espresso'
843
-                                )
844
-                            )
845
-                        ),
846
-                        'offset_input'           => new EE_Float_Input(
847
-                            [
848
-                                'html_name'       => 'offset_for_datetimes',
849
-                                'html_label_text' => esc_html__(
850
-                                    'Offset to apply (in hours):',
851
-                                    'event_espresso'
852
-                                ),
853
-                                'min_value'       => '-12',
854
-                                'max_value'       => '14',
855
-                                'step_value'      => '.25',
856
-                                'default'         => DatetimeOffsetFix::getOffset(),
857
-                            ]
858
-                        ),
859
-                        'date_range_explanation' => new EE_Form_Section_HTML(
860
-                            EEH_HTML::p(
861
-                                esc_html__(
862
-                                    '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.',
863
-                                    'event_espresso'
864
-                                )
865
-                            )
866
-                            . EEH_HTML::p(
867
-                                EEH_HTML::strong(
868
-                                    sprintf(
869
-                                        esc_html__(
870
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
871
-                                            'event_espresso'
872
-                                        ),
873
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
874
-                                        '</a>'
875
-                                    )
876
-                                )
877
-                            )
878
-                        ),
879
-                        'date_range_start_date'  => new EE_Datepicker_Input(
880
-                            [
881
-                                'html_name'       => 'offset_date_start_range',
882
-                                'html_label_text' => esc_html__(
883
-                                    'Start Date for dates the offset applied to:',
884
-                                    'event_espresso'
885
-                                ),
886
-                            ]
887
-                        ),
888
-                        'date_range_end_date'    => new EE_Datepicker_Input(
889
-                            [
890
-                                'html_name'       => 'offset_date_end_range',
891
-                                'html_label_text' => esc_html__(
892
-                                    'End Date for dates the offset is applied to:',
893
-                                    'event_espresso'
894
-                                ),
895
-                            ]
896
-                        ),
897
-                        'submit'                 => new EE_Submit_Input(
898
-                            [
899
-                                'html_label_text' => '',
900
-                                'default'         => esc_html__('Apply Offset', 'event_espresso'),
901
-                            ]
902
-                        ),
903
-                    ],
904
-                ]
905
-            );
906
-        }
907
-        return $this->datetime_fix_offset_form;
908
-    }
909
-
910
-
911
-    /**
912
-     * Callback for the run_datetime_offset_fix route.
913
-     *
914
-     * @throws EE_Error
915
-     */
916
-    protected function _apply_datetime_offset()
917
-    {
918
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
919
-            $form = $this->_get_datetime_offset_fix_form();
920
-            $form->receive_form_submission($this->_req_data);
921
-            if ($form->is_valid()) {
922
-                // save offset data so batch processor can get it.
923
-                DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
924
-                $utc_timezone          = new DateTimeZone('UTC');
925
-                $date_range_start_date = DateTime::createFromFormat(
926
-                    'm/d/Y H:i:s',
927
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
928
-                    $utc_timezone
929
-                );
930
-                $date_range_end_date   = DateTime::createFromFormat(
931
-                    'm/d/Y H:i:s',
932
-                    $form->get_input_value('date_range_end_date') . ' 23:59:59',
933
-                    $utc_timezone
934
-                );
935
-                if ($date_range_start_date instanceof DateTime) {
936
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
937
-                }
938
-                if ($date_range_end_date instanceof DateTime) {
939
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
940
-                }
941
-                // redirect to batch tool
942
-                wp_redirect(
943
-                    EE_Admin_Page::add_query_args_and_nonce(
944
-                        [
945
-                            'page'        => EED_Batch::PAGE_SLUG,
946
-                            'batch'       => EED_Batch::batch_job,
947
-                            'label'       => esc_html__('Applying Offset', 'event_espresso'),
948
-                            'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
949
-                            'return_url'  => urlencode(
950
-                                add_query_arg(
951
-                                    [
952
-                                        'action' => 'datetime_tools',
953
-                                    ],
954
-                                    EEH_URL::current_url_without_query_paramaters(
955
-                                        [
956
-                                            'return_action',
957
-                                            'run_datetime_offset_fix_nonce',
958
-                                            'return',
959
-                                            'datetime_tools_nonce',
960
-                                        ]
961
-                                    )
962
-                                )
963
-                            ),
964
-                        ],
965
-                        admin_url()
966
-                    )
967
-                );
968
-                exit;
969
-            }
970
-        }
971
-    }
17
+	/**
18
+	 * @var EE_Data_Migration_Manager
19
+	 */
20
+	protected $migration_manager;
21
+
22
+	/**
23
+	 * @var EE_Maintenance_Mode
24
+	 */
25
+	protected $maintenance_mode;
26
+
27
+	/**
28
+	 * @var EE_Form_Section_Proper
29
+	 */
30
+	protected $datetime_fix_offset_form;
31
+
32
+
33
+	/**
34
+	 * @param bool $routing
35
+	 * @throws EE_Error
36
+	 * @throws ReflectionException
37
+	 */
38
+	public function __construct($routing = true)
39
+	{
40
+		$this->migration_manager = EE_Data_Migration_Manager::instance();
41
+		$this->maintenance_mode  = EE_Maintenance_Mode::instance();
42
+		parent::__construct($routing);
43
+	}
44
+
45
+
46
+	protected function _init_page_props()
47
+	{
48
+		$this->page_slug        = EE_MAINTENANCE_PG_SLUG;
49
+		$this->page_label       = EE_MAINTENANCE_LABEL;
50
+		$this->_admin_base_url  = EE_MAINTENANCE_ADMIN_URL;
51
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
52
+	}
53
+
54
+
55
+	protected function _ajax_hooks()
56
+	{
57
+		add_action('wp_ajax_migration_step', [$this, 'migration_step']);
58
+		add_action('wp_ajax_add_error_to_migrations_ran', [$this, 'add_error_to_migrations_ran']);
59
+	}
60
+
61
+
62
+	protected function _define_page_props()
63
+	{
64
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
65
+		$this->_labels           = [
66
+			'buttons' => [
67
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
68
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
69
+			],
70
+		];
71
+	}
72
+
73
+
74
+	protected function _set_page_routes()
75
+	{
76
+		$this->_page_routes = [
77
+			'default'                             => [
78
+				'func'       => '_maintenance',
79
+				'capability' => 'manage_options',
80
+			],
81
+			'change_maintenance_level'            => [
82
+				'func'       => '_change_maintenance_level',
83
+				'capability' => 'manage_options',
84
+				'noheader'   => true,
85
+			],
86
+			'system_status'                       => [
87
+				'func'       => '_system_status',
88
+				'capability' => 'manage_options',
89
+			],
90
+			'download_system_status'              => [
91
+				'func'       => '_download_system_status',
92
+				'capability' => 'manage_options',
93
+				'noheader'   => true,
94
+			],
95
+			'send_migration_crash_report'         => [
96
+				'func'       => '_send_migration_crash_report',
97
+				'capability' => 'manage_options',
98
+				'noheader'   => true,
99
+			],
100
+			'confirm_migration_crash_report_sent' => [
101
+				'func'       => '_confirm_migration_crash_report_sent',
102
+				'capability' => 'manage_options',
103
+			],
104
+			'data_reset'                          => [
105
+				'func'       => '_data_reset_and_delete',
106
+				'capability' => 'manage_options',
107
+			],
108
+			'reset_db'                            => [
109
+				'func'       => '_reset_db',
110
+				'capability' => 'manage_options',
111
+				'noheader'   => true,
112
+				'args'       => ['nuke_old_ee4_data' => true],
113
+			],
114
+			'start_with_fresh_ee4_db'             => [
115
+				'func'       => '_reset_db',
116
+				'capability' => 'manage_options',
117
+				'noheader'   => true,
118
+				'args'       => ['nuke_old_ee4_data' => false],
119
+			],
120
+			'delete_db'                           => [
121
+				'func'       => '_delete_db',
122
+				'capability' => 'manage_options',
123
+				'noheader'   => true,
124
+			],
125
+			'rerun_migration_from_ee3'            => [
126
+				'func'       => '_rerun_migration_from_ee3',
127
+				'capability' => 'manage_options',
128
+				'noheader'   => true,
129
+			],
130
+			'reset_reservations'                  => [
131
+				'func'       => '_reset_reservations',
132
+				'capability' => 'manage_options',
133
+				'noheader'   => true,
134
+			],
135
+			'reset_capabilities'                  => [
136
+				'func'       => '_reset_capabilities',
137
+				'capability' => 'manage_options',
138
+				'noheader'   => true,
139
+			],
140
+			'reattempt_migration'                 => [
141
+				'func'       => '_reattempt_migration',
142
+				'capability' => 'manage_options',
143
+				'noheader'   => true,
144
+			],
145
+			'datetime_tools'                      => [
146
+				'func'       => '_datetime_tools',
147
+				'capability' => 'manage_options',
148
+			],
149
+			'run_datetime_offset_fix'             => [
150
+				'func'               => '_apply_datetime_offset',
151
+				'noheader'           => true,
152
+				'headers_sent_route' => 'datetime_tools',
153
+				'capability'         => 'manage_options',
154
+			],
155
+		];
156
+	}
157
+
158
+
159
+	protected function _set_page_config()
160
+	{
161
+		$this->_page_config = [
162
+			'default'        => [
163
+				'nav'           => [
164
+					'label' => esc_html__('Maintenance', 'event_espresso'),
165
+					'icon'  => 'dashicons-admin-tools',
166
+					'order' => 10,
167
+				],
168
+				'require_nonce' => false,
169
+			],
170
+			'data_reset'     => [
171
+				'nav'           => [
172
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
173
+					'icon'  => 'dashicons-trash',
174
+					'order' => 20,
175
+				],
176
+				'require_nonce' => false,
177
+			],
178
+			'datetime_tools' => [
179
+				'nav'           => [
180
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
181
+					'icon'  => 'dashicons-calendar-alt',
182
+					'order' => 25,
183
+				],
184
+				'require_nonce' => false,
185
+			],
186
+			'system_status'  => [
187
+				'nav'           => [
188
+					'label' => esc_html__("System Information", "event_espresso"),
189
+					'icon'  => 'dashicons-info',
190
+					'order' => 30,
191
+				],
192
+				'require_nonce' => false,
193
+			],
194
+		];
195
+	}
196
+
197
+
198
+	/**
199
+	 * default maintenance page.
200
+	 * If we're in maintenance mode level 2, then we need to show the migration scripts and all that UI.
201
+	 *
202
+	 * @throws EE_Error
203
+	 */
204
+	public function _maintenance()
205
+	{
206
+		$show_maintenance_switch         = true;
207
+		$show_backup_db_text             = false;
208
+		$show_migration_progress         = false;
209
+		$script_names                    = [];
210
+		$addons_should_be_upgraded_first = false;
211
+		// it all depends on if we're in maintenance model level 1 (frontend-only) or
212
+		// level 2 (everything except maintenance page)
213
+		try {
214
+			// get the current maintenance level and check if
215
+			// we are removed
216
+			$mMode_level  = $this->maintenance_mode->level();
217
+			$placed_in_mm = $this->maintenance_mode->set_maintenance_mode_if_db_old();
218
+			if ($mMode_level == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
219
+				// we just took the site out of maintenance mode, so notify the user.
220
+				// unfortunately this message appears to be echoed on the NEXT page load...
221
+				// oh well, we should really be checking for this on addon deactivation anyways
222
+				EE_Error::add_attention(
223
+					esc_html__(
224
+						'Site taken out of maintenance mode because no data migration scripts are required',
225
+						'event_espresso'
226
+					)
227
+				);
228
+				$this->_process_notices(['page' => 'espresso_maintenance_settings']);
229
+			}
230
+			// in case an exception is thrown while trying to handle migrations
231
+			if ($mMode_level === EE_Maintenance_Mode::level_2_complete_maintenance) {
232
+				$show_maintenance_switch = false;
233
+				$show_migration_progress = true;
234
+				if (isset($this->_req_data['continue_migration'])) {
235
+					$show_backup_db_text = false;
236
+				} else {
237
+					$show_backup_db_text = true;
238
+				}
239
+				$scripts_needing_to_run          =
240
+					$this->migration_manager->check_for_applicable_data_migration_scripts();
241
+				$addons_should_be_upgraded_first = $this->migration_manager->addons_need_updating();
242
+				$script_names                    = [];
243
+				$current_script                  = null;
244
+				foreach ($scripts_needing_to_run as $script) {
245
+					if ($script instanceof EE_Data_Migration_Script_Base) {
246
+						if (! $current_script) {
247
+							$current_script = $script;
248
+							$current_script->migration_page_hooks();
249
+						}
250
+						$script_names[] = $script->pretty_name();
251
+					}
252
+				}
253
+			}
254
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
255
+			$exception_thrown      = false;
256
+		} catch (EE_Error $e) {
257
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
258
+			// now, just so we can display the page correctly, make an error migration script stage object
259
+			// and also put the error on it. It only persists for the duration of this request
260
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
261
+			$most_recent_migration->add_error($e->getMessage());
262
+			$exception_thrown = true;
263
+		}
264
+		$current_db_state = $this->migration_manager->ensure_current_database_state_is_set();
265
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
266
+		if (
267
+			$exception_thrown
268
+			|| (
269
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
270
+				&& $most_recent_migration->is_broken()
271
+			)
272
+		) {
273
+			$this->_template_path                =
274
+				EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
275
+			$this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
276
+			$this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
277
+				[
278
+					'action'  => 'confirm_migration_crash_report_sent',
279
+					'success' => '0',
280
+				],
281
+				EE_MAINTENANCE_ADMIN_URL
282
+			);
283
+		} elseif ($addons_should_be_upgraded_first) {
284
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
285
+		} else {
286
+			if (
287
+				$most_recent_migration instanceof EE_Data_Migration_Script_Base
288
+				&& $most_recent_migration->can_continue()
289
+			) {
290
+				$show_backup_db_text                    = false;
291
+				$show_continue_current_migration_script = true;
292
+				$show_most_recent_migration             = true;
293
+			} elseif (isset($this->_req_data['continue_migration'])) {
294
+				$show_most_recent_migration             = true;
295
+				$show_continue_current_migration_script = false;
296
+			} else {
297
+				$show_most_recent_migration             = false;
298
+				$show_continue_current_migration_script = false;
299
+			}
300
+			if (isset($current_script)) {
301
+				$migrates_to          = $current_script->migrates_to_version();
302
+				$plugin_slug          = $migrates_to['slug'];
303
+				$new_version          = $migrates_to['version'];
304
+				$this->_template_args = array_merge(
305
+					$this->_template_args,
306
+					[
307
+						'current_db_state' => sprintf(
308
+							esc_html__("EE%s (%s)", "event_espresso"),
309
+							isset($current_db_state[ $plugin_slug ]) ? $current_db_state[ $plugin_slug ] : 3,
310
+							$plugin_slug
311
+						),
312
+						'next_db_state'    => sprintf(
313
+							esc_html__("EE%s (%s)", 'event_espresso'),
314
+							$new_version,
315
+							$plugin_slug
316
+						),
317
+					]
318
+				);
319
+			} else {
320
+				$this->_template_args['current_db_state'] = null;
321
+				$this->_template_args['next_db_state']    = null;
322
+			}
323
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
324
+			$this->_template_args = array_merge(
325
+				$this->_template_args,
326
+				[
327
+					'show_most_recent_migration'             => $show_most_recent_migration,
328
+					// flag for showing the most recent migration's status and/or errors
329
+					'show_migration_progress'                => $show_migration_progress,
330
+					// flag for showing the option to run migrations and see their progress
331
+					'show_backup_db_text'                    => $show_backup_db_text,
332
+					// flag for showing text telling the user to back up their DB
333
+					'show_maintenance_switch'                => $show_maintenance_switch,
334
+					// flag for showing the option to change maintenance mode between levels 0 and 1
335
+					'script_names'                           => $script_names,
336
+					// array of names of scripts that have run
337
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
338
+					// flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
339
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(
340
+						['action' => 'reset_db'],
341
+						EE_MAINTENANCE_ADMIN_URL
342
+					),
343
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(
344
+						['action' => 'data_reset'],
345
+						EE_MAINTENANCE_ADMIN_URL
346
+					),
347
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(
348
+						['action' => 'change_maintenance_level'],
349
+						EE_MAINTENANCE_ADMIN_URL
350
+					),
351
+					'ultimate_db_state'                      => sprintf(
352
+						esc_html__("EE%s", 'event_espresso'),
353
+						espresso_version()
354
+					),
355
+				]
356
+			);
357
+		}
358
+		$this->_template_args['most_recent_migration'] =
359
+			$most_recent_migration;// the actual most recently ran migration
360
+		// now render the migration options part, and put it in a variable
361
+		$migration_options_template_file                = apply_filters(
362
+			'FHEE__ee_migration_page__migration_options_template',
363
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
364
+		);
365
+		$migration_options_html                         = EEH_Template::display_template(
366
+			$migration_options_template_file,
367
+			$this->_template_args,
368
+			true
369
+		);
370
+		$this->_template_args['migration_options_html'] = $migration_options_html;
371
+		$this->_template_args['admin_page_content']     = EEH_Template::display_template(
372
+			$this->_template_path,
373
+			$this->_template_args,
374
+			true
375
+		);
376
+		$this->display_admin_page_with_sidebar();
377
+	}
378
+
379
+
380
+	/**
381
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
382
+	 *
383
+	 * @throws EE_Error
384
+	 */
385
+	public function migration_step()
386
+	{
387
+		$this->_template_args['data'] = $this->migration_manager->response_to_migration_ajax_request();
388
+		$this->_return_json();
389
+	}
390
+
391
+
392
+	/**
393
+	 * Can be used by js when it notices a response with HTML in it in order
394
+	 * to log the malformed response
395
+	 *
396
+	 * @throws EE_Error
397
+	 */
398
+	public function add_error_to_migrations_ran()
399
+	{
400
+		$this->migration_manager->add_error_to_migrations_ran($this->_req_data['message']);
401
+		$this->_template_args['data'] = ['ok' => true];
402
+		$this->_return_json();
403
+	}
404
+
405
+
406
+	/**
407
+	 * changes the maintenance level, provided there are still no migration scripts that should run
408
+	 *
409
+	 * @throws EE_Error
410
+	 */
411
+	public function _change_maintenance_level()
412
+	{
413
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
414
+		if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
415
+			$this->maintenance_mode->set_maintenance_level($new_level);
416
+			$success = true;
417
+		} else {
418
+			$this->maintenance_mode->set_maintenance_mode_if_db_old();
419
+			$success = false;
420
+		}
421
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
422
+	}
423
+
424
+
425
+	/**
426
+	 * a tab with options for resetting and/or deleting EE data
427
+	 *
428
+	 * @throws EE_Error
429
+	 * @throws DomainException
430
+	 */
431
+	public function _data_reset_and_delete()
432
+	{
433
+		$this->_template_path                              =
434
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
435
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
436
+			'reset_reservations',
437
+			'reset_reservations',
438
+			[],
439
+			'button button--caution ee-confirm'
440
+		);
441
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
442
+			'reset_capabilities',
443
+			'reset_capabilities',
444
+			[],
445
+			'button button--caution ee-confirm'
446
+		);
447
+		$this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
448
+			['action' => 'delete_db'],
449
+			EE_MAINTENANCE_ADMIN_URL
450
+		);
451
+		$this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
452
+			['action' => 'reset_db'],
453
+			EE_MAINTENANCE_ADMIN_URL
454
+		);
455
+		$this->_template_args['admin_page_content']        = EEH_Template::display_template(
456
+			$this->_template_path,
457
+			$this->_template_args,
458
+			true
459
+		);
460
+		$this->display_admin_page_with_no_sidebar();
461
+	}
462
+
463
+
464
+	/**
465
+	 * @throws EE_Error
466
+	 * @throws ReflectionException
467
+	 */
468
+	protected function _reset_reservations()
469
+	{
470
+		if (EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
471
+			EE_Error::add_success(
472
+				esc_html__(
473
+					'Ticket and datetime reserved counts have been successfully reset.',
474
+					'event_espresso'
475
+				)
476
+			);
477
+		} else {
478
+			EE_Error::add_success(
479
+				esc_html__(
480
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
481
+					'event_espresso'
482
+				)
483
+			);
484
+		}
485
+		$this->_redirect_after_action(true, '', '', ['action' => 'data_reset'], true);
486
+	}
487
+
488
+
489
+	/**
490
+	 * @throws EE_Error
491
+	 */
492
+	protected function _reset_capabilities()
493
+	{
494
+		$this->capabilities->init_caps(true);
495
+		EE_Error::add_success(
496
+			esc_html__(
497
+				'Default Event Espresso capabilities have been restored for all current roles.',
498
+				'event_espresso'
499
+			)
500
+		);
501
+		$this->_redirect_after_action(false, '', '', ['action' => 'data_reset'], true);
502
+	}
503
+
504
+
505
+	/**
506
+	 * resets the DMSs, so we can attempt to continue migrating after a fatal error
507
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
508
+	 * the fatal error in teh first place)
509
+	 *
510
+	 * @throws EE_Error
511
+	 */
512
+	protected function _reattempt_migration()
513
+	{
514
+		$this->migration_manager->reattempt();
515
+		$this->_redirect_after_action(false, '', '', ['action' => 'default'], true);
516
+	}
517
+
518
+
519
+	/**
520
+	 * shows the big ol' System Information page
521
+	 *
522
+	 * @throws EE_Error
523
+	 */
524
+	public function _system_status()
525
+	{
526
+		$this->_template_path                               =
527
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
528
+		$this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
529
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
530
+			[
531
+				'action' => 'download_system_status',
532
+			],
533
+			EE_MAINTENANCE_ADMIN_URL
534
+		);
535
+		$this->_template_args['admin_page_content']         = EEH_Template::display_template(
536
+			$this->_template_path,
537
+			$this->_template_args,
538
+			true
539
+		);
540
+		$this->display_admin_page_with_no_sidebar();
541
+	}
542
+
543
+
544
+	/**
545
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
546
+	 */
547
+	public function _download_system_status()
548
+	{
549
+		$status_info = EEM_System_Status::instance()->get_system_stati();
550
+		header('Content-Disposition: attachment');
551
+		header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
552
+		$output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
553
+		$output .= '<h1>' . sprintf(
554
+				__('System Information for %1$s', 'event_espresso'),
555
+				esc_url_raw(site_url())
556
+			) . '</h1>';
557
+		$output .= EEH_Template::layout_array_as_table($status_info);
558
+		echo esc_html($output);
559
+		die;
560
+	}
561
+
562
+
563
+	/**
564
+	 * @throws EE_Error
565
+	 */
566
+	public function _send_migration_crash_report()
567
+	{
568
+		$from      = $this->_req_data['from'];
569
+		$from_name = $this->_req_data['from_name'];
570
+		$body      = $this->_req_data['body'];
571
+		try {
572
+			$success = wp_mail(
573
+				EE_SUPPORT_EMAIL,
574
+				'Migration Crash Report',
575
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
576
+				[
577
+					"from:$from_name<$from>",
578
+				]
579
+			);
580
+		} catch (Exception $e) {
581
+			$success = false;
582
+		}
583
+		$this->_redirect_after_action(
584
+			$success,
585
+			esc_html__("Migration Crash Report", "event_espresso"),
586
+			esc_html__("sent", "event_espresso"),
587
+			['success' => $success, 'action' => 'confirm_migration_crash_report_sent']
588
+		);
589
+	}
590
+
591
+
592
+	/**
593
+	 * @throws EE_Error
594
+	 */
595
+	public function _confirm_migration_crash_report_sent()
596
+	{
597
+		try {
598
+			$most_recent_migration = $this->migration_manager->get_last_ran_script(true);
599
+		} catch (EE_Error $e) {
600
+			$this->migration_manager->add_error_to_migrations_ran($e->getMessage());
601
+			// now, just so we can display the page correctly, make an error migration script stage object
602
+			// and also put the error on it. It only persists for the duration of this request
603
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
604
+			$most_recent_migration->add_error($e->getMessage());
605
+		}
606
+		$success                                       = $this->_req_data['success'] === '1';
607
+		$this->_template_args['success']               = $success;
608
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
609
+		$this->_template_args['reset_db_action_url']   = EE_Admin_Page::add_query_args_and_nonce(
610
+			['action' => 'reset_db'],
611
+			EE_MAINTENANCE_ADMIN_URL
612
+		);
613
+		$this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
614
+			['action' => 'data_reset'],
615
+			EE_MAINTENANCE_ADMIN_URL
616
+		);
617
+		$this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
618
+			['action' => 'reattempt_migration'],
619
+			EE_MAINTENANCE_ADMIN_URL
620
+		);
621
+		$this->_template_path                          =
622
+			EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
623
+		$this->_template_args['admin_page_content']    = EEH_Template::display_template(
624
+			$this->_template_path,
625
+			$this->_template_args,
626
+			true
627
+		);
628
+		$this->display_admin_page_with_sidebar();
629
+	}
630
+
631
+
632
+	/**
633
+	 * Resets the entire EE4 database.
634
+	 * only sets up ee4 database for a fresh install-
635
+	 * doesn't actually clean out the old wp options, or cpts
636
+	 * (although it does erase old ee table data)
637
+	 *
638
+	 * @param boolean $nuke_old_ee4_data controls whether we destroy the old ee4 data,
639
+	 *                                   or just try initializing ee4 default data
640
+	 * @throws EE_Error
641
+	 * @throws ReflectionException
642
+	 */
643
+	public function _reset_db($nuke_old_ee4_data = true)
644
+	{
645
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
646
+		if ($nuke_old_ee4_data) {
647
+			EEH_Activation::delete_all_espresso_cpt_data();
648
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
649
+			EEH_Activation::remove_cron_tasks();
650
+		}
651
+		// make sure when we reset the registry's config that it
652
+		// switches to using the new singleton
653
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
654
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
655
+		EE_System::instance()->redirect_to_about_ee();
656
+	}
657
+
658
+
659
+	/**
660
+	 * Deletes ALL EE tables, Records, and Options from the database.
661
+	 *
662
+	 * @throws EE_Error
663
+	 * @throws ReflectionException
664
+	 */
665
+	public function _delete_db()
666
+	{
667
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
668
+		EEH_Activation::delete_all_espresso_cpt_data();
669
+		EEH_Activation::delete_all_espresso_tables_and_data();
670
+		EEH_Activation::remove_cron_tasks();
671
+		EEH_Activation::deactivate_event_espresso();
672
+		wp_safe_redirect(admin_url('plugins.php'));
673
+		exit;
674
+	}
675
+
676
+
677
+	/**
678
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
679
+	 *
680
+	 * @throws EE_Error
681
+	 * @throws ReflectionException
682
+	 */
683
+	public function _rerun_migration_from_ee3()
684
+	{
685
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
686
+		EEH_Activation::delete_all_espresso_cpt_data();
687
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
688
+		// set the db state to something that will require migrations
689
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
690
+		$this->maintenance_mode->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
691
+		$this->_redirect_after_action(
692
+			true,
693
+			esc_html__("Database", 'event_espresso'),
694
+			esc_html__("reset", 'event_espresso')
695
+		);
696
+	}
697
+
698
+
699
+	// none of the below group are currently used for Gateway Settings
700
+	protected function _add_screen_options()
701
+	{
702
+	}
703
+
704
+
705
+	protected function _add_feature_pointers()
706
+	{
707
+	}
708
+
709
+
710
+	public function admin_init()
711
+	{
712
+	}
713
+
714
+
715
+	public function admin_notices()
716
+	{
717
+	}
718
+
719
+
720
+	public function admin_footer_scripts()
721
+	{
722
+	}
723
+
724
+
725
+	public function load_scripts_styles()
726
+	{
727
+		wp_enqueue_script('ee_admin_js');
728
+		wp_enqueue_script(
729
+			'ee-maintenance',
730
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
731
+			['jquery'],
732
+			EVENT_ESPRESSO_VERSION,
733
+			true
734
+		);
735
+		wp_register_style(
736
+			'espresso_maintenance',
737
+			EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
738
+			[],
739
+			EVENT_ESPRESSO_VERSION
740
+		);
741
+		wp_enqueue_style('espresso_maintenance');
742
+		// localize script stuff
743
+		wp_localize_script(
744
+			'ee-maintenance',
745
+			'ee_maintenance',
746
+			[
747
+				'migrating'                        => wp_strip_all_tags(__("Updating Database...", "event_espresso")),
748
+				'next'                             => wp_strip_all_tags(__("Next", "event_espresso")),
749
+				'fatal_error'                      => wp_strip_all_tags(
750
+					__(
751
+						"A Fatal Error Has Occurred",
752
+						"event_espresso"
753
+					)
754
+				),
755
+				'click_next_when_ready'            => wp_strip_all_tags(
756
+					__(
757
+						"The current Database Update has ended. Click 'next' when ready to proceed",
758
+						"event_espresso"
759
+					)
760
+				),
761
+				'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
762
+				'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
763
+				'status_completed'                 => EE_Data_Migration_Manager::status_completed,
764
+				'confirm'                          => wp_strip_all_tags(
765
+					__(
766
+						'Are you sure you want to do this? It CANNOT be undone!',
767
+						'event_espresso'
768
+					)
769
+				),
770
+				'confirm_skip_migration'           => wp_strip_all_tags(
771
+					__(
772
+						'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
773
+						'event_espresso'
774
+					)
775
+				),
776
+			]
777
+		);
778
+	}
779
+
780
+
781
+	public function load_scripts_styles_default()
782
+	{
783
+	}
784
+
785
+
786
+	/**
787
+	 * Enqueue scripts and styles for the datetime tools page.
788
+	 */
789
+	public function load_scripts_styles_datetime_tools()
790
+	{
791
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
792
+	}
793
+
794
+
795
+	/**
796
+	 * @throws EE_Error
797
+	 */
798
+	protected function _datetime_tools()
799
+	{
800
+		$form_action                                = EE_Admin_Page::add_query_args_and_nonce(
801
+			[
802
+				'action'        => 'run_datetime_offset_fix',
803
+				'return_action' => $this->_req_action,
804
+			],
805
+			EE_MAINTENANCE_ADMIN_URL
806
+		);
807
+		$form                                       = $this->_get_datetime_offset_fix_form();
808
+		$this->_admin_page_title                    = esc_html__('Datetime Utilities', 'event_espresso');
809
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
810
+													  . $form->get_html_and_js()
811
+													  . $form->form_close();
812
+		$this->display_admin_page_with_sidebar();
813
+	}
814
+
815
+
816
+	/**
817
+	 * @throws EE_Error
818
+	 */
819
+	protected function _get_datetime_offset_fix_form()
820
+	{
821
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
822
+			$this->datetime_fix_offset_form = new EE_Form_Section_Proper(
823
+				[
824
+					'name'            => 'datetime_offset_fix_option',
825
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
826
+					'subsections'     => [
827
+						'title'                  => new EE_Form_Section_HTML(
828
+							EEH_HTML::h2(
829
+								esc_html__('Datetime Offset Tool', 'event_espresso')
830
+							)
831
+						),
832
+						'explanation'            => new EE_Form_Section_HTML(
833
+							EEH_HTML::p(
834
+								esc_html__(
835
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
836
+									'event_espresso'
837
+								)
838
+							)
839
+							. EEH_HTML::p(
840
+								esc_html__(
841
+									'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.',
842
+									'event_espresso'
843
+								)
844
+							)
845
+						),
846
+						'offset_input'           => new EE_Float_Input(
847
+							[
848
+								'html_name'       => 'offset_for_datetimes',
849
+								'html_label_text' => esc_html__(
850
+									'Offset to apply (in hours):',
851
+									'event_espresso'
852
+								),
853
+								'min_value'       => '-12',
854
+								'max_value'       => '14',
855
+								'step_value'      => '.25',
856
+								'default'         => DatetimeOffsetFix::getOffset(),
857
+							]
858
+						),
859
+						'date_range_explanation' => new EE_Form_Section_HTML(
860
+							EEH_HTML::p(
861
+								esc_html__(
862
+									'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.',
863
+									'event_espresso'
864
+								)
865
+							)
866
+							. EEH_HTML::p(
867
+								EEH_HTML::strong(
868
+									sprintf(
869
+										esc_html__(
870
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
871
+											'event_espresso'
872
+										),
873
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
874
+										'</a>'
875
+									)
876
+								)
877
+							)
878
+						),
879
+						'date_range_start_date'  => new EE_Datepicker_Input(
880
+							[
881
+								'html_name'       => 'offset_date_start_range',
882
+								'html_label_text' => esc_html__(
883
+									'Start Date for dates the offset applied to:',
884
+									'event_espresso'
885
+								),
886
+							]
887
+						),
888
+						'date_range_end_date'    => new EE_Datepicker_Input(
889
+							[
890
+								'html_name'       => 'offset_date_end_range',
891
+								'html_label_text' => esc_html__(
892
+									'End Date for dates the offset is applied to:',
893
+									'event_espresso'
894
+								),
895
+							]
896
+						),
897
+						'submit'                 => new EE_Submit_Input(
898
+							[
899
+								'html_label_text' => '',
900
+								'default'         => esc_html__('Apply Offset', 'event_espresso'),
901
+							]
902
+						),
903
+					],
904
+				]
905
+			);
906
+		}
907
+		return $this->datetime_fix_offset_form;
908
+	}
909
+
910
+
911
+	/**
912
+	 * Callback for the run_datetime_offset_fix route.
913
+	 *
914
+	 * @throws EE_Error
915
+	 */
916
+	protected function _apply_datetime_offset()
917
+	{
918
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
919
+			$form = $this->_get_datetime_offset_fix_form();
920
+			$form->receive_form_submission($this->_req_data);
921
+			if ($form->is_valid()) {
922
+				// save offset data so batch processor can get it.
923
+				DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
924
+				$utc_timezone          = new DateTimeZone('UTC');
925
+				$date_range_start_date = DateTime::createFromFormat(
926
+					'm/d/Y H:i:s',
927
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
928
+					$utc_timezone
929
+				);
930
+				$date_range_end_date   = DateTime::createFromFormat(
931
+					'm/d/Y H:i:s',
932
+					$form->get_input_value('date_range_end_date') . ' 23:59:59',
933
+					$utc_timezone
934
+				);
935
+				if ($date_range_start_date instanceof DateTime) {
936
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
937
+				}
938
+				if ($date_range_end_date instanceof DateTime) {
939
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
940
+				}
941
+				// redirect to batch tool
942
+				wp_redirect(
943
+					EE_Admin_Page::add_query_args_and_nonce(
944
+						[
945
+							'page'        => EED_Batch::PAGE_SLUG,
946
+							'batch'       => EED_Batch::batch_job,
947
+							'label'       => esc_html__('Applying Offset', 'event_espresso'),
948
+							'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
949
+							'return_url'  => urlencode(
950
+								add_query_arg(
951
+									[
952
+										'action' => 'datetime_tools',
953
+									],
954
+									EEH_URL::current_url_without_query_paramaters(
955
+										[
956
+											'return_action',
957
+											'run_datetime_offset_fix_nonce',
958
+											'return',
959
+											'datetime_tools_nonce',
960
+										]
961
+									)
962
+								)
963
+							),
964
+						],
965
+						admin_url()
966
+					)
967
+				);
968
+				exit;
969
+			}
970
+		}
971
+	}
972 972
 }
Please login to merge, or discard this patch.
Spacing   +30 added lines, -30 removed lines patch added patch discarded remove patch
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
                 $current_script                  = null;
244 244
                 foreach ($scripts_needing_to_run as $script) {
245 245
                     if ($script instanceof EE_Data_Migration_Script_Base) {
246
-                        if (! $current_script) {
246
+                        if ( ! $current_script) {
247 247
                             $current_script = $script;
248 248
                             $current_script->migration_page_hooks();
249 249
                         }
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
             )
272 272
         ) {
273 273
             $this->_template_path                =
274
-                EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
274
+                EE_MAINTENANCE_TEMPLATE_PATH.'ee_migration_was_borked_page.template.php';
275 275
             $this->_template_args['support_url'] = 'https://eventespresso.com/support/forums/';
276 276
             $this->_template_args['next_url']    = EEH_URL::add_query_args_and_nonce(
277 277
                 [
@@ -281,7 +281,7 @@  discard block
 block discarded – undo
281 281
                 EE_MAINTENANCE_ADMIN_URL
282 282
             );
283 283
         } elseif ($addons_should_be_upgraded_first) {
284
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
284
+            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_upgrade_addons_before_migrating.template.php';
285 285
         } else {
286 286
             if (
287 287
                 $most_recent_migration instanceof EE_Data_Migration_Script_Base
@@ -306,7 +306,7 @@  discard block
 block discarded – undo
306 306
                     [
307 307
                         'current_db_state' => sprintf(
308 308
                             esc_html__("EE%s (%s)", "event_espresso"),
309
-                            isset($current_db_state[ $plugin_slug ]) ? $current_db_state[ $plugin_slug ] : 3,
309
+                            isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3,
310 310
                             $plugin_slug
311 311
                         ),
312 312
                         'next_db_state'    => sprintf(
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
                 $this->_template_args['current_db_state'] = null;
321 321
                 $this->_template_args['next_db_state']    = null;
322 322
             }
323
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
323
+            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH.'ee_migration_page.template.php';
324 324
             $this->_template_args = array_merge(
325 325
                 $this->_template_args,
326 326
                 [
@@ -356,13 +356,13 @@  discard block
 block discarded – undo
356 356
             );
357 357
         }
358 358
         $this->_template_args['most_recent_migration'] =
359
-            $most_recent_migration;// the actual most recently ran migration
359
+            $most_recent_migration; // the actual most recently ran migration
360 360
         // now render the migration options part, and put it in a variable
361
-        $migration_options_template_file                = apply_filters(
361
+        $migration_options_template_file = apply_filters(
362 362
             'FHEE__ee_migration_page__migration_options_template',
363
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
363
+            EE_MAINTENANCE_TEMPLATE_PATH.'migration_options_from_ee4.template.php'
364 364
         );
365
-        $migration_options_html                         = EEH_Template::display_template(
365
+        $migration_options_html = EEH_Template::display_template(
366 366
             $migration_options_template_file,
367 367
             $this->_template_args,
368 368
             true
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
     public function _change_maintenance_level()
412 412
     {
413 413
         $new_level = absint($this->_req_data['maintenance_mode_level']);
414
-        if (! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
414
+        if ( ! $this->migration_manager->check_for_applicable_data_migration_scripts()) {
415 415
             $this->maintenance_mode->set_maintenance_level($new_level);
416 416
             $success = true;
417 417
         } else {
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
     public function _data_reset_and_delete()
432 432
     {
433 433
         $this->_template_path                              =
434
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
434
+            EE_MAINTENANCE_TEMPLATE_PATH.'ee_data_reset_and_delete.template.php';
435 435
         $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
436 436
             'reset_reservations',
437 437
             'reset_reservations',
@@ -444,15 +444,15 @@  discard block
 block discarded – undo
444 444
             [],
445 445
             'button button--caution ee-confirm'
446 446
         );
447
-        $this->_template_args['delete_db_url']             = EE_Admin_Page::add_query_args_and_nonce(
447
+        $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
448 448
             ['action' => 'delete_db'],
449 449
             EE_MAINTENANCE_ADMIN_URL
450 450
         );
451
-        $this->_template_args['reset_db_url']              = EE_Admin_Page::add_query_args_and_nonce(
451
+        $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
452 452
             ['action' => 'reset_db'],
453 453
             EE_MAINTENANCE_ADMIN_URL
454 454
         );
455
-        $this->_template_args['admin_page_content']        = EEH_Template::display_template(
455
+        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
456 456
             $this->_template_path,
457 457
             $this->_template_args,
458 458
             true
@@ -524,7 +524,7 @@  discard block
 block discarded – undo
524 524
     public function _system_status()
525 525
     {
526 526
         $this->_template_path                               =
527
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
527
+            EE_MAINTENANCE_TEMPLATE_PATH.'ee_system_stati_page.template.php';
528 528
         $this->_template_args['system_stati']               = EEM_System_Status::instance()->get_system_stati();
529 529
         $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
530 530
             [
@@ -532,7 +532,7 @@  discard block
 block discarded – undo
532 532
             ],
533 533
             EE_MAINTENANCE_ADMIN_URL
534 534
         );
535
-        $this->_template_args['admin_page_content']         = EEH_Template::display_template(
535
+        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
536 536
             $this->_template_path,
537 537
             $this->_template_args,
538 538
             true
@@ -548,12 +548,12 @@  discard block
 block discarded – undo
548 548
     {
549 549
         $status_info = EEM_System_Status::instance()->get_system_stati();
550 550
         header('Content-Disposition: attachment');
551
-        header("Content-Disposition: attachment; filename=system_status_" . sanitize_key(site_url()) . ".html");
551
+        header("Content-Disposition: attachment; filename=system_status_".sanitize_key(site_url()).".html");
552 552
         $output = '<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>';
553
-        $output .= '<h1>' . sprintf(
553
+        $output .= '<h1>'.sprintf(
554 554
                 __('System Information for %1$s', 'event_espresso'),
555 555
                 esc_url_raw(site_url())
556
-            ) . '</h1>';
556
+            ).'</h1>';
557 557
         $output .= EEH_Template::layout_array_as_table($status_info);
558 558
         echo esc_html($output);
559 559
         die;
@@ -572,7 +572,7 @@  discard block
 block discarded – undo
572 572
             $success = wp_mail(
573 573
                 EE_SUPPORT_EMAIL,
574 574
                 'Migration Crash Report',
575
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
575
+                $body."/r/n<br>".print_r(EEM_System_Status::instance()->get_system_stati(), true),
576 576
                 [
577 577
                     "from:$from_name<$from>",
578 578
                 ]
@@ -610,16 +610,16 @@  discard block
 block discarded – undo
610 610
             ['action' => 'reset_db'],
611 611
             EE_MAINTENANCE_ADMIN_URL
612 612
         );
613
-        $this->_template_args['reset_db_page_url']     = EE_Admin_Page::add_query_args_and_nonce(
613
+        $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(
614 614
             ['action' => 'data_reset'],
615 615
             EE_MAINTENANCE_ADMIN_URL
616 616
         );
617
-        $this->_template_args['reattempt_action_url']  = EE_Admin_Page::add_query_args_and_nonce(
617
+        $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(
618 618
             ['action' => 'reattempt_migration'],
619 619
             EE_MAINTENANCE_ADMIN_URL
620 620
         );
621 621
         $this->_template_path                          =
622
-            EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
622
+            EE_MAINTENANCE_TEMPLATE_PATH.'ee_confirm_migration_crash_report_sent.template.php';
623 623
         $this->_template_args['admin_page_content']    = EEH_Template::display_template(
624 624
             $this->_template_path,
625 625
             $this->_template_args,
@@ -727,14 +727,14 @@  discard block
 block discarded – undo
727 727
         wp_enqueue_script('ee_admin_js');
728 728
         wp_enqueue_script(
729 729
             'ee-maintenance',
730
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js',
730
+            EE_MAINTENANCE_ASSETS_URL.'ee-maintenance.js',
731 731
             ['jquery'],
732 732
             EVENT_ESPRESSO_VERSION,
733 733
             true
734 734
         );
735 735
         wp_register_style(
736 736
             'espresso_maintenance',
737
-            EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css',
737
+            EE_MAINTENANCE_ASSETS_URL.'ee-maintenance.css',
738 738
             [],
739 739
             EVENT_ESPRESSO_VERSION
740 740
         );
@@ -797,7 +797,7 @@  discard block
 block discarded – undo
797 797
      */
798 798
     protected function _datetime_tools()
799 799
     {
800
-        $form_action                                = EE_Admin_Page::add_query_args_and_nonce(
800
+        $form_action = EE_Admin_Page::add_query_args_and_nonce(
801 801
             [
802 802
                 'action'        => 'run_datetime_offset_fix',
803 803
                 'return_action' => $this->_req_action,
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
      */
819 819
     protected function _get_datetime_offset_fix_form()
820 820
     {
821
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
821
+        if ( ! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
822 822
             $this->datetime_fix_offset_form = new EE_Form_Section_Proper(
823 823
                 [
824 824
                     'name'            => 'datetime_offset_fix_option',
@@ -924,12 +924,12 @@  discard block
 block discarded – undo
924 924
                 $utc_timezone          = new DateTimeZone('UTC');
925 925
                 $date_range_start_date = DateTime::createFromFormat(
926 926
                     'm/d/Y H:i:s',
927
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
927
+                    $form->get_input_value('date_range_start_date').' 00:00:00',
928 928
                     $utc_timezone
929 929
                 );
930
-                $date_range_end_date   = DateTime::createFromFormat(
930
+                $date_range_end_date = DateTime::createFromFormat(
931 931
                     'm/d/Y H:i:s',
932
-                    $form->get_input_value('date_range_end_date') . ' 23:59:59',
932
+                    $form->get_input_value('date_range_end_date').' 23:59:59',
933 933
                     $utc_timezone
934 934
                 );
935 935
                 if ($date_range_start_date instanceof DateTime) {
Please login to merge, or discard this patch.
admin_pages/venues/Venues_Admin_Page.core.php 2 patches
Indentation   +1547 added lines, -1547 removed lines patch added patch discarded remove patch
@@ -13,1557 +13,1557 @@
 block discarded – undo
13 13
  */
14 14
 class Venues_Admin_Page extends EE_Admin_Page_CPT
15 15
 {
16
-    /**
17
-     * primary key for the venue model
18
-     */
19
-    private int $VNU_ID = 0;
20
-
21
-    /**
22
-     * This will hold the venue object for venue_details screen.
23
-     *
24
-     * @var EE_Venue|EE_CPT_Base|null $_cpt_model_obj
25
-     */
26
-    protected $_cpt_model_obj;
27
-
28
-
29
-    /**
30
-     * This will hold the category object for category_details screen.
31
-     *
32
-     * @var stdClass|null $_category
33
-     */
34
-    protected ?stdClass $_category = null;
35
-
36
-
37
-    /**
38
-     * This property will hold the venue model instance
39
-     *
40
-     * @var EEM_Venue|null $_venue_model
41
-     */
42
-    protected ?EEM_Venue $_venue_model = null;
43
-
44
-
45
-    /**
46
-     * @throws EE_Error
47
-     * @throws ReflectionException
48
-     */
49
-    protected function _init_page_props()
50
-    {
51
-        // is there a vnu_id in the request?
52
-        $this->VNU_ID = $this->request->getRequestParam('VNU_ID', 0, DataType::INT);
53
-        $this->VNU_ID = $this->request->getRequestParam('post', $this->VNU_ID, DataType::INT);
54
-        $this->VNU_ID = $this->request->getRequestParam('post_ID', $this->VNU_ID, DataType::INT);
55
-
56
-        $this->page_slug        = EE_VENUES_PG_SLUG;
57
-        $this->_admin_base_url  = EE_VENUES_ADMIN_URL;
58
-        $this->_admin_base_path = EE_ADMIN_PAGES . 'venues';
59
-        $this->page_label       = esc_html__('Event Venues', 'event_espresso');
60
-        $this->_cpt_model_names = [
61
-            'create_new' => 'EEM_Venue',
62
-            'edit'       => 'EEM_Venue',
63
-        ];
64
-        $this->_cpt_edit_routes = [
65
-            'espresso_venues' => 'edit',
66
-        ];
67
-        $this->_venue_model     = EEM_Venue::instance();
68
-    }
69
-
70
-
71
-    protected function _ajax_hooks()
72
-    {
73
-        // todo: all hooks for ee_venues ajax goes in here.
74
-    }
75
-
76
-
77
-    protected function _define_page_props()
78
-    {
79
-        $this->_admin_page_title = $this->page_label;
80
-        $this->_labels           = [
81
-            'buttons'      => [
82
-                'add'             => esc_html__('Add New Venue', 'event_espresso'),
83
-                'edit'            => esc_html__('Edit Venue', 'event_espresso'),
84
-                'delete'          => esc_html__('Delete Venue', 'event_espresso'),
85
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
86
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
87
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
88
-            ],
89
-            'editor_title' => [
90
-                'espresso_venues' => esc_html__('Edit Venue', 'event_espresso'),
91
-            ],
92
-            'publishbox'   => [
93
-                'create_new'          => esc_html__('Save New Venue', 'event_espresso'),
94
-                'edit'                => esc_html__('Update Venue', 'event_espresso'),
95
-                'add_category'        => esc_html__('Save New Category', 'event_espresso'),
96
-                'edit_category'       => esc_html__('Update Category', 'event_espresso'),
97
-                'google_map_settings' => esc_html__('Update Settings', 'event_espresso'),
98
-            ],
99
-        ];
100
-    }
101
-
102
-
103
-    protected function _set_page_routes()
104
-    {
105
-        // load formatter helper
106
-        // load field generator helper
107
-
108
-
109
-        $this->_page_routes = [
110
-            'default'                    => [
111
-                'func'       => [$this, '_overview_list_table'],
112
-                'capability' => 'ee_read_venues',
113
-            ],
114
-            'create_new'                 => [
115
-                'func'       => [$this, '_create_new_cpt_item'],
116
-                'capability' => 'ee_edit_venues',
117
-            ],
118
-            'edit'                       => [
119
-                'func'       => [$this, '_edit_cpt_item'],
120
-                'capability' => 'ee_edit_venue',
121
-                'obj_id'     => $this->VNU_ID,
122
-            ],
123
-            'trash_venue'                => [
124
-                'func'       => [$this, '_trash_or_restore_venue'],
125
-                'args'       => ['venue_status' => 'trash'],
126
-                'noheader'   => true,
127
-                'capability' => 'ee_delete_venue',
128
-                'obj_id'     => $this->VNU_ID,
129
-            ],
130
-            'trash_venues'               => [
131
-                'func'       => [$this, '_trash_or_restore_venues'],
132
-                'args'       => ['venue_status' => 'trash'],
133
-                'noheader'   => true,
134
-                'capability' => 'ee_delete_venues',
135
-            ],
136
-            'restore_venue'              => [
137
-                'func'       => [$this, '_trash_or_restore_venue'],
138
-                'args'       => ['venue_status' => 'draft'],
139
-                'noheader'   => true,
140
-                'capability' => 'ee_delete_venue',
141
-                'obj_id'     => $this->VNU_ID,
142
-            ],
143
-            'restore_venues'             => [
144
-                'func'       => [$this, '_trash_or_restore_venues'],
145
-                'args'       => ['venue_status' => 'draft'],
146
-                'noheader'   => true,
147
-                'capability' => 'ee_delete_venues',
148
-            ],
149
-            'delete_venues'              => [
150
-                'func'       => [$this, '_delete_venues'],
151
-                'noheader'   => true,
152
-                'capability' => 'ee_delete_venues',
153
-            ],
154
-            'delete_venue'               => [
155
-                'func'       => [$this, '_delete_venue'],
156
-                'args'       => ['redirect_after' => true],
157
-                'noheader'   => true,
158
-                'capability' => 'ee_delete_venue',
159
-                'obj_id'     => $this->VNU_ID,
160
-            ],
161
-            // settings related
162
-            'google_map_settings'        => [
163
-                'func'       => [$this, '_google_map_settings'],
164
-                'capability' => 'manage_options',
165
-            ],
166
-            'update_google_map_settings' => [
167
-                'func'       => [$this, '_update_google_map_settings'],
168
-                'capability' => 'manage_options',
169
-                'noheader'   => true,
170
-            ],
171
-            // venue category tab related
172
-            'add_category'               => [
173
-                'func'       => [$this, '_category_details'],
174
-                'args'       => ['add'],
175
-                'capability' => 'ee_edit_venue_category',
176
-            ],
177
-            'edit_category'              => [
178
-                'func'       => [$this, '_category_details'],
179
-                'args'       => ['edit'],
180
-                'capability' => 'ee_edit_venue_category',
181
-            ],
182
-            'delete_categories'          => [
183
-                'func'       => [$this, '_delete_categories'],
184
-                'noheader'   => true,
185
-                'capability' => 'ee_delete_venue_category',
186
-            ],
187
-
188
-            'delete_category' => [
189
-                'func'       => [$this, '_delete_categories'],
190
-                'noheader'   => true,
191
-                'capability' => 'ee_delete_venue_category',
192
-            ],
193
-
194
-            'insert_category' => [
195
-                'func'       => [$this, '_insert_or_update_category'],
196
-                'args'       => ['new_category' => true],
197
-                'noheader'   => true,
198
-                'capability' => 'ee_edit_venue_category',
199
-            ],
200
-
201
-            'update_category'   => [
202
-                'func'       => [$this, '_insert_or_update_category'],
203
-                'args'       => ['new_category' => false],
204
-                'noheader'   => true,
205
-                'capability' => 'ee_edit_venue_category',
206
-            ],
207
-            'export_categories' => [
208
-                'func'       => [$this, '_categories_export'],
209
-                'noheader'   => true,
210
-                'capability' => 'export',
211
-            ],
212
-            'import_categories' => [
213
-                'func'       => [$this, '_import_categories'],
214
-                'capability' => 'import',
215
-            ],
216
-            'category_list'     => [
217
-                'func'       => [$this, '_category_list_table'],
218
-                'capability' => 'ee_manage_venue_categories',
219
-            ],
220
-        ];
221
-    }
222
-
223
-
224
-    protected function _set_page_config()
225
-    {
226
-        $EVT_CAT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
227
-        $help_tabs  = [
228
-            'venues_editor_help_tab'                                               => [
229
-                'title'    => esc_html__('Venue Editor', 'event_espresso'),
230
-                'filename' => 'venues_editor',
231
-            ],
232
-            'venues_editor_title_richtexteditor_help_tab'                          => [
233
-                'title'    => esc_html__('Venue Title & Rich Text Editor', 'event_espresso'),
234
-                'filename' => 'venues_editor_title_richtexteditor',
235
-            ],
236
-            'venues_editor_tags_categories_help_tab'                               => [
237
-                'title'    => esc_html__('Venue Tags & Categories', 'event_espresso'),
238
-                'filename' => 'venues_editor_tags_categories',
239
-            ],
240
-            'venues_editor_physical_location_google_map_virtual_location_help_tab' => [
241
-                'title'    => esc_html__(
242
-                    'Venue Editor Physical Location & Google Map & Virtual Location',
243
-                    'event_espresso'
244
-                ),
245
-                'filename' => 'venues_editor_physical_location_google_map_virtual_location',
246
-            ],
247
-            'venues_editor_save_new_venue_help_tab'                                => [
248
-                'title'    => esc_html__('Save New Venue', 'event_espresso'),
249
-                'filename' => 'venues_editor_save_new_venue',
250
-            ],
251
-            'venues_editor_other_help_tab'                                         => [
252
-                'title'    => esc_html__('Venue Editor Other', 'event_espresso'),
253
-                'filename' => 'venues_editor_other',
254
-            ],
255
-        ];
256
-
257
-        $this->_page_config = [
258
-            'default'             => [
259
-                'nav'           => [
260
-                    'label' => esc_html__('Overview', 'event_espresso'),
261
-                    'icon'  => 'dashicons-list-view',
262
-                    'order' => 10,
263
-                ],
264
-                'list_table'    => 'Venues_Admin_List_Table',
265
-                'help_tabs'     => [
266
-                    'venues_overview_help_tab'                           => [
267
-                        'title'    => esc_html__('Venues Overview', 'event_espresso'),
268
-                        'filename' => 'venues_overview',
269
-                    ],
270
-                    'venues_overview_table_column_headings_help_tab'     => [
271
-                        'title'    => esc_html__('Venues Overview Table Column Headings', 'event_espresso'),
272
-                        'filename' => 'venues_overview_table_column_headings',
273
-                    ],
274
-                    'venues_overview_views_bulk_actions_search_help_tab' => [
275
-                        'title'    => esc_html__('Venues Overview Views & Bulk Actions & Search', 'event_espresso'),
276
-                        'filename' => 'venues_overview_views_bulk_actions_search',
277
-                    ],
278
-                ],
279
-                'metaboxes'     => ['_espresso_news_post_box', '_espresso_links_post_box'],
280
-                'require_nonce' => false,
281
-            ],
282
-            'create_new'          => [
283
-                'nav'           => [
284
-                    'label'      => esc_html__('Add Venue', 'event_espresso'),
285
-                    'icon'       => 'dashicons-plus-alt',
286
-                    'order'      => 15,
287
-                    'persistent' => false,
288
-                ],
289
-                'help_tabs'     => $help_tabs,
290
-                'metaboxes'     => ['_venue_editor_metaboxes'],
291
-                'require_nonce' => false,
292
-            ],
293
-            'edit'                => [
294
-                'nav'           => [
295
-                    'label'      => esc_html__('Edit Venue', 'event_espresso'),
296
-                    'icon'       => 'dashicons-edit-large',
297
-                    'order'      => 15,
298
-                    'persistent' => false,
299
-                    'url'        => $this->VNU_ID
300
-                        ? add_query_arg(['post' => $this->VNU_ID], $this->_current_page_view_url)
301
-                        : $this->_admin_base_url,
302
-                ],
303
-                'help_tabs'     => $help_tabs,
304
-                'metaboxes'     => ['_venue_editor_metaboxes'],
305
-                'require_nonce' => false,
306
-            ],
307
-            'google_map_settings' => [
308
-                'nav'           => [
309
-                    'label' => esc_html__('Google Maps', 'event_espresso'),
310
-                    'icon'  => 'dashicons-location-alt',
311
-                    'order' => 40,
312
-                ],
313
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
314
-                'help_tabs'     => [
315
-                    'general_settings_google_maps_help_tab' => [
316
-                        'title'    => esc_html__('Google Maps', 'event_espresso'),
317
-                        'filename' => 'general_settings_google_maps',
318
-                    ],
319
-                ],
320
-                'require_nonce' => false,
321
-            ],
322
-            // venue category stuff
323
-            'add_category'        => [
324
-                'nav'           => [
325
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
326
-                    'icon'       => 'dashicons-plus-alt',
327
-                    'order'      => 25,
328
-                    'persistent' => false,
329
-                ],
330
-                'metaboxes'     => ['_publish_post_box'],
331
-                'help_tabs'     => [
332
-                    'venues_add_category_help_tab' => [
333
-                        'title'    => esc_html__('Add New Venue Category', 'event_espresso'),
334
-                        'filename' => 'venues_add_category',
335
-                    ],
336
-                ],
337
-                'require_nonce' => false,
338
-            ],
339
-            'edit_category'       => [
340
-                'nav'           => [
341
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
342
-                    'icon'       => 'dashicons-edit-large',
343
-                    'order'      => 25,
344
-                    'persistent' => false,
345
-                    'url'        => $EVT_CAT_ID
346
-                        ? add_query_arg(['EVT_CAT_ID' => $EVT_CAT_ID], $this->_current_page_view_url)
347
-                        : $this->_admin_base_url,
348
-                ],
349
-                'metaboxes'     => ['_publish_post_box'],
350
-                'help_tabs'     => [
351
-                    'venues_edit_category_help_tab' => [
352
-                        'title'    => esc_html__('Edit Venue Category', 'event_espresso'),
353
-                        'filename' => 'venues_edit_category',
354
-                    ],
355
-                ],
356
-                'require_nonce' => false,
357
-            ],
358
-            'category_list'       => [
359
-                'nav'           => [
360
-                    'label' => esc_html__('Categories', 'event_espresso'),
361
-                    'icon'  => 'dashicons-networking',
362
-                    'order' => 20,
363
-                ],
364
-                'list_table'    => 'Venue_Categories_Admin_List_Table',
365
-                'help_tabs'     => [
366
-                    'venues_categories_help_tab'                       => [
367
-                        'title'    => esc_html__('Venue Categories', 'event_espresso'),
368
-                        'filename' => 'venues_categories',
369
-                    ],
370
-                    'venues_categories_table_column_headings_help_tab' => [
371
-                        'title'    => esc_html__('Venue Categories Table Column Headings', 'event_espresso'),
372
-                        'filename' => 'venues_categories_table_column_headings',
373
-                    ],
374
-                    'venues_categories_views_help_tab'                 => [
375
-                        'title'    => esc_html__('Venue Categories Views', 'event_espresso'),
376
-                        'filename' => 'venues_categories_views',
377
-                    ],
378
-                    'venues_categories_other_help_tab'                 => [
379
-                        'title'    => esc_html__('Venue Categories Other', 'event_espresso'),
380
-                        'filename' => 'venues_categories_other',
381
-                    ],
382
-                ],
383
-                'metaboxes'     => $this->_default_espresso_metaboxes,
384
-                'require_nonce' => false,
385
-            ],
386
-        ];
387
-    }
388
-
389
-
390
-    protected function _add_screen_options()
391
-    {
392
-        // todo
393
-    }
394
-
395
-
396
-    protected function _add_screen_options_default()
397
-    {
398
-        $this->_per_page_screen_option();
399
-    }
400
-
401
-
402
-    protected function _add_screen_options_category_list()
403
-    {
404
-        $page_title              = $this->_admin_page_title;
405
-        $this->_admin_page_title = esc_html__('Venue Categories', 'event_espresso');
406
-        $this->_per_page_screen_option();
407
-        $this->_admin_page_title = $page_title;
408
-    }
409
-
410
-
411
-    // none of the below group are currently used for Event Venues
412
-    protected function _add_feature_pointers()
413
-    {
414
-    }
415
-
416
-
417
-    public function admin_init()
418
-    {
419
-    }
420
-
421
-
422
-    public function admin_notices()
423
-    {
424
-    }
425
-
426
-
427
-    public function admin_footer_scripts()
428
-    {
429
-    }
430
-
431
-
432
-    public function load_scripts_styles_create_new()
433
-    {
434
-        $this->load_scripts_styles_edit();
435
-    }
436
-
437
-
438
-    public function load_scripts_styles()
439
-    {
440
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
441
-        wp_enqueue_style('ee-cat-admin');
442
-    }
443
-
444
-
445
-    public function load_scripts_styles_add_category()
446
-    {
447
-        $this->load_scripts_styles_edit_category();
448
-    }
449
-
450
-
451
-    public function load_scripts_styles_edit_category()
452
-    {
453
-    }
454
-
455
-
456
-    public function load_scripts_styles_edit()
457
-    {
458
-        // styles
459
-        wp_enqueue_style('espresso-ui-theme');
460
-        wp_register_style(
461
-            'espresso_venues',
462
-            EE_VENUES_ASSETS_URL . 'ee-venues-admin.css',
463
-            [],
464
-            EVENT_ESPRESSO_VERSION
465
-        );
466
-        wp_enqueue_style('espresso_venues');
467
-    }
468
-
469
-
470
-    protected function _set_list_table_views_default()
471
-    {
472
-        $this->_views = [
473
-            'all' => [
474
-                'slug'        => 'all',
475
-                'label'       => esc_html__('View All Venues', 'event_espresso'),
476
-                'count'       => 0,
477
-                'bulk_action' => [],
478
-            ],
479
-        ];
480
-
481
-        if ($this->capabilities->current_user_can('ee_delete_venues', 'espresso_venues_trash_venues')) {
482
-            $this->_views['all']['bulk_action'] = [
483
-                'trash_venues' => esc_html__('Move to Trash', 'event_espresso'),
484
-            ];
485
-            $this->_views['trash']              = [
486
-                'slug'        => 'trash',
487
-                'label'       => esc_html__('Trash', 'event_espresso'),
488
-                'count'       => 0,
489
-                'bulk_action' => [
490
-                    'restore_venues' => esc_html__('Restore from Trash', 'event_espresso'),
491
-                    'delete_venues'  => esc_html__('Delete', 'event_espresso'),
492
-                ],
493
-            ];
494
-        }
495
-    }
496
-
497
-
498
-    protected function _set_list_table_views_category_list()
499
-    {
500
-        $this->_views = [
501
-            'all' => [
502
-                'slug'        => 'all',
503
-                'label'       => esc_html__('All', 'event_espresso'),
504
-                'count'       => 0,
505
-                'bulk_action' => [
506
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
507
-                ],
508
-            ],
509
-        ];
510
-    }
511
-
512
-
513
-    /**
514
-     * @throws EE_Error
515
-     */
516
-    protected function _overview_list_table()
517
-    {
518
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
519
-        $this->_template_args['after_list_table'] = EEH_Template::get_button_or_link(
520
-            get_post_type_archive_link('espresso_venues'),
521
-            esc_html__("View Venue Archive Page", "event_espresso"),
522
-            'button'
523
-        );
524
-
525
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
526
-                'create_new',
527
-                'add',
528
-                [],
529
-                'add-new-h2'
530
-            );
531
-
532
-        $this->_search_btn_label = esc_html__('Venues', 'event_espresso');
533
-        $this->display_admin_list_table_page_with_sidebar();
534
-    }
535
-
536
-
537
-    /**
538
-     * @throws EE_Error
539
-     * @throws ReflectionException
540
-     */
541
-    public function extra_misc_actions_publish_box()
542
-    {
543
-        $extra_rows = [
544
-            'vnu_capacity' => $this->_cpt_model_obj->get_f('VNU_capacity'),
545
-            'vnu_url'      => $this->_cpt_model_obj->get_f('VNU_url'),
546
-            'vnu_phone'    => $this->_cpt_model_obj->get_f('VNU_phone'),
547
-        ];
548
-        $template   = EE_VENUES_TEMPLATE_PATH . 'venue_publish_box_extras.template.php';
549
-        EEH_Template::display_template($template, $extra_rows);
550
-    }
551
-
552
-
553
-    /*************        Google Maps        *************
16
+	/**
17
+	 * primary key for the venue model
18
+	 */
19
+	private int $VNU_ID = 0;
20
+
21
+	/**
22
+	 * This will hold the venue object for venue_details screen.
23
+	 *
24
+	 * @var EE_Venue|EE_CPT_Base|null $_cpt_model_obj
25
+	 */
26
+	protected $_cpt_model_obj;
27
+
28
+
29
+	/**
30
+	 * This will hold the category object for category_details screen.
31
+	 *
32
+	 * @var stdClass|null $_category
33
+	 */
34
+	protected ?stdClass $_category = null;
35
+
36
+
37
+	/**
38
+	 * This property will hold the venue model instance
39
+	 *
40
+	 * @var EEM_Venue|null $_venue_model
41
+	 */
42
+	protected ?EEM_Venue $_venue_model = null;
43
+
44
+
45
+	/**
46
+	 * @throws EE_Error
47
+	 * @throws ReflectionException
48
+	 */
49
+	protected function _init_page_props()
50
+	{
51
+		// is there a vnu_id in the request?
52
+		$this->VNU_ID = $this->request->getRequestParam('VNU_ID', 0, DataType::INT);
53
+		$this->VNU_ID = $this->request->getRequestParam('post', $this->VNU_ID, DataType::INT);
54
+		$this->VNU_ID = $this->request->getRequestParam('post_ID', $this->VNU_ID, DataType::INT);
55
+
56
+		$this->page_slug        = EE_VENUES_PG_SLUG;
57
+		$this->_admin_base_url  = EE_VENUES_ADMIN_URL;
58
+		$this->_admin_base_path = EE_ADMIN_PAGES . 'venues';
59
+		$this->page_label       = esc_html__('Event Venues', 'event_espresso');
60
+		$this->_cpt_model_names = [
61
+			'create_new' => 'EEM_Venue',
62
+			'edit'       => 'EEM_Venue',
63
+		];
64
+		$this->_cpt_edit_routes = [
65
+			'espresso_venues' => 'edit',
66
+		];
67
+		$this->_venue_model     = EEM_Venue::instance();
68
+	}
69
+
70
+
71
+	protected function _ajax_hooks()
72
+	{
73
+		// todo: all hooks for ee_venues ajax goes in here.
74
+	}
75
+
76
+
77
+	protected function _define_page_props()
78
+	{
79
+		$this->_admin_page_title = $this->page_label;
80
+		$this->_labels           = [
81
+			'buttons'      => [
82
+				'add'             => esc_html__('Add New Venue', 'event_espresso'),
83
+				'edit'            => esc_html__('Edit Venue', 'event_espresso'),
84
+				'delete'          => esc_html__('Delete Venue', 'event_espresso'),
85
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
86
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
87
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
88
+			],
89
+			'editor_title' => [
90
+				'espresso_venues' => esc_html__('Edit Venue', 'event_espresso'),
91
+			],
92
+			'publishbox'   => [
93
+				'create_new'          => esc_html__('Save New Venue', 'event_espresso'),
94
+				'edit'                => esc_html__('Update Venue', 'event_espresso'),
95
+				'add_category'        => esc_html__('Save New Category', 'event_espresso'),
96
+				'edit_category'       => esc_html__('Update Category', 'event_espresso'),
97
+				'google_map_settings' => esc_html__('Update Settings', 'event_espresso'),
98
+			],
99
+		];
100
+	}
101
+
102
+
103
+	protected function _set_page_routes()
104
+	{
105
+		// load formatter helper
106
+		// load field generator helper
107
+
108
+
109
+		$this->_page_routes = [
110
+			'default'                    => [
111
+				'func'       => [$this, '_overview_list_table'],
112
+				'capability' => 'ee_read_venues',
113
+			],
114
+			'create_new'                 => [
115
+				'func'       => [$this, '_create_new_cpt_item'],
116
+				'capability' => 'ee_edit_venues',
117
+			],
118
+			'edit'                       => [
119
+				'func'       => [$this, '_edit_cpt_item'],
120
+				'capability' => 'ee_edit_venue',
121
+				'obj_id'     => $this->VNU_ID,
122
+			],
123
+			'trash_venue'                => [
124
+				'func'       => [$this, '_trash_or_restore_venue'],
125
+				'args'       => ['venue_status' => 'trash'],
126
+				'noheader'   => true,
127
+				'capability' => 'ee_delete_venue',
128
+				'obj_id'     => $this->VNU_ID,
129
+			],
130
+			'trash_venues'               => [
131
+				'func'       => [$this, '_trash_or_restore_venues'],
132
+				'args'       => ['venue_status' => 'trash'],
133
+				'noheader'   => true,
134
+				'capability' => 'ee_delete_venues',
135
+			],
136
+			'restore_venue'              => [
137
+				'func'       => [$this, '_trash_or_restore_venue'],
138
+				'args'       => ['venue_status' => 'draft'],
139
+				'noheader'   => true,
140
+				'capability' => 'ee_delete_venue',
141
+				'obj_id'     => $this->VNU_ID,
142
+			],
143
+			'restore_venues'             => [
144
+				'func'       => [$this, '_trash_or_restore_venues'],
145
+				'args'       => ['venue_status' => 'draft'],
146
+				'noheader'   => true,
147
+				'capability' => 'ee_delete_venues',
148
+			],
149
+			'delete_venues'              => [
150
+				'func'       => [$this, '_delete_venues'],
151
+				'noheader'   => true,
152
+				'capability' => 'ee_delete_venues',
153
+			],
154
+			'delete_venue'               => [
155
+				'func'       => [$this, '_delete_venue'],
156
+				'args'       => ['redirect_after' => true],
157
+				'noheader'   => true,
158
+				'capability' => 'ee_delete_venue',
159
+				'obj_id'     => $this->VNU_ID,
160
+			],
161
+			// settings related
162
+			'google_map_settings'        => [
163
+				'func'       => [$this, '_google_map_settings'],
164
+				'capability' => 'manage_options',
165
+			],
166
+			'update_google_map_settings' => [
167
+				'func'       => [$this, '_update_google_map_settings'],
168
+				'capability' => 'manage_options',
169
+				'noheader'   => true,
170
+			],
171
+			// venue category tab related
172
+			'add_category'               => [
173
+				'func'       => [$this, '_category_details'],
174
+				'args'       => ['add'],
175
+				'capability' => 'ee_edit_venue_category',
176
+			],
177
+			'edit_category'              => [
178
+				'func'       => [$this, '_category_details'],
179
+				'args'       => ['edit'],
180
+				'capability' => 'ee_edit_venue_category',
181
+			],
182
+			'delete_categories'          => [
183
+				'func'       => [$this, '_delete_categories'],
184
+				'noheader'   => true,
185
+				'capability' => 'ee_delete_venue_category',
186
+			],
187
+
188
+			'delete_category' => [
189
+				'func'       => [$this, '_delete_categories'],
190
+				'noheader'   => true,
191
+				'capability' => 'ee_delete_venue_category',
192
+			],
193
+
194
+			'insert_category' => [
195
+				'func'       => [$this, '_insert_or_update_category'],
196
+				'args'       => ['new_category' => true],
197
+				'noheader'   => true,
198
+				'capability' => 'ee_edit_venue_category',
199
+			],
200
+
201
+			'update_category'   => [
202
+				'func'       => [$this, '_insert_or_update_category'],
203
+				'args'       => ['new_category' => false],
204
+				'noheader'   => true,
205
+				'capability' => 'ee_edit_venue_category',
206
+			],
207
+			'export_categories' => [
208
+				'func'       => [$this, '_categories_export'],
209
+				'noheader'   => true,
210
+				'capability' => 'export',
211
+			],
212
+			'import_categories' => [
213
+				'func'       => [$this, '_import_categories'],
214
+				'capability' => 'import',
215
+			],
216
+			'category_list'     => [
217
+				'func'       => [$this, '_category_list_table'],
218
+				'capability' => 'ee_manage_venue_categories',
219
+			],
220
+		];
221
+	}
222
+
223
+
224
+	protected function _set_page_config()
225
+	{
226
+		$EVT_CAT_ID = $this->request->getRequestParam('EVT_CAT_ID', 0, 'int');
227
+		$help_tabs  = [
228
+			'venues_editor_help_tab'                                               => [
229
+				'title'    => esc_html__('Venue Editor', 'event_espresso'),
230
+				'filename' => 'venues_editor',
231
+			],
232
+			'venues_editor_title_richtexteditor_help_tab'                          => [
233
+				'title'    => esc_html__('Venue Title & Rich Text Editor', 'event_espresso'),
234
+				'filename' => 'venues_editor_title_richtexteditor',
235
+			],
236
+			'venues_editor_tags_categories_help_tab'                               => [
237
+				'title'    => esc_html__('Venue Tags & Categories', 'event_espresso'),
238
+				'filename' => 'venues_editor_tags_categories',
239
+			],
240
+			'venues_editor_physical_location_google_map_virtual_location_help_tab' => [
241
+				'title'    => esc_html__(
242
+					'Venue Editor Physical Location & Google Map & Virtual Location',
243
+					'event_espresso'
244
+				),
245
+				'filename' => 'venues_editor_physical_location_google_map_virtual_location',
246
+			],
247
+			'venues_editor_save_new_venue_help_tab'                                => [
248
+				'title'    => esc_html__('Save New Venue', 'event_espresso'),
249
+				'filename' => 'venues_editor_save_new_venue',
250
+			],
251
+			'venues_editor_other_help_tab'                                         => [
252
+				'title'    => esc_html__('Venue Editor Other', 'event_espresso'),
253
+				'filename' => 'venues_editor_other',
254
+			],
255
+		];
256
+
257
+		$this->_page_config = [
258
+			'default'             => [
259
+				'nav'           => [
260
+					'label' => esc_html__('Overview', 'event_espresso'),
261
+					'icon'  => 'dashicons-list-view',
262
+					'order' => 10,
263
+				],
264
+				'list_table'    => 'Venues_Admin_List_Table',
265
+				'help_tabs'     => [
266
+					'venues_overview_help_tab'                           => [
267
+						'title'    => esc_html__('Venues Overview', 'event_espresso'),
268
+						'filename' => 'venues_overview',
269
+					],
270
+					'venues_overview_table_column_headings_help_tab'     => [
271
+						'title'    => esc_html__('Venues Overview Table Column Headings', 'event_espresso'),
272
+						'filename' => 'venues_overview_table_column_headings',
273
+					],
274
+					'venues_overview_views_bulk_actions_search_help_tab' => [
275
+						'title'    => esc_html__('Venues Overview Views & Bulk Actions & Search', 'event_espresso'),
276
+						'filename' => 'venues_overview_views_bulk_actions_search',
277
+					],
278
+				],
279
+				'metaboxes'     => ['_espresso_news_post_box', '_espresso_links_post_box'],
280
+				'require_nonce' => false,
281
+			],
282
+			'create_new'          => [
283
+				'nav'           => [
284
+					'label'      => esc_html__('Add Venue', 'event_espresso'),
285
+					'icon'       => 'dashicons-plus-alt',
286
+					'order'      => 15,
287
+					'persistent' => false,
288
+				],
289
+				'help_tabs'     => $help_tabs,
290
+				'metaboxes'     => ['_venue_editor_metaboxes'],
291
+				'require_nonce' => false,
292
+			],
293
+			'edit'                => [
294
+				'nav'           => [
295
+					'label'      => esc_html__('Edit Venue', 'event_espresso'),
296
+					'icon'       => 'dashicons-edit-large',
297
+					'order'      => 15,
298
+					'persistent' => false,
299
+					'url'        => $this->VNU_ID
300
+						? add_query_arg(['post' => $this->VNU_ID], $this->_current_page_view_url)
301
+						: $this->_admin_base_url,
302
+				],
303
+				'help_tabs'     => $help_tabs,
304
+				'metaboxes'     => ['_venue_editor_metaboxes'],
305
+				'require_nonce' => false,
306
+			],
307
+			'google_map_settings' => [
308
+				'nav'           => [
309
+					'label' => esc_html__('Google Maps', 'event_espresso'),
310
+					'icon'  => 'dashicons-location-alt',
311
+					'order' => 40,
312
+				],
313
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
314
+				'help_tabs'     => [
315
+					'general_settings_google_maps_help_tab' => [
316
+						'title'    => esc_html__('Google Maps', 'event_espresso'),
317
+						'filename' => 'general_settings_google_maps',
318
+					],
319
+				],
320
+				'require_nonce' => false,
321
+			],
322
+			// venue category stuff
323
+			'add_category'        => [
324
+				'nav'           => [
325
+					'label'      => esc_html__('Add Category', 'event_espresso'),
326
+					'icon'       => 'dashicons-plus-alt',
327
+					'order'      => 25,
328
+					'persistent' => false,
329
+				],
330
+				'metaboxes'     => ['_publish_post_box'],
331
+				'help_tabs'     => [
332
+					'venues_add_category_help_tab' => [
333
+						'title'    => esc_html__('Add New Venue Category', 'event_espresso'),
334
+						'filename' => 'venues_add_category',
335
+					],
336
+				],
337
+				'require_nonce' => false,
338
+			],
339
+			'edit_category'       => [
340
+				'nav'           => [
341
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
342
+					'icon'       => 'dashicons-edit-large',
343
+					'order'      => 25,
344
+					'persistent' => false,
345
+					'url'        => $EVT_CAT_ID
346
+						? add_query_arg(['EVT_CAT_ID' => $EVT_CAT_ID], $this->_current_page_view_url)
347
+						: $this->_admin_base_url,
348
+				],
349
+				'metaboxes'     => ['_publish_post_box'],
350
+				'help_tabs'     => [
351
+					'venues_edit_category_help_tab' => [
352
+						'title'    => esc_html__('Edit Venue Category', 'event_espresso'),
353
+						'filename' => 'venues_edit_category',
354
+					],
355
+				],
356
+				'require_nonce' => false,
357
+			],
358
+			'category_list'       => [
359
+				'nav'           => [
360
+					'label' => esc_html__('Categories', 'event_espresso'),
361
+					'icon'  => 'dashicons-networking',
362
+					'order' => 20,
363
+				],
364
+				'list_table'    => 'Venue_Categories_Admin_List_Table',
365
+				'help_tabs'     => [
366
+					'venues_categories_help_tab'                       => [
367
+						'title'    => esc_html__('Venue Categories', 'event_espresso'),
368
+						'filename' => 'venues_categories',
369
+					],
370
+					'venues_categories_table_column_headings_help_tab' => [
371
+						'title'    => esc_html__('Venue Categories Table Column Headings', 'event_espresso'),
372
+						'filename' => 'venues_categories_table_column_headings',
373
+					],
374
+					'venues_categories_views_help_tab'                 => [
375
+						'title'    => esc_html__('Venue Categories Views', 'event_espresso'),
376
+						'filename' => 'venues_categories_views',
377
+					],
378
+					'venues_categories_other_help_tab'                 => [
379
+						'title'    => esc_html__('Venue Categories Other', 'event_espresso'),
380
+						'filename' => 'venues_categories_other',
381
+					],
382
+				],
383
+				'metaboxes'     => $this->_default_espresso_metaboxes,
384
+				'require_nonce' => false,
385
+			],
386
+		];
387
+	}
388
+
389
+
390
+	protected function _add_screen_options()
391
+	{
392
+		// todo
393
+	}
394
+
395
+
396
+	protected function _add_screen_options_default()
397
+	{
398
+		$this->_per_page_screen_option();
399
+	}
400
+
401
+
402
+	protected function _add_screen_options_category_list()
403
+	{
404
+		$page_title              = $this->_admin_page_title;
405
+		$this->_admin_page_title = esc_html__('Venue Categories', 'event_espresso');
406
+		$this->_per_page_screen_option();
407
+		$this->_admin_page_title = $page_title;
408
+	}
409
+
410
+
411
+	// none of the below group are currently used for Event Venues
412
+	protected function _add_feature_pointers()
413
+	{
414
+	}
415
+
416
+
417
+	public function admin_init()
418
+	{
419
+	}
420
+
421
+
422
+	public function admin_notices()
423
+	{
424
+	}
425
+
426
+
427
+	public function admin_footer_scripts()
428
+	{
429
+	}
430
+
431
+
432
+	public function load_scripts_styles_create_new()
433
+	{
434
+		$this->load_scripts_styles_edit();
435
+	}
436
+
437
+
438
+	public function load_scripts_styles()
439
+	{
440
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
441
+		wp_enqueue_style('ee-cat-admin');
442
+	}
443
+
444
+
445
+	public function load_scripts_styles_add_category()
446
+	{
447
+		$this->load_scripts_styles_edit_category();
448
+	}
449
+
450
+
451
+	public function load_scripts_styles_edit_category()
452
+	{
453
+	}
454
+
455
+
456
+	public function load_scripts_styles_edit()
457
+	{
458
+		// styles
459
+		wp_enqueue_style('espresso-ui-theme');
460
+		wp_register_style(
461
+			'espresso_venues',
462
+			EE_VENUES_ASSETS_URL . 'ee-venues-admin.css',
463
+			[],
464
+			EVENT_ESPRESSO_VERSION
465
+		);
466
+		wp_enqueue_style('espresso_venues');
467
+	}
468
+
469
+
470
+	protected function _set_list_table_views_default()
471
+	{
472
+		$this->_views = [
473
+			'all' => [
474
+				'slug'        => 'all',
475
+				'label'       => esc_html__('View All Venues', 'event_espresso'),
476
+				'count'       => 0,
477
+				'bulk_action' => [],
478
+			],
479
+		];
480
+
481
+		if ($this->capabilities->current_user_can('ee_delete_venues', 'espresso_venues_trash_venues')) {
482
+			$this->_views['all']['bulk_action'] = [
483
+				'trash_venues' => esc_html__('Move to Trash', 'event_espresso'),
484
+			];
485
+			$this->_views['trash']              = [
486
+				'slug'        => 'trash',
487
+				'label'       => esc_html__('Trash', 'event_espresso'),
488
+				'count'       => 0,
489
+				'bulk_action' => [
490
+					'restore_venues' => esc_html__('Restore from Trash', 'event_espresso'),
491
+					'delete_venues'  => esc_html__('Delete', 'event_espresso'),
492
+				],
493
+			];
494
+		}
495
+	}
496
+
497
+
498
+	protected function _set_list_table_views_category_list()
499
+	{
500
+		$this->_views = [
501
+			'all' => [
502
+				'slug'        => 'all',
503
+				'label'       => esc_html__('All', 'event_espresso'),
504
+				'count'       => 0,
505
+				'bulk_action' => [
506
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
507
+				],
508
+			],
509
+		];
510
+	}
511
+
512
+
513
+	/**
514
+	 * @throws EE_Error
515
+	 */
516
+	protected function _overview_list_table()
517
+	{
518
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
519
+		$this->_template_args['after_list_table'] = EEH_Template::get_button_or_link(
520
+			get_post_type_archive_link('espresso_venues'),
521
+			esc_html__("View Venue Archive Page", "event_espresso"),
522
+			'button'
523
+		);
524
+
525
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
526
+				'create_new',
527
+				'add',
528
+				[],
529
+				'add-new-h2'
530
+			);
531
+
532
+		$this->_search_btn_label = esc_html__('Venues', 'event_espresso');
533
+		$this->display_admin_list_table_page_with_sidebar();
534
+	}
535
+
536
+
537
+	/**
538
+	 * @throws EE_Error
539
+	 * @throws ReflectionException
540
+	 */
541
+	public function extra_misc_actions_publish_box()
542
+	{
543
+		$extra_rows = [
544
+			'vnu_capacity' => $this->_cpt_model_obj->get_f('VNU_capacity'),
545
+			'vnu_url'      => $this->_cpt_model_obj->get_f('VNU_url'),
546
+			'vnu_phone'    => $this->_cpt_model_obj->get_f('VNU_phone'),
547
+		];
548
+		$template   = EE_VENUES_TEMPLATE_PATH . 'venue_publish_box_extras.template.php';
549
+		EEH_Template::display_template($template, $extra_rows);
550
+	}
551
+
552
+
553
+	/*************        Google Maps        *************
554 554
      *
555 555
      * @throws EE_Error
556 556
      * @throws EE_Error
557 557
      */
558 558
 
559 559
 
560
-    protected function _google_map_settings()
561
-    {
562
-        $this->_template_args['values']           = $this->_yes_no_values;
563
-        $default_map_settings                     = new stdClass();
564
-        $default_map_settings->use_google_maps    = true;
565
-        $default_map_settings->google_map_api_key = '';
566
-        // for event details pages (reg page)
567
-        $default_map_settings->event_details_map_width = 585;
568
-        // ee_map_width_single
569
-        $default_map_settings->event_details_map_height = 362;
570
-        // ee_map_height_single
571
-        $default_map_settings->event_details_map_zoom = 14;
572
-        // ee_map_zoom_single
573
-        $default_map_settings->event_details_display_nav = true;
574
-        // ee_map_nav_display_single
575
-        $default_map_settings->event_details_nav_size = false;
576
-        // ee_map_nav_size_single
577
-        $default_map_settings->event_details_control_type = 'default';
578
-        // ee_map_type_control_single
579
-        $default_map_settings->event_details_map_align = 'center';
580
-        // ee_map_align_single
581
-
582
-        // for event list pages
583
-        $default_map_settings->event_list_map_width = 300;
584
-        // ee_map_width
585
-        $default_map_settings->event_list_map_height = 185;
586
-        // ee_map_height
587
-        $default_map_settings->event_list_map_zoom = 12;
588
-        // ee_map_zoom
589
-        $default_map_settings->event_list_display_nav = false;
590
-        // ee_map_nav_display
591
-        $default_map_settings->event_list_nav_size = true;
592
-        // ee_map_nav_size
593
-        $default_map_settings->event_list_control_type = 'dropdown';
594
-        // ee_map_type_control
595
-        $default_map_settings->event_list_map_align = 'center';
596
-        // ee_map_align
597
-
598
-        $this->_template_args['map_settings'] =
599
-            isset(EE_Registry::instance()->CFG->map_settings)
600
-            && ! empty(EE_Registry::instance()->CFG->map_settings)
601
-                ? (object) array_merge(
602
-                (array) $default_map_settings,
603
-                (array) EE_Registry::instance()->CFG->map_settings
604
-            )
605
-                : $default_map_settings;
606
-
607
-        $this->_set_add_edit_form_tags('update_google_map_settings');
608
-        $this->_set_publish_post_box_vars();
609
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
610
-            EE_VENUES_TEMPLATE_PATH . 'google_map.template.php',
611
-            $this->_template_args,
612
-            true
613
-        );
614
-        $this->display_admin_page_with_sidebar();
615
-    }
616
-
617
-
618
-    /**
619
-     * @throws EE_Error
620
-     */
621
-    protected function _update_google_map_settings()
622
-    {
623
-        $map_settings = EE_Registry::instance()->CFG->map_settings;
624
-
625
-        $settings = [
626
-            'use_google_maps'            => 'int',
627
-            'google_map_api_key'         => 'string',
628
-            'event_details_map_width'    => 'int',
629
-            'event_details_map_zoom'     => 'int',
630
-            'event_details_display_nav'  => 'int',
631
-            'event_details_nav_size'     => 'int',
632
-            'event_details_control_type' => 'string',
633
-            'event_details_map_align'    => 'string',
634
-            'event_list_map_width'       => 'int',
635
-            'event_list_map_height'      => 'int',
636
-            'event_list_map_zoom'        => 'int',
637
-            'event_list_display_nav'     => 'int',
638
-            'event_list_nav_size'        => 'int',
639
-            'event_list_control_type'    => 'string',
640
-            'event_list_map_align'       => 'string',
641
-        ];
642
-
643
-        foreach ($settings as $setting => $type) {
644
-            $map_settings->{$setting} = $this->request->getRequestParam($setting, $map_settings->{$setting}, $type);
645
-        }
646
-
647
-        EE_Registry::instance()->CFG->map_settings = apply_filters(
648
-            'FHEE__Extend_General_Settings_Admin_Page___update_google_map_settings__CFG_map_settings',
649
-            $map_settings
650
-        );
651
-
652
-        $what    = 'Google Map Settings';
653
-        $success = $this->_update_espresso_configuration(
654
-            $what,
655
-            EE_Registry::instance()->CFG->map_settings,
656
-            __FILE__,
657
-            __FUNCTION__,
658
-            __LINE__
659
-        );
660
-        $this->_redirect_after_action($success, $what, 'updated', ['action' => 'google_map_settings']);
661
-    }
662
-
663
-
664
-    /**
665
-     * @throws EE_Error
666
-     * @throws ReflectionException
667
-     */
668
-    protected function _venue_editor_metaboxes()
669
-    {
670
-        $this->verify_cpt_object();
671
-
672
-        $this->addMetaBox(
673
-            'espresso_venue_address_options',
674
-            esc_html__('Physical Location', 'event_espresso'),
675
-            [$this, 'venue_address_metabox'],
676
-            $this->page_slug,
677
-            'side',
678
-            'core'
679
-        );
680
-        $this->addMetaBox(
681
-            'espresso_venue_gmap_options',
682
-            esc_html__('Google Map', 'event_espresso'),
683
-            [$this, 'venue_gmap_metabox'],
684
-            $this->page_slug,
685
-            'side'
686
-        );
687
-        $this->addMetaBox(
688
-            'espresso_venue_virtual_loc_options',
689
-            esc_html__('Virtual Location', 'event_espresso'),
690
-            [$this, 'venue_virtual_loc_metabox'],
691
-            $this->page_slug,
692
-            'side'
693
-        );
694
-    }
695
-
696
-
697
-    /**
698
-     * @throws EE_Error
699
-     * @throws ReflectionException
700
-     */
701
-    public function venue_gmap_metabox()
702
-    {
703
-        $template_args = [
704
-            'vnu_enable_for_gmap' => EEH_Form_Fields::select_input(
705
-                'vnu_enable_for_gmap',
706
-                $this->get_yes_no_values(),
707
-                $this->_cpt_model_obj instanceof EE_Venue && $this->_cpt_model_obj->enable_for_gmap()
708
-            ),
709
-            'vnu_google_map_link' => $this->_cpt_model_obj->google_map_link(),
710
-        ];
711
-        $template      = EE_VENUES_TEMPLATE_PATH . 'venue_gmap_metabox_content.template.php';
712
-        EEH_Template::display_template($template, $template_args);
713
-    }
714
-
715
-
716
-    /**
717
-     * @throws EE_Error
718
-     * @throws ReflectionException
719
-     */
720
-    public function venue_address_metabox()
721
-    {
722
-        $template_args['_venue'] = $this->_cpt_model_obj;
723
-
724
-        $template_args['states_dropdown']    = EEH_Form_Fields::generate_form_input(
725
-            new EE_Question_Form_Input(
726
-                EE_Question::new_instance(
727
-                    ['QST_display_text' => esc_html__('State', 'event_espresso'), 'QST_system' => 'state']
728
-                ),
729
-                EE_Answer::new_instance(
730
-                    [
731
-                        'ANS_value' => $this->_cpt_model_obj instanceof EE_Venue
732
-                            ? $this->_cpt_model_obj->state_ID()
733
-                            : 0,
734
-                    ]
735
-                ),
736
-                [
737
-                    'input_name'     => 'sta_id',
738
-                    'input_id'       => 'sta_id',
739
-                    'input_class'    => '',
740
-                    'input_prefix'   => '',
741
-                    'append_qstn_id' => false,
742
-                ]
743
-            )
744
-        );
745
-        $template_args['countries_dropdown'] = EEH_Form_Fields::generate_form_input(
746
-            new EE_Question_Form_Input(
747
-                EE_Question::new_instance(
748
-                    ['QST_display_text' => esc_html__('Country', 'event_espresso'), 'QST_system' => 'country']
749
-                ),
750
-                EE_Answer::new_instance(
751
-                    [
752
-                        'ANS_value' => $this->_cpt_model_obj instanceof EE_Venue
753
-                            ? $this->_cpt_model_obj->country_ID()
754
-                            : 0,
755
-                    ]
756
-                ),
757
-                [
758
-                    'input_name'     => 'cnt_iso',
759
-                    'input_id'       => 'cnt_iso',
760
-                    'input_class'    => '',
761
-                    'input_prefix'   => '',
762
-                    'append_qstn_id' => false,
763
-                ]
764
-            )
765
-        );
766
-
767
-        $template = EE_VENUES_TEMPLATE_PATH . 'venue_address_metabox_content.template.php';
768
-        EEH_Template::display_template($template, $template_args);
769
-    }
770
-
771
-
772
-    public function venue_virtual_loc_metabox()
773
-    {
774
-        $template_args = [
775
-            '_venue' => $this->_cpt_model_obj,
776
-        ];
777
-        $template      = EE_VENUES_TEMPLATE_PATH . 'venue_virtual_location_metabox_content.template.php';
778
-        EEH_Template::display_template($template, $template_args);
779
-    }
780
-
781
-
782
-    /**
783
-     * @throws EE_Error
784
-     * @throws ReflectionException
785
-     */
786
-    protected function _restore_cpt_item($post_id, $revision_id)
787
-    {
788
-        $this->_cpt_model_obj = $this->_venue_model->get_one_by_ID($post_id);
789
-        // meta revision restore
790
-        $this->_cpt_model_obj->restore_revision($revision_id);
791
-    }
792
-
793
-
794
-    /**
795
-     * Handles updates for venue cpts
796
-     *
797
-     * @param int     $post_id ID of Venue CPT
798
-     * @param WP_Post $post    Post object (with "blessed" WP properties)
799
-     * @return void
800
-     * @throws EE_Error
801
-     * @throws ReflectionException
802
-     */
803
-    protected function _insert_update_cpt_item($post_id, $post)
804
-    {
805
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_venues') {
806
-            return;// get out we're not processing the saving of venues.
807
-        }
808
-
809
-        $wheres = [$this->_venue_model->primary_key_name() => $post_id];
810
-
811
-        $venue_values = [
812
-            'VNU_address'         => $this->request->getRequestParam('vnu_address'),
813
-            'VNU_address2'        => $this->request->getRequestParam('vnu_address2'),
814
-            'VNU_city'            => $this->request->getRequestParam('vnu_city'),
815
-            'STA_ID'              => $this->request->getRequestParam('sta_id'),
816
-            'CNT_ISO'             => $this->request->getRequestParam('cnt_iso'),
817
-            'VNU_zip'             => $this->request->getRequestParam('vnu_zip'),
818
-            'VNU_phone'           => $this->request->getRequestParam('vnu_phone'),
819
-            'VNU_capacity'        => $this->request->requestParamIsSet('vnu_capacity')
820
-                ? str_replace(',', '', $this->request->getRequestParam('vnu_capacity'))
821
-                : EE_INF,
822
-            'VNU_url'             => $this->request->getRequestParam('vnu_url'),
823
-            'VNU_virtual_phone'   => $this->request->getRequestParam('vnu_virtual_phone'),
824
-            'VNU_virtual_url'     => $this->request->getRequestParam('vnu_virtual_url'),
825
-            'VNU_enable_for_gmap' => $this->request->getRequestParam('vnu_enable_for_gmap', false, 'bool'),
826
-            'VNU_google_map_link' => $this->request->getRequestParam('vnu_google_map_link'),
827
-        ];
828
-
829
-        // update venue
830
-        $success = $this->_venue_model->update($venue_values, [$wheres]);
831
-
832
-        // get venue_object for other metaboxes that might be added via the filter... though it would seem to make sense to just use $this->_venue_model->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
833
-        $get_one_where = [$this->_venue_model->primary_key_name() => $post_id, 'status' => $post->post_status];
834
-        $venue         = $this->_venue_model->get_one([$get_one_where]);
835
-
836
-        // notice we've applied a filter for venue metabox callbacks but we don't actually have any default venue metaboxes in use.  So this is just here for addons to more easily hook into venue saves.
837
-        $venue_update_callbacks = apply_filters(
838
-            'FHEE__Venues_Admin_Page___insert_update_cpt_item__venue_update_callbacks',
839
-            []
840
-        );
841
-        $att_success            = true;
842
-        foreach ($venue_update_callbacks as $v_callback) {
843
-            // if ANY of these updates fail then we want the appropriate global error message
844
-            $att_success = call_user_func_array($v_callback, [$venue, $this->request->requestParams()])
845
-                ? $att_success
846
-                : false;
847
-        }
848
-
849
-        // any errors?
850
-        if ($success && ! $att_success) {
851
-            EE_Error::add_error(
852
-                esc_html__(
853
-                    'Venue Details saved successfully but something went wrong with saving attachments.',
854
-                    'event_espresso'
855
-                ),
856
-                __FILE__,
857
-                __FUNCTION__,
858
-                __LINE__
859
-            );
860
-        } elseif ($success === false) {
861
-            EE_Error::add_error(
862
-                esc_html__('Venue Details did not save successfully.', 'event_espresso'),
863
-                __FILE__,
864
-                __FUNCTION__,
865
-                __LINE__
866
-            );
867
-        }
868
-    }
869
-
870
-
871
-    /**
872
-     * @param int $post_id
873
-     * @throws EE_Error
874
-     * @throws ReflectionException
875
-     */
876
-    public function trash_cpt_item($post_id)
877
-    {
878
-        $this->request->setRequestParam('VNU_ID', $post_id);
879
-        $this->_trash_or_restore_venue('trash', false);
880
-    }
881
-
882
-
883
-    /**
884
-     * @param int $post_id
885
-     * @throws EE_Error
886
-     * @throws ReflectionException
887
-     */
888
-    public function restore_cpt_item($post_id)
889
-    {
890
-        $this->request->setRequestParam('VNU_ID', $post_id);
891
-        $this->_trash_or_restore_venue('draft', false);
892
-    }
893
-
894
-
895
-    /**
896
-     * @param int $post_id
897
-     * @throws EE_Error
898
-     * @throws ReflectionException
899
-     */
900
-    public function delete_cpt_item($post_id)
901
-    {
902
-        $this->request->setRequestParam('VNU_ID', $post_id);
903
-        $this->_delete_venue(false);
904
-    }
905
-
906
-
907
-    public function get_venue_object()
908
-    {
909
-        return $this->_cpt_model_obj;
910
-    }
911
-
912
-
913
-    /**
914
-     * @param string    $venue_status
915
-     * @param bool|null $redirect_after
916
-     * @throws EE_Error
917
-     * @throws ReflectionException
918
-     */
919
-    protected function _trash_or_restore_venue(string $venue_status = 'trash', ?bool $redirect_after = true)
920
-    {
921
-        // loop thru venues
922
-        if ($this->VNU_ID) {
923
-            // clean status
924
-            $venue_status = sanitize_key($venue_status);
925
-            // grab status
926
-            if (! empty($venue_status)) {
927
-                $success = $this->_change_venue_status($this->VNU_ID, $venue_status);
928
-            } else {
929
-                $success = false;
930
-                $msg     = esc_html__(
931
-                    'An error occurred. The venue could not be moved to the trash because a valid venue status was not not supplied.',
932
-                    'event_espresso'
933
-                );
934
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
935
-            }
936
-        } else {
937
-            $success = false;
938
-            $msg     = esc_html__(
939
-                'An error occurred. The venue could not be moved to the trash because a valid venue ID was not not supplied.',
940
-                'event_espresso'
941
-            );
942
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
943
-        }
944
-        $action = $venue_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
945
-
946
-        if ($redirect_after) {
947
-            $this->_redirect_after_action($success, 'Venue', $action, ['action' => 'default']);
948
-        }
949
-    }
950
-
951
-
952
-    /**
953
-     * @param string $venue_status
954
-     * @throws EE_Error
955
-     * @throws ReflectionException
956
-     */
957
-    protected function _trash_or_restore_venues(string $venue_status = 'trash')
958
-    {
959
-        // clean status
960
-        $venue_status = sanitize_key($venue_status);
961
-        // grab status
962
-        if (! empty($venue_status)) {
963
-            $success = true;
964
-            // determine the event id and set to array.
965
-            $VNU_IDs = $this->request->getRequestParam('venue_id', [], 'int', true);
966
-            // loop thru events
967
-            foreach ($VNU_IDs as $VNU_ID) {
968
-                if ($VNU_ID = absint($VNU_ID)) {
969
-                    $results = $this->_change_venue_status($VNU_ID, $venue_status);
970
-                    $success = $results !== false ? $success : false;
971
-                } else {
972
-                    $msg = sprintf(
973
-                        esc_html__(
974
-                            'An error occurred. Venue #%d could not be moved to the trash because a valid venue ID was not not supplied.',
975
-                            'event_espresso'
976
-                        ),
977
-                        $VNU_ID
978
-                    );
979
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
980
-                    $success = false;
981
-                }
982
-            }
983
-        } else {
984
-            $success = false;
985
-            $msg     = esc_html__(
986
-                'An error occurred. The venue could not be moved to the trash because a valid venue status was not not supplied.',
987
-                'event_espresso'
988
-            );
989
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
990
-        }
991
-        // in order to force a pluralized result message we need to send back a success status greater than 1
992
-        $success = $success ? 2 : false;
993
-        $action  = $venue_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
994
-        $this->_redirect_after_action($success, 'Venues', $action, ['action' => 'default']);
995
-    }
996
-
997
-
998
-    /**
999
-     * _trash_or_restore_venues
1000
-     * //todo this is pretty much the same as the corresponding change_event_status method in Events_Admin_Page.  We
1001
-     * should probably abstract this up to the EE_Admin_Page_CPT (or even EE_Admin_Page) and make this a common method
1002
-     * accepting a certain number of params.
1003
-     *
1004
-     * @param int|null $VNU_ID
1005
-     * @param string   $venue_status
1006
-     * @return bool
1007
-     * @throws EE_Error
1008
-     * @throws ReflectionException
1009
-     */
1010
-    private function _change_venue_status(?int $VNU_ID = 0, string $venue_status = ''): bool
1011
-    {
1012
-        // grab venue id
1013
-        if (! $VNU_ID) {
1014
-            $msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1015
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1016
-            return false;
1017
-        }
1018
-
1019
-        $this->_cpt_model_obj = EEM_Venue::instance()->get_one_by_ID($VNU_ID);
1020
-
1021
-        // clean status
1022
-        $venue_status = sanitize_key($venue_status);
1023
-        // grab status
1024
-        if (! $venue_status) {
1025
-            $msg = esc_html__(
1026
-                'An error occurred. No Venue Status or an invalid Venue Status was received.',
1027
-                'event_espresso'
1028
-            );
1029
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1030
-            return false;
1031
-        }
1032
-
1033
-        // was event trashed or restored ?
1034
-        switch ($venue_status) {
1035
-            case 'draft':
1036
-                $action = 'restored from the trash';
1037
-                $hook   = 'AHEE_venue_restored_from_trash';
1038
-                break;
1039
-            case 'trash':
1040
-                $action = 'moved to the trash';
1041
-                $hook   = 'AHEE_venue_moved_to_trash';
1042
-                break;
1043
-            default:
1044
-                $action = 'updated';
1045
-                $hook   = false;
1046
-        }
1047
-        // use class to change status
1048
-        $this->_cpt_model_obj->set_status($venue_status);
1049
-        $success = $this->_cpt_model_obj->save();
1050
-
1051
-        if ($success === false) {
1052
-            $msg = sprintf(esc_html__('An error occurred. The venue could not be %s.', 'event_espresso'), $action);
1053
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1054
-            return false;
1055
-        }
1056
-        if ($hook) {
1057
-            do_action($hook);
1058
-        }
1059
-        return true;
1060
-    }
1061
-
1062
-
1063
-    /**
1064
-     * @param bool $redirect_after
1065
-     * @return void
1066
-     * @throws EE_Error
1067
-     * @throws ReflectionException
1068
-     */
1069
-    protected function _delete_venue(bool $redirect_after = true)
1070
-    {
1071
-        // loop thru venues
1072
-        if ($this->VNU_ID) {
1073
-            $success = $this->_delete_or_trash_venue($this->VNU_ID);
1074
-        } else {
1075
-            $success = false;
1076
-            $msg     = esc_html__(
1077
-                'An error occurred. An venue could not be deleted because a valid venue ID was not not supplied.',
1078
-                'event_espresso'
1079
-            );
1080
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1081
-        }
1082
-        if ($redirect_after) {
1083
-            $this->_redirect_after_action($success, 'Venue', 'deleted', ['action' => 'default']);
1084
-        }
1085
-    }
1086
-
1087
-
1088
-    /**
1089
-     * @throws EE_Error
1090
-     * @throws ReflectionException
1091
-     */
1092
-    protected function _delete_venues()
1093
-    {
1094
-        $success = true;
1095
-        // determine the event id and set to array.
1096
-        $VNU_IDs = $this->request->getRequestParam('venue_id', [], 'int', true);
1097
-        // loop thru events
1098
-        foreach ($VNU_IDs as $VNU_ID) {
1099
-            if ($VNU_ID = absint($VNU_ID)) {
1100
-                $results = $this->_delete_or_trash_venue($VNU_ID);
1101
-                $success = $results !== false ? $success : false;
1102
-            } else {
1103
-                $success = false;
1104
-                $msg     = esc_html__(
1105
-                    'An error occurred. An venue could not be deleted because a valid venue ID was not not supplied.',
1106
-                    'event_espresso'
1107
-                );
1108
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1109
-            }
1110
-        }
1111
-        // in order to force a pluralized result message we need to send back a success status greater than 1
1112
-        $success = $success ? 2 : false;
1113
-        $this->_redirect_after_action(
1114
-            $success,
1115
-            esc_html__('Venues', 'event_espresso'),
1116
-            esc_html__('deleted', 'event_espresso'),
1117
-            ['action' => 'default']
1118
-        );
1119
-    }
1120
-
1121
-
1122
-    // todo: put in parent
1123
-
1124
-
1125
-    /**
1126
-     * @param int|null $VNU_ID
1127
-     * @return bool
1128
-     * @throws EE_Error
1129
-     * @throws ReflectionException
1130
-     */
1131
-    private function _delete_or_trash_venue(?int $VNU_ID = 0): bool
1132
-    {
1133
-        // grab event id
1134
-        if (! $VNU_ID = absint($VNU_ID)) {
1135
-            $msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1136
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1137
-            return false;
1138
-        }
1139
-
1140
-
1141
-        $venue = EEM_Venue::instance()->get_one_by_ID($VNU_ID);
1142
-        // first need to remove all term relationships
1143
-        $venue->_remove_relations('Term_Taxonomy');
1144
-        $success = $venue->delete_permanently();
1145
-        // did it all go as planned ?
1146
-        if (! $success) {
1147
-            EE_Error::add_error(
1148
-                sprintf(
1149
-                    esc_html__('An error occurred. Venue ID # %d could not be deleted.', 'event_espresso'),
1150
-                    $VNU_ID
1151
-                ),
1152
-                __FILE__,
1153
-                __FUNCTION__,
1154
-                __LINE__
1155
-            );
1156
-            return false;
1157
-        }
1158
-        EE_Error::add_success(
1159
-            sprintf(esc_html__('Venue ID # %d has been deleted.', 'event_espresso'), $VNU_ID)
1160
-        );
1161
-        do_action('AHEE__Venues_Admin_Page___delete_or_trash_venue__after_venue_deleted');
1162
-        return true;
1163
-    }
1164
-
1165
-
1166
-
1167
-
1168
-    /***********/
1169
-    /* QUERIES */
1170
-
1171
-
1172
-    /**
1173
-     * @throws EE_Error
1174
-     * @throws ReflectionException
1175
-     */
1176
-    public function get_venues($per_page = 10, $count = false)
1177
-    {
1178
-        $orderby = $this->request->getRequestParam('orderby', '');
1179
-
1180
-        switch ($orderby) {
1181
-            case 'id':
1182
-                $orderby = 'VNU_ID';
1183
-                break;
1184
-
1185
-            case 'capacity':
1186
-                $orderby = 'VNU_capacity';
1187
-                break;
1188
-
1189
-            case 'city':
1190
-                $orderby = 'VNU_city';
1191
-                break;
1192
-
1193
-            default:
1194
-                $orderby = 'VNU_name';
1195
-        }
1196
-
1197
-        $sort         = $this->request->getRequestParam('order', 'ASC');
1198
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
1199
-        $per_page     = ! empty($per_page) ? $per_page : 10;
1200
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1201
-
1202
-        $offset = ($current_page - 1) * $per_page;
1203
-        $limit  = [$offset, $per_page];
1204
-
1205
-        $category = $this->request->getRequestParam('category');
1206
-        $category = $category > 0 ? $category : null;
1207
-
1208
-        $where = [];
1209
-
1210
-        // only set initial status if it is in the incoming request.  Otherwise the "all" view display's all statuses.
1211
-        $status = $this->request->getRequestParam('status');
1212
-        if ($status && $status !== 'all') {
1213
-            $where['status'] = $status;
1214
-        }
1215
-
1216
-        $venue_status = $this->request->getRequestParam('venue_status');
1217
-        if ($venue_status) {
1218
-            $where['status'] = $venue_status;
1219
-        }
1220
-
1221
-
1222
-        if ($category) {
1223
-            $where['Term_Taxonomy.taxonomy'] = 'espresso_venue_categories';
1224
-            $where['Term_Taxonomy.term_id']  = $category;
1225
-        }
1226
-
1227
-
1228
-        if (! $this->capabilities->current_user_can('ee_read_others_venues', 'get_venues')) {
1229
-            $where['VNU_wp_user'] = get_current_user_id();
1230
-        } else {
1231
-            if (! $this->capabilities->current_user_can('ee_read_private_venues', 'get_venues')) {
1232
-                $where['OR'] = [
1233
-                    'status*restrict_private' => ['!=', 'private'],
1234
-                    'AND'                     => [
1235
-                        'status*inclusive' => ['=', 'private'],
1236
-                        'VNU_wp_user'      => get_current_user_id(),
1237
-                    ],
1238
-                ];
1239
-            }
1240
-        }
1241
-
1242
-        $search_term = $this->request->getRequestParam('s');
1243
-        if ($search_term) {
1244
-            $search_term = '%' . $search_term . '%';
1245
-            $where['OR'] = [
1246
-                'VNU_name'               => ['LIKE', $search_term],
1247
-                'VNU_desc'               => ['LIKE', $search_term],
1248
-                'VNU_short_desc'         => ['LIKE', $search_term],
1249
-                'VNU_address'            => ['LIKE', $search_term],
1250
-                'VNU_address2'           => ['LIKE', $search_term],
1251
-                'VNU_city'               => ['LIKE', $search_term],
1252
-                'VNU_zip'                => ['LIKE', $search_term],
1253
-                'VNU_phone'              => ['LIKE', $search_term],
1254
-                'VNU_url'                => ['LIKE', $search_term],
1255
-                'VNU_virtual_phone'      => ['LIKE', $search_term],
1256
-                'VNU_virtual_url'        => ['LIKE', $search_term],
1257
-                'VNU_google_map_link'    => ['LIKE', $search_term],
1258
-                'Event.EVT_name'         => ['LIKE', $search_term],
1259
-                'Event.EVT_desc'         => ['LIKE', $search_term],
1260
-                'Event.EVT_phone'        => ['LIKE', $search_term],
1261
-                'Event.EVT_external_URL' => ['LIKE', $search_term],
1262
-            ];
1263
-        }
1264
-
1265
-
1266
-        return $count
1267
-            ? $this->_venue_model->count([$where], 'VNU_ID')
1268
-            : $this->_venue_model->get_all(
1269
-                [$where, 'limit' => $limit, 'order_by' => $orderby, 'order' => $sort]
1270
-            );
1271
-    }
1272
-
1273
-
1274
-
1275
-
1276
-    /** Venue Category Stuff **/
1277
-
1278
-    /**
1279
-     * set the _category property with the category object for the loaded page.
1280
-     *
1281
-     * @access private
1282
-     * @return void
1283
-     */
1284
-    private function _set_category_object()
1285
-    {
1286
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
1287
-            return;
1288
-        } // already have the category object so get out.
1289
-
1290
-        // set default category object
1291
-        $this->_set_empty_category_object();
1292
-
1293
-        // only set if we've got an id
1294
-        $category_ID = $this->request->getRequestParam('VEN_CAT_ID', 0, 'int');
1295
-        if (! $category_ID) {
1296
-            return;
1297
-        }
1298
-
1299
-        $term = get_term($category_ID, 'espresso_venue_categories');
1300
-
1301
-
1302
-        if (! empty($term)) {
1303
-            $this->_category->category_name       = $term->name;
1304
-            $this->_category->category_identifier = $term->slug;
1305
-            $this->_category->category_desc       = $term->description;
1306
-            $this->_category->id                  = $term->term_id;
1307
-            $this->_category->parent              = $term->parent;
1308
-        }
1309
-    }
1310
-
1311
-
1312
-    private function _set_empty_category_object()
1313
-    {
1314
-        $this->_category                = new stdClass();
1315
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
1316
-        $this->_category->id            = $this->_category->parent = 0;
1317
-    }
1318
-
1319
-
1320
-    /**
1321
-     * @throws EE_Error
1322
-     */
1323
-    protected function _category_list_table()
1324
-    {
1325
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1326
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1327
-                'add_category',
1328
-                'add_category',
1329
-                [],
1330
-                'add-new-h2'
1331
-            );
1332
-        $this->_search_btn_label = esc_html__('Venue Categories', 'event_espresso');
1333
-        $this->display_admin_list_table_page_with_sidebar();
1334
-    }
1335
-
1336
-
1337
-    /**
1338
-     * @throws EE_Error
1339
-     */
1340
-    protected function _category_details($view)
1341
-    {
1342
-        // load formatter helper
1343
-        // load field generator helper
1344
-
1345
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
1346
-        $this->_set_add_edit_form_tags($route);
1347
-
1348
-        $this->_set_category_object();
1349
-        $id = ! empty($this->_category->id) ? $this->_category->id : '';
1350
-
1351
-        $delete_action = 'delete_category';
1352
-
1353
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(['action' => 'category_list'], $this->_admin_base_url);
1354
-
1355
-        $this->_set_publish_post_box_vars('VEN_CAT_ID', $id, $delete_action, $redirect);
1356
-
1357
-        // take care of contents
1358
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
1359
-        $this->display_admin_page_with_sidebar();
1360
-    }
1361
-
1362
-
1363
-    protected function _category_details_content(): string
1364
-    {
1365
-        $editor_args['category_desc'] = [
1366
-            'type'          => 'wp_editor',
1367
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
1368
-            'class'         => 'my_editor_custom',
1369
-            'wpeditor_args' => ['media_buttons' => false],
1370
-        ];
1371
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
1372
-
1373
-        $all_terms = get_terms(
1374
-            ['espresso_venue_categories'],
1375
-            ['hide_empty' => 0, 'exclude' => [$this->_category->id]]
1376
-        );
1377
-
1378
-        // setup category select for term parents.
1379
-        $category_select_values[] = [
1380
-            'text' => esc_html__('No Parent', 'event_espresso'),
1381
-            'id'   => 0,
1382
-        ];
1383
-        foreach ($all_terms as $term) {
1384
-            $category_select_values[] = [
1385
-                'text' => $term->name,
1386
-                'id'   => $term->term_id,
1387
-            ];
1388
-        }
1389
-
1390
-        $category_select = EEH_Form_Fields::select_input(
1391
-            'category_parent',
1392
-            $category_select_values,
1393
-            $this->_category->parent
1394
-        );
1395
-        $template_args   = [
1396
-            'category'                 => $this->_category,
1397
-            'category_select'          => $category_select,
1398
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
1399
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
1400
-            'disable'                  => '',
1401
-            'disabled_message'         => false,
1402
-        ];
1403
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
1404
-        return EEH_Template::display_template($template, $template_args, true);
1405
-    }
1406
-
1407
-
1408
-    /**
1409
-     * @throws EE_Error
1410
-     */
1411
-    protected function _delete_categories()
1412
-    {
1413
-        $category_ID  = $this->request->getRequestParam('category_id', 0, 'int');
1414
-        $category_IDs = $this->request->getRequestParam('VEN_CAT_ID', [$category_ID], 'int', true);
1415
-
1416
-        foreach ($category_IDs as $cat_id) {
1417
-            $this->_delete_category($cat_id);
1418
-        }
1419
-
1420
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
1421
-        $query_args = [
1422
-            'action' => 'category_list',
1423
-        ];
1424
-        $this->_redirect_after_action(0, '', '', $query_args);
1425
-    }
1426
-
1427
-
1428
-    protected function _delete_category($cat_id)
1429
-    {
1430
-        $cat_id = absint($cat_id);
1431
-        wp_delete_term($cat_id, 'espresso_venue_categories');
1432
-    }
1433
-
1434
-
1435
-    /**
1436
-     * @throws EE_Error
1437
-     */
1438
-    protected function _insert_or_update_category($new_category)
1439
-    {
1440
-        $cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
1441
-        $success = 0; // we already have a success message so lets not send another.
1442
-        if ($cat_id) {
1443
-            $query_args = [
1444
-                'action'     => 'edit_category',
1445
-                'VEN_CAT_ID' => $cat_id,
1446
-            ];
1447
-        } else {
1448
-            $query_args = ['action' => 'add_category'];
1449
-        }
1450
-        $this->_redirect_after_action($success, '', '', $query_args, true);
1451
-    }
1452
-
1453
-
1454
-    private function _insert_category($update = false)
1455
-    {
1456
-        $category_ID     = $update ? $this->request->getRequestParam('VEN_CAT_ID', '', 'int') : '';
1457
-        $category_name   = $this->request->getRequestParam('category_name', '');
1458
-        $category_desc   = $this->request->getRequestParam('category_desc', '', 'html');
1459
-        $category_parent = $this->request->getRequestParam('category_parent', 0, 'int');
1460
-
1461
-        if (empty($category_name)) {
1462
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
1463
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1464
-            return false;
1465
-        }
1466
-
1467
-
1468
-        $term_args = [
1469
-            'name'        => $category_name,
1470
-            'description' => $category_desc,
1471
-            'parent'      => $category_parent,
1472
-        ];
1473
-
1474
-        $insert_ids = $update
1475
-            ? wp_update_term($category_ID, 'espresso_venue_categories', $term_args)
1476
-            : wp_insert_term(
1477
-                $category_name,
1478
-                'espresso_venue_categories',
1479
-                $term_args
1480
-            );
1481
-
1482
-        if (! is_array($insert_ids)) {
1483
-            EE_Error::add_error(
1484
-                esc_html__('An error occurred and the category has not been saved to the database.', 'event_espresso'),
1485
-                __FILE__,
1486
-                __FUNCTION__,
1487
-                __LINE__
1488
-            );
1489
-        } else {
1490
-            $category_ID = $insert_ids['term_id'];
1491
-            EE_Error::add_success(
1492
-                sprintf(
1493
-                    esc_html__('The category %s was successfully created', 'event_espresso'),
1494
-                    $category_name
1495
-                )
1496
-            );
1497
-        }
1498
-
1499
-        return $category_ID;
1500
-    }
1501
-
1502
-
1503
-    /**
1504
-     * TODO handle category exports()
1505
-     *
1506
-     * @return void
1507
-     */
1508
-    protected function _categories_export()
1509
-    {
1510
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
1511
-        $this->request->mergeRequestParams(
1512
-            [
1513
-                'export'       => 'report',
1514
-                'action'       => 'categories',
1515
-                'category_ids' => $this->request->getRequestParam('VEN_CAT_ID', 0, 'int'),
1516
-            ]
1517
-        );
1518
-
1519
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
1520
-            require_once(EE_CLASSES . 'EE_Export.class.php');
1521
-            $EE_Export = EE_Export::instance($this->request->requestParams());
1522
-            $EE_Export->export();
1523
-        }
1524
-    }
1525
-
1526
-
1527
-    protected function _import_categories()
1528
-    {
1529
-        require_once(EE_CLASSES . 'EE_Import.class.php');
1530
-        EE_Import::instance()->import();
1531
-    }
1532
-
1533
-
1534
-    /**
1535
-     * @throws EE_Error
1536
-     * @throws ReflectionException
1537
-     */
1538
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
1539
-    {
1540
-        // testing term stuff
1541
-        $orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
1542
-        $order       = $this->request->getRequestParam('order', 'DESC');
1543
-        $limit       = ($current_page - 1) * $per_page;
1544
-        $where       = ['taxonomy' => 'espresso_venue_categories'];
1545
-        $search_term = $this->request->getRequestParam('s');
1546
-        if ($search_term) {
1547
-            $search_term = '%' . $search_term . '%';
1548
-            $where['OR'] = [
1549
-                'Term.name'   => ['LIKE', $search_term],
1550
-                'description' => ['LIKE', $search_term],
1551
-            ];
1552
-        }
1553
-
1554
-        $query_params = [
1555
-            $where,
1556
-            'order_by'   => [$orderby => $order],
1557
-            'limit'      => $limit . ',' . $per_page,
1558
-            'force_join' => ['Term'],
1559
-        ];
1560
-
1561
-        return $count
1562
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
1563
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
1564
-    }
1565
-
1566
-
1567
-    /* end category stuff */
1568
-    /**************/
560
+	protected function _google_map_settings()
561
+	{
562
+		$this->_template_args['values']           = $this->_yes_no_values;
563
+		$default_map_settings                     = new stdClass();
564
+		$default_map_settings->use_google_maps    = true;
565
+		$default_map_settings->google_map_api_key = '';
566
+		// for event details pages (reg page)
567
+		$default_map_settings->event_details_map_width = 585;
568
+		// ee_map_width_single
569
+		$default_map_settings->event_details_map_height = 362;
570
+		// ee_map_height_single
571
+		$default_map_settings->event_details_map_zoom = 14;
572
+		// ee_map_zoom_single
573
+		$default_map_settings->event_details_display_nav = true;
574
+		// ee_map_nav_display_single
575
+		$default_map_settings->event_details_nav_size = false;
576
+		// ee_map_nav_size_single
577
+		$default_map_settings->event_details_control_type = 'default';
578
+		// ee_map_type_control_single
579
+		$default_map_settings->event_details_map_align = 'center';
580
+		// ee_map_align_single
581
+
582
+		// for event list pages
583
+		$default_map_settings->event_list_map_width = 300;
584
+		// ee_map_width
585
+		$default_map_settings->event_list_map_height = 185;
586
+		// ee_map_height
587
+		$default_map_settings->event_list_map_zoom = 12;
588
+		// ee_map_zoom
589
+		$default_map_settings->event_list_display_nav = false;
590
+		// ee_map_nav_display
591
+		$default_map_settings->event_list_nav_size = true;
592
+		// ee_map_nav_size
593
+		$default_map_settings->event_list_control_type = 'dropdown';
594
+		// ee_map_type_control
595
+		$default_map_settings->event_list_map_align = 'center';
596
+		// ee_map_align
597
+
598
+		$this->_template_args['map_settings'] =
599
+			isset(EE_Registry::instance()->CFG->map_settings)
600
+			&& ! empty(EE_Registry::instance()->CFG->map_settings)
601
+				? (object) array_merge(
602
+				(array) $default_map_settings,
603
+				(array) EE_Registry::instance()->CFG->map_settings
604
+			)
605
+				: $default_map_settings;
606
+
607
+		$this->_set_add_edit_form_tags('update_google_map_settings');
608
+		$this->_set_publish_post_box_vars();
609
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
610
+			EE_VENUES_TEMPLATE_PATH . 'google_map.template.php',
611
+			$this->_template_args,
612
+			true
613
+		);
614
+		$this->display_admin_page_with_sidebar();
615
+	}
616
+
617
+
618
+	/**
619
+	 * @throws EE_Error
620
+	 */
621
+	protected function _update_google_map_settings()
622
+	{
623
+		$map_settings = EE_Registry::instance()->CFG->map_settings;
624
+
625
+		$settings = [
626
+			'use_google_maps'            => 'int',
627
+			'google_map_api_key'         => 'string',
628
+			'event_details_map_width'    => 'int',
629
+			'event_details_map_zoom'     => 'int',
630
+			'event_details_display_nav'  => 'int',
631
+			'event_details_nav_size'     => 'int',
632
+			'event_details_control_type' => 'string',
633
+			'event_details_map_align'    => 'string',
634
+			'event_list_map_width'       => 'int',
635
+			'event_list_map_height'      => 'int',
636
+			'event_list_map_zoom'        => 'int',
637
+			'event_list_display_nav'     => 'int',
638
+			'event_list_nav_size'        => 'int',
639
+			'event_list_control_type'    => 'string',
640
+			'event_list_map_align'       => 'string',
641
+		];
642
+
643
+		foreach ($settings as $setting => $type) {
644
+			$map_settings->{$setting} = $this->request->getRequestParam($setting, $map_settings->{$setting}, $type);
645
+		}
646
+
647
+		EE_Registry::instance()->CFG->map_settings = apply_filters(
648
+			'FHEE__Extend_General_Settings_Admin_Page___update_google_map_settings__CFG_map_settings',
649
+			$map_settings
650
+		);
651
+
652
+		$what    = 'Google Map Settings';
653
+		$success = $this->_update_espresso_configuration(
654
+			$what,
655
+			EE_Registry::instance()->CFG->map_settings,
656
+			__FILE__,
657
+			__FUNCTION__,
658
+			__LINE__
659
+		);
660
+		$this->_redirect_after_action($success, $what, 'updated', ['action' => 'google_map_settings']);
661
+	}
662
+
663
+
664
+	/**
665
+	 * @throws EE_Error
666
+	 * @throws ReflectionException
667
+	 */
668
+	protected function _venue_editor_metaboxes()
669
+	{
670
+		$this->verify_cpt_object();
671
+
672
+		$this->addMetaBox(
673
+			'espresso_venue_address_options',
674
+			esc_html__('Physical Location', 'event_espresso'),
675
+			[$this, 'venue_address_metabox'],
676
+			$this->page_slug,
677
+			'side',
678
+			'core'
679
+		);
680
+		$this->addMetaBox(
681
+			'espresso_venue_gmap_options',
682
+			esc_html__('Google Map', 'event_espresso'),
683
+			[$this, 'venue_gmap_metabox'],
684
+			$this->page_slug,
685
+			'side'
686
+		);
687
+		$this->addMetaBox(
688
+			'espresso_venue_virtual_loc_options',
689
+			esc_html__('Virtual Location', 'event_espresso'),
690
+			[$this, 'venue_virtual_loc_metabox'],
691
+			$this->page_slug,
692
+			'side'
693
+		);
694
+	}
695
+
696
+
697
+	/**
698
+	 * @throws EE_Error
699
+	 * @throws ReflectionException
700
+	 */
701
+	public function venue_gmap_metabox()
702
+	{
703
+		$template_args = [
704
+			'vnu_enable_for_gmap' => EEH_Form_Fields::select_input(
705
+				'vnu_enable_for_gmap',
706
+				$this->get_yes_no_values(),
707
+				$this->_cpt_model_obj instanceof EE_Venue && $this->_cpt_model_obj->enable_for_gmap()
708
+			),
709
+			'vnu_google_map_link' => $this->_cpt_model_obj->google_map_link(),
710
+		];
711
+		$template      = EE_VENUES_TEMPLATE_PATH . 'venue_gmap_metabox_content.template.php';
712
+		EEH_Template::display_template($template, $template_args);
713
+	}
714
+
715
+
716
+	/**
717
+	 * @throws EE_Error
718
+	 * @throws ReflectionException
719
+	 */
720
+	public function venue_address_metabox()
721
+	{
722
+		$template_args['_venue'] = $this->_cpt_model_obj;
723
+
724
+		$template_args['states_dropdown']    = EEH_Form_Fields::generate_form_input(
725
+			new EE_Question_Form_Input(
726
+				EE_Question::new_instance(
727
+					['QST_display_text' => esc_html__('State', 'event_espresso'), 'QST_system' => 'state']
728
+				),
729
+				EE_Answer::new_instance(
730
+					[
731
+						'ANS_value' => $this->_cpt_model_obj instanceof EE_Venue
732
+							? $this->_cpt_model_obj->state_ID()
733
+							: 0,
734
+					]
735
+				),
736
+				[
737
+					'input_name'     => 'sta_id',
738
+					'input_id'       => 'sta_id',
739
+					'input_class'    => '',
740
+					'input_prefix'   => '',
741
+					'append_qstn_id' => false,
742
+				]
743
+			)
744
+		);
745
+		$template_args['countries_dropdown'] = EEH_Form_Fields::generate_form_input(
746
+			new EE_Question_Form_Input(
747
+				EE_Question::new_instance(
748
+					['QST_display_text' => esc_html__('Country', 'event_espresso'), 'QST_system' => 'country']
749
+				),
750
+				EE_Answer::new_instance(
751
+					[
752
+						'ANS_value' => $this->_cpt_model_obj instanceof EE_Venue
753
+							? $this->_cpt_model_obj->country_ID()
754
+							: 0,
755
+					]
756
+				),
757
+				[
758
+					'input_name'     => 'cnt_iso',
759
+					'input_id'       => 'cnt_iso',
760
+					'input_class'    => '',
761
+					'input_prefix'   => '',
762
+					'append_qstn_id' => false,
763
+				]
764
+			)
765
+		);
766
+
767
+		$template = EE_VENUES_TEMPLATE_PATH . 'venue_address_metabox_content.template.php';
768
+		EEH_Template::display_template($template, $template_args);
769
+	}
770
+
771
+
772
+	public function venue_virtual_loc_metabox()
773
+	{
774
+		$template_args = [
775
+			'_venue' => $this->_cpt_model_obj,
776
+		];
777
+		$template      = EE_VENUES_TEMPLATE_PATH . 'venue_virtual_location_metabox_content.template.php';
778
+		EEH_Template::display_template($template, $template_args);
779
+	}
780
+
781
+
782
+	/**
783
+	 * @throws EE_Error
784
+	 * @throws ReflectionException
785
+	 */
786
+	protected function _restore_cpt_item($post_id, $revision_id)
787
+	{
788
+		$this->_cpt_model_obj = $this->_venue_model->get_one_by_ID($post_id);
789
+		// meta revision restore
790
+		$this->_cpt_model_obj->restore_revision($revision_id);
791
+	}
792
+
793
+
794
+	/**
795
+	 * Handles updates for venue cpts
796
+	 *
797
+	 * @param int     $post_id ID of Venue CPT
798
+	 * @param WP_Post $post    Post object (with "blessed" WP properties)
799
+	 * @return void
800
+	 * @throws EE_Error
801
+	 * @throws ReflectionException
802
+	 */
803
+	protected function _insert_update_cpt_item($post_id, $post)
804
+	{
805
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_venues') {
806
+			return;// get out we're not processing the saving of venues.
807
+		}
808
+
809
+		$wheres = [$this->_venue_model->primary_key_name() => $post_id];
810
+
811
+		$venue_values = [
812
+			'VNU_address'         => $this->request->getRequestParam('vnu_address'),
813
+			'VNU_address2'        => $this->request->getRequestParam('vnu_address2'),
814
+			'VNU_city'            => $this->request->getRequestParam('vnu_city'),
815
+			'STA_ID'              => $this->request->getRequestParam('sta_id'),
816
+			'CNT_ISO'             => $this->request->getRequestParam('cnt_iso'),
817
+			'VNU_zip'             => $this->request->getRequestParam('vnu_zip'),
818
+			'VNU_phone'           => $this->request->getRequestParam('vnu_phone'),
819
+			'VNU_capacity'        => $this->request->requestParamIsSet('vnu_capacity')
820
+				? str_replace(',', '', $this->request->getRequestParam('vnu_capacity'))
821
+				: EE_INF,
822
+			'VNU_url'             => $this->request->getRequestParam('vnu_url'),
823
+			'VNU_virtual_phone'   => $this->request->getRequestParam('vnu_virtual_phone'),
824
+			'VNU_virtual_url'     => $this->request->getRequestParam('vnu_virtual_url'),
825
+			'VNU_enable_for_gmap' => $this->request->getRequestParam('vnu_enable_for_gmap', false, 'bool'),
826
+			'VNU_google_map_link' => $this->request->getRequestParam('vnu_google_map_link'),
827
+		];
828
+
829
+		// update venue
830
+		$success = $this->_venue_model->update($venue_values, [$wheres]);
831
+
832
+		// get venue_object for other metaboxes that might be added via the filter... though it would seem to make sense to just use $this->_venue_model->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
833
+		$get_one_where = [$this->_venue_model->primary_key_name() => $post_id, 'status' => $post->post_status];
834
+		$venue         = $this->_venue_model->get_one([$get_one_where]);
835
+
836
+		// notice we've applied a filter for venue metabox callbacks but we don't actually have any default venue metaboxes in use.  So this is just here for addons to more easily hook into venue saves.
837
+		$venue_update_callbacks = apply_filters(
838
+			'FHEE__Venues_Admin_Page___insert_update_cpt_item__venue_update_callbacks',
839
+			[]
840
+		);
841
+		$att_success            = true;
842
+		foreach ($venue_update_callbacks as $v_callback) {
843
+			// if ANY of these updates fail then we want the appropriate global error message
844
+			$att_success = call_user_func_array($v_callback, [$venue, $this->request->requestParams()])
845
+				? $att_success
846
+				: false;
847
+		}
848
+
849
+		// any errors?
850
+		if ($success && ! $att_success) {
851
+			EE_Error::add_error(
852
+				esc_html__(
853
+					'Venue Details saved successfully but something went wrong with saving attachments.',
854
+					'event_espresso'
855
+				),
856
+				__FILE__,
857
+				__FUNCTION__,
858
+				__LINE__
859
+			);
860
+		} elseif ($success === false) {
861
+			EE_Error::add_error(
862
+				esc_html__('Venue Details did not save successfully.', 'event_espresso'),
863
+				__FILE__,
864
+				__FUNCTION__,
865
+				__LINE__
866
+			);
867
+		}
868
+	}
869
+
870
+
871
+	/**
872
+	 * @param int $post_id
873
+	 * @throws EE_Error
874
+	 * @throws ReflectionException
875
+	 */
876
+	public function trash_cpt_item($post_id)
877
+	{
878
+		$this->request->setRequestParam('VNU_ID', $post_id);
879
+		$this->_trash_or_restore_venue('trash', false);
880
+	}
881
+
882
+
883
+	/**
884
+	 * @param int $post_id
885
+	 * @throws EE_Error
886
+	 * @throws ReflectionException
887
+	 */
888
+	public function restore_cpt_item($post_id)
889
+	{
890
+		$this->request->setRequestParam('VNU_ID', $post_id);
891
+		$this->_trash_or_restore_venue('draft', false);
892
+	}
893
+
894
+
895
+	/**
896
+	 * @param int $post_id
897
+	 * @throws EE_Error
898
+	 * @throws ReflectionException
899
+	 */
900
+	public function delete_cpt_item($post_id)
901
+	{
902
+		$this->request->setRequestParam('VNU_ID', $post_id);
903
+		$this->_delete_venue(false);
904
+	}
905
+
906
+
907
+	public function get_venue_object()
908
+	{
909
+		return $this->_cpt_model_obj;
910
+	}
911
+
912
+
913
+	/**
914
+	 * @param string    $venue_status
915
+	 * @param bool|null $redirect_after
916
+	 * @throws EE_Error
917
+	 * @throws ReflectionException
918
+	 */
919
+	protected function _trash_or_restore_venue(string $venue_status = 'trash', ?bool $redirect_after = true)
920
+	{
921
+		// loop thru venues
922
+		if ($this->VNU_ID) {
923
+			// clean status
924
+			$venue_status = sanitize_key($venue_status);
925
+			// grab status
926
+			if (! empty($venue_status)) {
927
+				$success = $this->_change_venue_status($this->VNU_ID, $venue_status);
928
+			} else {
929
+				$success = false;
930
+				$msg     = esc_html__(
931
+					'An error occurred. The venue could not be moved to the trash because a valid venue status was not not supplied.',
932
+					'event_espresso'
933
+				);
934
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
935
+			}
936
+		} else {
937
+			$success = false;
938
+			$msg     = esc_html__(
939
+				'An error occurred. The venue could not be moved to the trash because a valid venue ID was not not supplied.',
940
+				'event_espresso'
941
+			);
942
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
943
+		}
944
+		$action = $venue_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
945
+
946
+		if ($redirect_after) {
947
+			$this->_redirect_after_action($success, 'Venue', $action, ['action' => 'default']);
948
+		}
949
+	}
950
+
951
+
952
+	/**
953
+	 * @param string $venue_status
954
+	 * @throws EE_Error
955
+	 * @throws ReflectionException
956
+	 */
957
+	protected function _trash_or_restore_venues(string $venue_status = 'trash')
958
+	{
959
+		// clean status
960
+		$venue_status = sanitize_key($venue_status);
961
+		// grab status
962
+		if (! empty($venue_status)) {
963
+			$success = true;
964
+			// determine the event id and set to array.
965
+			$VNU_IDs = $this->request->getRequestParam('venue_id', [], 'int', true);
966
+			// loop thru events
967
+			foreach ($VNU_IDs as $VNU_ID) {
968
+				if ($VNU_ID = absint($VNU_ID)) {
969
+					$results = $this->_change_venue_status($VNU_ID, $venue_status);
970
+					$success = $results !== false ? $success : false;
971
+				} else {
972
+					$msg = sprintf(
973
+						esc_html__(
974
+							'An error occurred. Venue #%d could not be moved to the trash because a valid venue ID was not not supplied.',
975
+							'event_espresso'
976
+						),
977
+						$VNU_ID
978
+					);
979
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
980
+					$success = false;
981
+				}
982
+			}
983
+		} else {
984
+			$success = false;
985
+			$msg     = esc_html__(
986
+				'An error occurred. The venue could not be moved to the trash because a valid venue status was not not supplied.',
987
+				'event_espresso'
988
+			);
989
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
990
+		}
991
+		// in order to force a pluralized result message we need to send back a success status greater than 1
992
+		$success = $success ? 2 : false;
993
+		$action  = $venue_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
994
+		$this->_redirect_after_action($success, 'Venues', $action, ['action' => 'default']);
995
+	}
996
+
997
+
998
+	/**
999
+	 * _trash_or_restore_venues
1000
+	 * //todo this is pretty much the same as the corresponding change_event_status method in Events_Admin_Page.  We
1001
+	 * should probably abstract this up to the EE_Admin_Page_CPT (or even EE_Admin_Page) and make this a common method
1002
+	 * accepting a certain number of params.
1003
+	 *
1004
+	 * @param int|null $VNU_ID
1005
+	 * @param string   $venue_status
1006
+	 * @return bool
1007
+	 * @throws EE_Error
1008
+	 * @throws ReflectionException
1009
+	 */
1010
+	private function _change_venue_status(?int $VNU_ID = 0, string $venue_status = ''): bool
1011
+	{
1012
+		// grab venue id
1013
+		if (! $VNU_ID) {
1014
+			$msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1015
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1016
+			return false;
1017
+		}
1018
+
1019
+		$this->_cpt_model_obj = EEM_Venue::instance()->get_one_by_ID($VNU_ID);
1020
+
1021
+		// clean status
1022
+		$venue_status = sanitize_key($venue_status);
1023
+		// grab status
1024
+		if (! $venue_status) {
1025
+			$msg = esc_html__(
1026
+				'An error occurred. No Venue Status or an invalid Venue Status was received.',
1027
+				'event_espresso'
1028
+			);
1029
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1030
+			return false;
1031
+		}
1032
+
1033
+		// was event trashed or restored ?
1034
+		switch ($venue_status) {
1035
+			case 'draft':
1036
+				$action = 'restored from the trash';
1037
+				$hook   = 'AHEE_venue_restored_from_trash';
1038
+				break;
1039
+			case 'trash':
1040
+				$action = 'moved to the trash';
1041
+				$hook   = 'AHEE_venue_moved_to_trash';
1042
+				break;
1043
+			default:
1044
+				$action = 'updated';
1045
+				$hook   = false;
1046
+		}
1047
+		// use class to change status
1048
+		$this->_cpt_model_obj->set_status($venue_status);
1049
+		$success = $this->_cpt_model_obj->save();
1050
+
1051
+		if ($success === false) {
1052
+			$msg = sprintf(esc_html__('An error occurred. The venue could not be %s.', 'event_espresso'), $action);
1053
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1054
+			return false;
1055
+		}
1056
+		if ($hook) {
1057
+			do_action($hook);
1058
+		}
1059
+		return true;
1060
+	}
1061
+
1062
+
1063
+	/**
1064
+	 * @param bool $redirect_after
1065
+	 * @return void
1066
+	 * @throws EE_Error
1067
+	 * @throws ReflectionException
1068
+	 */
1069
+	protected function _delete_venue(bool $redirect_after = true)
1070
+	{
1071
+		// loop thru venues
1072
+		if ($this->VNU_ID) {
1073
+			$success = $this->_delete_or_trash_venue($this->VNU_ID);
1074
+		} else {
1075
+			$success = false;
1076
+			$msg     = esc_html__(
1077
+				'An error occurred. An venue could not be deleted because a valid venue ID was not not supplied.',
1078
+				'event_espresso'
1079
+			);
1080
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1081
+		}
1082
+		if ($redirect_after) {
1083
+			$this->_redirect_after_action($success, 'Venue', 'deleted', ['action' => 'default']);
1084
+		}
1085
+	}
1086
+
1087
+
1088
+	/**
1089
+	 * @throws EE_Error
1090
+	 * @throws ReflectionException
1091
+	 */
1092
+	protected function _delete_venues()
1093
+	{
1094
+		$success = true;
1095
+		// determine the event id and set to array.
1096
+		$VNU_IDs = $this->request->getRequestParam('venue_id', [], 'int', true);
1097
+		// loop thru events
1098
+		foreach ($VNU_IDs as $VNU_ID) {
1099
+			if ($VNU_ID = absint($VNU_ID)) {
1100
+				$results = $this->_delete_or_trash_venue($VNU_ID);
1101
+				$success = $results !== false ? $success : false;
1102
+			} else {
1103
+				$success = false;
1104
+				$msg     = esc_html__(
1105
+					'An error occurred. An venue could not be deleted because a valid venue ID was not not supplied.',
1106
+					'event_espresso'
1107
+				);
1108
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1109
+			}
1110
+		}
1111
+		// in order to force a pluralized result message we need to send back a success status greater than 1
1112
+		$success = $success ? 2 : false;
1113
+		$this->_redirect_after_action(
1114
+			$success,
1115
+			esc_html__('Venues', 'event_espresso'),
1116
+			esc_html__('deleted', 'event_espresso'),
1117
+			['action' => 'default']
1118
+		);
1119
+	}
1120
+
1121
+
1122
+	// todo: put in parent
1123
+
1124
+
1125
+	/**
1126
+	 * @param int|null $VNU_ID
1127
+	 * @return bool
1128
+	 * @throws EE_Error
1129
+	 * @throws ReflectionException
1130
+	 */
1131
+	private function _delete_or_trash_venue(?int $VNU_ID = 0): bool
1132
+	{
1133
+		// grab event id
1134
+		if (! $VNU_ID = absint($VNU_ID)) {
1135
+			$msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1136
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1137
+			return false;
1138
+		}
1139
+
1140
+
1141
+		$venue = EEM_Venue::instance()->get_one_by_ID($VNU_ID);
1142
+		// first need to remove all term relationships
1143
+		$venue->_remove_relations('Term_Taxonomy');
1144
+		$success = $venue->delete_permanently();
1145
+		// did it all go as planned ?
1146
+		if (! $success) {
1147
+			EE_Error::add_error(
1148
+				sprintf(
1149
+					esc_html__('An error occurred. Venue ID # %d could not be deleted.', 'event_espresso'),
1150
+					$VNU_ID
1151
+				),
1152
+				__FILE__,
1153
+				__FUNCTION__,
1154
+				__LINE__
1155
+			);
1156
+			return false;
1157
+		}
1158
+		EE_Error::add_success(
1159
+			sprintf(esc_html__('Venue ID # %d has been deleted.', 'event_espresso'), $VNU_ID)
1160
+		);
1161
+		do_action('AHEE__Venues_Admin_Page___delete_or_trash_venue__after_venue_deleted');
1162
+		return true;
1163
+	}
1164
+
1165
+
1166
+
1167
+
1168
+	/***********/
1169
+	/* QUERIES */
1170
+
1171
+
1172
+	/**
1173
+	 * @throws EE_Error
1174
+	 * @throws ReflectionException
1175
+	 */
1176
+	public function get_venues($per_page = 10, $count = false)
1177
+	{
1178
+		$orderby = $this->request->getRequestParam('orderby', '');
1179
+
1180
+		switch ($orderby) {
1181
+			case 'id':
1182
+				$orderby = 'VNU_ID';
1183
+				break;
1184
+
1185
+			case 'capacity':
1186
+				$orderby = 'VNU_capacity';
1187
+				break;
1188
+
1189
+			case 'city':
1190
+				$orderby = 'VNU_city';
1191
+				break;
1192
+
1193
+			default:
1194
+				$orderby = 'VNU_name';
1195
+		}
1196
+
1197
+		$sort         = $this->request->getRequestParam('order', 'ASC');
1198
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
1199
+		$per_page     = ! empty($per_page) ? $per_page : 10;
1200
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1201
+
1202
+		$offset = ($current_page - 1) * $per_page;
1203
+		$limit  = [$offset, $per_page];
1204
+
1205
+		$category = $this->request->getRequestParam('category');
1206
+		$category = $category > 0 ? $category : null;
1207
+
1208
+		$where = [];
1209
+
1210
+		// only set initial status if it is in the incoming request.  Otherwise the "all" view display's all statuses.
1211
+		$status = $this->request->getRequestParam('status');
1212
+		if ($status && $status !== 'all') {
1213
+			$where['status'] = $status;
1214
+		}
1215
+
1216
+		$venue_status = $this->request->getRequestParam('venue_status');
1217
+		if ($venue_status) {
1218
+			$where['status'] = $venue_status;
1219
+		}
1220
+
1221
+
1222
+		if ($category) {
1223
+			$where['Term_Taxonomy.taxonomy'] = 'espresso_venue_categories';
1224
+			$where['Term_Taxonomy.term_id']  = $category;
1225
+		}
1226
+
1227
+
1228
+		if (! $this->capabilities->current_user_can('ee_read_others_venues', 'get_venues')) {
1229
+			$where['VNU_wp_user'] = get_current_user_id();
1230
+		} else {
1231
+			if (! $this->capabilities->current_user_can('ee_read_private_venues', 'get_venues')) {
1232
+				$where['OR'] = [
1233
+					'status*restrict_private' => ['!=', 'private'],
1234
+					'AND'                     => [
1235
+						'status*inclusive' => ['=', 'private'],
1236
+						'VNU_wp_user'      => get_current_user_id(),
1237
+					],
1238
+				];
1239
+			}
1240
+		}
1241
+
1242
+		$search_term = $this->request->getRequestParam('s');
1243
+		if ($search_term) {
1244
+			$search_term = '%' . $search_term . '%';
1245
+			$where['OR'] = [
1246
+				'VNU_name'               => ['LIKE', $search_term],
1247
+				'VNU_desc'               => ['LIKE', $search_term],
1248
+				'VNU_short_desc'         => ['LIKE', $search_term],
1249
+				'VNU_address'            => ['LIKE', $search_term],
1250
+				'VNU_address2'           => ['LIKE', $search_term],
1251
+				'VNU_city'               => ['LIKE', $search_term],
1252
+				'VNU_zip'                => ['LIKE', $search_term],
1253
+				'VNU_phone'              => ['LIKE', $search_term],
1254
+				'VNU_url'                => ['LIKE', $search_term],
1255
+				'VNU_virtual_phone'      => ['LIKE', $search_term],
1256
+				'VNU_virtual_url'        => ['LIKE', $search_term],
1257
+				'VNU_google_map_link'    => ['LIKE', $search_term],
1258
+				'Event.EVT_name'         => ['LIKE', $search_term],
1259
+				'Event.EVT_desc'         => ['LIKE', $search_term],
1260
+				'Event.EVT_phone'        => ['LIKE', $search_term],
1261
+				'Event.EVT_external_URL' => ['LIKE', $search_term],
1262
+			];
1263
+		}
1264
+
1265
+
1266
+		return $count
1267
+			? $this->_venue_model->count([$where], 'VNU_ID')
1268
+			: $this->_venue_model->get_all(
1269
+				[$where, 'limit' => $limit, 'order_by' => $orderby, 'order' => $sort]
1270
+			);
1271
+	}
1272
+
1273
+
1274
+
1275
+
1276
+	/** Venue Category Stuff **/
1277
+
1278
+	/**
1279
+	 * set the _category property with the category object for the loaded page.
1280
+	 *
1281
+	 * @access private
1282
+	 * @return void
1283
+	 */
1284
+	private function _set_category_object()
1285
+	{
1286
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
1287
+			return;
1288
+		} // already have the category object so get out.
1289
+
1290
+		// set default category object
1291
+		$this->_set_empty_category_object();
1292
+
1293
+		// only set if we've got an id
1294
+		$category_ID = $this->request->getRequestParam('VEN_CAT_ID', 0, 'int');
1295
+		if (! $category_ID) {
1296
+			return;
1297
+		}
1298
+
1299
+		$term = get_term($category_ID, 'espresso_venue_categories');
1300
+
1301
+
1302
+		if (! empty($term)) {
1303
+			$this->_category->category_name       = $term->name;
1304
+			$this->_category->category_identifier = $term->slug;
1305
+			$this->_category->category_desc       = $term->description;
1306
+			$this->_category->id                  = $term->term_id;
1307
+			$this->_category->parent              = $term->parent;
1308
+		}
1309
+	}
1310
+
1311
+
1312
+	private function _set_empty_category_object()
1313
+	{
1314
+		$this->_category                = new stdClass();
1315
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
1316
+		$this->_category->id            = $this->_category->parent = 0;
1317
+	}
1318
+
1319
+
1320
+	/**
1321
+	 * @throws EE_Error
1322
+	 */
1323
+	protected function _category_list_table()
1324
+	{
1325
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1326
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1327
+				'add_category',
1328
+				'add_category',
1329
+				[],
1330
+				'add-new-h2'
1331
+			);
1332
+		$this->_search_btn_label = esc_html__('Venue Categories', 'event_espresso');
1333
+		$this->display_admin_list_table_page_with_sidebar();
1334
+	}
1335
+
1336
+
1337
+	/**
1338
+	 * @throws EE_Error
1339
+	 */
1340
+	protected function _category_details($view)
1341
+	{
1342
+		// load formatter helper
1343
+		// load field generator helper
1344
+
1345
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
1346
+		$this->_set_add_edit_form_tags($route);
1347
+
1348
+		$this->_set_category_object();
1349
+		$id = ! empty($this->_category->id) ? $this->_category->id : '';
1350
+
1351
+		$delete_action = 'delete_category';
1352
+
1353
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(['action' => 'category_list'], $this->_admin_base_url);
1354
+
1355
+		$this->_set_publish_post_box_vars('VEN_CAT_ID', $id, $delete_action, $redirect);
1356
+
1357
+		// take care of contents
1358
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
1359
+		$this->display_admin_page_with_sidebar();
1360
+	}
1361
+
1362
+
1363
+	protected function _category_details_content(): string
1364
+	{
1365
+		$editor_args['category_desc'] = [
1366
+			'type'          => 'wp_editor',
1367
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
1368
+			'class'         => 'my_editor_custom',
1369
+			'wpeditor_args' => ['media_buttons' => false],
1370
+		];
1371
+		$_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
1372
+
1373
+		$all_terms = get_terms(
1374
+			['espresso_venue_categories'],
1375
+			['hide_empty' => 0, 'exclude' => [$this->_category->id]]
1376
+		);
1377
+
1378
+		// setup category select for term parents.
1379
+		$category_select_values[] = [
1380
+			'text' => esc_html__('No Parent', 'event_espresso'),
1381
+			'id'   => 0,
1382
+		];
1383
+		foreach ($all_terms as $term) {
1384
+			$category_select_values[] = [
1385
+				'text' => $term->name,
1386
+				'id'   => $term->term_id,
1387
+			];
1388
+		}
1389
+
1390
+		$category_select = EEH_Form_Fields::select_input(
1391
+			'category_parent',
1392
+			$category_select_values,
1393
+			$this->_category->parent
1394
+		);
1395
+		$template_args   = [
1396
+			'category'                 => $this->_category,
1397
+			'category_select'          => $category_select,
1398
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
1399
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
1400
+			'disable'                  => '',
1401
+			'disabled_message'         => false,
1402
+		];
1403
+		$template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
1404
+		return EEH_Template::display_template($template, $template_args, true);
1405
+	}
1406
+
1407
+
1408
+	/**
1409
+	 * @throws EE_Error
1410
+	 */
1411
+	protected function _delete_categories()
1412
+	{
1413
+		$category_ID  = $this->request->getRequestParam('category_id', 0, 'int');
1414
+		$category_IDs = $this->request->getRequestParam('VEN_CAT_ID', [$category_ID], 'int', true);
1415
+
1416
+		foreach ($category_IDs as $cat_id) {
1417
+			$this->_delete_category($cat_id);
1418
+		}
1419
+
1420
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
1421
+		$query_args = [
1422
+			'action' => 'category_list',
1423
+		];
1424
+		$this->_redirect_after_action(0, '', '', $query_args);
1425
+	}
1426
+
1427
+
1428
+	protected function _delete_category($cat_id)
1429
+	{
1430
+		$cat_id = absint($cat_id);
1431
+		wp_delete_term($cat_id, 'espresso_venue_categories');
1432
+	}
1433
+
1434
+
1435
+	/**
1436
+	 * @throws EE_Error
1437
+	 */
1438
+	protected function _insert_or_update_category($new_category)
1439
+	{
1440
+		$cat_id  = $new_category ? $this->_insert_category() : $this->_insert_category(true);
1441
+		$success = 0; // we already have a success message so lets not send another.
1442
+		if ($cat_id) {
1443
+			$query_args = [
1444
+				'action'     => 'edit_category',
1445
+				'VEN_CAT_ID' => $cat_id,
1446
+			];
1447
+		} else {
1448
+			$query_args = ['action' => 'add_category'];
1449
+		}
1450
+		$this->_redirect_after_action($success, '', '', $query_args, true);
1451
+	}
1452
+
1453
+
1454
+	private function _insert_category($update = false)
1455
+	{
1456
+		$category_ID     = $update ? $this->request->getRequestParam('VEN_CAT_ID', '', 'int') : '';
1457
+		$category_name   = $this->request->getRequestParam('category_name', '');
1458
+		$category_desc   = $this->request->getRequestParam('category_desc', '', 'html');
1459
+		$category_parent = $this->request->getRequestParam('category_parent', 0, 'int');
1460
+
1461
+		if (empty($category_name)) {
1462
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
1463
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1464
+			return false;
1465
+		}
1466
+
1467
+
1468
+		$term_args = [
1469
+			'name'        => $category_name,
1470
+			'description' => $category_desc,
1471
+			'parent'      => $category_parent,
1472
+		];
1473
+
1474
+		$insert_ids = $update
1475
+			? wp_update_term($category_ID, 'espresso_venue_categories', $term_args)
1476
+			: wp_insert_term(
1477
+				$category_name,
1478
+				'espresso_venue_categories',
1479
+				$term_args
1480
+			);
1481
+
1482
+		if (! is_array($insert_ids)) {
1483
+			EE_Error::add_error(
1484
+				esc_html__('An error occurred and the category has not been saved to the database.', 'event_espresso'),
1485
+				__FILE__,
1486
+				__FUNCTION__,
1487
+				__LINE__
1488
+			);
1489
+		} else {
1490
+			$category_ID = $insert_ids['term_id'];
1491
+			EE_Error::add_success(
1492
+				sprintf(
1493
+					esc_html__('The category %s was successfully created', 'event_espresso'),
1494
+					$category_name
1495
+				)
1496
+			);
1497
+		}
1498
+
1499
+		return $category_ID;
1500
+	}
1501
+
1502
+
1503
+	/**
1504
+	 * TODO handle category exports()
1505
+	 *
1506
+	 * @return void
1507
+	 */
1508
+	protected function _categories_export()
1509
+	{
1510
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
1511
+		$this->request->mergeRequestParams(
1512
+			[
1513
+				'export'       => 'report',
1514
+				'action'       => 'categories',
1515
+				'category_ids' => $this->request->getRequestParam('VEN_CAT_ID', 0, 'int'),
1516
+			]
1517
+		);
1518
+
1519
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
1520
+			require_once(EE_CLASSES . 'EE_Export.class.php');
1521
+			$EE_Export = EE_Export::instance($this->request->requestParams());
1522
+			$EE_Export->export();
1523
+		}
1524
+	}
1525
+
1526
+
1527
+	protected function _import_categories()
1528
+	{
1529
+		require_once(EE_CLASSES . 'EE_Import.class.php');
1530
+		EE_Import::instance()->import();
1531
+	}
1532
+
1533
+
1534
+	/**
1535
+	 * @throws EE_Error
1536
+	 * @throws ReflectionException
1537
+	 */
1538
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
1539
+	{
1540
+		// testing term stuff
1541
+		$orderby     = $this->request->getRequestParam('orderby', 'Term.term_id');
1542
+		$order       = $this->request->getRequestParam('order', 'DESC');
1543
+		$limit       = ($current_page - 1) * $per_page;
1544
+		$where       = ['taxonomy' => 'espresso_venue_categories'];
1545
+		$search_term = $this->request->getRequestParam('s');
1546
+		if ($search_term) {
1547
+			$search_term = '%' . $search_term . '%';
1548
+			$where['OR'] = [
1549
+				'Term.name'   => ['LIKE', $search_term],
1550
+				'description' => ['LIKE', $search_term],
1551
+			];
1552
+		}
1553
+
1554
+		$query_params = [
1555
+			$where,
1556
+			'order_by'   => [$orderby => $order],
1557
+			'limit'      => $limit . ',' . $per_page,
1558
+			'force_join' => ['Term'],
1559
+		];
1560
+
1561
+		return $count
1562
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
1563
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
1564
+	}
1565
+
1566
+
1567
+	/* end category stuff */
1568
+	/**************/
1569 1569
 }
Please login to merge, or discard this patch.
Spacing   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
 
56 56
         $this->page_slug        = EE_VENUES_PG_SLUG;
57 57
         $this->_admin_base_url  = EE_VENUES_ADMIN_URL;
58
-        $this->_admin_base_path = EE_ADMIN_PAGES . 'venues';
58
+        $this->_admin_base_path = EE_ADMIN_PAGES.'venues';
59 59
         $this->page_label       = esc_html__('Event Venues', 'event_espresso');
60 60
         $this->_cpt_model_names = [
61 61
             'create_new' => 'EEM_Venue',
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
 
438 438
     public function load_scripts_styles()
439 439
     {
440
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
440
+        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', [], EVENT_ESPRESSO_VERSION);
441 441
         wp_enqueue_style('ee-cat-admin');
442 442
     }
443 443
 
@@ -459,7 +459,7 @@  discard block
 block discarded – undo
459 459
         wp_enqueue_style('espresso-ui-theme');
460 460
         wp_register_style(
461 461
             'espresso_venues',
462
-            EE_VENUES_ASSETS_URL . 'ee-venues-admin.css',
462
+            EE_VENUES_ASSETS_URL.'ee-venues-admin.css',
463 463
             [],
464 464
             EVENT_ESPRESSO_VERSION
465 465
         );
@@ -522,7 +522,7 @@  discard block
 block discarded – undo
522 522
             'button'
523 523
         );
524 524
 
525
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
525
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
526 526
                 'create_new',
527 527
                 'add',
528 528
                 [],
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
             'vnu_url'      => $this->_cpt_model_obj->get_f('VNU_url'),
546 546
             'vnu_phone'    => $this->_cpt_model_obj->get_f('VNU_phone'),
547 547
         ];
548
-        $template   = EE_VENUES_TEMPLATE_PATH . 'venue_publish_box_extras.template.php';
548
+        $template = EE_VENUES_TEMPLATE_PATH.'venue_publish_box_extras.template.php';
549 549
         EEH_Template::display_template($template, $extra_rows);
550 550
     }
551 551
 
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
         $this->_set_add_edit_form_tags('update_google_map_settings');
608 608
         $this->_set_publish_post_box_vars();
609 609
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
610
-            EE_VENUES_TEMPLATE_PATH . 'google_map.template.php',
610
+            EE_VENUES_TEMPLATE_PATH.'google_map.template.php',
611 611
             $this->_template_args,
612 612
             true
613 613
         );
@@ -708,7 +708,7 @@  discard block
 block discarded – undo
708 708
             ),
709 709
             'vnu_google_map_link' => $this->_cpt_model_obj->google_map_link(),
710 710
         ];
711
-        $template      = EE_VENUES_TEMPLATE_PATH . 'venue_gmap_metabox_content.template.php';
711
+        $template = EE_VENUES_TEMPLATE_PATH.'venue_gmap_metabox_content.template.php';
712 712
         EEH_Template::display_template($template, $template_args);
713 713
     }
714 714
 
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
     {
722 722
         $template_args['_venue'] = $this->_cpt_model_obj;
723 723
 
724
-        $template_args['states_dropdown']    = EEH_Form_Fields::generate_form_input(
724
+        $template_args['states_dropdown'] = EEH_Form_Fields::generate_form_input(
725 725
             new EE_Question_Form_Input(
726 726
                 EE_Question::new_instance(
727 727
                     ['QST_display_text' => esc_html__('State', 'event_espresso'), 'QST_system' => 'state']
@@ -764,7 +764,7 @@  discard block
 block discarded – undo
764 764
             )
765 765
         );
766 766
 
767
-        $template = EE_VENUES_TEMPLATE_PATH . 'venue_address_metabox_content.template.php';
767
+        $template = EE_VENUES_TEMPLATE_PATH.'venue_address_metabox_content.template.php';
768 768
         EEH_Template::display_template($template, $template_args);
769 769
     }
770 770
 
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
         $template_args = [
775 775
             '_venue' => $this->_cpt_model_obj,
776 776
         ];
777
-        $template      = EE_VENUES_TEMPLATE_PATH . 'venue_virtual_location_metabox_content.template.php';
777
+        $template      = EE_VENUES_TEMPLATE_PATH.'venue_virtual_location_metabox_content.template.php';
778 778
         EEH_Template::display_template($template, $template_args);
779 779
     }
780 780
 
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
     protected function _insert_update_cpt_item($post_id, $post)
804 804
     {
805 805
         if ($post instanceof WP_Post && $post->post_type !== 'espresso_venues') {
806
-            return;// get out we're not processing the saving of venues.
806
+            return; // get out we're not processing the saving of venues.
807 807
         }
808 808
 
809 809
         $wheres = [$this->_venue_model->primary_key_name() => $post_id];
@@ -838,7 +838,7 @@  discard block
 block discarded – undo
838 838
             'FHEE__Venues_Admin_Page___insert_update_cpt_item__venue_update_callbacks',
839 839
             []
840 840
         );
841
-        $att_success            = true;
841
+        $att_success = true;
842 842
         foreach ($venue_update_callbacks as $v_callback) {
843 843
             // if ANY of these updates fail then we want the appropriate global error message
844 844
             $att_success = call_user_func_array($v_callback, [$venue, $this->request->requestParams()])
@@ -923,7 +923,7 @@  discard block
 block discarded – undo
923 923
             // clean status
924 924
             $venue_status = sanitize_key($venue_status);
925 925
             // grab status
926
-            if (! empty($venue_status)) {
926
+            if ( ! empty($venue_status)) {
927 927
                 $success = $this->_change_venue_status($this->VNU_ID, $venue_status);
928 928
             } else {
929 929
                 $success = false;
@@ -959,7 +959,7 @@  discard block
 block discarded – undo
959 959
         // clean status
960 960
         $venue_status = sanitize_key($venue_status);
961 961
         // grab status
962
-        if (! empty($venue_status)) {
962
+        if ( ! empty($venue_status)) {
963 963
             $success = true;
964 964
             // determine the event id and set to array.
965 965
             $VNU_IDs = $this->request->getRequestParam('venue_id', [], 'int', true);
@@ -1010,7 +1010,7 @@  discard block
 block discarded – undo
1010 1010
     private function _change_venue_status(?int $VNU_ID = 0, string $venue_status = ''): bool
1011 1011
     {
1012 1012
         // grab venue id
1013
-        if (! $VNU_ID) {
1013
+        if ( ! $VNU_ID) {
1014 1014
             $msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1015 1015
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1016 1016
             return false;
@@ -1021,7 +1021,7 @@  discard block
 block discarded – undo
1021 1021
         // clean status
1022 1022
         $venue_status = sanitize_key($venue_status);
1023 1023
         // grab status
1024
-        if (! $venue_status) {
1024
+        if ( ! $venue_status) {
1025 1025
             $msg = esc_html__(
1026 1026
                 'An error occurred. No Venue Status or an invalid Venue Status was received.',
1027 1027
                 'event_espresso'
@@ -1131,7 +1131,7 @@  discard block
 block discarded – undo
1131 1131
     private function _delete_or_trash_venue(?int $VNU_ID = 0): bool
1132 1132
     {
1133 1133
         // grab event id
1134
-        if (! $VNU_ID = absint($VNU_ID)) {
1134
+        if ( ! $VNU_ID = absint($VNU_ID)) {
1135 1135
             $msg = esc_html__('An error occurred. No Venue ID or an invalid Venue ID was received.', 'event_espresso');
1136 1136
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1137 1137
             return false;
@@ -1143,7 +1143,7 @@  discard block
 block discarded – undo
1143 1143
         $venue->_remove_relations('Term_Taxonomy');
1144 1144
         $success = $venue->delete_permanently();
1145 1145
         // did it all go as planned ?
1146
-        if (! $success) {
1146
+        if ( ! $success) {
1147 1147
             EE_Error::add_error(
1148 1148
                 sprintf(
1149 1149
                     esc_html__('An error occurred. Venue ID # %d could not be deleted.', 'event_espresso'),
@@ -1225,10 +1225,10 @@  discard block
 block discarded – undo
1225 1225
         }
1226 1226
 
1227 1227
 
1228
-        if (! $this->capabilities->current_user_can('ee_read_others_venues', 'get_venues')) {
1228
+        if ( ! $this->capabilities->current_user_can('ee_read_others_venues', 'get_venues')) {
1229 1229
             $where['VNU_wp_user'] = get_current_user_id();
1230 1230
         } else {
1231
-            if (! $this->capabilities->current_user_can('ee_read_private_venues', 'get_venues')) {
1231
+            if ( ! $this->capabilities->current_user_can('ee_read_private_venues', 'get_venues')) {
1232 1232
                 $where['OR'] = [
1233 1233
                     'status*restrict_private' => ['!=', 'private'],
1234 1234
                     'AND'                     => [
@@ -1241,7 +1241,7 @@  discard block
 block discarded – undo
1241 1241
 
1242 1242
         $search_term = $this->request->getRequestParam('s');
1243 1243
         if ($search_term) {
1244
-            $search_term = '%' . $search_term . '%';
1244
+            $search_term = '%'.$search_term.'%';
1245 1245
             $where['OR'] = [
1246 1246
                 'VNU_name'               => ['LIKE', $search_term],
1247 1247
                 'VNU_desc'               => ['LIKE', $search_term],
@@ -1292,14 +1292,14 @@  discard block
 block discarded – undo
1292 1292
 
1293 1293
         // only set if we've got an id
1294 1294
         $category_ID = $this->request->getRequestParam('VEN_CAT_ID', 0, 'int');
1295
-        if (! $category_ID) {
1295
+        if ( ! $category_ID) {
1296 1296
             return;
1297 1297
         }
1298 1298
 
1299 1299
         $term = get_term($category_ID, 'espresso_venue_categories');
1300 1300
 
1301 1301
 
1302
-        if (! empty($term)) {
1302
+        if ( ! empty($term)) {
1303 1303
             $this->_category->category_name       = $term->name;
1304 1304
             $this->_category->category_identifier = $term->slug;
1305 1305
             $this->_category->category_desc       = $term->description;
@@ -1323,7 +1323,7 @@  discard block
 block discarded – undo
1323 1323
     protected function _category_list_table()
1324 1324
     {
1325 1325
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1326
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
1326
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
1327 1327
                 'add_category',
1328 1328
                 'add_category',
1329 1329
                 [],
@@ -1368,7 +1368,7 @@  discard block
 block discarded – undo
1368 1368
             'class'         => 'my_editor_custom',
1369 1369
             'wpeditor_args' => ['media_buttons' => false],
1370 1370
         ];
1371
-        $_wp_editor                   = $this->_generate_admin_form_fields($editor_args, 'array');
1371
+        $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
1372 1372
 
1373 1373
         $all_terms = get_terms(
1374 1374
             ['espresso_venue_categories'],
@@ -1392,7 +1392,7 @@  discard block
 block discarded – undo
1392 1392
             $category_select_values,
1393 1393
             $this->_category->parent
1394 1394
         );
1395
-        $template_args   = [
1395
+        $template_args = [
1396 1396
             'category'                 => $this->_category,
1397 1397
             'category_select'          => $category_select,
1398 1398
             'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
@@ -1400,7 +1400,7 @@  discard block
 block discarded – undo
1400 1400
             'disable'                  => '',
1401 1401
             'disabled_message'         => false,
1402 1402
         ];
1403
-        $template        = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
1403
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
1404 1404
         return EEH_Template::display_template($template, $template_args, true);
1405 1405
     }
1406 1406
 
@@ -1479,7 +1479,7 @@  discard block
 block discarded – undo
1479 1479
                 $term_args
1480 1480
             );
1481 1481
 
1482
-        if (! is_array($insert_ids)) {
1482
+        if ( ! is_array($insert_ids)) {
1483 1483
             EE_Error::add_error(
1484 1484
                 esc_html__('An error occurred and the category has not been saved to the database.', 'event_espresso'),
1485 1485
                 __FILE__,
@@ -1516,8 +1516,8 @@  discard block
 block discarded – undo
1516 1516
             ]
1517 1517
         );
1518 1518
 
1519
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
1520
-            require_once(EE_CLASSES . 'EE_Export.class.php');
1519
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
1520
+            require_once(EE_CLASSES.'EE_Export.class.php');
1521 1521
             $EE_Export = EE_Export::instance($this->request->requestParams());
1522 1522
             $EE_Export->export();
1523 1523
         }
@@ -1526,7 +1526,7 @@  discard block
 block discarded – undo
1526 1526
 
1527 1527
     protected function _import_categories()
1528 1528
     {
1529
-        require_once(EE_CLASSES . 'EE_Import.class.php');
1529
+        require_once(EE_CLASSES.'EE_Import.class.php');
1530 1530
         EE_Import::instance()->import();
1531 1531
     }
1532 1532
 
@@ -1544,7 +1544,7 @@  discard block
 block discarded – undo
1544 1544
         $where       = ['taxonomy' => 'espresso_venue_categories'];
1545 1545
         $search_term = $this->request->getRequestParam('s');
1546 1546
         if ($search_term) {
1547
-            $search_term = '%' . $search_term . '%';
1547
+            $search_term = '%'.$search_term.'%';
1548 1548
             $where['OR'] = [
1549 1549
                 'Term.name'   => ['LIKE', $search_term],
1550 1550
                 'description' => ['LIKE', $search_term],
@@ -1554,7 +1554,7 @@  discard block
 block discarded – undo
1554 1554
         $query_params = [
1555 1555
             $where,
1556 1556
             'order_by'   => [$orderby => $order],
1557
-            'limit'      => $limit . ',' . $per_page,
1557
+            'limit'      => $limit.','.$per_page,
1558 1558
             'force_join' => ['Term'],
1559 1559
         ];
1560 1560
 
Please login to merge, or discard this patch.