Completed
Branch dev (431075)
by
unknown
07:30 queued 05:22
created
admin_pages/messages/Messages_Admin_Page.core.php 1 patch
Indentation   +4640 added lines, -4640 removed lines patch added patch discarded remove patch
@@ -16,2683 +16,2683 @@  discard block
 block discarded – undo
16 16
  */
17 17
 class Messages_Admin_Page extends EE_Admin_Page
18 18
 {
19
-    /**
20
-     * @var EEM_Message
21
-     */
22
-    private $MSG_MODEL;
23
-
24
-    /**
25
-     * @var EEM_Message_Template
26
-     */
27
-    private $MTP_MODEL;
28
-
29
-    /**
30
-     * @var EEM_Message_Template_Group
31
-     */
32
-    private $MTG_MODEL;
33
-
34
-    /**
35
-     * @var EE_Message_Resource_Manager $_message_resource_manager
36
-     */
37
-    protected $_message_resource_manager;
38
-
39
-    /**
40
-     * @var string
41
-     */
42
-    protected $_active_message_type_name = '';
43
-
44
-    /**
45
-     * @var string
46
-     */
47
-    protected $_active_messenger_name = '';
48
-
49
-    /**
50
-     * @var EE_messenger $_active_messenger
51
-     */
52
-    protected $_active_messenger;
53
-
54
-    protected $_activate_meta_box_type;
55
-
56
-    protected $_current_message_meta_box;
57
-
58
-    protected $_current_message_meta_box_object;
59
-
60
-    protected $_context_switcher;
61
-
62
-    protected $_shortcodes           = [];
63
-
64
-    protected $_active_messengers    = [];
65
-
66
-    protected $_active_message_types = [];
67
-
68
-    /**
69
-     * @var EE_Message_Template_Group $_message_template_group
70
-     */
71
-    protected $_message_template_group;
72
-
73
-    protected $_m_mt_settings = [];
74
-
75
-
76
-    /**
77
-     * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
78
-     * IF there is no group then it gets automatically set to the Default template pack.
79
-     *
80
-     * @since 4.5.0
81
-     *
82
-     * @var EE_Messages_Template_Pack
83
-     */
84
-    protected $_template_pack;
85
-
86
-
87
-    /**
88
-     * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
89
-     * group is.  If there is no group then it automatically gets set to default.
90
-     *
91
-     * @since 4.5.0
92
-     *
93
-     * @var string
94
-     */
95
-    protected $_variation;
96
-
97
-
98
-    /**
99
-     * @param bool $routing
100
-     * @throws EE_Error
101
-     * @throws ReflectionException
102
-     */
103
-    public function __construct($routing = true)
104
-    {
105
-        // make sure messages autoloader is running
106
-        EED_Messages::set_autoloaders();
107
-        parent::__construct($routing);
108
-    }
109
-
110
-
111
-    /**
112
-     * @return EEM_Message
113
-     * @throws EE_Error
114
-     */
115
-    public function getMsgModel()
116
-    {
117
-        if (! $this->MSG_MODEL instanceof EEM_Message) {
118
-            $this->MSG_MODEL = EEM_Message::instance();
119
-        }
120
-        return $this->MSG_MODEL;
121
-    }
122
-
123
-
124
-    /**
125
-     * @return EEM_Message_Template
126
-     * @throws EE_Error
127
-     */
128
-    public function getMtpModel()
129
-    {
130
-        if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
131
-            $this->MTP_MODEL = EEM_Message_Template::instance();
132
-        }
133
-        return $this->MTP_MODEL;
134
-    }
135
-
136
-
137
-    /**
138
-     * @return EEM_Message_Template_Group
139
-     * @throws EE_Error
140
-     */
141
-    public function getMtgModel()
142
-    {
143
-        if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
144
-            $this->MTG_MODEL = EEM_Message_Template_Group::instance();
145
-        }
146
-        return $this->MTG_MODEL;
147
-    }
148
-
149
-
150
-    /**
151
-     * @throws EE_Error
152
-     * @throws ReflectionException
153
-     */
154
-    protected function _init_page_props()
155
-    {
156
-        $this->page_slug        = EE_MSG_PG_SLUG;
157
-        $this->page_label       = esc_html__('Messages Settings', 'event_espresso');
158
-        $this->_admin_base_url  = EE_MSG_ADMIN_URL;
159
-        $this->_admin_base_path = EE_MSG_ADMIN;
160
-
161
-        $messenger    = $this->request->getRequestParam('messenger', '');
162
-        $message_type = $this->request->getRequestParam('message_type', '');
163
-        $this->_active_messenger_name    = $this->request->getRequestParam('MTP_messenger', $messenger);
164
-        $this->_active_message_type_name = $this->request->getRequestParam('MTP_message_type', $message_type);
165
-
166
-        $this->_load_message_resource_manager();
167
-    }
168
-
169
-
170
-    /**
171
-     * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
172
-     *
173
-     * @throws EE_Error
174
-     * @throws InvalidDataTypeException
175
-     * @throws InvalidInterfaceException
176
-     * @throws InvalidArgumentException
177
-     * @throws ReflectionException
178
-     */
179
-    protected function _load_message_resource_manager()
180
-    {
181
-        $this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
182
-    }
183
-
184
-
185
-    /**
186
-     * @return array
187
-     * @throws EE_Error
188
-     * @throws InvalidArgumentException
189
-     * @throws InvalidDataTypeException
190
-     * @throws InvalidInterfaceException
191
-     * @deprecated 4.9.9.rc.014
192
-     */
193
-    public function get_messengers_for_list_table()
194
-    {
195
-        EE_Error::doing_it_wrong(
196
-            __METHOD__,
197
-            sprintf(
198
-                esc_html__(
199
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
200
-                    'event_espresso'
201
-                ),
202
-                'Messages_Admin_Page::get_messengers_select_input()'
203
-            ),
204
-            '4.9.9.rc.014'
205
-        );
206
-
207
-        $m_values          = [];
208
-        $active_messengers = $this->getMsgModel()->get_all(['group_by' => 'MSG_messenger']);
209
-        // setup messengers for selects
210
-        $i = 1;
211
-        foreach ($active_messengers as $active_messenger) {
212
-            if ($active_messenger instanceof EE_Message) {
213
-                $m_values[ $i ]['id']   = $active_messenger->messenger();
214
-                $m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
215
-                $i++;
216
-            }
217
-        }
218
-
219
-        return $m_values;
220
-    }
221
-
222
-
223
-    /**
224
-     * @return array
225
-     * @throws EE_Error
226
-     * @throws InvalidArgumentException
227
-     * @throws InvalidDataTypeException
228
-     * @throws InvalidInterfaceException
229
-     * @deprecated 4.9.9.rc.014
230
-     */
231
-    public function get_message_types_for_list_table()
232
-    {
233
-        EE_Error::doing_it_wrong(
234
-            __METHOD__,
235
-            sprintf(
236
-                esc_html__(
237
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
238
-                    'event_espresso'
239
-                ),
240
-                'Messages_Admin_Page::get_message_types_select_input()'
241
-            ),
242
-            '4.9.9.rc.014'
243
-        );
244
-
245
-        $mt_values       = [];
246
-        $active_messages = $this->getMsgModel()->get_all(['group_by' => 'MSG_message_type']);
247
-        $i               = 1;
248
-        foreach ($active_messages as $active_message) {
249
-            if ($active_message instanceof EE_Message) {
250
-                $mt_values[ $i ]['id']   = $active_message->message_type();
251
-                $mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
252
-                $i++;
253
-            }
254
-        }
255
-
256
-        return $mt_values;
257
-    }
258
-
259
-
260
-    /**
261
-     * @return array
262
-     * @throws EE_Error
263
-     * @throws InvalidArgumentException
264
-     * @throws InvalidDataTypeException
265
-     * @throws InvalidInterfaceException
266
-     * @deprecated 4.9.9.rc.014
267
-     */
268
-    public function get_contexts_for_message_types_for_list_table()
269
-    {
270
-        EE_Error::doing_it_wrong(
271
-            __METHOD__,
272
-            sprintf(
273
-                esc_html__(
274
-                    'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
275
-                    'event_espresso'
276
-                ),
277
-                'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
278
-            ),
279
-            '4.9.9.rc.014'
280
-        );
281
-
282
-        $contexts                = [];
283
-        $active_message_contexts = $this->getMsgModel()->get_all(['group_by' => 'MSG_context']);
284
-        foreach ($active_message_contexts as $active_message) {
285
-            if ($active_message instanceof EE_Message) {
286
-                $message_type = $active_message->message_type_object();
287
-                if ($message_type instanceof EE_message_type) {
288
-                    $message_type_contexts = $message_type->get_contexts();
289
-                    foreach ($message_type_contexts as $context => $context_details) {
290
-                        $contexts[ $context ] = $context_details['label'];
291
-                    }
292
-                }
293
-            }
294
-        }
295
-
296
-        return $contexts;
297
-    }
298
-
299
-
300
-    /**
301
-     * Generate select input with provided messenger options array.
302
-     *
303
-     * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
304
-     *                                 labels.
305
-     * @return string
306
-     * @throws EE_Error
307
-     */
308
-    public function get_messengers_select_input($messenger_options)
309
-    {
310
-        // if empty or just one value then just return an empty string
311
-        if (
312
-            empty($messenger_options)
313
-            || ! is_array($messenger_options)
314
-            || count($messenger_options) === 1
315
-        ) {
316
-            return '';
317
-        }
318
-        // merge in default
319
-        $messenger_options = array_merge(
320
-            ['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
321
-            $messenger_options
322
-        );
323
-        $input             = new EE_Select_Input(
324
-            $messenger_options,
325
-            [
326
-                'html_name'  => 'ee_messenger_filter_by',
327
-                'html_id'    => 'ee_messenger_filter_by',
328
-                'html_class' => 'wide',
329
-                'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
330
-            ]
331
-        );
332
-
333
-        return $input->get_html_for_input();
334
-    }
335
-
336
-
337
-    /**
338
-     * Generate select input with provided message type options array.
339
-     *
340
-     * @param array $message_type_options Array of message types indexed by message type slug, and values are the
341
-     *                                    message type labels
342
-     * @return string
343
-     * @throws EE_Error
344
-     */
345
-    public function get_message_types_select_input($message_type_options)
346
-    {
347
-        // if empty or count of options is 1 then just return an empty string
348
-        if (
349
-            empty($message_type_options)
350
-            || ! is_array($message_type_options)
351
-            || count($message_type_options) === 1
352
-        ) {
353
-            return '';
354
-        }
355
-        // merge in default
356
-        $message_type_options = array_merge(
357
-            ['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
358
-            $message_type_options
359
-        );
360
-        $input                = new EE_Select_Input(
361
-            $message_type_options,
362
-            [
363
-                'html_name'  => 'ee_message_type_filter_by',
364
-                'html_id'    => 'ee_message_type_filter_by',
365
-                'html_class' => 'wide',
366
-                'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
367
-            ]
368
-        );
369
-
370
-        return $input->get_html_for_input();
371
-    }
372
-
373
-
374
-    /**
375
-     * Generate select input with provide message type contexts array.
376
-     *
377
-     * @param array $context_options Array of message type contexts indexed by context slug, and values are the
378
-     *                               context label.
379
-     * @return string
380
-     * @throws EE_Error
381
-     */
382
-    public function get_contexts_for_message_types_select_input($context_options)
383
-    {
384
-        // if empty or count of options is one then just return empty string
385
-        if (
386
-            empty($context_options)
387
-            || ! is_array($context_options)
388
-            || count($context_options) === 1
389
-        ) {
390
-            return '';
391
-        }
392
-        // merge in default
393
-        $context_options = array_merge(
394
-            ['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
395
-            $context_options
396
-        );
397
-        $input           = new EE_Select_Input(
398
-            $context_options,
399
-            [
400
-                'html_name'  => 'ee_context_filter_by',
401
-                'html_id'    => 'ee_context_filter_by',
402
-                'html_class' => 'wide',
403
-                'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
404
-            ]
405
-        );
406
-
407
-        return $input->get_html_for_input();
408
-    }
409
-
410
-
411
-    protected function _ajax_hooks()
412
-    {
413
-        add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
414
-        add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
415
-        add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
416
-        add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
417
-        add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
418
-        add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
419
-    }
420
-
421
-
422
-    protected function _define_page_props()
423
-    {
424
-        $this->_admin_page_title = $this->page_label;
425
-        $this->_labels           = [
426
-            'buttons'    => [
427
-                'add'    => esc_html__('Add New Message Template', 'event_espresso'),
428
-                'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
429
-                'delete' => esc_html__('Delete Message Template', 'event_espresso'),
430
-            ],
431
-            'publishbox' => esc_html__('Update Actions', 'event_espresso'),
432
-        ];
433
-    }
434
-
435
-
436
-    /**
437
-     *        an array for storing key => value pairs of request actions and their corresponding methods
438
-     *
439
-     * @access protected
440
-     * @return void
441
-     */
442
-    protected function _set_page_routes()
443
-    {
444
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
445
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
446
-        $MSG_ID = $this->request->getRequestParam('MSG_ID', 0, 'int');
447
-
448
-        $this->_page_routes = [
449
-            'default'                          => [
450
-                'func'       => '_message_queue_list_table',
451
-                'capability' => 'ee_read_global_messages',
452
-            ],
453
-            'global_mtps'                      => [
454
-                'func'       => '_ee_default_messages_overview_list_table',
455
-                'capability' => 'ee_read_global_messages',
456
-            ],
457
-            'custom_mtps'                      => [
458
-                'func'       => '_custom_mtps_preview',
459
-                'capability' => 'ee_read_messages',
460
-            ],
461
-            'add_new_message_template'         => [
462
-                'func'       => 'add_message_template',
463
-                'capability' => 'ee_edit_messages',
464
-                'noheader'   => true,
465
-            ],
466
-            'edit_message_template'            => [
467
-                'func'       => '_edit_message_template',
468
-                'capability' => 'ee_edit_message',
469
-                'obj_id'     => $GRP_ID,
470
-            ],
471
-            'preview_message'                  => [
472
-                'func'               => '_preview_message',
473
-                'capability'         => 'ee_read_message',
474
-                'obj_id'             => $GRP_ID,
475
-                'noheader'           => true,
476
-                'headers_sent_route' => 'display_preview_message',
477
-            ],
478
-            'display_preview_message'          => [
479
-                'func'       => '_display_preview_message',
480
-                'capability' => 'ee_read_message',
481
-                'obj_id'     => $GRP_ID,
482
-            ],
483
-            'insert_message_template'          => [
484
-                'func'       => '_insert_or_update_message_template',
485
-                'capability' => 'ee_edit_messages',
486
-                'args'       => ['new' => true],
487
-                'noheader'   => true,
488
-            ],
489
-            'update_message_template'          => [
490
-                'func'       => '_insert_or_update_message_template',
491
-                'capability' => 'ee_edit_message',
492
-                'obj_id'     => $GRP_ID,
493
-                'args'       => ['new' => false],
494
-                'noheader'   => true,
495
-            ],
496
-            'trash_message_template'           => [
497
-                'func'       => '_trash_or_restore_message_template',
498
-                'capability' => 'ee_delete_message',
499
-                'obj_id'     => $GRP_ID,
500
-                'args'       => ['trash' => true, 'all' => true],
501
-                'noheader'   => true,
502
-            ],
503
-            'trash_message_template_context'   => [
504
-                'func'       => '_trash_or_restore_message_template',
505
-                'capability' => 'ee_delete_message',
506
-                'obj_id'     => $GRP_ID,
507
-                'args'       => ['trash' => true],
508
-                'noheader'   => true,
509
-            ],
510
-            'restore_message_template'         => [
511
-                'func'       => '_trash_or_restore_message_template',
512
-                'capability' => 'ee_delete_message',
513
-                'obj_id'     => $GRP_ID,
514
-                'args'       => ['trash' => false, 'all' => true],
515
-                'noheader'   => true,
516
-            ],
517
-            'restore_message_template_context' => [
518
-                'func'       => '_trash_or_restore_message_template',
519
-                'capability' => 'ee_delete_message',
520
-                'obj_id'     => $GRP_ID,
521
-                'args'       => ['trash' => false],
522
-                'noheader'   => true,
523
-            ],
524
-            'delete_message_template'          => [
525
-                'func'       => '_delete_message_template',
526
-                'capability' => 'ee_delete_message',
527
-                'obj_id'     => $GRP_ID,
528
-                'noheader'   => true,
529
-            ],
530
-            'reset_to_default'                 => [
531
-                'func'       => '_reset_to_default_template',
532
-                'capability' => 'ee_edit_message',
533
-                'obj_id'     => $GRP_ID,
534
-                'noheader'   => true,
535
-            ],
536
-            'settings'                         => [
537
-                'func'       => '_settings',
538
-                'capability' => 'manage_options',
539
-            ],
540
-            'update_global_settings'           => [
541
-                'func'       => '_update_global_settings',
542
-                'capability' => 'manage_options',
543
-                'noheader'   => true,
544
-            ],
545
-            'generate_now'                     => [
546
-                'func'       => '_generate_now',
547
-                'capability' => 'ee_send_message',
548
-                'noheader'   => true,
549
-            ],
550
-            'generate_and_send_now'            => [
551
-                'func'       => '_generate_and_send_now',
552
-                'capability' => 'ee_send_message',
553
-                'noheader'   => true,
554
-            ],
555
-            'queue_for_resending'              => [
556
-                'func'       => '_queue_for_resending',
557
-                'capability' => 'ee_send_message',
558
-                'noheader'   => true,
559
-            ],
560
-            'send_now'                         => [
561
-                'func'       => '_send_now',
562
-                'capability' => 'ee_send_message',
563
-                'noheader'   => true,
564
-            ],
565
-            'delete_ee_message'                => [
566
-                'func'       => '_delete_ee_messages',
567
-                'capability' => 'ee_delete_messages',
568
-                'noheader'   => true,
569
-            ],
570
-            'delete_ee_messages'               => [
571
-                'func'       => '_delete_ee_messages',
572
-                'capability' => 'ee_delete_messages',
573
-                'noheader'   => true,
574
-                'obj_id'     => $MSG_ID,
575
-            ],
576
-        ];
577
-    }
578
-
579
-
580
-    protected function _set_page_config()
581
-    {
582
-        $this->_page_config = [
583
-            'default'                  => [
584
-                'nav'           => [
585
-                    'label' => esc_html__('Message Activity', 'event_espresso'),
586
-                    'order' => 10,
587
-                ],
588
-                'list_table'    => 'EE_Message_List_Table',
589
-                // 'qtips' => array( 'EE_Message_List_Table_Tips' ),
590
-                'require_nonce' => false,
591
-            ],
592
-            'global_mtps'              => [
593
-                'nav'           => [
594
-                    'label' => esc_html__('Default Message Templates', 'event_espresso'),
595
-                    'order' => 20,
596
-                ],
597
-                'list_table'    => 'Messages_Template_List_Table',
598
-                'help_tabs'     => [
599
-                    'messages_overview_help_tab'                                => [
600
-                        'title'    => esc_html__('Messages Overview', 'event_espresso'),
601
-                        'filename' => 'messages_overview',
602
-                    ],
603
-                    'messages_overview_messages_table_column_headings_help_tab' => [
604
-                        'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
605
-                        'filename' => 'messages_overview_table_column_headings',
606
-                    ],
607
-                    'messages_overview_messages_filters_help_tab'               => [
608
-                        'title'    => esc_html__('Message Filters', 'event_espresso'),
609
-                        'filename' => 'messages_overview_filters',
610
-                    ],
611
-                    'messages_overview_messages_views_help_tab'                 => [
612
-                        'title'    => esc_html__('Message Views', 'event_espresso'),
613
-                        'filename' => 'messages_overview_views',
614
-                    ],
615
-                    'message_overview_message_types_help_tab'                   => [
616
-                        'title'    => esc_html__('Message Types', 'event_espresso'),
617
-                        'filename' => 'messages_overview_types',
618
-                    ],
619
-                    'messages_overview_messengers_help_tab'                     => [
620
-                        'title'    => esc_html__('Messengers', 'event_espresso'),
621
-                        'filename' => 'messages_overview_messengers',
622
-                    ],
623
-                ],
624
-                'require_nonce' => false,
625
-            ],
626
-            'custom_mtps'              => [
627
-                'nav'           => [
628
-                    'label' => esc_html__('Custom Message Templates', 'event_espresso'),
629
-                    'order' => 30,
630
-                ],
631
-                'help_tabs'     => [],
632
-                'require_nonce' => false,
633
-            ],
634
-            'add_new_message_template' => [
635
-                'nav'           => [
636
-                    'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
637
-                    'order'      => 5,
638
-                    'persistent' => false,
639
-                ],
640
-                'require_nonce' => false,
641
-            ],
642
-            'edit_message_template'    => [
643
-                'labels'        => [
644
-                    'buttons'    => [
645
-                        'reset' => esc_html__('Reset Templates', 'event_espresso'),
646
-                    ],
647
-                    'publishbox' => esc_html__('Update Actions', 'event_espresso'),
648
-                ],
649
-                'nav'           => [
650
-                    'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
651
-                    'order'      => 5,
652
-                    'persistent' => false,
653
-                    'url'        => '',
654
-                ],
655
-                'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
656
-                'has_metaboxes' => true,
657
-                'help_tabs'     => [
658
-                    'edit_message_template'            => [
659
-                        'title'    => esc_html__('Message Template Editor', 'event_espresso'),
660
-                        'callback' => 'edit_message_template_help_tab',
661
-                    ],
662
-                    'message_templates_help_tab'       => [
663
-                        'title'    => esc_html__('Message Templates', 'event_espresso'),
664
-                        'filename' => 'messages_templates',
665
-                    ],
666
-                    'message_template_shortcodes'      => [
667
-                        'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
668
-                        'callback' => 'message_template_shortcodes_help_tab',
669
-                    ],
670
-                    'message_preview_help_tab'         => [
671
-                        'title'    => esc_html__('Message Preview', 'event_espresso'),
672
-                        'filename' => 'messages_preview',
673
-                    ],
674
-                    'messages_overview_other_help_tab' => [
675
-                        'title'    => esc_html__('Messages Other', 'event_espresso'),
676
-                        'filename' => 'messages_overview_other',
677
-                    ],
678
-                ],
679
-                'require_nonce' => false,
680
-            ],
681
-            'display_preview_message'  => [
682
-                'nav'           => [
683
-                    'label'      => esc_html__('Message Preview', 'event_espresso'),
684
-                    'order'      => 5,
685
-                    'url'        => '',
686
-                    'persistent' => false,
687
-                ],
688
-                'help_tabs'     => [
689
-                    'preview_message' => [
690
-                        'title'    => esc_html__('About Previews', 'event_espresso'),
691
-                        'callback' => 'preview_message_help_tab',
692
-                    ],
693
-                ],
694
-                'require_nonce' => false,
695
-            ],
696
-            'settings'                 => [
697
-                'nav'           => [
698
-                    'label' => esc_html__('Settings', 'event_espresso'),
699
-                    'order' => 40,
700
-                ],
701
-                'metaboxes'     => ['_messages_settings_metaboxes'],
702
-                'help_tabs'     => [
703
-                    'messages_settings_help_tab'               => [
704
-                        'title'    => esc_html__('Messages Settings', 'event_espresso'),
705
-                        'filename' => 'messages_settings',
706
-                    ],
707
-                    'messages_settings_message_types_help_tab' => [
708
-                        'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
709
-                        'filename' => 'messages_settings_message_types',
710
-                    ],
711
-                    'messages_settings_messengers_help_tab'    => [
712
-                        'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
713
-                        'filename' => 'messages_settings_messengers',
714
-                    ],
715
-                ],
716
-                'require_nonce' => false,
717
-            ],
718
-        ];
719
-    }
720
-
721
-
722
-    protected function _add_screen_options()
723
-    {
724
-        // todo
725
-    }
726
-
727
-
728
-    protected function _add_screen_options_global_mtps()
729
-    {
730
-        /**
731
-         * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
732
-         * uses the $_admin_page_title property and we want different outputs in the different spots.
733
-         */
734
-        $page_title              = $this->_admin_page_title;
735
-        $this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
736
-        $this->_per_page_screen_option();
737
-        $this->_admin_page_title = $page_title;
738
-    }
739
-
740
-
741
-    protected function _add_screen_options_default()
742
-    {
743
-        $this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
744
-        $this->_per_page_screen_option();
745
-    }
746
-
747
-
748
-    // none of the below group are currently used for Messages
749
-    protected function _add_feature_pointers()
750
-    {
751
-    }
752
-
753
-
754
-    public function admin_init()
755
-    {
756
-    }
757
-
758
-
759
-    public function admin_notices()
760
-    {
761
-    }
762
-
763
-
764
-    public function admin_footer_scripts()
765
-    {
766
-    }
767
-
768
-
769
-    public function messages_help_tab()
770
-    {
771
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
772
-    }
773
-
774
-
775
-    public function messengers_help_tab()
776
-    {
777
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
778
-    }
779
-
780
-
781
-    public function message_types_help_tab()
782
-    {
783
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
784
-    }
785
-
786
-
787
-    public function messages_overview_help_tab()
788
-    {
789
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
790
-    }
791
-
792
-
793
-    public function message_templates_help_tab()
794
-    {
795
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
796
-    }
797
-
798
-
799
-    public function edit_message_template_help_tab()
800
-    {
801
-        $args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
802
-                        . esc_attr__('Editor Title', 'event_espresso')
803
-                        . '" />';
804
-        $args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
805
-                        . esc_attr__('Context Switcher and Preview', 'event_espresso')
806
-                        . '" />';
807
-        $args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
808
-                        . esc_attr__('Message Template Form Fields', 'event_espresso')
809
-                        . '" />';
810
-        $args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
811
-                        . esc_attr__('Shortcodes Metabox', 'event_espresso')
812
-                        . '" />';
813
-        $args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
814
-                        . esc_attr__('Publish Metabox', 'event_espresso')
815
-                        . '" />';
816
-        EEH_Template::display_template(
817
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
818
-            $args
819
-        );
820
-    }
821
-
822
-
823
-    /**
824
-     * @throws ReflectionException
825
-     * @throws EE_Error
826
-     */
827
-    public function message_template_shortcodes_help_tab()
828
-    {
829
-        $this->_set_shortcodes();
830
-        $args['shortcodes'] = $this->_shortcodes;
831
-        EEH_Template::display_template(
832
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
833
-            $args
834
-        );
835
-    }
836
-
837
-
838
-    public function preview_message_help_tab()
839
-    {
840
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
841
-    }
842
-
843
-
844
-    public function settings_help_tab()
845
-    {
846
-        $args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
847
-                        . '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
848
-        $args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
849
-                        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
850
-        $args['img3'] = '<div class="switch">'
851
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
852
-                        . ' type="checkbox" checked="checked">'
853
-                        . '<label for="ee-on-off-toggle-on"></label>'
854
-                        . '</div>';
855
-        $args['img4'] = '<div class="switch">'
856
-                        . '<input class="ee-on-off-toggle ee-toggle-round-flat"'
857
-                        . ' type="checkbox">'
858
-                        . '<label for="ee-on-off-toggle-on"></label>'
859
-                        . '</div>';
860
-        EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
861
-    }
862
-
863
-
864
-    public function load_scripts_styles()
865
-    {
866
-        wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
867
-        wp_enqueue_style('espresso_ee_msg');
868
-
869
-        wp_register_script(
870
-            'ee-messages-settings',
871
-            EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
872
-            ['jquery-ui-droppable', 'ee-serialize-full-array'],
873
-            EVENT_ESPRESSO_VERSION,
874
-            true
875
-        );
876
-        wp_register_script(
877
-            'ee-msg-list-table-js',
878
-            EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
879
-            ['ee-dialog'],
880
-            EVENT_ESPRESSO_VERSION
881
-        );
882
-    }
883
-
884
-
885
-    public function load_scripts_styles_default()
886
-    {
887
-        wp_enqueue_script('ee-msg-list-table-js');
888
-    }
889
-
890
-
891
-    public function wp_editor_css($mce_css)
892
-    {
893
-        // if we're on the edit_message_template route
894
-        if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
895
-            $message_type_name = $this->_active_message_type_name;
896
-
897
-            // we're going to REPLACE the existing mce css
898
-            // we need to get the css file location from the active messenger
899
-            $mce_css = $this->_active_messenger->get_variation(
900
-                $this->_template_pack,
901
-                $message_type_name,
902
-                true,
903
-                'wpeditor',
904
-                $this->_variation
905
-            );
906
-        }
907
-
908
-        return $mce_css;
909
-    }
910
-
911
-
912
-    /**
913
-     * @throws EE_Error
914
-     * @throws ReflectionException
915
-     */
916
-    public function load_scripts_styles_edit_message_template()
917
-    {
918
-
919
-        $this->_set_shortcodes();
920
-
921
-        EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
922
-            esc_html__(
923
-                '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.',
924
-                'event_espresso'
925
-            ),
926
-            $this->_message_template_group->messenger_obj()->label['singular'],
927
-            $this->_message_template_group->message_type_obj()->label['singular']
928
-        );
929
-        EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
930
-            '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?',
931
-            'event_espresso'
932
-        );
933
-        EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
934
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
935
-            'event_espresso'
936
-        );
937
-
938
-        wp_register_script(
939
-            'ee_msgs_edit_js',
940
-            EE_MSG_ASSETS_URL . 'ee_message_editor.js',
941
-            ['jquery'],
942
-            EVENT_ESPRESSO_VERSION
943
-        );
944
-
945
-        wp_enqueue_script('ee_admin_js');
946
-        wp_enqueue_script('ee_msgs_edit_js');
947
-
948
-        // add in special css for tiny_mce
949
-        add_filter('mce_css', [$this, 'wp_editor_css']);
950
-    }
951
-
952
-
953
-    /**
954
-     * @throws EE_Error
955
-     * @throws ReflectionException
956
-     */
957
-    public function load_scripts_styles_display_preview_message()
958
-    {
959
-        $this->_set_message_template_group();
960
-        if ($this->_active_messenger_name) {
961
-            $this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
962
-                $this->_active_messenger_name
963
-            );
964
-        }
965
-
966
-        wp_enqueue_style(
967
-            'espresso_preview_css',
968
-            $this->_active_messenger->get_variation(
969
-                $this->_template_pack,
970
-                $this->_active_message_type_name,
971
-                true,
972
-                'preview',
973
-                $this->_variation
974
-            )
975
-        );
976
-    }
977
-
978
-
979
-    public function load_scripts_styles_settings()
980
-    {
981
-        wp_register_style(
982
-            'ee-message-settings',
983
-            EE_MSG_ASSETS_URL . 'ee_message_settings.css',
984
-            [],
985
-            EVENT_ESPRESSO_VERSION
986
-        );
987
-        wp_enqueue_style('ee-text-links');
988
-        wp_enqueue_style('ee-message-settings');
989
-        wp_enqueue_script('ee-messages-settings');
990
-    }
991
-
992
-
993
-    /**
994
-     * set views array for List Table
995
-     */
996
-    public function _set_list_table_views_global_mtps()
997
-    {
998
-        $this->_views = [
999
-            'in_use' => [
1000
-                'slug'  => 'in_use',
1001
-                'label' => esc_html__('In Use', 'event_espresso'),
1002
-                'count' => 0,
1003
-            ],
1004
-        ];
1005
-    }
1006
-
1007
-
1008
-    /**
1009
-     * Set views array for the Custom Template List Table
1010
-     */
1011
-    public function _set_list_table_views_custom_mtps()
1012
-    {
1013
-        $this->_set_list_table_views_global_mtps();
1014
-        $this->_views['in_use']['bulk_action'] = [
1015
-            'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
1016
-        ];
1017
-    }
1018
-
1019
-
1020
-    /**
1021
-     * set views array for message queue list table
1022
-     *
1023
-     * @throws InvalidDataTypeException
1024
-     * @throws InvalidInterfaceException
1025
-     * @throws InvalidArgumentException
1026
-     * @throws EE_Error
1027
-     * @throws ReflectionException
1028
-     */
1029
-    public function _set_list_table_views_default()
1030
-    {
1031
-        EE_Registry::instance()->load_helper('Template');
1032
-
1033
-        $common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
1034
-            'ee_send_message',
1035
-            'message_list_table_bulk_actions'
1036
-        )
1037
-            ? [
1038
-                'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
1039
-                'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
1040
-                'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
1041
-                'send_now'              => esc_html__('Send Now', 'event_espresso'),
1042
-            ]
1043
-            : [];
1044
-
1045
-        $delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
1046
-            'ee_delete_messages',
1047
-            'message_list_table_bulk_actions'
1048
-        )
1049
-            ? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1050
-            : [];
1051
-
1052
-
1053
-        $this->_views = [
1054
-            'all' => [
1055
-                'slug'        => 'all',
1056
-                'label'       => esc_html__('All', 'event_espresso'),
1057
-                'count'       => 0,
1058
-                'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1059
-            ],
1060
-        ];
1061
-
1062
-
1063
-        foreach ($this->getMsgModel()->all_statuses() as $status) {
1064
-            if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1065
-                continue;
1066
-            }
1067
-            $status_bulk_actions = $common_bulk_actions;
1068
-            // unset bulk actions not applying to status
1069
-            if (! empty($status_bulk_actions)) {
1070
-                switch ($status) {
1071
-                    case EEM_Message::status_idle:
1072
-                    case EEM_Message::status_resend:
1073
-                        $status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1074
-                        break;
1075
-
1076
-                    case EEM_Message::status_failed:
1077
-                    case EEM_Message::status_debug_only:
1078
-                    case EEM_Message::status_messenger_executing:
1079
-                        $status_bulk_actions = [];
1080
-                        break;
1081
-
1082
-                    case EEM_Message::status_incomplete:
1083
-                        unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1084
-                        break;
1085
-
1086
-                    case EEM_Message::status_retry:
1087
-                    case EEM_Message::status_sent:
1088
-                        unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1089
-                        break;
1090
-                }
1091
-            }
1092
-
1093
-            // skip adding messenger executing status to views because it will be included with the Failed view.
1094
-            if ($status === EEM_Message::status_messenger_executing) {
1095
-                continue;
1096
-            }
1097
-
1098
-            $this->_views[ strtolower($status) ] = [
1099
-                'slug'        => strtolower($status),
1100
-                'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1101
-                'count'       => 0,
1102
-                'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1103
-            ];
1104
-        }
1105
-    }
1106
-
1107
-
1108
-    /**
1109
-     * @throws EE_Error
1110
-     */
1111
-    protected function _ee_default_messages_overview_list_table()
1112
-    {
1113
-        $this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1114
-        $this->display_admin_list_table_page_with_no_sidebar();
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * @throws EE_Error
1120
-     * @throws ReflectionException
1121
-     */
1122
-    protected function _message_queue_list_table()
1123
-    {
1124
-        $this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1125
-        $this->_template_args['per_column']        = 6;
1126
-        $this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1127
-        $this->_template_args['before_list_table'] = '<h3>'
1128
-                                                     . $this->getMsgModel()->get_pretty_label_for_results()
1129
-                                                     . '</h3>';
1130
-        $this->display_admin_list_table_page_with_no_sidebar();
1131
-    }
1132
-
1133
-
1134
-    /**
1135
-     * @throws EE_Error
1136
-     */
1137
-    protected function _message_legend_items()
1138
-    {
1139
-
1140
-        $action_css_classes = EEH_MSG_Template::get_message_action_icons();
1141
-        $action_items       = [];
1142
-
1143
-        foreach ($action_css_classes as $action_item => $action_details) {
1144
-            if ($action_item === 'see_notifications_for') {
1145
-                continue;
1146
-            }
1147
-            $action_items[ $action_item ] = [
1148
-                'class' => $action_details['css_class'],
1149
-                'desc'  => $action_details['label'],
1150
-            ];
1151
-        }
1152
-
1153
-        /** @var array $status_items status legend setup */
1154
-        $status_items = [
1155
-            'sent_status'                => [
1156
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1157
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1158
-            ],
1159
-            'idle_status'                => [
1160
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1161
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1162
-            ],
1163
-            'failed_status'              => [
1164
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1165
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1166
-            ],
1167
-            'messenger_executing_status' => [
1168
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1169
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1170
-            ],
1171
-            'resend_status'              => [
1172
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1173
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1174
-            ],
1175
-            'incomplete_status'          => [
1176
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1177
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1178
-            ],
1179
-            'retry_status'               => [
1180
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1181
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1182
-            ],
1183
-        ];
1184
-        if (EEM_Message::debug()) {
1185
-            $status_items['debug_only_status'] = [
1186
-                'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1187
-                'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1188
-            ];
1189
-        }
1190
-
1191
-        return array_merge($action_items, $status_items);
1192
-    }
1193
-
1194
-
1195
-    /**
1196
-     * @throws EE_Error
1197
-     */
1198
-    protected function _custom_mtps_preview()
1199
-    {
1200
-        $this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1201
-        $this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1202
-                                                . ' alt="' . esc_attr__(
1203
-                                                    'Preview Custom Message Templates screenshot',
1204
-                                                    'event_espresso'
1205
-                                                ) . '" />';
1206
-        $this->_template_args['preview_text'] = '<strong>'
1207
-                                                . esc_html__(
1208
-                                                    '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.',
1209
-                                                    'event_espresso'
1210
-                                                )
1211
-                                                . '</strong>';
1212
-
1213
-        $this->display_admin_caf_preview_page('custom_message_types', false);
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * get_message_templates
1219
-     * This gets all the message templates for listing on the overview list.
1220
-     *
1221
-     * @access public
1222
-     * @param int    $per_page the amount of templates groups to show per page
1223
-     * @param string $type     the current _view we're getting templates for
1224
-     * @param bool   $count    return count?
1225
-     * @param bool   $all      disregard any paging info (get all data);
1226
-     * @param bool   $global   whether to return just global (true) or custom templates (false)
1227
-     * @return array
1228
-     * @throws EE_Error
1229
-     * @throws InvalidArgumentException
1230
-     * @throws InvalidDataTypeException
1231
-     * @throws InvalidInterfaceException
1232
-     */
1233
-    public function get_message_templates(
1234
-        $per_page = 10,
1235
-        $type = 'in_use',
1236
-        $count = false,
1237
-        $all = false,
1238
-        $global = true
1239
-    ) {
1240
-        $orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1241
-        $this->request->setRequestParam('orderby', $orderby);
1242
-
1243
-        $order        = $this->request->getRequestParam('order', 'ASC');
1244
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
1245
-        $per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1246
-
1247
-        $offset = ($current_page - 1) * $per_page;
1248
-        $limit  = $all ? null : [$offset, $per_page];
1249
-
1250
-        // options will match what is in the _views array property
1251
-        return $type === 'in_use'
1252
-            ? $this->getMtgModel()->get_all_active_message_templates(
1253
-                $orderby,
1254
-                $order,
1255
-                $limit,
1256
-                $count,
1257
-                $global,
1258
-                true
1259
-            )
1260
-            : $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1261
-                $orderby,
1262
-                $order,
1263
-                $limit,
1264
-                $count,
1265
-                $global
1266
-            );
1267
-    }
1268
-
1269
-
1270
-    /**
1271
-     * filters etc might need a list of installed message_types
1272
-     *
1273
-     * @return array an array of message type objects
1274
-     */
1275
-    public function get_installed_message_types()
1276
-    {
1277
-        $installed_message_types = $this->_message_resource_manager->installed_message_types();
1278
-        $installed               = [];
1279
-
1280
-        foreach ($installed_message_types as $message_type) {
1281
-            $installed[ $message_type->name ] = $message_type;
1282
-        }
1283
-
1284
-        return $installed;
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * This is used when creating a custom template. All Custom Templates start based off another template.
1290
-     *
1291
-     * @param string $message_type
1292
-     * @param string $messenger
1293
-     * @param string $GRP_ID
1294
-     *
1295
-     * @throws EE_error
1296
-     * @throws ReflectionException
1297
-     */
1298
-    public function add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1299
-    {
1300
-        // set values override any request data
1301
-        $message_type = ! empty($message_type) ? $message_type : $this->_active_message_type_name;
1302
-        $messenger    = ! empty($messenger) ? $messenger : $this->_active_messenger_name;
1303
-        $GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1304
-
1305
-        // we need messenger and message type.  They should be coming from the event editor. If not here then return error
1306
-        if (empty($message_type) || empty($messenger)) {
1307
-            throw new EE_Error(
1308
-                esc_html__(
1309
-                    'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1310
-                    'event_espresso'
1311
-                )
1312
-            );
1313
-        }
1314
-
1315
-        // we need the GRP_ID for the template being used as the base for the new template
1316
-        if (empty($GRP_ID)) {
1317
-            throw new EE_Error(
1318
-                esc_html__(
1319
-                    'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1320
-                    'event_espresso'
1321
-                )
1322
-            );
1323
-        }
1324
-
1325
-        // let's just make sure the template gets generated!
1326
-
1327
-        // we need to reassign some variables for what the insert is expecting
1328
-        $this->request->setRequestParam('MTP_messenger', $messenger);
1329
-        $this->request->setRequestParam('MTP_message_type', $message_type);
1330
-        $this->request->setRequestParam('GRP_ID', $GRP_ID);
1331
-
1332
-        $this->_insert_or_update_message_template(true);
1333
-    }
1334
-
1335
-
1336
-    /**
1337
-     * @param string $message_type     message type slug
1338
-     * @param string $messenger        messenger slug
1339
-     * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1340
-     *                                 off of.
1341
-     * @throws EE_error
1342
-     * @throws ReflectionException
1343
-     * @deprecated 4.10.29.p
1344
-     */
1345
-    protected function _add_message_template($message_type, $messenger, $GRP_ID)
1346
-    {
1347
-        $this->add_message_template($message_type, $messenger, $GRP_ID);
1348
-    }
1349
-
1350
-
1351
-    /**
1352
-     * _edit_message_template
1353
-     *
1354
-     * @access protected
1355
-     * @return void
1356
-     * @throws InvalidIdentifierException
1357
-     * @throws DomainException
1358
-     * @throws EE_Error
1359
-     * @throws InvalidArgumentException
1360
-     * @throws ReflectionException
1361
-     * @throws InvalidDataTypeException
1362
-     * @throws InvalidInterfaceException
1363
-     */
1364
-    protected function _edit_message_template()
1365
-    {
1366
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1367
-        $template_fields = '';
1368
-        $sidebar_fields  = '';
1369
-        // we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1370
-        // valid html in the templates.
1371
-        add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1372
-
1373
-        $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
1374
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
1375
-
1376
-        $this->_set_shortcodes(); // this also sets the _message_template property.
1377
-        $message_template_group = $this->_message_template_group;
1378
-        $c_label                = $message_template_group->context_label();
1379
-        $c_config               = $message_template_group->contexts_config();
1380
-
1381
-        reset($c_config);
1382
-        $context = $this->request->getRequestParam('context', key($c_config));
1383
-        $context = strtolower($context);
1384
-
1385
-        $action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1386
-
1387
-        $edit_message_template_form_url = add_query_arg(
1388
-            ['action' => $action, 'noheader' => true],
1389
-            EE_MSG_ADMIN_URL
1390
-        );
1391
-
1392
-        // set active messenger for this view
1393
-        $this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1394
-            $message_template_group->messenger()
1395
-        );
1396
-        $this->_active_message_type_name = $message_template_group->message_type();
1397
-
1398
-
1399
-        // Do we have any validation errors?
1400
-        $validators = $this->_get_transient();
1401
-        $v_fields   = ! empty($validators) ? array_keys($validators) : [];
1402
-
1403
-
1404
-        // we need to assemble the title from Various details
1405
-        $context_label = sprintf(
1406
-            esc_html__('(%s %s)', 'event_espresso'),
1407
-            $c_config[ $context ]['label'],
1408
-            ucwords($c_label['label'])
1409
-        );
1410
-
1411
-        $title = sprintf(
1412
-            esc_html__(' %s %s Template %s', 'event_espresso'),
1413
-            ucwords($message_template_group->messenger_obj()->label['singular']),
1414
-            ucwords($message_template_group->message_type_obj()->label['singular']),
1415
-            $context_label
1416
-        );
1417
-
1418
-        $this->_template_args['GRP_ID']           = $GRP_ID;
1419
-        $this->_template_args['message_template'] = $message_template_group;
1420
-        $this->_template_args['is_extra_fields']  = false;
1421
-
1422
-
1423
-        // let's get EEH_MSG_Template so we can get template form fields
1424
-        $template_field_structure = EEH_MSG_Template::get_fields(
1425
-            $message_template_group->messenger(),
1426
-            $message_template_group->message_type()
1427
-        );
1428
-
1429
-        if (! $template_field_structure) {
1430
-            $template_field_structure = false;
1431
-            $template_fields          = esc_html__(
1432
-                'There was an error in assembling the fields for this display (you should see an error message)',
1433
-                'event_espresso'
1434
-            );
1435
-        }
1436
-
1437
-
1438
-        $message_templates = $message_template_group->context_templates();
1439
-
1440
-
1441
-        // if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1442
-        // will get handled in the "extra" array.
1443
-        if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1444
-            foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1445
-                unset($template_field_structure[ $context ][ $reference_field ]);
1446
-            }
1447
-        }
1448
-
1449
-        // let's loop through the template_field_structure and actually assemble the input fields!
1450
-        if (! empty($template_field_structure)) {
1451
-            foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1452
-                // if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1453
-                // the extra array and reset them.
1454
-                if ($template_field === 'extra') {
1455
-                    $this->_template_args['is_extra_fields'] = true;
1456
-                    foreach ($field_setup_array as $reference_field => $new_fields_array) {
1457
-                        $message_template = $message_templates[ $context ][ $reference_field ];
1458
-                        $content          = $message_template instanceof EE_Message_Template
1459
-                            ? $message_template->get('MTP_content')
1460
-                            : '';
1461
-                        foreach ($new_fields_array as $extra_field => $extra_array) {
1462
-                            // let's verify if we need this extra field via the shortcodes parameter.
1463
-                            $continue = false;
1464
-                            if (isset($extra_array['shortcodes_required'])) {
1465
-                                foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1466
-                                    if (! array_key_exists($shortcode, $this->_shortcodes)) {
1467
-                                        $continue = true;
1468
-                                    }
1469
-                                }
1470
-                                if ($continue) {
1471
-                                    continue;
1472
-                                }
1473
-                            }
1474
-
1475
-                            $field_id = $reference_field . '-' . $extra_field . '-content';
1476
-
1477
-                            $template_form_fields[ $field_id ]         = $extra_array;
1478
-                            $template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1479
-                                                                         . $reference_field
1480
-                                                                         . '][content]['
1481
-                                                                         . $extra_field . ']';
1482
-                            $css_class                                 = isset($extra_array['css_class'])
1483
-                                ? $extra_array['css_class']
1484
-                                : '';
1485
-
1486
-                            $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1487
-                                                                              && in_array($extra_field, $v_fields, true)
1488
-                                                                              && (
1489
-                                                                                  is_array($validators[ $extra_field ])
1490
-                                                                                  && isset($validators[ $extra_field ]['msg'])
1491
-                                                                              )
1492
-                                ? 'validate-error ' . $css_class
1493
-                                : $css_class;
1494
-
1495
-                            $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1496
-                                                                          && isset($content[ $extra_field ])
1497
-                                ? $content[ $extra_field ]
1498
-                                : '';
1499
-
1500
-                            // do we have a validation error?  if we do then let's use that value instead
1501
-                            $template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1502
-                                ? $validators[ $extra_field ]['value']
1503
-                                : $template_form_fields[ $field_id ]['value'];
1504
-
1505
-
1506
-                            $template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1507
-
1508
-                            // shortcode selector
1509
-                            $field_name_to_use                                   = $extra_field === 'main'
1510
-                                ? 'content'
1511
-                                : $extra_field;
1512
-                            $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1513
-                                $field_name_to_use,
1514
-                                $field_id
1515
-                            );
1516
-                        }
1517
-                        $template_field_MTP_id           = $reference_field . '-MTP_ID';
1518
-                        $template_field_template_name_id = $reference_field . '-name';
1519
-
1520
-                        $template_form_fields[ $template_field_MTP_id ] = [
1521
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1522
-                            'label'      => null,
1523
-                            'input'      => 'hidden',
1524
-                            'type'       => 'int',
1525
-                            'required'   => false,
1526
-                            'validation' => false,
1527
-                            'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1528
-                            'css_class'  => '',
1529
-                            'format'     => '%d',
1530
-                            'db-col'     => 'MTP_ID',
1531
-                        ];
1532
-
1533
-                        $template_form_fields[ $template_field_template_name_id ] = [
1534
-                            'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1535
-                            'label'      => null,
1536
-                            'input'      => 'hidden',
1537
-                            'type'       => 'string',
1538
-                            'required'   => false,
1539
-                            'validation' => true,
1540
-                            'value'      => $reference_field,
1541
-                            'css_class'  => '',
1542
-                            'format'     => '%s',
1543
-                            'db-col'     => 'MTP_template_field',
1544
-                        ];
1545
-                    }
1546
-                    continue; // skip the next stuff, we got the necessary fields here for this dataset.
1547
-                } else {
1548
-                    $field_id                                   = $template_field . '-content';
1549
-                    $template_form_fields[ $field_id ]          = $field_setup_array;
1550
-                    $template_form_fields[ $field_id ]['name']  =
1551
-                        'MTP_template_fields[' . $template_field . '][content]';
1552
-                    $message_template                           =
1553
-                        isset($message_templates[ $context ][ $template_field ])
1554
-                            ? $message_templates[ $context ][ $template_field ]
1555
-                            : null;
1556
-                    $template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1557
-                                                                  && is_array($message_templates[ $context ])
1558
-                                                                  && $message_template instanceof EE_Message_Template
1559
-                        ? $message_template->get('MTP_content')
1560
-                        : '';
1561
-
1562
-                    // do we have a validator error for this field?  if we do then we'll use that value instead
1563
-                    $template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1564
-                        ? $validators[ $template_field ]['value']
1565
-                        : $template_form_fields[ $field_id ]['value'];
1566
-
1567
-
1568
-                    $template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1569
-                    $css_class                                      = isset($field_setup_array['css_class'])
1570
-                        ? $field_setup_array['css_class']
1571
-                        : '';
1572
-                    $template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1573
-                                                                      && in_array($template_field, $v_fields, true)
1574
-                                                                      && isset($validators[ $template_field ]['msg'])
1575
-                        ? 'validate-error ' . $css_class
1576
-                        : $css_class;
1577
-
1578
-                    // shortcode selector
1579
-                    $template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1580
-                        $template_field,
1581
-                        $field_id
1582
-                    );
1583
-                }
1584
-
1585
-                // k took care of content field(s) now let's take care of others.
1586
-
1587
-                $template_field_MTP_id                 = $template_field . '-MTP_ID';
1588
-                $template_field_field_template_name_id = $template_field . '-name';
1589
-
1590
-                // foreach template field there are actually two form fields created
1591
-                $template_form_fields[ $template_field_MTP_id ] = [
1592
-                    'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1593
-                    'label'      => null,
1594
-                    'input'      => 'hidden',
1595
-                    'type'       => 'int',
1596
-                    'required'   => false,
1597
-                    'validation' => true,
1598
-                    'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1599
-                    'css_class'  => '',
1600
-                    'format'     => '%d',
1601
-                    'db-col'     => 'MTP_ID',
1602
-                ];
1603
-
1604
-                $template_form_fields[ $template_field_field_template_name_id ] = [
1605
-                    'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1606
-                    'label'      => null,
1607
-                    'input'      => 'hidden',
1608
-                    'type'       => 'string',
1609
-                    'required'   => false,
1610
-                    'validation' => true,
1611
-                    'value'      => $template_field,
1612
-                    'css_class'  => '',
1613
-                    'format'     => '%s',
1614
-                    'db-col'     => 'MTP_template_field',
1615
-                ];
1616
-            }
1617
-
1618
-            // add other fields
1619
-            $template_form_fields['ee-msg-current-context'] = [
1620
-                'name'       => 'MTP_context',
1621
-                'label'      => null,
1622
-                'input'      => 'hidden',
1623
-                'type'       => 'string',
1624
-                'required'   => false,
1625
-                'validation' => true,
1626
-                'value'      => $context,
1627
-                'css_class'  => '',
1628
-                'format'     => '%s',
1629
-                'db-col'     => 'MTP_context',
1630
-            ];
1631
-
1632
-            $template_form_fields['ee-msg-grp-id'] = [
1633
-                'name'       => 'GRP_ID',
1634
-                'label'      => null,
1635
-                'input'      => 'hidden',
1636
-                'type'       => 'int',
1637
-                'required'   => false,
1638
-                'validation' => true,
1639
-                'value'      => $GRP_ID,
1640
-                'css_class'  => '',
1641
-                'format'     => '%d',
1642
-                'db-col'     => 'GRP_ID',
1643
-            ];
1644
-
1645
-            $template_form_fields['ee-msg-messenger'] = [
1646
-                'name'       => 'MTP_messenger',
1647
-                'label'      => null,
1648
-                'input'      => 'hidden',
1649
-                'type'       => 'string',
1650
-                'required'   => false,
1651
-                'validation' => true,
1652
-                'value'      => $message_template_group->messenger(),
1653
-                'css_class'  => '',
1654
-                'format'     => '%s',
1655
-                'db-col'     => 'MTP_messenger',
1656
-            ];
1657
-
1658
-            $template_form_fields['ee-msg-message-type'] = [
1659
-                'name'       => 'MTP_message_type',
1660
-                'label'      => null,
1661
-                'input'      => 'hidden',
1662
-                'type'       => 'string',
1663
-                'required'   => false,
1664
-                'validation' => true,
1665
-                'value'      => $message_template_group->message_type(),
1666
-                'css_class'  => '',
1667
-                'format'     => '%s',
1668
-                'db-col'     => 'MTP_message_type',
1669
-            ];
1670
-
1671
-            $sidebar_form_fields['ee-msg-is-global'] = [
1672
-                'name'       => 'MTP_is_global',
1673
-                'label'      => esc_html__('Global Template', 'event_espresso'),
1674
-                'input'      => 'hidden',
1675
-                'type'       => 'int',
1676
-                'required'   => false,
1677
-                'validation' => true,
1678
-                'value'      => $message_template_group->get('MTP_is_global'),
1679
-                'css_class'  => '',
1680
-                'format'     => '%d',
1681
-                'db-col'     => 'MTP_is_global',
1682
-            ];
1683
-
1684
-            $sidebar_form_fields['ee-msg-is-override'] = [
1685
-                'name'       => 'MTP_is_override',
1686
-                'label'      => esc_html__('Override all custom', 'event_espresso'),
1687
-                'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1688
-                'type'       => 'int',
1689
-                'required'   => false,
1690
-                'validation' => true,
1691
-                'value'      => $message_template_group->get('MTP_is_override'),
1692
-                'css_class'  => '',
1693
-                'format'     => '%d',
1694
-                'db-col'     => 'MTP_is_override',
1695
-            ];
1696
-
1697
-            $sidebar_form_fields['ee-msg-is-active'] = [
1698
-                'name'       => 'MTP_is_active',
1699
-                'label'      => esc_html__('Active Template', 'event_espresso'),
1700
-                'input'      => 'hidden',
1701
-                'type'       => 'int',
1702
-                'required'   => false,
1703
-                'validation' => true,
1704
-                'value'      => $message_template_group->is_active(),
1705
-                'css_class'  => '',
1706
-                'format'     => '%d',
1707
-                'db-col'     => 'MTP_is_active',
1708
-            ];
1709
-
1710
-            $sidebar_form_fields['ee-msg-deleted'] = [
1711
-                'name'       => 'MTP_deleted',
1712
-                'label'      => null,
1713
-                'input'      => 'hidden',
1714
-                'type'       => 'int',
1715
-                'required'   => false,
1716
-                'validation' => true,
1717
-                'value'      => $message_template_group->get('MTP_deleted'),
1718
-                'css_class'  => '',
1719
-                'format'     => '%d',
1720
-                'db-col'     => 'MTP_deleted',
1721
-            ];
1722
-            $sidebar_form_fields['ee-msg-author']  = [
1723
-                'name'       => 'MTP_user_id',
1724
-                'label'      => esc_html__('Author', 'event_espresso'),
1725
-                'input'      => 'hidden',
1726
-                'type'       => 'int',
1727
-                'required'   => false,
1728
-                'validation' => false,
1729
-                'value'      => $message_template_group->user(),
1730
-                'format'     => '%d',
1731
-                'db-col'     => 'MTP_user_id',
1732
-            ];
1733
-
1734
-            $sidebar_form_fields['ee-msg-route'] = [
1735
-                'name'  => 'action',
1736
-                'input' => 'hidden',
1737
-                'type'  => 'string',
1738
-                'value' => $action,
1739
-            ];
1740
-
1741
-            $sidebar_form_fields['ee-msg-id']        = [
1742
-                'name'  => 'id',
1743
-                'input' => 'hidden',
1744
-                'type'  => 'int',
1745
-                'value' => $GRP_ID,
1746
-            ];
1747
-            $sidebar_form_fields['ee-msg-evt-nonce'] = [
1748
-                'name'  => $action . '_nonce',
1749
-                'input' => 'hidden',
1750
-                'type'  => 'string',
1751
-                'value' => wp_create_nonce($action . '_nonce'),
1752
-            ];
1753
-
1754
-            $template_switch = $this->request->getRequestParam('template_switch');
1755
-            if ($template_switch) {
1756
-                $sidebar_form_fields['ee-msg-template-switch'] = [
1757
-                    'name'  => 'template_switch',
1758
-                    'input' => 'hidden',
1759
-                    'type'  => 'int',
1760
-                    'value' => 1,
1761
-                ];
1762
-            }
1763
-
1764
-
1765
-            $template_fields = $this->_generate_admin_form_fields($template_form_fields);
1766
-            $sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1767
-        } //end if ( !empty($template_field_structure) )
1768
-
1769
-        // set extra content for publish box
1770
-        $this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1771
-        $this->_set_publish_post_box_vars(
1772
-            'id',
1773
-            $GRP_ID,
1774
-            false,
1775
-            add_query_arg(
1776
-                ['action' => 'global_mtps'],
1777
-                $this->_admin_base_url
1778
-            )
1779
-        );
1780
-
1781
-        // add preview button
1782
-        $preview_url    = parent::add_query_args_and_nonce(
1783
-            [
1784
-                'message_type' => $message_template_group->message_type(),
1785
-                'messenger'    => $message_template_group->messenger(),
1786
-                'context'      => $context,
1787
-                'GRP_ID'       => $GRP_ID,
1788
-                'evt_id'       => $EVT_ID ?: false,
1789
-                'action'       => 'preview_message',
1790
-            ],
1791
-            $this->_admin_base_url
1792
-        );
1793
-        $preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1794
-                          . esc_html__('Preview', 'event_espresso')
1795
-                          . '</a>';
1796
-
1797
-
1798
-        // setup context switcher
1799
-        $this->_set_context_switcher(
1800
-            $message_template_group,
1801
-            [
1802
-                'page'    => 'espresso_messages',
1803
-                'action'  => 'edit_message_template',
1804
-                'id'      => $GRP_ID,
1805
-                'evt_id'  => $EVT_ID,
1806
-                'context' => $context,
1807
-                'extra'   => $preview_button,
1808
-            ]
1809
-        );
1810
-
1811
-
1812
-        // main box
1813
-        $this->_template_args['template_fields']                         = $template_fields;
1814
-        $this->_template_args['sidebar_box_id']                          = 'details';
1815
-        $this->_template_args['action']                                  = $action;
1816
-        $this->_template_args['context']                                 = $context;
1817
-        $this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1818
-        $this->_template_args['learn_more_about_message_templates_link'] =
1819
-            $this->_learn_more_about_message_templates_link();
1820
-
1821
-
1822
-        $this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1823
-        $this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1824
-            $message_template_group,
1825
-            $context,
1826
-            $context_label
1827
-        );
1828
-        $this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1829
-        $this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1830
-
1831
-        $this->_template_path = $this->_template_args['GRP_ID']
1832
-            ? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1833
-            : EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1834
-
1835
-        // send along EE_Message_Template_Group object for further template use.
1836
-        $this->_template_args['MTP'] = $message_template_group;
1837
-
1838
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1839
-            $this->_template_path,
1840
-            $this->_template_args,
1841
-            true
1842
-        );
1843
-
1844
-
1845
-        // finally, let's set the admin_page title
1846
-        $this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1847
-
1848
-
1849
-        // we need to take care of setting the shortcodes property for use elsewhere.
1850
-        $this->_set_shortcodes();
1851
-
1852
-
1853
-        // final template wrapper
1854
-        $this->display_admin_page_with_sidebar();
1855
-    }
1856
-
1857
-
1858
-    public function filter_tinymce_init($mceInit, $editor_id)
1859
-    {
1860
-        return $mceInit;
1861
-    }
1862
-
1863
-
1864
-    public function add_context_switcher()
1865
-    {
1866
-        return $this->_context_switcher;
1867
-    }
1868
-
1869
-
1870
-    /**
1871
-     * Adds the activation/deactivation toggle for the message template context.
1872
-     *
1873
-     * @param EE_Message_Template_Group $message_template_group
1874
-     * @param string                    $context
1875
-     * @param string                    $context_label
1876
-     * @return string
1877
-     * @throws DomainException
1878
-     * @throws EE_Error
1879
-     * @throws InvalidIdentifierException
1880
-     * @throws ReflectionException
1881
-     */
1882
-    protected function add_active_context_element(
1883
-        EE_Message_Template_Group $message_template_group,
1884
-        $context,
1885
-        $context_label
1886
-    ) {
1887
-        $template_args = [
1888
-            'context'                   => $context,
1889
-            'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1890
-            'is_active'                 => $message_template_group->is_context_active($context),
1891
-            'on_off_action'             => $message_template_group->is_context_active($context)
1892
-                ? 'context-off'
1893
-                : 'context-on',
1894
-            'context_label'             => str_replace(['(', ')'], '', $context_label),
1895
-            'message_template_group_id' => $message_template_group->ID(),
1896
-        ];
1897
-        return EEH_Template::display_template(
1898
-            EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1899
-            $template_args,
1900
-            true
1901
-        );
1902
-    }
1903
-
1904
-
1905
-    /**
1906
-     * Ajax callback for `toggle_context_template` ajax action.
1907
-     * Handles toggling the message context on or off.
1908
-     *
1909
-     * @throws EE_Error
1910
-     * @throws InvalidArgumentException
1911
-     * @throws InvalidDataTypeException
1912
-     * @throws InvalidIdentifierException
1913
-     * @throws InvalidInterfaceException
1914
-     */
1915
-    public function toggle_context_template()
1916
-    {
1917
-        $success = true;
1918
-        // check for required data
1919
-        if (
1920
-            ! (
1921
-                $this->request->requestParamIsSet('message_template_group_id')
1922
-                && $this->request->requestParamIsSet('context')
1923
-                && $this->request->requestParamIsSet('status')
1924
-            )
1925
-        ) {
1926
-            EE_Error::add_error(
1927
-                esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1928
-                __FILE__,
1929
-                __FUNCTION__,
1930
-                __LINE__
1931
-            );
1932
-            $success = false;
1933
-        }
1934
-
1935
-        $nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1936
-        $context = $this->request->getRequestParam('context', '');
1937
-        $status  = $this->request->getRequestParam('status', '');
1938
-
1939
-        $this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1940
-
1941
-        if ($status !== 'off' && $status !== 'on') {
1942
-            EE_Error::add_error(
1943
-                sprintf(
1944
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1945
-                    $status
1946
-                ),
1947
-                __FILE__,
1948
-                __FUNCTION__,
1949
-                __LINE__
1950
-            );
1951
-            $success = false;
1952
-        }
1953
-        $message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, 'int');
1954
-        $message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1955
-        if (! $message_template_group instanceof EE_Message_Template_Group) {
1956
-            EE_Error::add_error(
1957
-                sprintf(
1958
-                    esc_html__(
1959
-                        'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1960
-                        'event_espresso'
1961
-                    ),
1962
-                    $message_template_group_id,
1963
-                    'EE_Message_Template_Group'
1964
-                ),
1965
-                __FILE__,
1966
-                __FUNCTION__,
1967
-                __LINE__
1968
-            );
1969
-            $success = false;
1970
-        }
1971
-        if ($success) {
1972
-            $success = $status === 'off'
1973
-                ? $message_template_group->deactivate_context($context)
1974
-                : $message_template_group->activate_context($context);
1975
-        }
1976
-        $this->_template_args['success'] = $success;
1977
-        $this->_return_json();
1978
-    }
1979
-
1980
-
1981
-    public function _add_form_element_before()
1982
-    {
1983
-        return '<form method="post" action="'
1984
-               . $this->_template_args['edit_message_template_form_url']
1985
-               . '" id="ee-msg-edit-frm">';
1986
-    }
1987
-
1988
-
1989
-    public function _add_form_element_after()
1990
-    {
1991
-        return '</form>';
1992
-    }
1993
-
1994
-
1995
-    /**
1996
-     * This executes switching the template pack for a message template.
1997
-     *
1998
-     * @throws EE_Error
1999
-     * @throws InvalidDataTypeException
2000
-     * @throws InvalidInterfaceException
2001
-     * @throws InvalidArgumentException
2002
-     * @throws ReflectionException
2003
-     * @since 4.5.0
2004
-     */
2005
-    public function switch_template_pack()
2006
-    {
2007
-
2008
-        $GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, 'int');
2009
-        $template_pack = $this->request->getRequestParam('template_pack', '');
2010
-
2011
-        // verify we have needed values.
2012
-        if (empty($GRP_ID) || empty($template_pack)) {
2013
-            $this->_template_args['error'] = true;
2014
-            EE_Error::add_error(
2015
-                esc_html__('The required date for switching templates is not available.', 'event_espresso'),
2016
-                __FILE__,
2017
-                __FUNCTION__,
2018
-                __LINE__
2019
-            );
2020
-        } else {
2021
-            // get template, set the new template_pack and then reset to default
2022
-            /** @var EE_Message_Template_Group $message_template_group */
2023
-            $message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
2024
-
2025
-            $message_template_group->set_template_pack_name($template_pack);
2026
-            $this->request->setRequestParam('msgr', $message_template_group->messenger());
2027
-            $this->request->setRequestParam('mt', $message_template_group->message_type());
2028
-
2029
-            $query_args = $this->_reset_to_default_template();
2030
-
2031
-            if (empty($query_args['id'])) {
2032
-                EE_Error::add_error(
2033
-                    esc_html__(
2034
-                        'Something went wrong with switching the template pack. Please try again or contact EE support',
2035
-                        'event_espresso'
2036
-                    ),
2037
-                    __FILE__,
2038
-                    __FUNCTION__,
2039
-                    __LINE__
2040
-                );
2041
-                $this->_template_args['error'] = true;
2042
-            } else {
2043
-                $template_label       = $message_template_group->get_template_pack()->label;
2044
-                $template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2045
-                EE_Error::add_success(
2046
-                    sprintf(
2047
-                        esc_html__(
2048
-                            'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2049
-                            'event_espresso'
2050
-                        ),
2051
-                        $template_label,
2052
-                        $template_pack_labels->template_pack
2053
-                    )
2054
-                );
2055
-                // generate the redirect url for js.
2056
-                $url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2057
-
2058
-                $this->_template_args['data']['redirect_url'] = $url;
2059
-                $this->_template_args['success']              = true;
2060
-            }
2061
-
2062
-            $this->_return_json();
2063
-        }
2064
-    }
2065
-
2066
-
2067
-    /**
2068
-     * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2069
-     * they want.
2070
-     *
2071
-     * @access protected
2072
-     * @return array|void
2073
-     * @throws EE_Error
2074
-     * @throws InvalidArgumentException
2075
-     * @throws InvalidDataTypeException
2076
-     * @throws InvalidInterfaceException
2077
-     * @throws ReflectionException
2078
-     */
2079
-    protected function _reset_to_default_template()
2080
-    {
2081
-        $templates    = [];
2082
-        $GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, 'int');
2083
-        $messenger    = $this->request->getRequestParam('msgr');
2084
-        $message_type = $this->request->getRequestParam('mt');
2085
-        // we need to make sure we've got the info we need.
2086
-        if (! ($GRP_ID && $messenger && $message_type)) {
2087
-            EE_Error::add_error(
2088
-                esc_html__(
2089
-                    '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.',
2090
-                    'event_espresso'
2091
-                ),
2092
-                __FILE__,
2093
-                __FUNCTION__,
2094
-                __LINE__
2095
-            );
2096
-        }
2097
-
2098
-        // all templates will be reset to whatever the defaults are
2099
-        // for the global template matching the messenger and message type.
2100
-        $success = ! empty($GRP_ID);
2101
-
2102
-        if ($success) {
2103
-            // let's first determine if the incoming template is a global template,
2104
-            // if it isn't then we need to get the global template matching messenger and message type.
2105
-            // $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
2106
-
2107
-
2108
-            // note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2109
-            $success = $this->_delete_mtp_permanently($GRP_ID, false);
2110
-
2111
-            if ($success) {
2112
-                // if successfully deleted, lets generate the new ones.
2113
-                // Note. We set GLOBAL to true, because resets on ANY template
2114
-                // will use the related global template defaults for regeneration.
2115
-                // This means that if a custom template is reset it resets to whatever the related global template is.
2116
-                // HOWEVER, we DO keep the template pack and template variation set
2117
-                // for the current custom template when resetting.
2118
-                $templates = $this->_generate_new_templates($messenger, $message_type, $GRP_ID, true);
2119
-            }
2120
-        }
2121
-
2122
-        // any error messages?
2123
-        if (! $success) {
2124
-            EE_Error::add_error(
2125
-                esc_html__(
2126
-                    'Something went wrong with deleting existing templates. Unable to reset to default',
2127
-                    'event_espresso'
2128
-                ),
2129
-                __FILE__,
2130
-                __FUNCTION__,
2131
-                __LINE__
2132
-            );
2133
-        }
2134
-
2135
-        // all good, let's add a success message!
2136
-        if ($success && ! empty($templates)) {
2137
-            // the info for the template we generated is the first element in the returned array
2138
-            EE_Error::overwrite_success();
2139
-            EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2140
-        }
2141
-
2142
-
2143
-        $query_args = [
2144
-            'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
2145
-            'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
2146
-            'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2147
-        ];
2148
-
2149
-        // if called via ajax then we return query args otherwise redirect
2150
-        if ($this->request->isAjax()) {
2151
-            return $query_args;
2152
-        }
2153
-        $this->_redirect_after_action(false, '', '', $query_args, true);
2154
-    }
2155
-
2156
-
2157
-    /**
2158
-     * Retrieve and set the message preview for display.
2159
-     *
2160
-     * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2161
-     * @return string
2162
-     * @throws ReflectionException
2163
-     * @throws EE_Error
2164
-     * @throws InvalidArgumentException
2165
-     * @throws InvalidDataTypeException
2166
-     * @throws InvalidInterfaceException
2167
-     */
2168
-    public function _preview_message($send = false)
2169
-    {
2170
-        // first make sure we've got the necessary parameters
2171
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2172
-        if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2173
-            EE_Error::add_error(
2174
-                esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2175
-                __FILE__,
2176
-                __FUNCTION__,
2177
-                __LINE__
2178
-            );
2179
-        }
2180
-
2181
-        $context = $this->request->getRequestParam('context');
2182
-        // get the preview!
2183
-        $preview = EED_Messages::preview_message(
2184
-            $this->_active_message_type_name,
2185
-            $context,
2186
-            $this->_active_messenger_name,
2187
-            $send
2188
-        );
2189
-
2190
-        if ($send) {
2191
-            return $preview;
2192
-        }
2193
-
2194
-        // if we have an evt_id set on the request, use it.
2195
-        $EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
2196
-
2197
-        // let's add a button to go back to the edit view
2198
-        $query_args             = [
2199
-            'id'      => $GRP_ID,
2200
-            'evt_id'  => $EVT_ID,
2201
-            'context' => $context,
2202
-            'action'  => 'edit_message_template',
2203
-        ];
2204
-        $go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2205
-        $preview_button         = '<a href="'
2206
-                                  . $go_back_url
2207
-                                  . '" class="button-secondary messages-preview-go-back-button">'
2208
-                                  . esc_html__('Go Back to Edit', 'event_espresso')
2209
-                                  . '</a>';
2210
-        $message_types          = $this->get_installed_message_types();
2211
-        $active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2212
-        $active_messenger_label = $active_messenger instanceof EE_messenger
2213
-            ? ucwords($active_messenger->label['singular'])
2214
-            : esc_html__('Unknown Messenger', 'event_espresso');
2215
-        // let's provide a helpful title for context
2216
-        $preview_title = sprintf(
2217
-            esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2218
-            $active_messenger_label,
2219
-            ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2220
-        );
2221
-        if (empty($preview)) {
2222
-            $this->noEventsErrorMessage();
2223
-        }
2224
-        // setup display of preview.
2225
-        $this->_admin_page_title                    = $preview_title;
2226
-        $this->_template_args['admin_page_title']   = $preview_title;
2227
-        $this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2228
-        $this->_template_args['data']['force_json'] = true;
2229
-
2230
-        return '';
2231
-    }
2232
-
2233
-
2234
-    /**
2235
-     * Used to set an error if there are no events available for generating a preview/test send.
2236
-     *
2237
-     * @param bool $test_send Whether the error should be generated for the context of a test send.
2238
-     */
2239
-    protected function noEventsErrorMessage($test_send = false)
2240
-    {
2241
-        $events_url = parent::add_query_args_and_nonce(
2242
-            [
2243
-                'action' => 'default',
2244
-                'page'   => 'espresso_events',
2245
-            ],
2246
-            admin_url('admin.php')
2247
-        );
2248
-        $message    = $test_send
2249
-            ? esc_html__(
2250
-                '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!',
2251
-                'event_espresso'
2252
-            )
2253
-            : esc_html__(
2254
-                '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!',
2255
-                'event_espresso'
2256
-            );
2257
-
2258
-        EE_Error::add_attention(
2259
-            sprintf(
2260
-                $message,
2261
-                "<a href='{$events_url}'>",
2262
-                '</a>'
2263
-            )
2264
-        );
2265
-    }
2266
-
2267
-
2268
-    /**
2269
-     * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2270
-     * gets called automatically.
2271
-     *
2272
-     * @return void
2273
-     * @throws EE_Error
2274
-     * @since 4.5.0
2275
-     *
2276
-     */
2277
-    protected function _display_preview_message()
2278
-    {
2279
-        $this->display_admin_page_with_no_sidebar();
2280
-    }
2281
-
2282
-
2283
-    /**
2284
-     * registers metaboxes that should show up on the "edit_message_template" page
2285
-     *
2286
-     * @access protected
2287
-     * @return void
2288
-     */
2289
-    protected function _register_edit_meta_boxes()
2290
-    {
2291
-        add_meta_box(
2292
-            'mtp_valid_shortcodes',
2293
-            esc_html__('Valid Shortcodes', 'event_espresso'),
2294
-            [$this, 'shortcode_meta_box'],
2295
-            $this->_current_screen->id,
2296
-            'side'
2297
-        );
2298
-        add_meta_box(
2299
-            'mtp_extra_actions',
2300
-            esc_html__('Extra Actions', 'event_espresso'),
2301
-            [$this, 'extra_actions_meta_box'],
2302
-            $this->_current_screen->id,
2303
-            'side',
2304
-            'high'
2305
-        );
2306
-        add_meta_box(
2307
-            'mtp_templates',
2308
-            esc_html__('Template Styles', 'event_espresso'),
2309
-            [$this, 'template_pack_meta_box'],
2310
-            $this->_current_screen->id,
2311
-            'side',
2312
-            'high'
2313
-        );
2314
-    }
2315
-
2316
-
2317
-    /**
2318
-     * metabox content for all template pack and variation selection.
2319
-     *
2320
-     * @return void
2321
-     * @throws DomainException
2322
-     * @throws EE_Error
2323
-     * @throws InvalidArgumentException
2324
-     * @throws ReflectionException
2325
-     * @throws InvalidDataTypeException
2326
-     * @throws InvalidInterfaceException
2327
-     * @since 4.5.0
2328
-     */
2329
-    public function template_pack_meta_box()
2330
-    {
2331
-        $this->_set_message_template_group();
2332
-
2333
-        $tp_collection = EEH_MSG_Template::get_template_pack_collection();
2334
-
2335
-        $tp_select_values = [];
2336
-
2337
-        foreach ($tp_collection as $tp) {
2338
-            // only include template packs that support this messenger and message type!
2339
-            $supports = $tp->get_supports();
2340
-            if (
2341
-                ! isset($supports[ $this->_message_template_group->messenger() ])
2342
-                || ! in_array(
2343
-                    $this->_message_template_group->message_type(),
2344
-                    $supports[ $this->_message_template_group->messenger() ],
2345
-                    true
2346
-                )
2347
-            ) {
2348
-                // not supported
2349
-                continue;
2350
-            }
2351
-
2352
-            $tp_select_values[] = [
2353
-                'text' => $tp->label,
2354
-                'id'   => $tp->dbref,
2355
-            ];
2356
-        }
2357
-
2358
-        // if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2359
-        // the default template pack.  This still allows for the odd template pack to override.
2360
-        if (empty($tp_select_values)) {
2361
-            $tp_select_values[] = [
2362
-                'text' => esc_html__('Default', 'event_espresso'),
2363
-                'id'   => 'default',
2364
-            ];
2365
-        }
2366
-
2367
-        // setup variation select values for the currently selected template.
2368
-        $variations               = $this->_message_template_group->get_template_pack()->get_variations(
2369
-            $this->_message_template_group->messenger(),
2370
-            $this->_message_template_group->message_type()
2371
-        );
2372
-        $variations_select_values = [];
2373
-        foreach ($variations as $variation => $label) {
2374
-            $variations_select_values[] = [
2375
-                'text' => $label,
2376
-                'id'   => $variation,
2377
-            ];
2378
-        }
2379
-
2380
-        $template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2381
-
2382
-        $template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2383
-            'MTP_template_pack',
2384
-            $tp_select_values,
2385
-            $this->_message_template_group->get_template_pack_name()
2386
-        );
2387
-        $template_args['variations_selector']            = EEH_Form_Fields::select_input(
2388
-            'MTP_template_variation',
2389
-            $variations_select_values,
2390
-            $this->_message_template_group->get_template_pack_variation()
2391
-        );
2392
-        $template_args['template_pack_label']            = $template_pack_labels->template_pack;
2393
-        $template_args['template_variation_label']       = $template_pack_labels->template_variation;
2394
-        $template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2395
-        $template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2396
-
2397
-        $template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2398
-
2399
-        EEH_Template::display_template($template, $template_args);
2400
-    }
2401
-
2402
-
2403
-    /**
2404
-     * This meta box holds any extra actions related to Message Templates
2405
-     * For now, this includes Resetting templates to defaults and sending a test email.
2406
-     *
2407
-     * @access  public
2408
-     * @return void
2409
-     * @throws EE_Error
2410
-     */
2411
-    public function extra_actions_meta_box()
2412
-    {
2413
-        $template_form_fields = [];
2414
-
2415
-        $extra_args = [
2416
-            'msgr'   => $this->_message_template_group->messenger(),
2417
-            'mt'     => $this->_message_template_group->message_type(),
2418
-            'GRP_ID' => $this->_message_template_group->GRP_ID(),
2419
-        ];
2420
-        // first we need to see if there are any fields
2421
-        $fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2422
-
2423
-        if (! empty($fields)) {
2424
-            // yup there be fields
2425
-            foreach ($fields as $field => $config) {
2426
-                $field_id = $this->_message_template_group->messenger() . '_' . $field;
2427
-                $existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2428
-                $default  = isset($config['default']) ? $config['default'] : '';
2429
-                $default  = isset($config['value']) ? $config['value'] : $default;
2430
-
2431
-                // if type is hidden and the value is empty
2432
-                // something may have gone wrong so let's correct with the defaults
2433
-                $fix                = $config['input'] === 'hidden'
2434
-                                      && isset($existing[ $field ])
2435
-                                      && empty($existing[ $field ])
2436
-                    ? $default
2437
-                    : '';
2438
-                $existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2439
-                    ? $existing[ $field ]
2440
-                    : $fix;
2441
-
2442
-                $template_form_fields[ $field_id ] = [
2443
-                    'name'       => 'test_settings_fld[' . $field . ']',
2444
-                    'label'      => $config['label'],
2445
-                    'input'      => $config['input'],
2446
-                    'type'       => $config['type'],
2447
-                    'required'   => $config['required'],
2448
-                    'validation' => $config['validation'],
2449
-                    'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2450
-                    'css_class'  => $config['css_class'],
2451
-                    'options'    => isset($config['options']) ? $config['options'] : [],
2452
-                    'default'    => $default,
2453
-                    'format'     => $config['format'],
2454
-                ];
2455
-            }
2456
-        }
2457
-
2458
-        $test_settings_html = ! empty($template_form_fields)
2459
-            ? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2460
-            : '';
2461
-
2462
-        // print out $test_settings_fields
2463
-        if (! empty($test_settings_html)) {
2464
-            $test_settings_html .= '<input type="submit" class="button-primary mtp-test-button alignright" ';
2465
-            $test_settings_html .= 'name="test_button" value="';
2466
-            $test_settings_html .= esc_html__('Test Send', 'event_espresso');
2467
-            $test_settings_html .= '" /><div style="clear:both"></div>';
2468
-        }
2469
-
2470
-        // and button
2471
-        $test_settings_html .= '<p>';
2472
-        $test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2473
-        $test_settings_html .= '</p>';
2474
-        $test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2475
-        $test_settings_html .= $this->get_action_link_or_button(
2476
-            'reset_to_default',
2477
-            'reset',
2478
-            $extra_args,
2479
-            'button-primary reset-default-button'
2480
-        );
2481
-        $test_settings_html .= '</div><div style="clear:both"></div>';
2482
-        echo $test_settings_html; // already escaped
2483
-    }
2484
-
2485
-
2486
-    /**
2487
-     * This returns the shortcode selector skeleton for a given context and field.
2488
-     *
2489
-     * @param string $field           The name of the field retrieving shortcodes for.
2490
-     * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2491
-     * @return string
2492
-     * @throws DomainException
2493
-     * @throws EE_Error
2494
-     * @throws InvalidArgumentException
2495
-     * @throws ReflectionException
2496
-     * @throws InvalidDataTypeException
2497
-     * @throws InvalidInterfaceException
2498
-     * @since 4.9.rc.000
2499
-     */
2500
-    protected function _get_shortcode_selector($field, $linked_input_id)
2501
-    {
2502
-        $template_args = [
2503
-            'shortcodes'      => $this->_get_shortcodes([$field]),
2504
-            'fieldname'       => $field,
2505
-            'linked_input_id' => $linked_input_id,
2506
-        ];
2507
-
2508
-        return EEH_Template::display_template(
2509
-            EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2510
-            $template_args,
2511
-            true
2512
-        );
2513
-    }
2514
-
2515
-
2516
-    /**
2517
-     * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2518
-     * page)
2519
-     *
2520
-     * @access public
2521
-     * @return void
2522
-     * @throws EE_Error
2523
-     * @throws InvalidArgumentException
2524
-     * @throws ReflectionException
2525
-     * @throws InvalidDataTypeException
2526
-     * @throws InvalidInterfaceException
2527
-     */
2528
-    public function shortcode_meta_box()
2529
-    {
2530
-        $shortcodes = $this->_get_shortcodes([], false);
2531
-        // just make sure the shortcodes property is set
2532
-        // $messenger = $this->_message_template_group->messenger_obj();
2533
-        // now let's set the content depending on the status of the shortcodes array
2534
-        if (empty($shortcodes)) {
2535
-            echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2536
-            return;
2537
-        }
2538
-        ?>
19
+	/**
20
+	 * @var EEM_Message
21
+	 */
22
+	private $MSG_MODEL;
23
+
24
+	/**
25
+	 * @var EEM_Message_Template
26
+	 */
27
+	private $MTP_MODEL;
28
+
29
+	/**
30
+	 * @var EEM_Message_Template_Group
31
+	 */
32
+	private $MTG_MODEL;
33
+
34
+	/**
35
+	 * @var EE_Message_Resource_Manager $_message_resource_manager
36
+	 */
37
+	protected $_message_resource_manager;
38
+
39
+	/**
40
+	 * @var string
41
+	 */
42
+	protected $_active_message_type_name = '';
43
+
44
+	/**
45
+	 * @var string
46
+	 */
47
+	protected $_active_messenger_name = '';
48
+
49
+	/**
50
+	 * @var EE_messenger $_active_messenger
51
+	 */
52
+	protected $_active_messenger;
53
+
54
+	protected $_activate_meta_box_type;
55
+
56
+	protected $_current_message_meta_box;
57
+
58
+	protected $_current_message_meta_box_object;
59
+
60
+	protected $_context_switcher;
61
+
62
+	protected $_shortcodes           = [];
63
+
64
+	protected $_active_messengers    = [];
65
+
66
+	protected $_active_message_types = [];
67
+
68
+	/**
69
+	 * @var EE_Message_Template_Group $_message_template_group
70
+	 */
71
+	protected $_message_template_group;
72
+
73
+	protected $_m_mt_settings = [];
74
+
75
+
76
+	/**
77
+	 * This is set via the _set_message_template_group method and holds whatever the template pack for the group is.
78
+	 * IF there is no group then it gets automatically set to the Default template pack.
79
+	 *
80
+	 * @since 4.5.0
81
+	 *
82
+	 * @var EE_Messages_Template_Pack
83
+	 */
84
+	protected $_template_pack;
85
+
86
+
87
+	/**
88
+	 * This is set via the _set_message_template_group method and holds whatever the template pack variation for the
89
+	 * group is.  If there is no group then it automatically gets set to default.
90
+	 *
91
+	 * @since 4.5.0
92
+	 *
93
+	 * @var string
94
+	 */
95
+	protected $_variation;
96
+
97
+
98
+	/**
99
+	 * @param bool $routing
100
+	 * @throws EE_Error
101
+	 * @throws ReflectionException
102
+	 */
103
+	public function __construct($routing = true)
104
+	{
105
+		// make sure messages autoloader is running
106
+		EED_Messages::set_autoloaders();
107
+		parent::__construct($routing);
108
+	}
109
+
110
+
111
+	/**
112
+	 * @return EEM_Message
113
+	 * @throws EE_Error
114
+	 */
115
+	public function getMsgModel()
116
+	{
117
+		if (! $this->MSG_MODEL instanceof EEM_Message) {
118
+			$this->MSG_MODEL = EEM_Message::instance();
119
+		}
120
+		return $this->MSG_MODEL;
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return EEM_Message_Template
126
+	 * @throws EE_Error
127
+	 */
128
+	public function getMtpModel()
129
+	{
130
+		if (! $this->MTP_MODEL instanceof EEM_Message_Template) {
131
+			$this->MTP_MODEL = EEM_Message_Template::instance();
132
+		}
133
+		return $this->MTP_MODEL;
134
+	}
135
+
136
+
137
+	/**
138
+	 * @return EEM_Message_Template_Group
139
+	 * @throws EE_Error
140
+	 */
141
+	public function getMtgModel()
142
+	{
143
+		if (! $this->MTG_MODEL instanceof EEM_Message_Template_Group) {
144
+			$this->MTG_MODEL = EEM_Message_Template_Group::instance();
145
+		}
146
+		return $this->MTG_MODEL;
147
+	}
148
+
149
+
150
+	/**
151
+	 * @throws EE_Error
152
+	 * @throws ReflectionException
153
+	 */
154
+	protected function _init_page_props()
155
+	{
156
+		$this->page_slug        = EE_MSG_PG_SLUG;
157
+		$this->page_label       = esc_html__('Messages Settings', 'event_espresso');
158
+		$this->_admin_base_url  = EE_MSG_ADMIN_URL;
159
+		$this->_admin_base_path = EE_MSG_ADMIN;
160
+
161
+		$messenger    = $this->request->getRequestParam('messenger', '');
162
+		$message_type = $this->request->getRequestParam('message_type', '');
163
+		$this->_active_messenger_name    = $this->request->getRequestParam('MTP_messenger', $messenger);
164
+		$this->_active_message_type_name = $this->request->getRequestParam('MTP_message_type', $message_type);
165
+
166
+		$this->_load_message_resource_manager();
167
+	}
168
+
169
+
170
+	/**
171
+	 * loads messenger objects into the $_active_messengers property (so we can access the needed methods)
172
+	 *
173
+	 * @throws EE_Error
174
+	 * @throws InvalidDataTypeException
175
+	 * @throws InvalidInterfaceException
176
+	 * @throws InvalidArgumentException
177
+	 * @throws ReflectionException
178
+	 */
179
+	protected function _load_message_resource_manager()
180
+	{
181
+		$this->_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
182
+	}
183
+
184
+
185
+	/**
186
+	 * @return array
187
+	 * @throws EE_Error
188
+	 * @throws InvalidArgumentException
189
+	 * @throws InvalidDataTypeException
190
+	 * @throws InvalidInterfaceException
191
+	 * @deprecated 4.9.9.rc.014
192
+	 */
193
+	public function get_messengers_for_list_table()
194
+	{
195
+		EE_Error::doing_it_wrong(
196
+			__METHOD__,
197
+			sprintf(
198
+				esc_html__(
199
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a messenger filter dropdown which is now generated differently via %s',
200
+					'event_espresso'
201
+				),
202
+				'Messages_Admin_Page::get_messengers_select_input()'
203
+			),
204
+			'4.9.9.rc.014'
205
+		);
206
+
207
+		$m_values          = [];
208
+		$active_messengers = $this->getMsgModel()->get_all(['group_by' => 'MSG_messenger']);
209
+		// setup messengers for selects
210
+		$i = 1;
211
+		foreach ($active_messengers as $active_messenger) {
212
+			if ($active_messenger instanceof EE_Message) {
213
+				$m_values[ $i ]['id']   = $active_messenger->messenger();
214
+				$m_values[ $i ]['text'] = ucwords($active_messenger->messenger_label());
215
+				$i++;
216
+			}
217
+		}
218
+
219
+		return $m_values;
220
+	}
221
+
222
+
223
+	/**
224
+	 * @return array
225
+	 * @throws EE_Error
226
+	 * @throws InvalidArgumentException
227
+	 * @throws InvalidDataTypeException
228
+	 * @throws InvalidInterfaceException
229
+	 * @deprecated 4.9.9.rc.014
230
+	 */
231
+	public function get_message_types_for_list_table()
232
+	{
233
+		EE_Error::doing_it_wrong(
234
+			__METHOD__,
235
+			sprintf(
236
+				esc_html__(
237
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type filter dropdown which is now generated differently via %s',
238
+					'event_espresso'
239
+				),
240
+				'Messages_Admin_Page::get_message_types_select_input()'
241
+			),
242
+			'4.9.9.rc.014'
243
+		);
244
+
245
+		$mt_values       = [];
246
+		$active_messages = $this->getMsgModel()->get_all(['group_by' => 'MSG_message_type']);
247
+		$i               = 1;
248
+		foreach ($active_messages as $active_message) {
249
+			if ($active_message instanceof EE_Message) {
250
+				$mt_values[ $i ]['id']   = $active_message->message_type();
251
+				$mt_values[ $i ]['text'] = ucwords($active_message->message_type_label());
252
+				$i++;
253
+			}
254
+		}
255
+
256
+		return $mt_values;
257
+	}
258
+
259
+
260
+	/**
261
+	 * @return array
262
+	 * @throws EE_Error
263
+	 * @throws InvalidArgumentException
264
+	 * @throws InvalidDataTypeException
265
+	 * @throws InvalidInterfaceException
266
+	 * @deprecated 4.9.9.rc.014
267
+	 */
268
+	public function get_contexts_for_message_types_for_list_table()
269
+	{
270
+		EE_Error::doing_it_wrong(
271
+			__METHOD__,
272
+			sprintf(
273
+				esc_html__(
274
+					'This method is no longer in use.  There is no replacement for it. The method was used to generate a set of values for use in creating a message type context filter dropdown which is now generated differently via %s',
275
+					'event_espresso'
276
+				),
277
+				'Messages_Admin_Page::get_contexts_for_message_types_select_input()'
278
+			),
279
+			'4.9.9.rc.014'
280
+		);
281
+
282
+		$contexts                = [];
283
+		$active_message_contexts = $this->getMsgModel()->get_all(['group_by' => 'MSG_context']);
284
+		foreach ($active_message_contexts as $active_message) {
285
+			if ($active_message instanceof EE_Message) {
286
+				$message_type = $active_message->message_type_object();
287
+				if ($message_type instanceof EE_message_type) {
288
+					$message_type_contexts = $message_type->get_contexts();
289
+					foreach ($message_type_contexts as $context => $context_details) {
290
+						$contexts[ $context ] = $context_details['label'];
291
+					}
292
+				}
293
+			}
294
+		}
295
+
296
+		return $contexts;
297
+	}
298
+
299
+
300
+	/**
301
+	 * Generate select input with provided messenger options array.
302
+	 *
303
+	 * @param array $messenger_options Array of messengers indexed by messenger slug and values are the messenger
304
+	 *                                 labels.
305
+	 * @return string
306
+	 * @throws EE_Error
307
+	 */
308
+	public function get_messengers_select_input($messenger_options)
309
+	{
310
+		// if empty or just one value then just return an empty string
311
+		if (
312
+			empty($messenger_options)
313
+			|| ! is_array($messenger_options)
314
+			|| count($messenger_options) === 1
315
+		) {
316
+			return '';
317
+		}
318
+		// merge in default
319
+		$messenger_options = array_merge(
320
+			['none_selected' => esc_html__('Show All Messengers', 'event_espresso')],
321
+			$messenger_options
322
+		);
323
+		$input             = new EE_Select_Input(
324
+			$messenger_options,
325
+			[
326
+				'html_name'  => 'ee_messenger_filter_by',
327
+				'html_id'    => 'ee_messenger_filter_by',
328
+				'html_class' => 'wide',
329
+				'default'    => $this->request->getRequestParam('ee_messenger_filter_by', 'none_selected', 'title'),
330
+			]
331
+		);
332
+
333
+		return $input->get_html_for_input();
334
+	}
335
+
336
+
337
+	/**
338
+	 * Generate select input with provided message type options array.
339
+	 *
340
+	 * @param array $message_type_options Array of message types indexed by message type slug, and values are the
341
+	 *                                    message type labels
342
+	 * @return string
343
+	 * @throws EE_Error
344
+	 */
345
+	public function get_message_types_select_input($message_type_options)
346
+	{
347
+		// if empty or count of options is 1 then just return an empty string
348
+		if (
349
+			empty($message_type_options)
350
+			|| ! is_array($message_type_options)
351
+			|| count($message_type_options) === 1
352
+		) {
353
+			return '';
354
+		}
355
+		// merge in default
356
+		$message_type_options = array_merge(
357
+			['none_selected' => esc_html__('Show All Message Types', 'event_espresso')],
358
+			$message_type_options
359
+		);
360
+		$input                = new EE_Select_Input(
361
+			$message_type_options,
362
+			[
363
+				'html_name'  => 'ee_message_type_filter_by',
364
+				'html_id'    => 'ee_message_type_filter_by',
365
+				'html_class' => 'wide',
366
+				'default'    => $this->request->getRequestParam('ee_message_type_filter_by', 'none_selected', 'title'),
367
+			]
368
+		);
369
+
370
+		return $input->get_html_for_input();
371
+	}
372
+
373
+
374
+	/**
375
+	 * Generate select input with provide message type contexts array.
376
+	 *
377
+	 * @param array $context_options Array of message type contexts indexed by context slug, and values are the
378
+	 *                               context label.
379
+	 * @return string
380
+	 * @throws EE_Error
381
+	 */
382
+	public function get_contexts_for_message_types_select_input($context_options)
383
+	{
384
+		// if empty or count of options is one then just return empty string
385
+		if (
386
+			empty($context_options)
387
+			|| ! is_array($context_options)
388
+			|| count($context_options) === 1
389
+		) {
390
+			return '';
391
+		}
392
+		// merge in default
393
+		$context_options = array_merge(
394
+			['none_selected' => esc_html__('Show all Contexts', 'event_espresso')],
395
+			$context_options
396
+		);
397
+		$input           = new EE_Select_Input(
398
+			$context_options,
399
+			[
400
+				'html_name'  => 'ee_context_filter_by',
401
+				'html_id'    => 'ee_context_filter_by',
402
+				'html_class' => 'wide',
403
+				'default'    => $this->request->getRequestParam('ee_context_filter_by', 'none_selected', 'title'),
404
+			]
405
+		);
406
+
407
+		return $input->get_html_for_input();
408
+	}
409
+
410
+
411
+	protected function _ajax_hooks()
412
+	{
413
+		add_action('wp_ajax_activate_messenger', [$this, 'activate_messenger_toggle']);
414
+		add_action('wp_ajax_activate_mt', [$this, 'activate_mt_toggle']);
415
+		add_action('wp_ajax_ee_msgs_save_settings', [$this, 'save_settings']);
416
+		add_action('wp_ajax_ee_msgs_update_mt_form', [$this, 'update_mt_form']);
417
+		add_action('wp_ajax_switch_template_pack', [$this, 'switch_template_pack']);
418
+		add_action('wp_ajax_toggle_context_template', [$this, 'toggle_context_template']);
419
+	}
420
+
421
+
422
+	protected function _define_page_props()
423
+	{
424
+		$this->_admin_page_title = $this->page_label;
425
+		$this->_labels           = [
426
+			'buttons'    => [
427
+				'add'    => esc_html__('Add New Message Template', 'event_espresso'),
428
+				'edit'   => esc_html__('Edit Message Template', 'event_espresso'),
429
+				'delete' => esc_html__('Delete Message Template', 'event_espresso'),
430
+			],
431
+			'publishbox' => esc_html__('Update Actions', 'event_espresso'),
432
+		];
433
+	}
434
+
435
+
436
+	/**
437
+	 *        an array for storing key => value pairs of request actions and their corresponding methods
438
+	 *
439
+	 * @access protected
440
+	 * @return void
441
+	 */
442
+	protected function _set_page_routes()
443
+	{
444
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
445
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
446
+		$MSG_ID = $this->request->getRequestParam('MSG_ID', 0, 'int');
447
+
448
+		$this->_page_routes = [
449
+			'default'                          => [
450
+				'func'       => '_message_queue_list_table',
451
+				'capability' => 'ee_read_global_messages',
452
+			],
453
+			'global_mtps'                      => [
454
+				'func'       => '_ee_default_messages_overview_list_table',
455
+				'capability' => 'ee_read_global_messages',
456
+			],
457
+			'custom_mtps'                      => [
458
+				'func'       => '_custom_mtps_preview',
459
+				'capability' => 'ee_read_messages',
460
+			],
461
+			'add_new_message_template'         => [
462
+				'func'       => 'add_message_template',
463
+				'capability' => 'ee_edit_messages',
464
+				'noheader'   => true,
465
+			],
466
+			'edit_message_template'            => [
467
+				'func'       => '_edit_message_template',
468
+				'capability' => 'ee_edit_message',
469
+				'obj_id'     => $GRP_ID,
470
+			],
471
+			'preview_message'                  => [
472
+				'func'               => '_preview_message',
473
+				'capability'         => 'ee_read_message',
474
+				'obj_id'             => $GRP_ID,
475
+				'noheader'           => true,
476
+				'headers_sent_route' => 'display_preview_message',
477
+			],
478
+			'display_preview_message'          => [
479
+				'func'       => '_display_preview_message',
480
+				'capability' => 'ee_read_message',
481
+				'obj_id'     => $GRP_ID,
482
+			],
483
+			'insert_message_template'          => [
484
+				'func'       => '_insert_or_update_message_template',
485
+				'capability' => 'ee_edit_messages',
486
+				'args'       => ['new' => true],
487
+				'noheader'   => true,
488
+			],
489
+			'update_message_template'          => [
490
+				'func'       => '_insert_or_update_message_template',
491
+				'capability' => 'ee_edit_message',
492
+				'obj_id'     => $GRP_ID,
493
+				'args'       => ['new' => false],
494
+				'noheader'   => true,
495
+			],
496
+			'trash_message_template'           => [
497
+				'func'       => '_trash_or_restore_message_template',
498
+				'capability' => 'ee_delete_message',
499
+				'obj_id'     => $GRP_ID,
500
+				'args'       => ['trash' => true, 'all' => true],
501
+				'noheader'   => true,
502
+			],
503
+			'trash_message_template_context'   => [
504
+				'func'       => '_trash_or_restore_message_template',
505
+				'capability' => 'ee_delete_message',
506
+				'obj_id'     => $GRP_ID,
507
+				'args'       => ['trash' => true],
508
+				'noheader'   => true,
509
+			],
510
+			'restore_message_template'         => [
511
+				'func'       => '_trash_or_restore_message_template',
512
+				'capability' => 'ee_delete_message',
513
+				'obj_id'     => $GRP_ID,
514
+				'args'       => ['trash' => false, 'all' => true],
515
+				'noheader'   => true,
516
+			],
517
+			'restore_message_template_context' => [
518
+				'func'       => '_trash_or_restore_message_template',
519
+				'capability' => 'ee_delete_message',
520
+				'obj_id'     => $GRP_ID,
521
+				'args'       => ['trash' => false],
522
+				'noheader'   => true,
523
+			],
524
+			'delete_message_template'          => [
525
+				'func'       => '_delete_message_template',
526
+				'capability' => 'ee_delete_message',
527
+				'obj_id'     => $GRP_ID,
528
+				'noheader'   => true,
529
+			],
530
+			'reset_to_default'                 => [
531
+				'func'       => '_reset_to_default_template',
532
+				'capability' => 'ee_edit_message',
533
+				'obj_id'     => $GRP_ID,
534
+				'noheader'   => true,
535
+			],
536
+			'settings'                         => [
537
+				'func'       => '_settings',
538
+				'capability' => 'manage_options',
539
+			],
540
+			'update_global_settings'           => [
541
+				'func'       => '_update_global_settings',
542
+				'capability' => 'manage_options',
543
+				'noheader'   => true,
544
+			],
545
+			'generate_now'                     => [
546
+				'func'       => '_generate_now',
547
+				'capability' => 'ee_send_message',
548
+				'noheader'   => true,
549
+			],
550
+			'generate_and_send_now'            => [
551
+				'func'       => '_generate_and_send_now',
552
+				'capability' => 'ee_send_message',
553
+				'noheader'   => true,
554
+			],
555
+			'queue_for_resending'              => [
556
+				'func'       => '_queue_for_resending',
557
+				'capability' => 'ee_send_message',
558
+				'noheader'   => true,
559
+			],
560
+			'send_now'                         => [
561
+				'func'       => '_send_now',
562
+				'capability' => 'ee_send_message',
563
+				'noheader'   => true,
564
+			],
565
+			'delete_ee_message'                => [
566
+				'func'       => '_delete_ee_messages',
567
+				'capability' => 'ee_delete_messages',
568
+				'noheader'   => true,
569
+			],
570
+			'delete_ee_messages'               => [
571
+				'func'       => '_delete_ee_messages',
572
+				'capability' => 'ee_delete_messages',
573
+				'noheader'   => true,
574
+				'obj_id'     => $MSG_ID,
575
+			],
576
+		];
577
+	}
578
+
579
+
580
+	protected function _set_page_config()
581
+	{
582
+		$this->_page_config = [
583
+			'default'                  => [
584
+				'nav'           => [
585
+					'label' => esc_html__('Message Activity', 'event_espresso'),
586
+					'order' => 10,
587
+				],
588
+				'list_table'    => 'EE_Message_List_Table',
589
+				// 'qtips' => array( 'EE_Message_List_Table_Tips' ),
590
+				'require_nonce' => false,
591
+			],
592
+			'global_mtps'              => [
593
+				'nav'           => [
594
+					'label' => esc_html__('Default Message Templates', 'event_espresso'),
595
+					'order' => 20,
596
+				],
597
+				'list_table'    => 'Messages_Template_List_Table',
598
+				'help_tabs'     => [
599
+					'messages_overview_help_tab'                                => [
600
+						'title'    => esc_html__('Messages Overview', 'event_espresso'),
601
+						'filename' => 'messages_overview',
602
+					],
603
+					'messages_overview_messages_table_column_headings_help_tab' => [
604
+						'title'    => esc_html__('Messages Table Column Headings', 'event_espresso'),
605
+						'filename' => 'messages_overview_table_column_headings',
606
+					],
607
+					'messages_overview_messages_filters_help_tab'               => [
608
+						'title'    => esc_html__('Message Filters', 'event_espresso'),
609
+						'filename' => 'messages_overview_filters',
610
+					],
611
+					'messages_overview_messages_views_help_tab'                 => [
612
+						'title'    => esc_html__('Message Views', 'event_espresso'),
613
+						'filename' => 'messages_overview_views',
614
+					],
615
+					'message_overview_message_types_help_tab'                   => [
616
+						'title'    => esc_html__('Message Types', 'event_espresso'),
617
+						'filename' => 'messages_overview_types',
618
+					],
619
+					'messages_overview_messengers_help_tab'                     => [
620
+						'title'    => esc_html__('Messengers', 'event_espresso'),
621
+						'filename' => 'messages_overview_messengers',
622
+					],
623
+				],
624
+				'require_nonce' => false,
625
+			],
626
+			'custom_mtps'              => [
627
+				'nav'           => [
628
+					'label' => esc_html__('Custom Message Templates', 'event_espresso'),
629
+					'order' => 30,
630
+				],
631
+				'help_tabs'     => [],
632
+				'require_nonce' => false,
633
+			],
634
+			'add_new_message_template' => [
635
+				'nav'           => [
636
+					'label'      => esc_html__('Add New Message Templates', 'event_espresso'),
637
+					'order'      => 5,
638
+					'persistent' => false,
639
+				],
640
+				'require_nonce' => false,
641
+			],
642
+			'edit_message_template'    => [
643
+				'labels'        => [
644
+					'buttons'    => [
645
+						'reset' => esc_html__('Reset Templates', 'event_espresso'),
646
+					],
647
+					'publishbox' => esc_html__('Update Actions', 'event_espresso'),
648
+				],
649
+				'nav'           => [
650
+					'label'      => esc_html__('Edit Message Templates', 'event_espresso'),
651
+					'order'      => 5,
652
+					'persistent' => false,
653
+					'url'        => '',
654
+				],
655
+				'metaboxes'     => ['_publish_post_box', '_register_edit_meta_boxes'],
656
+				'has_metaboxes' => true,
657
+				'help_tabs'     => [
658
+					'edit_message_template'            => [
659
+						'title'    => esc_html__('Message Template Editor', 'event_espresso'),
660
+						'callback' => 'edit_message_template_help_tab',
661
+					],
662
+					'message_templates_help_tab'       => [
663
+						'title'    => esc_html__('Message Templates', 'event_espresso'),
664
+						'filename' => 'messages_templates',
665
+					],
666
+					'message_template_shortcodes'      => [
667
+						'title'    => esc_html__('Message Shortcodes', 'event_espresso'),
668
+						'callback' => 'message_template_shortcodes_help_tab',
669
+					],
670
+					'message_preview_help_tab'         => [
671
+						'title'    => esc_html__('Message Preview', 'event_espresso'),
672
+						'filename' => 'messages_preview',
673
+					],
674
+					'messages_overview_other_help_tab' => [
675
+						'title'    => esc_html__('Messages Other', 'event_espresso'),
676
+						'filename' => 'messages_overview_other',
677
+					],
678
+				],
679
+				'require_nonce' => false,
680
+			],
681
+			'display_preview_message'  => [
682
+				'nav'           => [
683
+					'label'      => esc_html__('Message Preview', 'event_espresso'),
684
+					'order'      => 5,
685
+					'url'        => '',
686
+					'persistent' => false,
687
+				],
688
+				'help_tabs'     => [
689
+					'preview_message' => [
690
+						'title'    => esc_html__('About Previews', 'event_espresso'),
691
+						'callback' => 'preview_message_help_tab',
692
+					],
693
+				],
694
+				'require_nonce' => false,
695
+			],
696
+			'settings'                 => [
697
+				'nav'           => [
698
+					'label' => esc_html__('Settings', 'event_espresso'),
699
+					'order' => 40,
700
+				],
701
+				'metaboxes'     => ['_messages_settings_metaboxes'],
702
+				'help_tabs'     => [
703
+					'messages_settings_help_tab'               => [
704
+						'title'    => esc_html__('Messages Settings', 'event_espresso'),
705
+						'filename' => 'messages_settings',
706
+					],
707
+					'messages_settings_message_types_help_tab' => [
708
+						'title'    => esc_html__('Activating / Deactivating Message Types', 'event_espresso'),
709
+						'filename' => 'messages_settings_message_types',
710
+					],
711
+					'messages_settings_messengers_help_tab'    => [
712
+						'title'    => esc_html__('Activating / Deactivating Messengers', 'event_espresso'),
713
+						'filename' => 'messages_settings_messengers',
714
+					],
715
+				],
716
+				'require_nonce' => false,
717
+			],
718
+		];
719
+	}
720
+
721
+
722
+	protected function _add_screen_options()
723
+	{
724
+		// todo
725
+	}
726
+
727
+
728
+	protected function _add_screen_options_global_mtps()
729
+	{
730
+		/**
731
+		 * Note: the reason for the value swap here on $this->_admin_page_title is because $this->_per_page_screen_options
732
+		 * uses the $_admin_page_title property and we want different outputs in the different spots.
733
+		 */
734
+		$page_title              = $this->_admin_page_title;
735
+		$this->_admin_page_title = esc_html__('Global Message Templates', 'event_espresso');
736
+		$this->_per_page_screen_option();
737
+		$this->_admin_page_title = $page_title;
738
+	}
739
+
740
+
741
+	protected function _add_screen_options_default()
742
+	{
743
+		$this->_admin_page_title = esc_html__('Message Activity', 'event_espresso');
744
+		$this->_per_page_screen_option();
745
+	}
746
+
747
+
748
+	// none of the below group are currently used for Messages
749
+	protected function _add_feature_pointers()
750
+	{
751
+	}
752
+
753
+
754
+	public function admin_init()
755
+	{
756
+	}
757
+
758
+
759
+	public function admin_notices()
760
+	{
761
+	}
762
+
763
+
764
+	public function admin_footer_scripts()
765
+	{
766
+	}
767
+
768
+
769
+	public function messages_help_tab()
770
+	{
771
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_help_tab.template.php');
772
+	}
773
+
774
+
775
+	public function messengers_help_tab()
776
+	{
777
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messenger_help_tab.template.php');
778
+	}
779
+
780
+
781
+	public function message_types_help_tab()
782
+	{
783
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_type_help_tab.template.php');
784
+	}
785
+
786
+
787
+	public function messages_overview_help_tab()
788
+	{
789
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_overview_help_tab.template.php');
790
+	}
791
+
792
+
793
+	public function message_templates_help_tab()
794
+	{
795
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_message_templates_help_tab.template.php');
796
+	}
797
+
798
+
799
+	public function edit_message_template_help_tab()
800
+	{
801
+		$args['img1'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/editor.png' . '" alt="'
802
+						. esc_attr__('Editor Title', 'event_espresso')
803
+						. '" />';
804
+		$args['img2'] = '<img src="' . EE_MSG_ASSETS_URL . 'images/switch-context.png' . '" alt="'
805
+						. esc_attr__('Context Switcher and Preview', 'event_espresso')
806
+						. '" />';
807
+		$args['img3'] = '<img class="left" src="' . EE_MSG_ASSETS_URL . 'images/form-fields.png' . '" alt="'
808
+						. esc_attr__('Message Template Form Fields', 'event_espresso')
809
+						. '" />';
810
+		$args['img4'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/shortcodes-metabox.png' . '" alt="'
811
+						. esc_attr__('Shortcodes Metabox', 'event_espresso')
812
+						. '" />';
813
+		$args['img5'] = '<img class="right" src="' . EE_MSG_ASSETS_URL . 'images/publish-meta-box.png' . '" alt="'
814
+						. esc_attr__('Publish Metabox', 'event_espresso')
815
+						. '" />';
816
+		EEH_Template::display_template(
817
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_templates_editor_help_tab.template.php',
818
+			$args
819
+		);
820
+	}
821
+
822
+
823
+	/**
824
+	 * @throws ReflectionException
825
+	 * @throws EE_Error
826
+	 */
827
+	public function message_template_shortcodes_help_tab()
828
+	{
829
+		$this->_set_shortcodes();
830
+		$args['shortcodes'] = $this->_shortcodes;
831
+		EEH_Template::display_template(
832
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_shortcodes_help_tab.template.php',
833
+			$args
834
+		);
835
+	}
836
+
837
+
838
+	public function preview_message_help_tab()
839
+	{
840
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_preview_help_tab.template.php');
841
+	}
842
+
843
+
844
+	public function settings_help_tab()
845
+	{
846
+		$args['img1'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png'
847
+						. '" alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />';
848
+		$args['img2'] = '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
849
+						. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />';
850
+		$args['img3'] = '<div class="switch">'
851
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
852
+						. ' type="checkbox" checked="checked">'
853
+						. '<label for="ee-on-off-toggle-on"></label>'
854
+						. '</div>';
855
+		$args['img4'] = '<div class="switch">'
856
+						. '<input class="ee-on-off-toggle ee-toggle-round-flat"'
857
+						. ' type="checkbox">'
858
+						. '<label for="ee-on-off-toggle-on"></label>'
859
+						. '</div>';
860
+		EEH_Template::display_template(EE_MSG_TEMPLATE_PATH . 'ee_msg_messages_settings_help_tab.template.php', $args);
861
+	}
862
+
863
+
864
+	public function load_scripts_styles()
865
+	{
866
+		wp_register_style('espresso_ee_msg', EE_MSG_ASSETS_URL . 'ee_message_admin.css', EVENT_ESPRESSO_VERSION);
867
+		wp_enqueue_style('espresso_ee_msg');
868
+
869
+		wp_register_script(
870
+			'ee-messages-settings',
871
+			EE_MSG_ASSETS_URL . 'ee-messages-settings.js',
872
+			['jquery-ui-droppable', 'ee-serialize-full-array'],
873
+			EVENT_ESPRESSO_VERSION,
874
+			true
875
+		);
876
+		wp_register_script(
877
+			'ee-msg-list-table-js',
878
+			EE_MSG_ASSETS_URL . 'ee_message_admin_list_table.js',
879
+			['ee-dialog'],
880
+			EVENT_ESPRESSO_VERSION
881
+		);
882
+	}
883
+
884
+
885
+	public function load_scripts_styles_default()
886
+	{
887
+		wp_enqueue_script('ee-msg-list-table-js');
888
+	}
889
+
890
+
891
+	public function wp_editor_css($mce_css)
892
+	{
893
+		// if we're on the edit_message_template route
894
+		if ($this->_req_action === 'edit_message_template' && $this->_active_messenger instanceof EE_messenger) {
895
+			$message_type_name = $this->_active_message_type_name;
896
+
897
+			// we're going to REPLACE the existing mce css
898
+			// we need to get the css file location from the active messenger
899
+			$mce_css = $this->_active_messenger->get_variation(
900
+				$this->_template_pack,
901
+				$message_type_name,
902
+				true,
903
+				'wpeditor',
904
+				$this->_variation
905
+			);
906
+		}
907
+
908
+		return $mce_css;
909
+	}
910
+
911
+
912
+	/**
913
+	 * @throws EE_Error
914
+	 * @throws ReflectionException
915
+	 */
916
+	public function load_scripts_styles_edit_message_template()
917
+	{
918
+
919
+		$this->_set_shortcodes();
920
+
921
+		EE_Registry::$i18n_js_strings['confirm_default_reset']        = sprintf(
922
+			esc_html__(
923
+				'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.',
924
+				'event_espresso'
925
+			),
926
+			$this->_message_template_group->messenger_obj()->label['singular'],
927
+			$this->_message_template_group->message_type_obj()->label['singular']
928
+		);
929
+		EE_Registry::$i18n_js_strings['confirm_switch_template_pack'] = esc_html__(
930
+			'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?',
931
+			'event_espresso'
932
+		);
933
+		EE_Registry::$i18n_js_strings['server_error']                 = esc_html__(
934
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
935
+			'event_espresso'
936
+		);
937
+
938
+		wp_register_script(
939
+			'ee_msgs_edit_js',
940
+			EE_MSG_ASSETS_URL . 'ee_message_editor.js',
941
+			['jquery'],
942
+			EVENT_ESPRESSO_VERSION
943
+		);
944
+
945
+		wp_enqueue_script('ee_admin_js');
946
+		wp_enqueue_script('ee_msgs_edit_js');
947
+
948
+		// add in special css for tiny_mce
949
+		add_filter('mce_css', [$this, 'wp_editor_css']);
950
+	}
951
+
952
+
953
+	/**
954
+	 * @throws EE_Error
955
+	 * @throws ReflectionException
956
+	 */
957
+	public function load_scripts_styles_display_preview_message()
958
+	{
959
+		$this->_set_message_template_group();
960
+		if ($this->_active_messenger_name) {
961
+			$this->_active_messenger = $this->_message_resource_manager->get_active_messenger(
962
+				$this->_active_messenger_name
963
+			);
964
+		}
965
+
966
+		wp_enqueue_style(
967
+			'espresso_preview_css',
968
+			$this->_active_messenger->get_variation(
969
+				$this->_template_pack,
970
+				$this->_active_message_type_name,
971
+				true,
972
+				'preview',
973
+				$this->_variation
974
+			)
975
+		);
976
+	}
977
+
978
+
979
+	public function load_scripts_styles_settings()
980
+	{
981
+		wp_register_style(
982
+			'ee-message-settings',
983
+			EE_MSG_ASSETS_URL . 'ee_message_settings.css',
984
+			[],
985
+			EVENT_ESPRESSO_VERSION
986
+		);
987
+		wp_enqueue_style('ee-text-links');
988
+		wp_enqueue_style('ee-message-settings');
989
+		wp_enqueue_script('ee-messages-settings');
990
+	}
991
+
992
+
993
+	/**
994
+	 * set views array for List Table
995
+	 */
996
+	public function _set_list_table_views_global_mtps()
997
+	{
998
+		$this->_views = [
999
+			'in_use' => [
1000
+				'slug'  => 'in_use',
1001
+				'label' => esc_html__('In Use', 'event_espresso'),
1002
+				'count' => 0,
1003
+			],
1004
+		];
1005
+	}
1006
+
1007
+
1008
+	/**
1009
+	 * Set views array for the Custom Template List Table
1010
+	 */
1011
+	public function _set_list_table_views_custom_mtps()
1012
+	{
1013
+		$this->_set_list_table_views_global_mtps();
1014
+		$this->_views['in_use']['bulk_action'] = [
1015
+			'trash_message_template' => esc_html__('Move to Trash', 'event_espresso'),
1016
+		];
1017
+	}
1018
+
1019
+
1020
+	/**
1021
+	 * set views array for message queue list table
1022
+	 *
1023
+	 * @throws InvalidDataTypeException
1024
+	 * @throws InvalidInterfaceException
1025
+	 * @throws InvalidArgumentException
1026
+	 * @throws EE_Error
1027
+	 * @throws ReflectionException
1028
+	 */
1029
+	public function _set_list_table_views_default()
1030
+	{
1031
+		EE_Registry::instance()->load_helper('Template');
1032
+
1033
+		$common_bulk_actions = EE_Registry::instance()->CAP->current_user_can(
1034
+			'ee_send_message',
1035
+			'message_list_table_bulk_actions'
1036
+		)
1037
+			? [
1038
+				'generate_now'          => esc_html__('Generate Now', 'event_espresso'),
1039
+				'generate_and_send_now' => esc_html__('Generate and Send Now', 'event_espresso'),
1040
+				'queue_for_resending'   => esc_html__('Queue for Resending', 'event_espresso'),
1041
+				'send_now'              => esc_html__('Send Now', 'event_espresso'),
1042
+			]
1043
+			: [];
1044
+
1045
+		$delete_bulk_action = EE_Registry::instance()->CAP->current_user_can(
1046
+			'ee_delete_messages',
1047
+			'message_list_table_bulk_actions'
1048
+		)
1049
+			? ['delete_ee_messages' => esc_html__('Delete Messages', 'event_espresso')]
1050
+			: [];
1051
+
1052
+
1053
+		$this->_views = [
1054
+			'all' => [
1055
+				'slug'        => 'all',
1056
+				'label'       => esc_html__('All', 'event_espresso'),
1057
+				'count'       => 0,
1058
+				'bulk_action' => array_merge($common_bulk_actions, $delete_bulk_action),
1059
+			],
1060
+		];
1061
+
1062
+
1063
+		foreach ($this->getMsgModel()->all_statuses() as $status) {
1064
+			if ($status === EEM_Message::status_debug_only && ! EEM_Message::debug()) {
1065
+				continue;
1066
+			}
1067
+			$status_bulk_actions = $common_bulk_actions;
1068
+			// unset bulk actions not applying to status
1069
+			if (! empty($status_bulk_actions)) {
1070
+				switch ($status) {
1071
+					case EEM_Message::status_idle:
1072
+					case EEM_Message::status_resend:
1073
+						$status_bulk_actions['send_now'] = $common_bulk_actions['send_now'];
1074
+						break;
1075
+
1076
+					case EEM_Message::status_failed:
1077
+					case EEM_Message::status_debug_only:
1078
+					case EEM_Message::status_messenger_executing:
1079
+						$status_bulk_actions = [];
1080
+						break;
1081
+
1082
+					case EEM_Message::status_incomplete:
1083
+						unset($status_bulk_actions['queue_for_resending'], $status_bulk_actions['send_now']);
1084
+						break;
1085
+
1086
+					case EEM_Message::status_retry:
1087
+					case EEM_Message::status_sent:
1088
+						unset($status_bulk_actions['generate_now'], $status_bulk_actions['generate_and_send_now']);
1089
+						break;
1090
+				}
1091
+			}
1092
+
1093
+			// skip adding messenger executing status to views because it will be included with the Failed view.
1094
+			if ($status === EEM_Message::status_messenger_executing) {
1095
+				continue;
1096
+			}
1097
+
1098
+			$this->_views[ strtolower($status) ] = [
1099
+				'slug'        => strtolower($status),
1100
+				'label'       => EEH_Template::pretty_status($status, false, 'sentence'),
1101
+				'count'       => 0,
1102
+				'bulk_action' => array_merge($status_bulk_actions, $delete_bulk_action),
1103
+			];
1104
+		}
1105
+	}
1106
+
1107
+
1108
+	/**
1109
+	 * @throws EE_Error
1110
+	 */
1111
+	protected function _ee_default_messages_overview_list_table()
1112
+	{
1113
+		$this->_admin_page_title = esc_html__('Default Message Templates', 'event_espresso');
1114
+		$this->display_admin_list_table_page_with_no_sidebar();
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * @throws EE_Error
1120
+	 * @throws ReflectionException
1121
+	 */
1122
+	protected function _message_queue_list_table()
1123
+	{
1124
+		$this->_search_btn_label                   = esc_html__('Message Activity', 'event_espresso');
1125
+		$this->_template_args['per_column']        = 6;
1126
+		$this->_template_args['after_list_table']  = $this->_display_legend($this->_message_legend_items());
1127
+		$this->_template_args['before_list_table'] = '<h3>'
1128
+													 . $this->getMsgModel()->get_pretty_label_for_results()
1129
+													 . '</h3>';
1130
+		$this->display_admin_list_table_page_with_no_sidebar();
1131
+	}
1132
+
1133
+
1134
+	/**
1135
+	 * @throws EE_Error
1136
+	 */
1137
+	protected function _message_legend_items()
1138
+	{
1139
+
1140
+		$action_css_classes = EEH_MSG_Template::get_message_action_icons();
1141
+		$action_items       = [];
1142
+
1143
+		foreach ($action_css_classes as $action_item => $action_details) {
1144
+			if ($action_item === 'see_notifications_for') {
1145
+				continue;
1146
+			}
1147
+			$action_items[ $action_item ] = [
1148
+				'class' => $action_details['css_class'],
1149
+				'desc'  => $action_details['label'],
1150
+			];
1151
+		}
1152
+
1153
+		/** @var array $status_items status legend setup */
1154
+		$status_items = [
1155
+			'sent_status'                => [
1156
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_sent,
1157
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_sent, false, 'sentence'),
1158
+			],
1159
+			'idle_status'                => [
1160
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_idle,
1161
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_idle, false, 'sentence'),
1162
+			],
1163
+			'failed_status'              => [
1164
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_failed,
1165
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_failed, false, 'sentence'),
1166
+			],
1167
+			'messenger_executing_status' => [
1168
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_messenger_executing,
1169
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_messenger_executing, false, 'sentence'),
1170
+			],
1171
+			'resend_status'              => [
1172
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_resend,
1173
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_resend, false, 'sentence'),
1174
+			],
1175
+			'incomplete_status'          => [
1176
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_incomplete,
1177
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_incomplete, false, 'sentence'),
1178
+			],
1179
+			'retry_status'               => [
1180
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_retry,
1181
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_retry, false, 'sentence'),
1182
+			],
1183
+		];
1184
+		if (EEM_Message::debug()) {
1185
+			$status_items['debug_only_status'] = [
1186
+				'class' => 'ee-status-legend ee-status-legend-' . EEM_Message::status_debug_only,
1187
+				'desc'  => EEH_Template::pretty_status(EEM_Message::status_debug_only, false, 'sentence'),
1188
+			];
1189
+		}
1190
+
1191
+		return array_merge($action_items, $status_items);
1192
+	}
1193
+
1194
+
1195
+	/**
1196
+	 * @throws EE_Error
1197
+	 */
1198
+	protected function _custom_mtps_preview()
1199
+	{
1200
+		$this->_admin_page_title              = esc_html__('Custom Message Templates (Preview)', 'event_espresso');
1201
+		$this->_template_args['preview_img']  = '<img src="' . EE_MSG_ASSETS_URL . 'images/custom_mtps_preview.png"'
1202
+												. ' alt="' . esc_attr__(
1203
+													'Preview Custom Message Templates screenshot',
1204
+													'event_espresso'
1205
+												) . '" />';
1206
+		$this->_template_args['preview_text'] = '<strong>'
1207
+												. esc_html__(
1208
+													'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.',
1209
+													'event_espresso'
1210
+												)
1211
+												. '</strong>';
1212
+
1213
+		$this->display_admin_caf_preview_page('custom_message_types', false);
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * get_message_templates
1219
+	 * This gets all the message templates for listing on the overview list.
1220
+	 *
1221
+	 * @access public
1222
+	 * @param int    $per_page the amount of templates groups to show per page
1223
+	 * @param string $type     the current _view we're getting templates for
1224
+	 * @param bool   $count    return count?
1225
+	 * @param bool   $all      disregard any paging info (get all data);
1226
+	 * @param bool   $global   whether to return just global (true) or custom templates (false)
1227
+	 * @return array
1228
+	 * @throws EE_Error
1229
+	 * @throws InvalidArgumentException
1230
+	 * @throws InvalidDataTypeException
1231
+	 * @throws InvalidInterfaceException
1232
+	 */
1233
+	public function get_message_templates(
1234
+		$per_page = 10,
1235
+		$type = 'in_use',
1236
+		$count = false,
1237
+		$all = false,
1238
+		$global = true
1239
+	) {
1240
+		$orderby = $this->request->getRequestParam('orderby', 'GRP_ID');
1241
+		$this->request->setRequestParam('orderby', $orderby);
1242
+
1243
+		$order        = $this->request->getRequestParam('order', 'ASC');
1244
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
1245
+		$per_page     = $this->request->getRequestParam('perpage', $per_page, 'int');
1246
+
1247
+		$offset = ($current_page - 1) * $per_page;
1248
+		$limit  = $all ? null : [$offset, $per_page];
1249
+
1250
+		// options will match what is in the _views array property
1251
+		return $type === 'in_use'
1252
+			? $this->getMtgModel()->get_all_active_message_templates(
1253
+				$orderby,
1254
+				$order,
1255
+				$limit,
1256
+				$count,
1257
+				$global,
1258
+				true
1259
+			)
1260
+			: $this->getMtgModel()->get_all_trashed_grouped_message_templates(
1261
+				$orderby,
1262
+				$order,
1263
+				$limit,
1264
+				$count,
1265
+				$global
1266
+			);
1267
+	}
1268
+
1269
+
1270
+	/**
1271
+	 * filters etc might need a list of installed message_types
1272
+	 *
1273
+	 * @return array an array of message type objects
1274
+	 */
1275
+	public function get_installed_message_types()
1276
+	{
1277
+		$installed_message_types = $this->_message_resource_manager->installed_message_types();
1278
+		$installed               = [];
1279
+
1280
+		foreach ($installed_message_types as $message_type) {
1281
+			$installed[ $message_type->name ] = $message_type;
1282
+		}
1283
+
1284
+		return $installed;
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * This is used when creating a custom template. All Custom Templates start based off another template.
1290
+	 *
1291
+	 * @param string $message_type
1292
+	 * @param string $messenger
1293
+	 * @param string $GRP_ID
1294
+	 *
1295
+	 * @throws EE_error
1296
+	 * @throws ReflectionException
1297
+	 */
1298
+	public function add_message_template($message_type = '', $messenger = '', $GRP_ID = '')
1299
+	{
1300
+		// set values override any request data
1301
+		$message_type = ! empty($message_type) ? $message_type : $this->_active_message_type_name;
1302
+		$messenger    = ! empty($messenger) ? $messenger : $this->_active_messenger_name;
1303
+		$GRP_ID       = ! empty($GRP_ID) ? $GRP_ID : $this->request->getRequestParam('GRP_ID', 0, 'int');
1304
+
1305
+		// we need messenger and message type.  They should be coming from the event editor. If not here then return error
1306
+		if (empty($message_type) || empty($messenger)) {
1307
+			throw new EE_Error(
1308
+				esc_html__(
1309
+					'Sorry, but we can\'t create new templates because we\'re missing the messenger or message type',
1310
+					'event_espresso'
1311
+				)
1312
+			);
1313
+		}
1314
+
1315
+		// we need the GRP_ID for the template being used as the base for the new template
1316
+		if (empty($GRP_ID)) {
1317
+			throw new EE_Error(
1318
+				esc_html__(
1319
+					'In order to create a custom message template the GRP_ID of the template being used as a base is needed',
1320
+					'event_espresso'
1321
+				)
1322
+			);
1323
+		}
1324
+
1325
+		// let's just make sure the template gets generated!
1326
+
1327
+		// we need to reassign some variables for what the insert is expecting
1328
+		$this->request->setRequestParam('MTP_messenger', $messenger);
1329
+		$this->request->setRequestParam('MTP_message_type', $message_type);
1330
+		$this->request->setRequestParam('GRP_ID', $GRP_ID);
1331
+
1332
+		$this->_insert_or_update_message_template(true);
1333
+	}
1334
+
1335
+
1336
+	/**
1337
+	 * @param string $message_type     message type slug
1338
+	 * @param string $messenger        messenger slug
1339
+	 * @param int    $GRP_ID           GRP_ID for the related message template group this new template will be based
1340
+	 *                                 off of.
1341
+	 * @throws EE_error
1342
+	 * @throws ReflectionException
1343
+	 * @deprecated 4.10.29.p
1344
+	 */
1345
+	protected function _add_message_template($message_type, $messenger, $GRP_ID)
1346
+	{
1347
+		$this->add_message_template($message_type, $messenger, $GRP_ID);
1348
+	}
1349
+
1350
+
1351
+	/**
1352
+	 * _edit_message_template
1353
+	 *
1354
+	 * @access protected
1355
+	 * @return void
1356
+	 * @throws InvalidIdentifierException
1357
+	 * @throws DomainException
1358
+	 * @throws EE_Error
1359
+	 * @throws InvalidArgumentException
1360
+	 * @throws ReflectionException
1361
+	 * @throws InvalidDataTypeException
1362
+	 * @throws InvalidInterfaceException
1363
+	 */
1364
+	protected function _edit_message_template()
1365
+	{
1366
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1367
+		$template_fields = '';
1368
+		$sidebar_fields  = '';
1369
+		// we filter the tinyMCE settings to remove the validation since message templates by their nature will not have
1370
+		// valid html in the templates.
1371
+		add_filter('tiny_mce_before_init', [$this, 'filter_tinymce_init'], 10, 2);
1372
+
1373
+		$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
1374
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
1375
+
1376
+		$this->_set_shortcodes(); // this also sets the _message_template property.
1377
+		$message_template_group = $this->_message_template_group;
1378
+		$c_label                = $message_template_group->context_label();
1379
+		$c_config               = $message_template_group->contexts_config();
1380
+
1381
+		reset($c_config);
1382
+		$context = $this->request->getRequestParam('context', key($c_config));
1383
+		$context = strtolower($context);
1384
+
1385
+		$action = empty($GRP_ID) ? 'insert_message_template' : 'update_message_template';
1386
+
1387
+		$edit_message_template_form_url = add_query_arg(
1388
+			['action' => $action, 'noheader' => true],
1389
+			EE_MSG_ADMIN_URL
1390
+		);
1391
+
1392
+		// set active messenger for this view
1393
+		$this->_active_messenger         = $this->_message_resource_manager->get_active_messenger(
1394
+			$message_template_group->messenger()
1395
+		);
1396
+		$this->_active_message_type_name = $message_template_group->message_type();
1397
+
1398
+
1399
+		// Do we have any validation errors?
1400
+		$validators = $this->_get_transient();
1401
+		$v_fields   = ! empty($validators) ? array_keys($validators) : [];
1402
+
1403
+
1404
+		// we need to assemble the title from Various details
1405
+		$context_label = sprintf(
1406
+			esc_html__('(%s %s)', 'event_espresso'),
1407
+			$c_config[ $context ]['label'],
1408
+			ucwords($c_label['label'])
1409
+		);
1410
+
1411
+		$title = sprintf(
1412
+			esc_html__(' %s %s Template %s', 'event_espresso'),
1413
+			ucwords($message_template_group->messenger_obj()->label['singular']),
1414
+			ucwords($message_template_group->message_type_obj()->label['singular']),
1415
+			$context_label
1416
+		);
1417
+
1418
+		$this->_template_args['GRP_ID']           = $GRP_ID;
1419
+		$this->_template_args['message_template'] = $message_template_group;
1420
+		$this->_template_args['is_extra_fields']  = false;
1421
+
1422
+
1423
+		// let's get EEH_MSG_Template so we can get template form fields
1424
+		$template_field_structure = EEH_MSG_Template::get_fields(
1425
+			$message_template_group->messenger(),
1426
+			$message_template_group->message_type()
1427
+		);
1428
+
1429
+		if (! $template_field_structure) {
1430
+			$template_field_structure = false;
1431
+			$template_fields          = esc_html__(
1432
+				'There was an error in assembling the fields for this display (you should see an error message)',
1433
+				'event_espresso'
1434
+			);
1435
+		}
1436
+
1437
+
1438
+		$message_templates = $message_template_group->context_templates();
1439
+
1440
+
1441
+		// if we have the extra key.. then we need to remove the content index from the template_field_structure as it
1442
+		// will get handled in the "extra" array.
1443
+		if (is_array($template_field_structure[ $context ]) && isset($template_field_structure[ $context ]['extra'])) {
1444
+			foreach ($template_field_structure[ $context ]['extra'] as $reference_field => $new_fields) {
1445
+				unset($template_field_structure[ $context ][ $reference_field ]);
1446
+			}
1447
+		}
1448
+
1449
+		// let's loop through the template_field_structure and actually assemble the input fields!
1450
+		if (! empty($template_field_structure)) {
1451
+			foreach ($template_field_structure[ $context ] as $template_field => $field_setup_array) {
1452
+				// if this is an 'extra' template field then we need to remove any existing fields that are keyed up in
1453
+				// the extra array and reset them.
1454
+				if ($template_field === 'extra') {
1455
+					$this->_template_args['is_extra_fields'] = true;
1456
+					foreach ($field_setup_array as $reference_field => $new_fields_array) {
1457
+						$message_template = $message_templates[ $context ][ $reference_field ];
1458
+						$content          = $message_template instanceof EE_Message_Template
1459
+							? $message_template->get('MTP_content')
1460
+							: '';
1461
+						foreach ($new_fields_array as $extra_field => $extra_array) {
1462
+							// let's verify if we need this extra field via the shortcodes parameter.
1463
+							$continue = false;
1464
+							if (isset($extra_array['shortcodes_required'])) {
1465
+								foreach ((array) $extra_array['shortcodes_required'] as $shortcode) {
1466
+									if (! array_key_exists($shortcode, $this->_shortcodes)) {
1467
+										$continue = true;
1468
+									}
1469
+								}
1470
+								if ($continue) {
1471
+									continue;
1472
+								}
1473
+							}
1474
+
1475
+							$field_id = $reference_field . '-' . $extra_field . '-content';
1476
+
1477
+							$template_form_fields[ $field_id ]         = $extra_array;
1478
+							$template_form_fields[ $field_id ]['name'] = 'MTP_template_fields['
1479
+																		 . $reference_field
1480
+																		 . '][content]['
1481
+																		 . $extra_field . ']';
1482
+							$css_class                                 = isset($extra_array['css_class'])
1483
+								? $extra_array['css_class']
1484
+								: '';
1485
+
1486
+							$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1487
+																			  && in_array($extra_field, $v_fields, true)
1488
+																			  && (
1489
+																				  is_array($validators[ $extra_field ])
1490
+																				  && isset($validators[ $extra_field ]['msg'])
1491
+																			  )
1492
+								? 'validate-error ' . $css_class
1493
+								: $css_class;
1494
+
1495
+							$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1496
+																		  && isset($content[ $extra_field ])
1497
+								? $content[ $extra_field ]
1498
+								: '';
1499
+
1500
+							// do we have a validation error?  if we do then let's use that value instead
1501
+							$template_form_fields[ $field_id ]['value'] = isset($validators[ $extra_field ])
1502
+								? $validators[ $extra_field ]['value']
1503
+								: $template_form_fields[ $field_id ]['value'];
1504
+
1505
+
1506
+							$template_form_fields[ $field_id ]['db-col'] = 'MTP_content';
1507
+
1508
+							// shortcode selector
1509
+							$field_name_to_use                                   = $extra_field === 'main'
1510
+								? 'content'
1511
+								: $extra_field;
1512
+							$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1513
+								$field_name_to_use,
1514
+								$field_id
1515
+							);
1516
+						}
1517
+						$template_field_MTP_id           = $reference_field . '-MTP_ID';
1518
+						$template_field_template_name_id = $reference_field . '-name';
1519
+
1520
+						$template_form_fields[ $template_field_MTP_id ] = [
1521
+							'name'       => 'MTP_template_fields[' . $reference_field . '][MTP_ID]',
1522
+							'label'      => null,
1523
+							'input'      => 'hidden',
1524
+							'type'       => 'int',
1525
+							'required'   => false,
1526
+							'validation' => false,
1527
+							'value'      => ! empty($message_templates) ? $message_template->ID() : '',
1528
+							'css_class'  => '',
1529
+							'format'     => '%d',
1530
+							'db-col'     => 'MTP_ID',
1531
+						];
1532
+
1533
+						$template_form_fields[ $template_field_template_name_id ] = [
1534
+							'name'       => 'MTP_template_fields[' . $reference_field . '][name]',
1535
+							'label'      => null,
1536
+							'input'      => 'hidden',
1537
+							'type'       => 'string',
1538
+							'required'   => false,
1539
+							'validation' => true,
1540
+							'value'      => $reference_field,
1541
+							'css_class'  => '',
1542
+							'format'     => '%s',
1543
+							'db-col'     => 'MTP_template_field',
1544
+						];
1545
+					}
1546
+					continue; // skip the next stuff, we got the necessary fields here for this dataset.
1547
+				} else {
1548
+					$field_id                                   = $template_field . '-content';
1549
+					$template_form_fields[ $field_id ]          = $field_setup_array;
1550
+					$template_form_fields[ $field_id ]['name']  =
1551
+						'MTP_template_fields[' . $template_field . '][content]';
1552
+					$message_template                           =
1553
+						isset($message_templates[ $context ][ $template_field ])
1554
+							? $message_templates[ $context ][ $template_field ]
1555
+							: null;
1556
+					$template_form_fields[ $field_id ]['value'] = ! empty($message_templates)
1557
+																  && is_array($message_templates[ $context ])
1558
+																  && $message_template instanceof EE_Message_Template
1559
+						? $message_template->get('MTP_content')
1560
+						: '';
1561
+
1562
+					// do we have a validator error for this field?  if we do then we'll use that value instead
1563
+					$template_form_fields[ $field_id ]['value'] = isset($validators[ $template_field ])
1564
+						? $validators[ $template_field ]['value']
1565
+						: $template_form_fields[ $field_id ]['value'];
1566
+
1567
+
1568
+					$template_form_fields[ $field_id ]['db-col']    = 'MTP_content';
1569
+					$css_class                                      = isset($field_setup_array['css_class'])
1570
+						? $field_setup_array['css_class']
1571
+						: '';
1572
+					$template_form_fields[ $field_id ]['css_class'] = ! empty($v_fields)
1573
+																	  && in_array($template_field, $v_fields, true)
1574
+																	  && isset($validators[ $template_field ]['msg'])
1575
+						? 'validate-error ' . $css_class
1576
+						: $css_class;
1577
+
1578
+					// shortcode selector
1579
+					$template_form_fields[ $field_id ]['append_content'] = $this->_get_shortcode_selector(
1580
+						$template_field,
1581
+						$field_id
1582
+					);
1583
+				}
1584
+
1585
+				// k took care of content field(s) now let's take care of others.
1586
+
1587
+				$template_field_MTP_id                 = $template_field . '-MTP_ID';
1588
+				$template_field_field_template_name_id = $template_field . '-name';
1589
+
1590
+				// foreach template field there are actually two form fields created
1591
+				$template_form_fields[ $template_field_MTP_id ] = [
1592
+					'name'       => 'MTP_template_fields[' . $template_field . '][MTP_ID]',
1593
+					'label'      => null,
1594
+					'input'      => 'hidden',
1595
+					'type'       => 'int',
1596
+					'required'   => false,
1597
+					'validation' => true,
1598
+					'value'      => $message_template instanceof EE_Message_Template ? $message_template->ID() : '',
1599
+					'css_class'  => '',
1600
+					'format'     => '%d',
1601
+					'db-col'     => 'MTP_ID',
1602
+				];
1603
+
1604
+				$template_form_fields[ $template_field_field_template_name_id ] = [
1605
+					'name'       => 'MTP_template_fields[' . $template_field . '][name]',
1606
+					'label'      => null,
1607
+					'input'      => 'hidden',
1608
+					'type'       => 'string',
1609
+					'required'   => false,
1610
+					'validation' => true,
1611
+					'value'      => $template_field,
1612
+					'css_class'  => '',
1613
+					'format'     => '%s',
1614
+					'db-col'     => 'MTP_template_field',
1615
+				];
1616
+			}
1617
+
1618
+			// add other fields
1619
+			$template_form_fields['ee-msg-current-context'] = [
1620
+				'name'       => 'MTP_context',
1621
+				'label'      => null,
1622
+				'input'      => 'hidden',
1623
+				'type'       => 'string',
1624
+				'required'   => false,
1625
+				'validation' => true,
1626
+				'value'      => $context,
1627
+				'css_class'  => '',
1628
+				'format'     => '%s',
1629
+				'db-col'     => 'MTP_context',
1630
+			];
1631
+
1632
+			$template_form_fields['ee-msg-grp-id'] = [
1633
+				'name'       => 'GRP_ID',
1634
+				'label'      => null,
1635
+				'input'      => 'hidden',
1636
+				'type'       => 'int',
1637
+				'required'   => false,
1638
+				'validation' => true,
1639
+				'value'      => $GRP_ID,
1640
+				'css_class'  => '',
1641
+				'format'     => '%d',
1642
+				'db-col'     => 'GRP_ID',
1643
+			];
1644
+
1645
+			$template_form_fields['ee-msg-messenger'] = [
1646
+				'name'       => 'MTP_messenger',
1647
+				'label'      => null,
1648
+				'input'      => 'hidden',
1649
+				'type'       => 'string',
1650
+				'required'   => false,
1651
+				'validation' => true,
1652
+				'value'      => $message_template_group->messenger(),
1653
+				'css_class'  => '',
1654
+				'format'     => '%s',
1655
+				'db-col'     => 'MTP_messenger',
1656
+			];
1657
+
1658
+			$template_form_fields['ee-msg-message-type'] = [
1659
+				'name'       => 'MTP_message_type',
1660
+				'label'      => null,
1661
+				'input'      => 'hidden',
1662
+				'type'       => 'string',
1663
+				'required'   => false,
1664
+				'validation' => true,
1665
+				'value'      => $message_template_group->message_type(),
1666
+				'css_class'  => '',
1667
+				'format'     => '%s',
1668
+				'db-col'     => 'MTP_message_type',
1669
+			];
1670
+
1671
+			$sidebar_form_fields['ee-msg-is-global'] = [
1672
+				'name'       => 'MTP_is_global',
1673
+				'label'      => esc_html__('Global Template', 'event_espresso'),
1674
+				'input'      => 'hidden',
1675
+				'type'       => 'int',
1676
+				'required'   => false,
1677
+				'validation' => true,
1678
+				'value'      => $message_template_group->get('MTP_is_global'),
1679
+				'css_class'  => '',
1680
+				'format'     => '%d',
1681
+				'db-col'     => 'MTP_is_global',
1682
+			];
1683
+
1684
+			$sidebar_form_fields['ee-msg-is-override'] = [
1685
+				'name'       => 'MTP_is_override',
1686
+				'label'      => esc_html__('Override all custom', 'event_espresso'),
1687
+				'input'      => $message_template_group->is_global() ? 'checkbox' : 'hidden',
1688
+				'type'       => 'int',
1689
+				'required'   => false,
1690
+				'validation' => true,
1691
+				'value'      => $message_template_group->get('MTP_is_override'),
1692
+				'css_class'  => '',
1693
+				'format'     => '%d',
1694
+				'db-col'     => 'MTP_is_override',
1695
+			];
1696
+
1697
+			$sidebar_form_fields['ee-msg-is-active'] = [
1698
+				'name'       => 'MTP_is_active',
1699
+				'label'      => esc_html__('Active Template', 'event_espresso'),
1700
+				'input'      => 'hidden',
1701
+				'type'       => 'int',
1702
+				'required'   => false,
1703
+				'validation' => true,
1704
+				'value'      => $message_template_group->is_active(),
1705
+				'css_class'  => '',
1706
+				'format'     => '%d',
1707
+				'db-col'     => 'MTP_is_active',
1708
+			];
1709
+
1710
+			$sidebar_form_fields['ee-msg-deleted'] = [
1711
+				'name'       => 'MTP_deleted',
1712
+				'label'      => null,
1713
+				'input'      => 'hidden',
1714
+				'type'       => 'int',
1715
+				'required'   => false,
1716
+				'validation' => true,
1717
+				'value'      => $message_template_group->get('MTP_deleted'),
1718
+				'css_class'  => '',
1719
+				'format'     => '%d',
1720
+				'db-col'     => 'MTP_deleted',
1721
+			];
1722
+			$sidebar_form_fields['ee-msg-author']  = [
1723
+				'name'       => 'MTP_user_id',
1724
+				'label'      => esc_html__('Author', 'event_espresso'),
1725
+				'input'      => 'hidden',
1726
+				'type'       => 'int',
1727
+				'required'   => false,
1728
+				'validation' => false,
1729
+				'value'      => $message_template_group->user(),
1730
+				'format'     => '%d',
1731
+				'db-col'     => 'MTP_user_id',
1732
+			];
1733
+
1734
+			$sidebar_form_fields['ee-msg-route'] = [
1735
+				'name'  => 'action',
1736
+				'input' => 'hidden',
1737
+				'type'  => 'string',
1738
+				'value' => $action,
1739
+			];
1740
+
1741
+			$sidebar_form_fields['ee-msg-id']        = [
1742
+				'name'  => 'id',
1743
+				'input' => 'hidden',
1744
+				'type'  => 'int',
1745
+				'value' => $GRP_ID,
1746
+			];
1747
+			$sidebar_form_fields['ee-msg-evt-nonce'] = [
1748
+				'name'  => $action . '_nonce',
1749
+				'input' => 'hidden',
1750
+				'type'  => 'string',
1751
+				'value' => wp_create_nonce($action . '_nonce'),
1752
+			];
1753
+
1754
+			$template_switch = $this->request->getRequestParam('template_switch');
1755
+			if ($template_switch) {
1756
+				$sidebar_form_fields['ee-msg-template-switch'] = [
1757
+					'name'  => 'template_switch',
1758
+					'input' => 'hidden',
1759
+					'type'  => 'int',
1760
+					'value' => 1,
1761
+				];
1762
+			}
1763
+
1764
+
1765
+			$template_fields = $this->_generate_admin_form_fields($template_form_fields);
1766
+			$sidebar_fields  = $this->_generate_admin_form_fields($sidebar_form_fields);
1767
+		} //end if ( !empty($template_field_structure) )
1768
+
1769
+		// set extra content for publish box
1770
+		$this->_template_args['publish_box_extra_content'] = $sidebar_fields;
1771
+		$this->_set_publish_post_box_vars(
1772
+			'id',
1773
+			$GRP_ID,
1774
+			false,
1775
+			add_query_arg(
1776
+				['action' => 'global_mtps'],
1777
+				$this->_admin_base_url
1778
+			)
1779
+		);
1780
+
1781
+		// add preview button
1782
+		$preview_url    = parent::add_query_args_and_nonce(
1783
+			[
1784
+				'message_type' => $message_template_group->message_type(),
1785
+				'messenger'    => $message_template_group->messenger(),
1786
+				'context'      => $context,
1787
+				'GRP_ID'       => $GRP_ID,
1788
+				'evt_id'       => $EVT_ID ?: false,
1789
+				'action'       => 'preview_message',
1790
+			],
1791
+			$this->_admin_base_url
1792
+		);
1793
+		$preview_button = '<a href="' . $preview_url . '" class="button-secondary messages-preview-button">'
1794
+						  . esc_html__('Preview', 'event_espresso')
1795
+						  . '</a>';
1796
+
1797
+
1798
+		// setup context switcher
1799
+		$this->_set_context_switcher(
1800
+			$message_template_group,
1801
+			[
1802
+				'page'    => 'espresso_messages',
1803
+				'action'  => 'edit_message_template',
1804
+				'id'      => $GRP_ID,
1805
+				'evt_id'  => $EVT_ID,
1806
+				'context' => $context,
1807
+				'extra'   => $preview_button,
1808
+			]
1809
+		);
1810
+
1811
+
1812
+		// main box
1813
+		$this->_template_args['template_fields']                         = $template_fields;
1814
+		$this->_template_args['sidebar_box_id']                          = 'details';
1815
+		$this->_template_args['action']                                  = $action;
1816
+		$this->_template_args['context']                                 = $context;
1817
+		$this->_template_args['edit_message_template_form_url']          = $edit_message_template_form_url;
1818
+		$this->_template_args['learn_more_about_message_templates_link'] =
1819
+			$this->_learn_more_about_message_templates_link();
1820
+
1821
+
1822
+		$this->_template_args['before_admin_page_content'] = $this->add_context_switcher();
1823
+		$this->_template_args['before_admin_page_content'] .= $this->add_active_context_element(
1824
+			$message_template_group,
1825
+			$context,
1826
+			$context_label
1827
+		);
1828
+		$this->_template_args['before_admin_page_content'] .= $this->_add_form_element_before();
1829
+		$this->_template_args['after_admin_page_content']  = $this->_add_form_element_after();
1830
+
1831
+		$this->_template_path = $this->_template_args['GRP_ID']
1832
+			? EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_edit_meta_box.template.php'
1833
+			: EE_MSG_TEMPLATE_PATH . 'ee_msg_details_main_add_meta_box.template.php';
1834
+
1835
+		// send along EE_Message_Template_Group object for further template use.
1836
+		$this->_template_args['MTP'] = $message_template_group;
1837
+
1838
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1839
+			$this->_template_path,
1840
+			$this->_template_args,
1841
+			true
1842
+		);
1843
+
1844
+
1845
+		// finally, let's set the admin_page title
1846
+		$this->_admin_page_title = sprintf(esc_html__('Editing %s', 'event_espresso'), $title);
1847
+
1848
+
1849
+		// we need to take care of setting the shortcodes property for use elsewhere.
1850
+		$this->_set_shortcodes();
1851
+
1852
+
1853
+		// final template wrapper
1854
+		$this->display_admin_page_with_sidebar();
1855
+	}
1856
+
1857
+
1858
+	public function filter_tinymce_init($mceInit, $editor_id)
1859
+	{
1860
+		return $mceInit;
1861
+	}
1862
+
1863
+
1864
+	public function add_context_switcher()
1865
+	{
1866
+		return $this->_context_switcher;
1867
+	}
1868
+
1869
+
1870
+	/**
1871
+	 * Adds the activation/deactivation toggle for the message template context.
1872
+	 *
1873
+	 * @param EE_Message_Template_Group $message_template_group
1874
+	 * @param string                    $context
1875
+	 * @param string                    $context_label
1876
+	 * @return string
1877
+	 * @throws DomainException
1878
+	 * @throws EE_Error
1879
+	 * @throws InvalidIdentifierException
1880
+	 * @throws ReflectionException
1881
+	 */
1882
+	protected function add_active_context_element(
1883
+		EE_Message_Template_Group $message_template_group,
1884
+		$context,
1885
+		$context_label
1886
+	) {
1887
+		$template_args = [
1888
+			'context'                   => $context,
1889
+			'nonce'                     => wp_create_nonce('activate_' . $context . '_toggle_nonce'),
1890
+			'is_active'                 => $message_template_group->is_context_active($context),
1891
+			'on_off_action'             => $message_template_group->is_context_active($context)
1892
+				? 'context-off'
1893
+				: 'context-on',
1894
+			'context_label'             => str_replace(['(', ')'], '', $context_label),
1895
+			'message_template_group_id' => $message_template_group->ID(),
1896
+		];
1897
+		return EEH_Template::display_template(
1898
+			EE_MSG_TEMPLATE_PATH . 'ee_msg_editor_active_context_element.template.php',
1899
+			$template_args,
1900
+			true
1901
+		);
1902
+	}
1903
+
1904
+
1905
+	/**
1906
+	 * Ajax callback for `toggle_context_template` ajax action.
1907
+	 * Handles toggling the message context on or off.
1908
+	 *
1909
+	 * @throws EE_Error
1910
+	 * @throws InvalidArgumentException
1911
+	 * @throws InvalidDataTypeException
1912
+	 * @throws InvalidIdentifierException
1913
+	 * @throws InvalidInterfaceException
1914
+	 */
1915
+	public function toggle_context_template()
1916
+	{
1917
+		$success = true;
1918
+		// check for required data
1919
+		if (
1920
+			! (
1921
+				$this->request->requestParamIsSet('message_template_group_id')
1922
+				&& $this->request->requestParamIsSet('context')
1923
+				&& $this->request->requestParamIsSet('status')
1924
+			)
1925
+		) {
1926
+			EE_Error::add_error(
1927
+				esc_html__('Required data for doing this action is not available.', 'event_espresso'),
1928
+				__FILE__,
1929
+				__FUNCTION__,
1930
+				__LINE__
1931
+			);
1932
+			$success = false;
1933
+		}
1934
+
1935
+		$nonce   = $this->request->getRequestParam('toggle_context_nonce', '');
1936
+		$context = $this->request->getRequestParam('context', '');
1937
+		$status  = $this->request->getRequestParam('status', '');
1938
+
1939
+		$this->_verify_nonce($nonce, "activate_{$context}_toggle_nonce");
1940
+
1941
+		if ($status !== 'off' && $status !== 'on') {
1942
+			EE_Error::add_error(
1943
+				sprintf(
1944
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
1945
+					$status
1946
+				),
1947
+				__FILE__,
1948
+				__FUNCTION__,
1949
+				__LINE__
1950
+			);
1951
+			$success = false;
1952
+		}
1953
+		$message_template_group_id = $this->request->getRequestParam('message_template_group_id', 0, 'int');
1954
+		$message_template_group    = $this->getMtgModel()->get_one_by_ID($message_template_group_id);
1955
+		if (! $message_template_group instanceof EE_Message_Template_Group) {
1956
+			EE_Error::add_error(
1957
+				sprintf(
1958
+					esc_html__(
1959
+						'Unable to change the active state because the given id "%1$d" does not match a valid "%2$s"',
1960
+						'event_espresso'
1961
+					),
1962
+					$message_template_group_id,
1963
+					'EE_Message_Template_Group'
1964
+				),
1965
+				__FILE__,
1966
+				__FUNCTION__,
1967
+				__LINE__
1968
+			);
1969
+			$success = false;
1970
+		}
1971
+		if ($success) {
1972
+			$success = $status === 'off'
1973
+				? $message_template_group->deactivate_context($context)
1974
+				: $message_template_group->activate_context($context);
1975
+		}
1976
+		$this->_template_args['success'] = $success;
1977
+		$this->_return_json();
1978
+	}
1979
+
1980
+
1981
+	public function _add_form_element_before()
1982
+	{
1983
+		return '<form method="post" action="'
1984
+			   . $this->_template_args['edit_message_template_form_url']
1985
+			   . '" id="ee-msg-edit-frm">';
1986
+	}
1987
+
1988
+
1989
+	public function _add_form_element_after()
1990
+	{
1991
+		return '</form>';
1992
+	}
1993
+
1994
+
1995
+	/**
1996
+	 * This executes switching the template pack for a message template.
1997
+	 *
1998
+	 * @throws EE_Error
1999
+	 * @throws InvalidDataTypeException
2000
+	 * @throws InvalidInterfaceException
2001
+	 * @throws InvalidArgumentException
2002
+	 * @throws ReflectionException
2003
+	 * @since 4.5.0
2004
+	 */
2005
+	public function switch_template_pack()
2006
+	{
2007
+
2008
+		$GRP_ID        = $this->request->getRequestParam('GRP_ID', 0, 'int');
2009
+		$template_pack = $this->request->getRequestParam('template_pack', '');
2010
+
2011
+		// verify we have needed values.
2012
+		if (empty($GRP_ID) || empty($template_pack)) {
2013
+			$this->_template_args['error'] = true;
2014
+			EE_Error::add_error(
2015
+				esc_html__('The required date for switching templates is not available.', 'event_espresso'),
2016
+				__FILE__,
2017
+				__FUNCTION__,
2018
+				__LINE__
2019
+			);
2020
+		} else {
2021
+			// get template, set the new template_pack and then reset to default
2022
+			/** @var EE_Message_Template_Group $message_template_group */
2023
+			$message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
2024
+
2025
+			$message_template_group->set_template_pack_name($template_pack);
2026
+			$this->request->setRequestParam('msgr', $message_template_group->messenger());
2027
+			$this->request->setRequestParam('mt', $message_template_group->message_type());
2028
+
2029
+			$query_args = $this->_reset_to_default_template();
2030
+
2031
+			if (empty($query_args['id'])) {
2032
+				EE_Error::add_error(
2033
+					esc_html__(
2034
+						'Something went wrong with switching the template pack. Please try again or contact EE support',
2035
+						'event_espresso'
2036
+					),
2037
+					__FILE__,
2038
+					__FUNCTION__,
2039
+					__LINE__
2040
+				);
2041
+				$this->_template_args['error'] = true;
2042
+			} else {
2043
+				$template_label       = $message_template_group->get_template_pack()->label;
2044
+				$template_pack_labels = $message_template_group->messenger_obj()->get_supports_labels();
2045
+				EE_Error::add_success(
2046
+					sprintf(
2047
+						esc_html__(
2048
+							'This message template has been successfully switched to use the %1$s %2$s.  Please wait while the page reloads with your new template.',
2049
+							'event_espresso'
2050
+						),
2051
+						$template_label,
2052
+						$template_pack_labels->template_pack
2053
+					)
2054
+				);
2055
+				// generate the redirect url for js.
2056
+				$url = self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2057
+
2058
+				$this->_template_args['data']['redirect_url'] = $url;
2059
+				$this->_template_args['success']              = true;
2060
+			}
2061
+
2062
+			$this->_return_json();
2063
+		}
2064
+	}
2065
+
2066
+
2067
+	/**
2068
+	 * This handles resetting the template for the given messenger/message_type so that users can start from scratch if
2069
+	 * they want.
2070
+	 *
2071
+	 * @access protected
2072
+	 * @return array|void
2073
+	 * @throws EE_Error
2074
+	 * @throws InvalidArgumentException
2075
+	 * @throws InvalidDataTypeException
2076
+	 * @throws InvalidInterfaceException
2077
+	 * @throws ReflectionException
2078
+	 */
2079
+	protected function _reset_to_default_template()
2080
+	{
2081
+		$templates    = [];
2082
+		$GRP_ID       = $this->request->getRequestParam('GRP_ID', 0, 'int');
2083
+		$messenger    = $this->request->getRequestParam('msgr');
2084
+		$message_type = $this->request->getRequestParam('mt');
2085
+		// we need to make sure we've got the info we need.
2086
+		if (! ($GRP_ID && $messenger && $message_type)) {
2087
+			EE_Error::add_error(
2088
+				esc_html__(
2089
+					'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.',
2090
+					'event_espresso'
2091
+				),
2092
+				__FILE__,
2093
+				__FUNCTION__,
2094
+				__LINE__
2095
+			);
2096
+		}
2097
+
2098
+		// all templates will be reset to whatever the defaults are
2099
+		// for the global template matching the messenger and message type.
2100
+		$success = ! empty($GRP_ID);
2101
+
2102
+		if ($success) {
2103
+			// let's first determine if the incoming template is a global template,
2104
+			// if it isn't then we need to get the global template matching messenger and message type.
2105
+			// $MTPG = $this->getMtgModel()->get_one_by_ID( $GRP_ID );
2106
+
2107
+
2108
+			// note this is ONLY deleting the template fields (Message Template rows) NOT the message template group.
2109
+			$success = $this->_delete_mtp_permanently($GRP_ID, false);
2110
+
2111
+			if ($success) {
2112
+				// if successfully deleted, lets generate the new ones.
2113
+				// Note. We set GLOBAL to true, because resets on ANY template
2114
+				// will use the related global template defaults for regeneration.
2115
+				// This means that if a custom template is reset it resets to whatever the related global template is.
2116
+				// HOWEVER, we DO keep the template pack and template variation set
2117
+				// for the current custom template when resetting.
2118
+				$templates = $this->_generate_new_templates($messenger, $message_type, $GRP_ID, true);
2119
+			}
2120
+		}
2121
+
2122
+		// any error messages?
2123
+		if (! $success) {
2124
+			EE_Error::add_error(
2125
+				esc_html__(
2126
+					'Something went wrong with deleting existing templates. Unable to reset to default',
2127
+					'event_espresso'
2128
+				),
2129
+				__FILE__,
2130
+				__FUNCTION__,
2131
+				__LINE__
2132
+			);
2133
+		}
2134
+
2135
+		// all good, let's add a success message!
2136
+		if ($success && ! empty($templates)) {
2137
+			// the info for the template we generated is the first element in the returned array
2138
+			EE_Error::overwrite_success();
2139
+			EE_Error::add_success(esc_html__('Templates have been reset to defaults.', 'event_espresso'));
2140
+		}
2141
+
2142
+
2143
+		$query_args = [
2144
+			'id'      => isset($templates['GRP_ID']) ? $templates['GRP_ID'] : null,
2145
+			'context' => isset($templates['MTP_context']) ? $templates['MTP_context'] : null,
2146
+			'action'  => isset($templates['GRP_ID']) ? 'edit_message_template' : 'global_mtps',
2147
+		];
2148
+
2149
+		// if called via ajax then we return query args otherwise redirect
2150
+		if ($this->request->isAjax()) {
2151
+			return $query_args;
2152
+		}
2153
+		$this->_redirect_after_action(false, '', '', $query_args, true);
2154
+	}
2155
+
2156
+
2157
+	/**
2158
+	 * Retrieve and set the message preview for display.
2159
+	 *
2160
+	 * @param bool $send if TRUE then we are doing an actual TEST send with the results of the preview.
2161
+	 * @return string
2162
+	 * @throws ReflectionException
2163
+	 * @throws EE_Error
2164
+	 * @throws InvalidArgumentException
2165
+	 * @throws InvalidDataTypeException
2166
+	 * @throws InvalidInterfaceException
2167
+	 */
2168
+	public function _preview_message($send = false)
2169
+	{
2170
+		// first make sure we've got the necessary parameters
2171
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2172
+		if (! ($GRP_ID && $this->_active_messenger_name && $this->_active_message_type_name)) {
2173
+			EE_Error::add_error(
2174
+				esc_html__('Missing necessary parameters for displaying preview', 'event_espresso'),
2175
+				__FILE__,
2176
+				__FUNCTION__,
2177
+				__LINE__
2178
+			);
2179
+		}
2180
+
2181
+		$context = $this->request->getRequestParam('context');
2182
+		// get the preview!
2183
+		$preview = EED_Messages::preview_message(
2184
+			$this->_active_message_type_name,
2185
+			$context,
2186
+			$this->_active_messenger_name,
2187
+			$send
2188
+		);
2189
+
2190
+		if ($send) {
2191
+			return $preview;
2192
+		}
2193
+
2194
+		// if we have an evt_id set on the request, use it.
2195
+		$EVT_ID = $this->request->getRequestParam('evt_id', 0, 'int');
2196
+
2197
+		// let's add a button to go back to the edit view
2198
+		$query_args             = [
2199
+			'id'      => $GRP_ID,
2200
+			'evt_id'  => $EVT_ID,
2201
+			'context' => $context,
2202
+			'action'  => 'edit_message_template',
2203
+		];
2204
+		$go_back_url            = parent::add_query_args_and_nonce($query_args, $this->_admin_base_url);
2205
+		$preview_button         = '<a href="'
2206
+								  . $go_back_url
2207
+								  . '" class="button-secondary messages-preview-go-back-button">'
2208
+								  . esc_html__('Go Back to Edit', 'event_espresso')
2209
+								  . '</a>';
2210
+		$message_types          = $this->get_installed_message_types();
2211
+		$active_messenger       = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
2212
+		$active_messenger_label = $active_messenger instanceof EE_messenger
2213
+			? ucwords($active_messenger->label['singular'])
2214
+			: esc_html__('Unknown Messenger', 'event_espresso');
2215
+		// let's provide a helpful title for context
2216
+		$preview_title = sprintf(
2217
+			esc_html__('Viewing Preview for %s %s Message Template', 'event_espresso'),
2218
+			$active_messenger_label,
2219
+			ucwords($message_types[ $this->_active_message_type_name ]->label['singular'])
2220
+		);
2221
+		if (empty($preview)) {
2222
+			$this->noEventsErrorMessage();
2223
+		}
2224
+		// setup display of preview.
2225
+		$this->_admin_page_title                    = $preview_title;
2226
+		$this->_template_args['admin_page_title']   = $preview_title;
2227
+		$this->_template_args['admin_page_content'] = $preview_button . '<br />' . $preview;
2228
+		$this->_template_args['data']['force_json'] = true;
2229
+
2230
+		return '';
2231
+	}
2232
+
2233
+
2234
+	/**
2235
+	 * Used to set an error if there are no events available for generating a preview/test send.
2236
+	 *
2237
+	 * @param bool $test_send Whether the error should be generated for the context of a test send.
2238
+	 */
2239
+	protected function noEventsErrorMessage($test_send = false)
2240
+	{
2241
+		$events_url = parent::add_query_args_and_nonce(
2242
+			[
2243
+				'action' => 'default',
2244
+				'page'   => 'espresso_events',
2245
+			],
2246
+			admin_url('admin.php')
2247
+		);
2248
+		$message    = $test_send
2249
+			? esc_html__(
2250
+				'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!',
2251
+				'event_espresso'
2252
+			)
2253
+			: esc_html__(
2254
+				'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!',
2255
+				'event_espresso'
2256
+			);
2257
+
2258
+		EE_Error::add_attention(
2259
+			sprintf(
2260
+				$message,
2261
+				"<a href='{$events_url}'>",
2262
+				'</a>'
2263
+			)
2264
+		);
2265
+	}
2266
+
2267
+
2268
+	/**
2269
+	 * The initial _preview_message is on a no headers route.  It will optionally call this if necessary otherwise it
2270
+	 * gets called automatically.
2271
+	 *
2272
+	 * @return void
2273
+	 * @throws EE_Error
2274
+	 * @since 4.5.0
2275
+	 *
2276
+	 */
2277
+	protected function _display_preview_message()
2278
+	{
2279
+		$this->display_admin_page_with_no_sidebar();
2280
+	}
2281
+
2282
+
2283
+	/**
2284
+	 * registers metaboxes that should show up on the "edit_message_template" page
2285
+	 *
2286
+	 * @access protected
2287
+	 * @return void
2288
+	 */
2289
+	protected function _register_edit_meta_boxes()
2290
+	{
2291
+		add_meta_box(
2292
+			'mtp_valid_shortcodes',
2293
+			esc_html__('Valid Shortcodes', 'event_espresso'),
2294
+			[$this, 'shortcode_meta_box'],
2295
+			$this->_current_screen->id,
2296
+			'side'
2297
+		);
2298
+		add_meta_box(
2299
+			'mtp_extra_actions',
2300
+			esc_html__('Extra Actions', 'event_espresso'),
2301
+			[$this, 'extra_actions_meta_box'],
2302
+			$this->_current_screen->id,
2303
+			'side',
2304
+			'high'
2305
+		);
2306
+		add_meta_box(
2307
+			'mtp_templates',
2308
+			esc_html__('Template Styles', 'event_espresso'),
2309
+			[$this, 'template_pack_meta_box'],
2310
+			$this->_current_screen->id,
2311
+			'side',
2312
+			'high'
2313
+		);
2314
+	}
2315
+
2316
+
2317
+	/**
2318
+	 * metabox content for all template pack and variation selection.
2319
+	 *
2320
+	 * @return void
2321
+	 * @throws DomainException
2322
+	 * @throws EE_Error
2323
+	 * @throws InvalidArgumentException
2324
+	 * @throws ReflectionException
2325
+	 * @throws InvalidDataTypeException
2326
+	 * @throws InvalidInterfaceException
2327
+	 * @since 4.5.0
2328
+	 */
2329
+	public function template_pack_meta_box()
2330
+	{
2331
+		$this->_set_message_template_group();
2332
+
2333
+		$tp_collection = EEH_MSG_Template::get_template_pack_collection();
2334
+
2335
+		$tp_select_values = [];
2336
+
2337
+		foreach ($tp_collection as $tp) {
2338
+			// only include template packs that support this messenger and message type!
2339
+			$supports = $tp->get_supports();
2340
+			if (
2341
+				! isset($supports[ $this->_message_template_group->messenger() ])
2342
+				|| ! in_array(
2343
+					$this->_message_template_group->message_type(),
2344
+					$supports[ $this->_message_template_group->messenger() ],
2345
+					true
2346
+				)
2347
+			) {
2348
+				// not supported
2349
+				continue;
2350
+			}
2351
+
2352
+			$tp_select_values[] = [
2353
+				'text' => $tp->label,
2354
+				'id'   => $tp->dbref,
2355
+			];
2356
+		}
2357
+
2358
+		// if empty $tp_select_values then we make sure default is set because EVERY message type should be supported by
2359
+		// the default template pack.  This still allows for the odd template pack to override.
2360
+		if (empty($tp_select_values)) {
2361
+			$tp_select_values[] = [
2362
+				'text' => esc_html__('Default', 'event_espresso'),
2363
+				'id'   => 'default',
2364
+			];
2365
+		}
2366
+
2367
+		// setup variation select values for the currently selected template.
2368
+		$variations               = $this->_message_template_group->get_template_pack()->get_variations(
2369
+			$this->_message_template_group->messenger(),
2370
+			$this->_message_template_group->message_type()
2371
+		);
2372
+		$variations_select_values = [];
2373
+		foreach ($variations as $variation => $label) {
2374
+			$variations_select_values[] = [
2375
+				'text' => $label,
2376
+				'id'   => $variation,
2377
+			];
2378
+		}
2379
+
2380
+		$template_pack_labels = $this->_message_template_group->messenger_obj()->get_supports_labels();
2381
+
2382
+		$template_args['template_packs_selector']        = EEH_Form_Fields::select_input(
2383
+			'MTP_template_pack',
2384
+			$tp_select_values,
2385
+			$this->_message_template_group->get_template_pack_name()
2386
+		);
2387
+		$template_args['variations_selector']            = EEH_Form_Fields::select_input(
2388
+			'MTP_template_variation',
2389
+			$variations_select_values,
2390
+			$this->_message_template_group->get_template_pack_variation()
2391
+		);
2392
+		$template_args['template_pack_label']            = $template_pack_labels->template_pack;
2393
+		$template_args['template_variation_label']       = $template_pack_labels->template_variation;
2394
+		$template_args['template_pack_description']      = $template_pack_labels->template_pack_description;
2395
+		$template_args['template_variation_description'] = $template_pack_labels->template_variation_description;
2396
+
2397
+		$template = EE_MSG_TEMPLATE_PATH . 'template_pack_and_variations_metabox.template.php';
2398
+
2399
+		EEH_Template::display_template($template, $template_args);
2400
+	}
2401
+
2402
+
2403
+	/**
2404
+	 * This meta box holds any extra actions related to Message Templates
2405
+	 * For now, this includes Resetting templates to defaults and sending a test email.
2406
+	 *
2407
+	 * @access  public
2408
+	 * @return void
2409
+	 * @throws EE_Error
2410
+	 */
2411
+	public function extra_actions_meta_box()
2412
+	{
2413
+		$template_form_fields = [];
2414
+
2415
+		$extra_args = [
2416
+			'msgr'   => $this->_message_template_group->messenger(),
2417
+			'mt'     => $this->_message_template_group->message_type(),
2418
+			'GRP_ID' => $this->_message_template_group->GRP_ID(),
2419
+		];
2420
+		// first we need to see if there are any fields
2421
+		$fields = $this->_message_template_group->messenger_obj()->get_test_settings_fields();
2422
+
2423
+		if (! empty($fields)) {
2424
+			// yup there be fields
2425
+			foreach ($fields as $field => $config) {
2426
+				$field_id = $this->_message_template_group->messenger() . '_' . $field;
2427
+				$existing = $this->_message_template_group->messenger_obj()->get_existing_test_settings();
2428
+				$default  = isset($config['default']) ? $config['default'] : '';
2429
+				$default  = isset($config['value']) ? $config['value'] : $default;
2430
+
2431
+				// if type is hidden and the value is empty
2432
+				// something may have gone wrong so let's correct with the defaults
2433
+				$fix                = $config['input'] === 'hidden'
2434
+									  && isset($existing[ $field ])
2435
+									  && empty($existing[ $field ])
2436
+					? $default
2437
+					: '';
2438
+				$existing[ $field ] = isset($existing[ $field ]) && empty($fix)
2439
+					? $existing[ $field ]
2440
+					: $fix;
2441
+
2442
+				$template_form_fields[ $field_id ] = [
2443
+					'name'       => 'test_settings_fld[' . $field . ']',
2444
+					'label'      => $config['label'],
2445
+					'input'      => $config['input'],
2446
+					'type'       => $config['type'],
2447
+					'required'   => $config['required'],
2448
+					'validation' => $config['validation'],
2449
+					'value'      => isset($existing[ $field ]) ? $existing[ $field ] : $default,
2450
+					'css_class'  => $config['css_class'],
2451
+					'options'    => isset($config['options']) ? $config['options'] : [],
2452
+					'default'    => $default,
2453
+					'format'     => $config['format'],
2454
+				];
2455
+			}
2456
+		}
2457
+
2458
+		$test_settings_html = ! empty($template_form_fields)
2459
+			? $this->_generate_admin_form_fields($template_form_fields, 'string', 'ee_tst_settings_flds')
2460
+			: '';
2461
+
2462
+		// print out $test_settings_fields
2463
+		if (! empty($test_settings_html)) {
2464
+			$test_settings_html .= '<input type="submit" class="button-primary mtp-test-button alignright" ';
2465
+			$test_settings_html .= 'name="test_button" value="';
2466
+			$test_settings_html .= esc_html__('Test Send', 'event_espresso');
2467
+			$test_settings_html .= '" /><div style="clear:both"></div>';
2468
+		}
2469
+
2470
+		// and button
2471
+		$test_settings_html .= '<p>';
2472
+		$test_settings_html .= esc_html__('Need to reset this message type and start over?', 'event_espresso');
2473
+		$test_settings_html .= '</p>';
2474
+		$test_settings_html .= '<div class="publishing-action alignright resetbutton">';
2475
+		$test_settings_html .= $this->get_action_link_or_button(
2476
+			'reset_to_default',
2477
+			'reset',
2478
+			$extra_args,
2479
+			'button-primary reset-default-button'
2480
+		);
2481
+		$test_settings_html .= '</div><div style="clear:both"></div>';
2482
+		echo $test_settings_html; // already escaped
2483
+	}
2484
+
2485
+
2486
+	/**
2487
+	 * This returns the shortcode selector skeleton for a given context and field.
2488
+	 *
2489
+	 * @param string $field           The name of the field retrieving shortcodes for.
2490
+	 * @param string $linked_input_id The css id of the input that the shortcodes get added to.
2491
+	 * @return string
2492
+	 * @throws DomainException
2493
+	 * @throws EE_Error
2494
+	 * @throws InvalidArgumentException
2495
+	 * @throws ReflectionException
2496
+	 * @throws InvalidDataTypeException
2497
+	 * @throws InvalidInterfaceException
2498
+	 * @since 4.9.rc.000
2499
+	 */
2500
+	protected function _get_shortcode_selector($field, $linked_input_id)
2501
+	{
2502
+		$template_args = [
2503
+			'shortcodes'      => $this->_get_shortcodes([$field]),
2504
+			'fieldname'       => $field,
2505
+			'linked_input_id' => $linked_input_id,
2506
+		];
2507
+
2508
+		return EEH_Template::display_template(
2509
+			EE_MSG_TEMPLATE_PATH . 'shortcode_selector_skeleton.template.php',
2510
+			$template_args,
2511
+			true
2512
+		);
2513
+	}
2514
+
2515
+
2516
+	/**
2517
+	 * This just takes care of returning the meta box content for shortcodes (only used on the edit message template
2518
+	 * page)
2519
+	 *
2520
+	 * @access public
2521
+	 * @return void
2522
+	 * @throws EE_Error
2523
+	 * @throws InvalidArgumentException
2524
+	 * @throws ReflectionException
2525
+	 * @throws InvalidDataTypeException
2526
+	 * @throws InvalidInterfaceException
2527
+	 */
2528
+	public function shortcode_meta_box()
2529
+	{
2530
+		$shortcodes = $this->_get_shortcodes([], false);
2531
+		// just make sure the shortcodes property is set
2532
+		// $messenger = $this->_message_template_group->messenger_obj();
2533
+		// now let's set the content depending on the status of the shortcodes array
2534
+		if (empty($shortcodes)) {
2535
+			echo '<p>' . esc_html__('There are no valid shortcodes available', 'event_espresso') . '</p>';
2536
+			return;
2537
+		}
2538
+		?>
2539 2539
         <div style="float:right; margin-top:10px">
2540 2540
             <?php echo $this->_get_help_tab_link('message_template_shortcodes'); // already escaped
2541
-            ?>
2541
+			?>
2542 2542
         </div>
2543 2543
         <p class="small-text">
2544 2544
             <?php printf(
2545
-                esc_html__(
2546
-                    'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2547
-                    'event_espresso'
2548
-                ),
2549
-                '<span class="dashicons dashicons-menu"></span>'
2550
-            ); ?>
2545
+				esc_html__(
2546
+					'You can view the shortcodes usable in your template by clicking the %s icon next to each field.',
2547
+					'event_espresso'
2548
+				),
2549
+				'<span class="dashicons dashicons-menu"></span>'
2550
+			); ?>
2551 2551
         </p>
2552 2552
         <?php
2553
-    }
2554
-
2555
-
2556
-    /**
2557
-     * used to set the $_shortcodes property for when its needed elsewhere.
2558
-     *
2559
-     * @access protected
2560
-     * @return void
2561
-     * @throws EE_Error
2562
-     * @throws InvalidArgumentException
2563
-     * @throws ReflectionException
2564
-     * @throws InvalidDataTypeException
2565
-     * @throws InvalidInterfaceException
2566
-     */
2567
-    protected function _set_shortcodes()
2568
-    {
2569
-
2570
-        // no need to run this if the property is already set
2571
-        if (! empty($this->_shortcodes)) {
2572
-            return;
2573
-        }
2574
-
2575
-        $this->_shortcodes = $this->_get_shortcodes();
2576
-    }
2577
-
2578
-
2579
-    /**
2580
-     * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2581
-     * property)
2582
-     *
2583
-     * @access  protected
2584
-     * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2585
-     *                         for. Defaults to all (for the given context)
2586
-     * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2587
-     * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2588
-     *                         true just an array of shortcode/label pairs.
2589
-     * @throws EE_Error
2590
-     * @throws InvalidArgumentException
2591
-     * @throws ReflectionException
2592
-     * @throws InvalidDataTypeException
2593
-     * @throws InvalidInterfaceException
2594
-     */
2595
-    protected function _get_shortcodes($fields = [], $merged = true)
2596
-    {
2597
-        $this->_set_message_template_group();
2598
-
2599
-        // we need the messenger and message template to retrieve the valid shortcodes array.
2600
-        $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
2601
-        if (empty($GRP_ID)) {
2602
-            return [];
2603
-        }
2604
-        $context = $this->request->getRequestParam(
2605
-            'messenger',
2606
-            key($this->_message_template_group->contexts_config())
2607
-        );
2608
-        return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2609
-    }
2610
-
2611
-
2612
-    /**
2613
-     * This sets the _message_template property (containing the called message_template object)
2614
-     *
2615
-     * @access protected
2616
-     * @return void
2617
-     * @throws EE_Error
2618
-     * @throws InvalidArgumentException
2619
-     * @throws ReflectionException
2620
-     * @throws InvalidDataTypeException
2621
-     * @throws InvalidInterfaceException
2622
-     */
2623
-    protected function _set_message_template_group()
2624
-    {
2625
-        // get out if this is already set.
2626
-        if (! empty($this->_message_template_group)) {
2627
-            return;
2628
-        }
2629
-
2630
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2631
-        $GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
2632
-
2633
-        // let's get the message templates
2634
-        $this->_message_template_group = ! empty($GRP_ID)
2635
-            ? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2636
-            : $this->getMtgModel()->create_default_object();
2637
-
2638
-        $this->_template_pack = $this->_message_template_group->get_template_pack();
2639
-        $this->_variation     = $this->_message_template_group->get_template_pack_variation();
2640
-    }
2641
-
2642
-
2643
-    /**
2644
-     * sets up a context switcher for edit forms
2645
-     *
2646
-     * @access  protected
2647
-     * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2648
-     * @param array                     $args                  various things the context switcher needs.
2649
-     * @throws EE_Error
2650
-     */
2651
-    protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2652
-    {
2653
-        $context_details = $template_group_object->contexts_config();
2654
-        $context_label   = $template_group_object->context_label();
2655
-        ob_start();
2656
-        ?>
2553
+	}
2554
+
2555
+
2556
+	/**
2557
+	 * used to set the $_shortcodes property for when its needed elsewhere.
2558
+	 *
2559
+	 * @access protected
2560
+	 * @return void
2561
+	 * @throws EE_Error
2562
+	 * @throws InvalidArgumentException
2563
+	 * @throws ReflectionException
2564
+	 * @throws InvalidDataTypeException
2565
+	 * @throws InvalidInterfaceException
2566
+	 */
2567
+	protected function _set_shortcodes()
2568
+	{
2569
+
2570
+		// no need to run this if the property is already set
2571
+		if (! empty($this->_shortcodes)) {
2572
+			return;
2573
+		}
2574
+
2575
+		$this->_shortcodes = $this->_get_shortcodes();
2576
+	}
2577
+
2578
+
2579
+	/**
2580
+	 * gets all shortcodes for a given template group. (typically used by _set_shortcodes to set the $_shortcodes
2581
+	 * property)
2582
+	 *
2583
+	 * @access  protected
2584
+	 * @param array   $fields  include an array of specific field names that you want to be used to get the shortcodes
2585
+	 *                         for. Defaults to all (for the given context)
2586
+	 * @param boolean $merged  Whether to merge all the shortcodes into one list of unique shortcodes
2587
+	 * @return array Shortcodes indexed by fieldname and the an array of shortcode/label pairs OR if merged is
2588
+	 *                         true just an array of shortcode/label pairs.
2589
+	 * @throws EE_Error
2590
+	 * @throws InvalidArgumentException
2591
+	 * @throws ReflectionException
2592
+	 * @throws InvalidDataTypeException
2593
+	 * @throws InvalidInterfaceException
2594
+	 */
2595
+	protected function _get_shortcodes($fields = [], $merged = true)
2596
+	{
2597
+		$this->_set_message_template_group();
2598
+
2599
+		// we need the messenger and message template to retrieve the valid shortcodes array.
2600
+		$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
2601
+		if (empty($GRP_ID)) {
2602
+			return [];
2603
+		}
2604
+		$context = $this->request->getRequestParam(
2605
+			'messenger',
2606
+			key($this->_message_template_group->contexts_config())
2607
+		);
2608
+		return $this->_message_template_group->get_shortcodes($context, $fields, $merged);
2609
+	}
2610
+
2611
+
2612
+	/**
2613
+	 * This sets the _message_template property (containing the called message_template object)
2614
+	 *
2615
+	 * @access protected
2616
+	 * @return void
2617
+	 * @throws EE_Error
2618
+	 * @throws InvalidArgumentException
2619
+	 * @throws ReflectionException
2620
+	 * @throws InvalidDataTypeException
2621
+	 * @throws InvalidInterfaceException
2622
+	 */
2623
+	protected function _set_message_template_group()
2624
+	{
2625
+		// get out if this is already set.
2626
+		if (! empty($this->_message_template_group)) {
2627
+			return;
2628
+		}
2629
+
2630
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
2631
+		$GRP_ID = $this->request->getRequestParam('id', $GRP_ID, 'int');
2632
+
2633
+		// let's get the message templates
2634
+		$this->_message_template_group = ! empty($GRP_ID)
2635
+			? $this->getMtgModel()->get_one_by_ID($GRP_ID)
2636
+			: $this->getMtgModel()->create_default_object();
2637
+
2638
+		$this->_template_pack = $this->_message_template_group->get_template_pack();
2639
+		$this->_variation     = $this->_message_template_group->get_template_pack_variation();
2640
+	}
2641
+
2642
+
2643
+	/**
2644
+	 * sets up a context switcher for edit forms
2645
+	 *
2646
+	 * @access  protected
2647
+	 * @param EE_Message_Template_Group $template_group_object the template group object being displayed on the form
2648
+	 * @param array                     $args                  various things the context switcher needs.
2649
+	 * @throws EE_Error
2650
+	 */
2651
+	protected function _set_context_switcher(EE_Message_Template_Group $template_group_object, $args)
2652
+	{
2653
+		$context_details = $template_group_object->contexts_config();
2654
+		$context_label   = $template_group_object->context_label();
2655
+		ob_start();
2656
+		?>
2657 2657
         <div class="ee-msg-switcher-container">
2658 2658
             <form method="get" action="<?php echo esc_url_raw(EE_MSG_ADMIN_URL); ?>" id="ee-msg-context-switcher-frm">
2659 2659
                 <?php
2660
-                foreach ($args as $name => $value) {
2661
-                    if ($name === 'context' || empty($value) || $name === 'extra') {
2662
-                        continue;
2663
-                    }
2664
-                    ?>
2660
+				foreach ($args as $name => $value) {
2661
+					if ($name === 'context' || empty($value) || $name === 'extra') {
2662
+						continue;
2663
+					}
2664
+					?>
2665 2665
                     <input type="hidden"
2666 2666
                            name="<?php echo esc_attr($name); ?>"
2667 2667
                            value="<?php echo esc_attr($value); ?>"
2668 2668
                     />
2669 2669
                     <?php
2670
-                }
2671
-                // setup nonce_url
2672
-                wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2673
-                $id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2674
-                ?>
2670
+				}
2671
+				// setup nonce_url
2672
+				wp_nonce_field($args['action'] . '_nonce', $args['action'] . '_nonce', false);
2673
+				$id = 'ee-' . sanitize_key($context_label['label']) . '-select';
2674
+				?>
2675 2675
                 <label for='<?php echo esc_attr($id); ?>' class='screen-reader-text'>
2676 2676
                     <?php esc_html_e('message context options', 'event_espresso'); ?>
2677 2677
                 </label>
2678 2678
                 <select id="<?php echo esc_attr($id); ?>" name="context">
2679 2679
                     <?php
2680
-                    $context_templates = $template_group_object->context_templates();
2681
-                    if (is_array($context_templates)) :
2682
-                        foreach ($context_templates as $context => $template_fields) :
2683
-                            $checked = ($context === $args['context']) ? 'selected="selected"' : '';
2684
-                            ?>
2680
+					$context_templates = $template_group_object->context_templates();
2681
+					if (is_array($context_templates)) :
2682
+						foreach ($context_templates as $context => $template_fields) :
2683
+							$checked = ($context === $args['context']) ? 'selected="selected"' : '';
2684
+							?>
2685 2685
                             <option value="<?php echo esc_attr($context); ?>" <?php echo $checked; ?>>
2686 2686
                                 <?php echo $context_details[ $context ]['label']; // already escaped
2687
-                                ?>
2687
+								?>
2688 2688
                             </option>
2689 2689
                         <?php endforeach;
2690
-                    endif; ?>
2690
+					endif; ?>
2691 2691
                 </select>
2692 2692
                 <?php $button_text = sprintf(
2693
-                    esc_html__('Switch %s', 'event_espresso'),
2694
-                    ucwords($context_label['label'])
2695
-                ); ?>
2693
+					esc_html__('Switch %s', 'event_espresso'),
2694
+					ucwords($context_label['label'])
2695
+				); ?>
2696 2696
                 <input class='button-secondary'
2697 2697
                        id="submit-msg-context-switcher-sbmt"
2698 2698
                        type="submit"
@@ -2700,1995 +2700,1995 @@  discard block
 block discarded – undo
2700 2700
                 />
2701 2701
             </form>
2702 2702
             <?php echo $args['extra']; // already escaped
2703
-            ?>
2703
+			?>
2704 2704
         </div> <!-- end .ee-msg-switcher-container -->
2705 2705
         <?php
2706
-        $this->_context_switcher = ob_get_clean();
2707
-    }
2708
-
2709
-
2710
-    /**
2711
-     * @param bool $new
2712
-     * @throws EE_Error
2713
-     * @throws ReflectionException
2714
-     */
2715
-    protected function _insert_or_update_message_template($new = false)
2716
-    {
2717
-        $form_data    = $this->getMessageTemplateFormData();
2718
-        $GRP_ID       = $form_data['GRP_ID'];
2719
-        $messenger    = $form_data['MTP_messenger'];
2720
-        $message_type = $form_data['MTP_message_type'];
2721
-        $context      = $form_data['MTP_context'];
2722
-
2723
-        // if this is "new" then we need to generate the default contexts
2724
-        // for the selected messenger/message_type for user to edit.
2725
-        list($success, $query_args) = $new
2726
-            ? $this->generateNewTemplates($GRP_ID, $messenger, $message_type)
2727
-            : $this->updateExistingTemplates($GRP_ID, $messenger, $message_type, $context, $form_data);
2728
-
2729
-        $success     = $success ? 1 : 0;
2730
-        $action_desc = $new ? 'created' : 'updated';
2731
-        $item_desc   = $this->generateUpdateDescription($messenger, $message_type, $context);
2732
-        $override    = $this->performTestSendAfterUpdate($messenger, $message_type, $context);
2733
-
2734
-        $this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2735
-    }
2736
-
2737
-
2738
-    /**
2739
-     * retrieve and sanitize form data
2740
-     *
2741
-     * @return array
2742
-     * @since 4.10.29.p
2743
-     */
2744
-    protected function getMessageTemplateFormData()
2745
-    {
2746
-        return [
2747
-            'GRP_ID'           => $this->request->getRequestParam('GRP_ID', 0, 'int'),
2748
-            'MTP_context'      => strtolower($this->request->getRequestParam('MTP_context', '')),
2749
-            'MTP_messenger'    => strtolower($this->request->getRequestParam('MTP_messenger', '')),
2750
-            'MTP_message_type' => strtolower($this->request->getRequestParam('MTP_message_type', '')),
2751
-            'MTP_user_id'      => $this->request->getRequestParam('MTP_user_id', 0, 'int'),
2752
-            'MTP_is_global'    => $this->request->getRequestParam('MTP_is_global', 0, 'int'),
2753
-            'MTP_is_override'  => $this->request->getRequestParam('MTP_is_override', 0, 'int'),
2754
-            'MTP_deleted'      => $this->request->getRequestParam('MTP_deleted', 0, 'int'),
2755
-            'MTP_is_active'    => $this->request->getRequestParam('MTP_is_active', 0, 'int'),
2756
-        ];
2757
-    }
2758
-
2759
-
2760
-    /**
2761
-     * @param int    $GRP_ID
2762
-     * @param string $messenger
2763
-     * @param string $message_type
2764
-     * @return array no return on AJAX requests
2765
-     * @throws EE_Error
2766
-     * @throws ReflectionException
2767
-     * @since 4.10.29.p
2768
-     */
2769
-    private function generateNewTemplates($GRP_ID, $messenger, $message_type)
2770
-    {
2771
-        $new_templates = $this->_generate_new_templates($messenger, [$message_type], $GRP_ID);
2772
-        $success       = ! empty($new_templates);
2773
-
2774
-        // we return things differently if doing ajax
2775
-        if ($this->request->isAjax()) {
2776
-            $this->_template_args['success'] = $success;
2777
-            $this->_template_args['error']   = ! $success;
2778
-            $this->_template_args['content'] = '';
2779
-            $this->_template_args['data']    = [
2780
-                'grpID'        => $new_templates['GRP_ID'],
2781
-                'templateName' => $new_templates['template_name'],
2782
-            ];
2783
-            if ($success) {
2784
-                EE_Error::overwrite_success();
2785
-                EE_Error::add_success(
2786
-                    esc_html__(
2787
-                        'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2788
-                        'event_espresso'
2789
-                    )
2790
-                );
2791
-            }
2792
-            $this->_return_json();
2793
-        }
2794
-        return [
2795
-            $success,
2796
-            // 'query_args'
2797
-            [
2798
-                'id'      => $new_templates['GRP_ID'],
2799
-                'context' => $new_templates['MTP_context'],
2800
-                'action'  => 'edit_message_template',
2801
-            ],
2802
-        ];
2803
-    }
2804
-
2805
-
2806
-    /**
2807
-     * @param int    $GRP_ID
2808
-     * @param string $messenger
2809
-     * @param string $message_type
2810
-     * @param string $context
2811
-     * @param array  $form_data
2812
-     * @return array
2813
-     * @throws EE_Error
2814
-     * @since 4.10.29.p
2815
-     */
2816
-    private function updateExistingTemplates(
2817
-        $GRP_ID,
2818
-        $messenger,
2819
-        $message_type,
2820
-        $context,
2821
-        array $form_data
2822
-    ) {
2823
-        $success         = false;
2824
-        $template_fields = $this->getTemplateFields();
2825
-        if ($template_fields) {
2826
-            // if field data is valid, then success will be true
2827
-            $success = $this->validateTemplateFields(
2828
-                $messenger,
2829
-                $message_type,
2830
-                $context,
2831
-                $template_fields
2832
-            );
2833
-            if ($success) {
2834
-                $field_data = [];
2835
-                foreach ($template_fields as $template_field => $content) {
2836
-                    // combine top-level form data with content for this field
2837
-                    $field_data = $this->getTemplateFieldFormData($content, $form_data);
2838
-                    $success    = $this->updateMessageTemplates($template_field, $field_data) ? $success : false;
2839
-                }
2840
-                // we can use the last set_column_values for the MTPG update
2841
-                // (because its the same for all of these specific MTPs)
2842
-                $success = $this->updateMessageTemplateGroup($field_data) ? $success : false;
2843
-            }
2844
-        }
2845
-
2846
-        return [
2847
-            $success,
2848
-            // 'query_args'
2849
-            [
2850
-                'id'      => $GRP_ID,
2851
-                'context' => $context,
2852
-                'action'  => 'edit_message_template',
2853
-            ],
2854
-        ];
2855
-    }
2856
-
2857
-
2858
-    /**
2859
-     * @return array
2860
-     * @since 4.10.29.p
2861
-     */
2862
-    private function getTemplateFields()
2863
-    {
2864
-        $template_fields = $this->request->getRequestParam('MTP_template_fields', null, 'html', true);
2865
-        if (empty($template_fields)) {
2866
-            EE_Error::add_error(
2867
-                esc_html__(
2868
-                    'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2869
-                    'event_espresso'
2870
-                ),
2871
-                __FILE__,
2872
-                __FUNCTION__,
2873
-                __LINE__
2874
-            );
2875
-            return null;
2876
-        }
2877
-        // messages content is expected to be escaped
2878
-        return EEH_Array::addSlashesRecursively($template_fields);
2879
-    }
2880
-
2881
-
2882
-    /**
2883
-     * @param string $messenger
2884
-     * @param string $message_type
2885
-     * @param string $context
2886
-     * @param array  $template_fields
2887
-     * @return bool
2888
-     * @throws EE_Error
2889
-     * @since   4.10.29.p
2890
-     */
2891
-    private function validateTemplateFields(
2892
-        $messenger,
2893
-        $message_type,
2894
-        $context,
2895
-        array $template_fields
2896
-    ) {
2897
-        // first validate all fields!
2898
-        // this filter allows client code to add its own validation to the template fields as well.
2899
-        // returning an empty array means everything passed validation.
2900
-        // errors in validation should be represented in an array with the following shape:
2901
-        // array(
2902
-        //   'fieldname' => array(
2903
-        //          'msg' => 'error message'
2904
-        //          'value' => 'value for field producing error'
2905
-        // )
2906
-        $custom_validation = (array) apply_filters(
2907
-            'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2908
-            [],
2909
-            $template_fields,
2910
-            $context,
2911
-            $messenger,
2912
-            $message_type
2913
-        );
2914
-
2915
-        $system_validation = $this->getMtgModel()->validate(
2916
-            $template_fields,
2917
-            $context,
2918
-            $messenger,
2919
-            $message_type
2920
-        );
2921
-
2922
-        $system_validation = ! is_array($system_validation) && $system_validation ? [] : $system_validation;
2923
-        $validates         = array_merge($custom_validation, $system_validation);
2924
-
2925
-        // if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2926
-        // appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2927
-        //  WE need to make sure there is no actual error messages in validates.
2928
-        if (empty($validates)) {
2929
-            return true;
2930
-        }
2931
-
2932
-        // add the transient so when the form loads we know which fields to highlight
2933
-        $this->_add_transient('edit_message_template', $validates);
2934
-        // setup notices
2935
-        foreach ($validates as $error) {
2936
-            if (isset($error['msg'])) {
2937
-                EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2938
-            }
2939
-        }
2940
-        return false;
2941
-    }
2942
-
2943
-
2944
-    /**
2945
-     * @param array $field_data
2946
-     * @param array $form_data
2947
-     * @return array
2948
-     * @since   4.10.29.p
2949
-     */
2950
-    private function getTemplateFieldFormData(array $field_data, array $form_data)
2951
-    {
2952
-        return $form_data + [
2953
-                'MTP_ID'             => $field_data['MTP_ID'],
2954
-                'MTP_template_field' => $field_data['name'],
2955
-                // if they aren't allowed to use all JS, restrict them to standard allowed post tags
2956
-                'MTP_content'        => ! current_user_can('unfiltered_html')
2957
-                    ? $this->sanitizeMessageTemplateContent($field_data['content'])
2958
-                    : $field_data['content'],
2959
-            ];
2960
-    }
2961
-
2962
-
2963
-    /**
2964
-     * @param string $template_field
2965
-     * @param array  $form_data
2966
-     * @return bool
2967
-     * @throws EE_Error
2968
-     * @since 4.10.29.p
2969
-     */
2970
-    private function updateMessageTemplates($template_field, array $form_data)
2971
-    {
2972
-        $MTP_ID                  = $form_data['MTP_ID'];
2973
-        $message_template_fields = [
2974
-            'GRP_ID'             => $form_data['GRP_ID'],
2975
-            'MTP_template_field' => $form_data['MTP_template_field'],
2976
-            'MTP_context'        => $form_data['MTP_context'],
2977
-            'MTP_content'        => $form_data['MTP_content'],
2978
-        ];
2979
-
2980
-        $hasMtpID = ! empty($MTP_ID);
2981
-        // if we have a MTP_ID for this field then update it, otherwise insert.
2982
-        // this has already been through the template field validator and sanitized, so it will be
2983
-        // safe to insert this field.  Why insert?  This typically happens when we introduce a new
2984
-        // message template field in a messenger/message type and existing users don't have the
2985
-        // default setup for it.
2986
-        // @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2987
-        $updated = $hasMtpID
2988
-            ? $this->getMtpModel()->update($message_template_fields, [['MTP_ID' => $MTP_ID]])
2989
-            : $this->getMtpModel()->insert($message_template_fields);
2990
-
2991
-        $insert_failed = ! $hasMtpID && ! $updated;
2992
-        // updates will return 0 if the field was not changed (ie: no changes = nothing actually updated)
2993
-        // but we won't consider that a problem, but if it returns false, then something went BOOM!
2994
-        $update_failed = $hasMtpID && $updated === false;
2995
-
2996
-        if ($insert_failed || $update_failed) {
2997
-            EE_Error::add_error(
2998
-                sprintf(
2999
-                    esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
3000
-                    $template_field
3001
-                ),
3002
-                __FILE__,
3003
-                __FUNCTION__,
3004
-                __LINE__
3005
-            );
3006
-            return false;
3007
-        }
3008
-        return true;
3009
-    }
3010
-
3011
-
3012
-    /**
3013
-     * @param array $form_data
3014
-     * @return bool
3015
-     * @throws EE_Error
3016
-     * @since 4.10.29.p
3017
-     */
3018
-    private function updateMessageTemplateGroup(array $form_data)
3019
-    {
3020
-        $GRP_ID  = $form_data['GRP_ID'];
3021
-        $updated = $this->getMtgModel()->update(
3022
-        // fields and values
3023
-            [
3024
-                'MTP_user_id'      => $form_data['MTP_user_id'],
3025
-                'MTP_messenger'    => $form_data['MTP_messenger'],
3026
-                'MTP_message_type' => $form_data['MTP_message_type'],
3027
-                'MTP_is_global'    => $form_data['MTP_is_global'],
3028
-                'MTP_is_override'  => $form_data['MTP_is_override'],
3029
-                'MTP_deleted'      => $form_data['MTP_deleted'],
3030
-                'MTP_is_active'    => $form_data['MTP_is_active'],
3031
-                'MTP_name'         => $this->request->getRequestParam('ee_msg_non_global_fields[MTP_name]', ''),
3032
-                'MTP_description'  => $this->request->getRequestParam(
3033
-                    'ee_msg_non_global_fields[MTP_description]',
3034
-                    ''
3035
-                ),
3036
-            ],
3037
-            // where
3038
-            [['GRP_ID' => $GRP_ID]]
3039
-        );
3040
-
3041
-        if ($updated === false) {
3042
-            EE_Error::add_error(
3043
-                sprintf(
3044
-                    esc_html__(
3045
-                        'The Message Template Group (%d) was NOT updated for some reason',
3046
-                        'event_espresso'
3047
-                    ),
3048
-                    $form_data['GRP_ID']
3049
-                ),
3050
-                __FILE__,
3051
-                __FUNCTION__,
3052
-                __LINE__
3053
-            );
3054
-            return false;
3055
-        }
3056
-        // k now we need to ensure the template_pack and template_variation fields are set.
3057
-        $template_pack      = $this->request->getRequestParam('MTP_template_pack', 'default');
3058
-        $template_variation = $this->request->getRequestParam('MTP_template_variation', 'default');
3059
-
3060
-        $message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3061
-        if ($message_template_group instanceof EE_Message_Template_Group) {
3062
-            $message_template_group->set_template_pack_name($template_pack);
3063
-            $message_template_group->set_template_pack_variation($template_variation);
3064
-        }
3065
-        return true;
3066
-    }
3067
-
3068
-
3069
-    /**
3070
-     * recursively runs wp_kses() on message template content in a model safe manner
3071
-     *
3072
-     * @param array|string $content
3073
-     * @return array|string
3074
-     * @since   4.10.29.p
3075
-     */
3076
-    private function sanitizeMessageTemplateContent($content)
3077
-    {
3078
-        if (is_array($content)) {
3079
-            foreach ($content as $key => $value) {
3080
-                $content[ $key ] = $this->sanitizeMessageTemplateContent($value);
3081
-            }
3082
-            return $content;
3083
-        }
3084
-        // remove slashes so wp_kses() works properly
3085
-        // wp_kses_stripslashes() only removes slashes from double-quotes,
3086
-        // so attributes using single quotes always appear invalid.
3087
-        $content = stripslashes($content);
3088
-        $content = wp_kses($content, wp_kses_allowed_html('post'));
3089
-        // But currently the models expect slashed data, so after wp_kses()
3090
-        // runs we need to re-slash the data. Sheesh.
3091
-        // See https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
3092
-        return addslashes($content);
3093
-    }
3094
-
3095
-
3096
-    /**
3097
-     * @param string $messenger
3098
-     * @param string $message_type
3099
-     * @param string $context
3100
-     * @return string
3101
-     * @since 4.10.29.p
3102
-     */
3103
-    private function generateUpdateDescription($messenger, $message_type, $context)
3104
-    {
3105
-        // need the message type and messenger objects to be able to use the labels for the notices
3106
-        $messenger_object = $this->_message_resource_manager->get_messenger($messenger);
3107
-        $messenger_label  = $messenger_object instanceof EE_messenger
3108
-            ? ucwords($messenger_object->label['singular'])
3109
-            : '';
3110
-
3111
-        $message_type_object = $this->_message_resource_manager->get_message_type($message_type);
3112
-        $message_type_label  = $message_type_object instanceof EE_message_type
3113
-            ? ucwords($message_type_object->label['singular'])
3114
-            : '';
3115
-
3116
-        $context   = ucwords(str_replace('_', ' ', $context));
3117
-        $item_desc = $messenger_label && $message_type_label
3118
-            ? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
3119
-            : '';
3120
-        $item_desc .= 'Message Template';
3121
-        return $item_desc;
3122
-    }
3123
-
3124
-
3125
-    /**
3126
-     * @param string $messenger
3127
-     * @param string $message_type
3128
-     * @param string $context
3129
-     * @return bool
3130
-     * @throws EE_Error
3131
-     * @throws ReflectionException
3132
-     * @since 4.10.29.p
3133
-     */
3134
-    private function performTestSendAfterUpdate($messenger, $message_type, $context)
3135
-    {
3136
-        // was a test send triggered?
3137
-        if ($this->request->requestParamIsSet('test_button')) {
3138
-            EE_Error::overwrite_success();
3139
-            $this->_do_test_send($context, $messenger, $message_type);
3140
-            return true;
3141
-        }
3142
-        return false;
3143
-    }
3144
-
3145
-
3146
-    /**
3147
-     * processes a test send request to do an actual messenger delivery test for the given message template being tested
3148
-     *
3149
-     * @param string $context      what context being tested
3150
-     * @param string $messenger    messenger being tested
3151
-     * @param string $message_type message type being tested
3152
-     * @throws EE_Error
3153
-     * @throws InvalidArgumentException
3154
-     * @throws InvalidDataTypeException
3155
-     * @throws InvalidInterfaceException
3156
-     * @throws ReflectionException
3157
-     */
3158
-    protected function _do_test_send($context, $messenger, $message_type)
3159
-    {
3160
-        // set things up for preview
3161
-        $this->request->setRequestParam('messenger', $messenger);
3162
-        $this->request->setRequestParam('message_type', $message_type);
3163
-        $this->request->setRequestParam('context', $context);
3164
-        $GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
3165
-        $this->request->setRequestParam('GRP_ID', $GRP_ID);
3166
-
3167
-        $active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
3168
-        $test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
3169
-
3170
-        // let's save any existing fields that might be required by the messenger
3171
-        if (
3172
-            ! empty($test_settings_fld)
3173
-            && $active_messenger instanceof EE_messenger
3174
-            && apply_filters(
3175
-                'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3176
-                true,
3177
-                $test_settings_fld,
3178
-                $active_messenger
3179
-            )
3180
-        ) {
3181
-            $active_messenger->set_existing_test_settings($test_settings_fld);
3182
-        }
3183
-
3184
-        /**
3185
-         * Use filter to add additional controls on whether message can send or not
3186
-         */
3187
-        if (
3188
-            apply_filters(
3189
-                'FHEE__Messages_Admin_Page__do_test_send__can_send',
3190
-                true,
3191
-                $context,
3192
-                $this->request->requestParams(),
3193
-                $messenger,
3194
-                $message_type
3195
-            )
3196
-        ) {
3197
-            if (EEM_Event::instance()->count() > 0) {
3198
-                $success = $this->_preview_message(true);
3199
-                if ($success) {
3200
-                    EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3201
-                } else {
3202
-                    EE_Error::add_error(
3203
-                        esc_html__('The test message was not sent', 'event_espresso'),
3204
-                        __FILE__,
3205
-                        __FUNCTION__,
3206
-                        __LINE__
3207
-                    );
3208
-                }
3209
-            } else {
3210
-                $this->noEventsErrorMessage(true);
3211
-            }
3212
-        }
3213
-    }
3214
-
3215
-
3216
-    /**
3217
-     * _generate_new_templates
3218
-     * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3219
-     * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3220
-     * for the event.
3221
-     *
3222
-     *
3223
-     * @param string $messenger      the messenger we are generating templates for
3224
-     * @param array  $message_types  array of message types that the templates are generated for.
3225
-     * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3226
-     *                               indicate the message_template_group being used as the base.
3227
-     *
3228
-     * @param bool   $global
3229
-     *
3230
-     * @return array|bool array of data required for the redirect to the correct edit page or bool if
3231
-     *                               encountering problems.
3232
-     * @throws EE_Error
3233
-     * @throws ReflectionException
3234
-     */
3235
-    protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3236
-    {
3237
-        // if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3238
-        // just don't generate any templates.
3239
-        if (empty($message_types)) {
3240
-            return [];
3241
-        }
3242
-
3243
-        $templates = EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3244
-        return $templates[0];
3245
-    }
3246
-
3247
-
3248
-    /**
3249
-     * [_trash_or_restore_message_template]
3250
-     *
3251
-     * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3252
-     * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3253
-     *                        an individual context (FALSE).
3254
-     * @return void
3255
-     * @throws EE_Error
3256
-     * @throws InvalidArgumentException
3257
-     * @throws InvalidDataTypeException
3258
-     * @throws InvalidInterfaceException
3259
-     */
3260
-    protected function _trash_or_restore_message_template($trash = true, $all = false)
3261
-    {
3262
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3263
-
3264
-        $success = 1;
3265
-
3266
-        // incoming GRP_IDs
3267
-        if ($all) {
3268
-            // Checkboxes
3269
-            $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3270
-            if (! empty($checkboxes)) {
3271
-                // if array has more than one element then success message should be plural.
3272
-                // todo: what about nonce?
3273
-                $success = count($checkboxes) > 1 ? 2 : 1;
3274
-
3275
-                // cycle through checkboxes
3276
-                while (list($GRP_ID, $value) = each($checkboxes)) {
3277
-                    $trashed_or_restored = $trash
3278
-                        ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3279
-                        : $this->getMtgModel()->restore_by_ID($GRP_ID);
3280
-                    if (! $trashed_or_restored) {
3281
-                        $success = 0;
3282
-                    }
3283
-                }
3284
-            } else {
3285
-                // grab single GRP_ID and handle
3286
-                $GRP_ID = $this->request->getRequestParam('id', 0, 'int');
3287
-                if (! empty($GRP_ID)) {
3288
-                    $trashed_or_restored = $trash
3289
-                        ? $this->getMtgModel()->delete_by_ID($GRP_ID)
3290
-                        : $this->getMtgModel()->restore_by_ID($GRP_ID);
3291
-                    if (! $trashed_or_restored) {
3292
-                        $success = 0;
3293
-                    }
3294
-                } else {
3295
-                    $success = 0;
3296
-                }
3297
-            }
3298
-        }
3299
-
3300
-        $action_desc = $trash
3301
-            ? esc_html__('moved to the trash', 'event_espresso')
3302
-            : esc_html__('restored', 'event_espresso');
3303
-
3304
-        $template_switch = $this->request->getRequestParam('template_switch', false, 'bool');
3305
-        $action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
3306
-
3307
-        $item_desc = $all ? _n(
3308
-            'Message Template Group',
3309
-            'Message Template Groups',
3310
-            $success,
3311
-            'event_espresso'
3312
-        ) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3313
-
3314
-        $item_desc = $template_switch
3315
-            ? _n('template', 'templates', $success, 'event_espresso')
3316
-            : $item_desc;
3317
-
3318
-        $this->_redirect_after_action($success, $item_desc, $action_desc, []);
3319
-    }
3320
-
3321
-
3322
-    /**
3323
-     * [_delete_message_template]
3324
-     * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3325
-     *
3326
-     * @return void
3327
-     * @throws EE_Error
3328
-     * @throws InvalidArgumentException
3329
-     * @throws InvalidDataTypeException
3330
-     * @throws InvalidInterfaceException
3331
-     * @throws ReflectionException
3332
-     */
3333
-    protected function _delete_message_template()
3334
-    {
3335
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3336
-
3337
-        // checkboxes
3338
-        $checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3339
-        if (! empty($checkboxes)) {
3340
-            // if array has more than one element then success message should be plural
3341
-            $success = count($checkboxes) > 1 ? 2 : 1;
3342
-
3343
-            // cycle through bulk action checkboxes
3344
-            while (list($GRP_ID, $value) = each($checkboxes)) {
3345
-                $success = $this->_delete_mtp_permanently($GRP_ID) ? $success : false;
3346
-            }
3347
-        } else {
3348
-            // grab single grp_id and delete
3349
-            $GRP_ID  = $this->request->getRequestParam('id', 0, 'int');
3350
-            $success = $this->_delete_mtp_permanently($GRP_ID);
3351
-        }
3352
-
3353
-        $this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3354
-    }
3355
-
3356
-
3357
-    /**
3358
-     * helper for permanently deleting a mtP group and all related message_templates
3359
-     *
3360
-     * @param int  $GRP_ID        The group being deleted
3361
-     * @param bool $include_group whether to delete the Message Template Group as well.
3362
-     * @return bool boolean to indicate the success of the deletes or not.
3363
-     * @throws EE_Error
3364
-     * @throws InvalidArgumentException
3365
-     * @throws InvalidDataTypeException
3366
-     * @throws InvalidInterfaceException
3367
-     * @throws ReflectionException
3368
-     * @throws ReflectionException
3369
-     */
3370
-    private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3371
-    {
3372
-        $success = true;
3373
-        // first let's GET this group
3374
-        $MTG = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3375
-        // then delete permanently all the related Message Templates
3376
-        $deleted = $MTG->delete_related_permanently('Message_Template');
3377
-
3378
-        if ($deleted === 0) {
3379
-            $success = false;
3380
-        }
3381
-
3382
-        // now delete permanently this particular group
3383
-
3384
-        if ($include_group && ! $MTG->delete_permanently()) {
3385
-            $success = false;
3386
-        }
3387
-
3388
-        return $success;
3389
-    }
3390
-
3391
-
3392
-    /**
3393
-     *    _learn_more_about_message_templates_link
3394
-     *
3395
-     * @access protected
3396
-     * @return string
3397
-     */
3398
-    protected function _learn_more_about_message_templates_link()
3399
-    {
3400
-        return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3401
-               . esc_html__('learn more about how message templates works', 'event_espresso')
3402
-               . '</a>';
3403
-    }
3404
-
3405
-
3406
-    /**
3407
-     * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3408
-     * ajax and other routes.
3409
-     *
3410
-     * @return void
3411
-     * @throws DomainException
3412
-     * @throws EE_Error
3413
-     */
3414
-    protected function _settings()
3415
-    {
3416
-        $this->_set_m_mt_settings();
3417
-
3418
-        // let's setup the messenger tabs
3419
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3420
-            $this->_m_mt_settings['messenger_tabs'],
3421
-            'messenger_links',
3422
-            '|',
3423
-            $this->request->getRequestParam('selected_messenger', 'email')
3424
-        );
3425
-
3426
-        $this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3427
-        $this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3428
-
3429
-        $this->display_admin_page_with_sidebar();
3430
-    }
3431
-
3432
-
3433
-    /**
3434
-     * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3435
-     *
3436
-     * @access protected
3437
-     * @return void
3438
-     * @throws DomainException
3439
-     */
3440
-    protected function _set_m_mt_settings()
3441
-    {
3442
-        // first if this is already set then lets get out no need to regenerate data.
3443
-        if (! empty($this->_m_mt_settings)) {
3444
-            return;
3445
-        }
3446
-
3447
-        // get all installed messengers and message_types
3448
-        $messengers    = $this->_message_resource_manager->installed_messengers();
3449
-        $message_types = $this->_message_resource_manager->installed_message_types();
3450
-
3451
-
3452
-        // assemble the array for the _tab_text_links helper
3453
-
3454
-        foreach ($messengers as $messenger) {
3455
-            $this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3456
-                'label' => ucwords($messenger->label['singular']),
3457
-                'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3458
-                    ? 'messenger-active'
3459
-                    : '',
3460
-                'href'  => $messenger->name,
3461
-                'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3462
-                'slug'  => $messenger->name,
3463
-                'obj'   => $messenger,
3464
-            ];
3465
-
3466
-
3467
-            $message_types_for_messenger = $messenger->get_valid_message_types();
3468
-
3469
-            foreach ($message_types as $message_type) {
3470
-                // first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3471
-                // it shouldn't show in either the inactive OR active metabox.
3472
-                if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3473
-                    continue;
3474
-                }
3475
-
3476
-                $a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3477
-                    $messenger->name,
3478
-                    $message_type->name
3479
-                )
3480
-                    ? 'active'
3481
-                    : 'inactive';
3482
-
3483
-                $this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3484
-                    'label'    => ucwords($message_type->label['singular']),
3485
-                    'class'    => 'message-type-' . $a_or_i,
3486
-                    'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3487
-                    'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3488
-                    'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3489
-                    'title'    => $a_or_i === 'active'
3490
-                        ? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3491
-                        : esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3492
-                    'content'  => $a_or_i === 'active'
3493
-                        ? $this->_message_type_settings_content($message_type, $messenger, true)
3494
-                        : $this->_message_type_settings_content($message_type, $messenger),
3495
-                    'slug'     => $message_type->name,
3496
-                    'active'   => $a_or_i === 'active',
3497
-                    'obj'      => $message_type,
3498
-                ];
3499
-            }
3500
-        }
3501
-    }
3502
-
3503
-
3504
-    /**
3505
-     * This just prepares the content for the message type settings
3506
-     *
3507
-     * @param EE_message_type $message_type The message type object
3508
-     * @param EE_messenger    $messenger    The messenger object
3509
-     * @param boolean         $active       Whether the message type is active or not
3510
-     * @return string html output for the content
3511
-     * @throws DomainException
3512
-     */
3513
-    protected function _message_type_settings_content($message_type, $messenger, $active = false)
3514
-    {
3515
-        // get message type fields
3516
-        $fields                                         = $message_type->get_admin_settings_fields();
3517
-        $settings_template_args['template_form_fields'] = '';
3518
-
3519
-        if (! empty($fields) && $active) {
3520
-            $existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3521
-            foreach ($fields as $fldname => $fldprops) {
3522
-                $field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3523
-                $template_form_field[ $field_id ] = [
3524
-                    'name'       => 'message_type_settings[' . $fldname . ']',
3525
-                    'label'      => $fldprops['label'],
3526
-                    'input'      => $fldprops['field_type'],
3527
-                    'type'       => $fldprops['value_type'],
3528
-                    'required'   => $fldprops['required'],
3529
-                    'validation' => $fldprops['validation'],
3530
-                    'value'      => isset($existing_settings[ $fldname ])
3531
-                        ? $existing_settings[ $fldname ]
3532
-                        : $fldprops['default'],
3533
-                    'options'    => isset($fldprops['options'])
3534
-                        ? $fldprops['options']
3535
-                        : [],
3536
-                    'default'    => isset($existing_settings[ $fldname ])
3537
-                        ? $existing_settings[ $fldname ]
3538
-                        : $fldprops['default'],
3539
-                    'css_class'  => 'no-drag',
3540
-                    'format'     => $fldprops['format'],
3541
-                ];
3542
-            }
3543
-
3544
-
3545
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3546
-                ? $this->_generate_admin_form_fields(
3547
-                    $template_form_field,
3548
-                    'string',
3549
-                    'ee_mt_activate_form'
3550
-                )
3551
-                : '';
3552
-        }
3553
-
3554
-        $settings_template_args['description'] = $message_type->description;
3555
-        // we also need some hidden fields
3556
-        $hidden_fields = [
3557
-            'message_type_settings[messenger]' . $message_type->name    => [
3558
-                'type'  => 'hidden',
3559
-                'value' => $messenger->name,
3560
-            ],
3561
-            'message_type_settings[message_type]' . $message_type->name => [
3562
-                'type'  => 'hidden',
3563
-                'value' => $message_type->name,
3564
-            ],
3565
-            'type' . $message_type->name                                => [
3566
-                'type'  => 'hidden',
3567
-                'value' => 'message_type',
3568
-            ],
3569
-        ];
3570
-
3571
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3572
-            $hidden_fields,
3573
-            'array'
3574
-        );
3575
-        $settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3576
-            ? ' hidden'
3577
-            : '';
3578
-
3579
-
3580
-        $template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3581
-        return EEH_Template::display_template($template, $settings_template_args, true);
3582
-    }
3583
-
3584
-
3585
-    /**
3586
-     * Generate all the metaboxes for the message types and register them for the messages settings page.
3587
-     *
3588
-     * @access protected
3589
-     * @return void
3590
-     * @throws DomainException
3591
-     */
3592
-    protected function _messages_settings_metaboxes()
3593
-    {
3594
-        $this->_set_m_mt_settings();
3595
-        $m_boxes         = $mt_boxes = [];
3596
-        $m_template_args = $mt_template_args = [];
3597
-
3598
-        $selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3599
-
3600
-        if (isset($this->_m_mt_settings['messenger_tabs'])) {
3601
-            foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3602
-                $is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3603
-                $hide_on_message     = $is_messenger_active ? '' : 'hidden';
3604
-                $hide_off_message    = $is_messenger_active ? 'hidden' : '';
3605
-
3606
-                // messenger meta boxes
3607
-                $active         = $selected_messenger === $messenger;
3608
-                $active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'])
3609
-                    ? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3610
-                    : '';
3611
-
3612
-                $m_boxes[ $messenger . '_a_box' ] = sprintf(
3613
-                    esc_html__('%s Settings', 'event_espresso'),
3614
-                    $tab_array['label']
3615
-                );
3616
-
3617
-                $m_template_args[ $messenger . '_a_box' ] = [
3618
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3619
-                    'inactive_message_types' => isset(
3620
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3621
-                    )
3622
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3623
-                        : '',
3624
-                    'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3625
-                    'hidden'                 => $active ? '' : ' hidden',
3626
-                    'hide_on_message'        => $hide_on_message,
3627
-                    'messenger'              => $messenger,
3628
-                    'active'                 => $active,
3629
-                ];
3630
-
3631
-                // message type meta boxes
3632
-                // (which is really just the inactive container for each messenger
3633
-                // showing inactive message types for that messenger)
3634
-                $mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3635
-                $mt_template_args[ $messenger . '_i_box' ] = [
3636
-                    'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3637
-                    'inactive_message_types' => isset(
3638
-                        $this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3639
-                    )
3640
-                        ? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3641
-                        : '',
3642
-                    'hidden'                 => $active ? '' : ' hidden',
3643
-                    'hide_on_message'        => $hide_on_message,
3644
-                    'hide_off_message'       => $hide_off_message,
3645
-                    'messenger'              => $messenger,
3646
-                    'active'                 => $active,
3647
-                ];
3648
-            }
3649
-        }
3650
-
3651
-
3652
-        // register messenger metaboxes
3653
-        $m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3654
-        foreach ($m_boxes as $box => $label) {
3655
-            $callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3656
-            $msgr          = str_replace('_a_box', '', $box);
3657
-            add_meta_box(
3658
-                'espresso_' . $msgr . '_settings',
3659
-                $label,
3660
-                function ($post, $metabox) {
3661
-                    EEH_Template::display_template(
3662
-                        $metabox['args']['template_path'],
3663
-                        $metabox['args']['template_args']
3664
-                    );
3665
-                },
3666
-                $this->_current_screen->id,
3667
-                'normal',
3668
-                'high',
3669
-                $callback_args
3670
-            );
3671
-        }
3672
-
3673
-        // register message type metaboxes
3674
-        $mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3675
-        foreach ($mt_boxes as $box => $label) {
3676
-            $callback_args = [
3677
-                'template_path' => $mt_template_path,
3678
-                'template_args' => $mt_template_args[ $box ],
3679
-            ];
3680
-            $mt            = str_replace('_i_box', '', $box);
3681
-            add_meta_box(
3682
-                'espresso_' . $mt . '_inactive_mts',
3683
-                $label,
3684
-                function ($post, $metabox) {
3685
-                    EEH_Template::display_template(
3686
-                        $metabox['args']['template_path'],
3687
-                        $metabox['args']['template_args']
3688
-                    );
3689
-                },
3690
-                $this->_current_screen->id,
3691
-                'side',
3692
-                'high',
3693
-                $callback_args
3694
-            );
3695
-        }
3696
-
3697
-        // register metabox for global messages settings but only when on the main site.  On single site installs this
3698
-        // will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3699
-        if (is_main_site()) {
3700
-            add_meta_box(
3701
-                'espresso_global_message_settings',
3702
-                esc_html__('Global Message Settings', 'event_espresso'),
3703
-                [$this, 'global_messages_settings_metabox_content'],
3704
-                $this->_current_screen->id,
3705
-                'normal',
3706
-                'low',
3707
-                []
3708
-            );
3709
-        }
3710
-    }
3711
-
3712
-
3713
-    /**
3714
-     *  This generates the content for the global messages settings metabox.
3715
-     *
3716
-     * @return void
3717
-     * @throws EE_Error
3718
-     * @throws InvalidArgumentException
3719
-     * @throws ReflectionException
3720
-     * @throws InvalidDataTypeException
3721
-     * @throws InvalidInterfaceException
3722
-     */
3723
-    public function global_messages_settings_metabox_content()
3724
-    {
3725
-        $form = $this->_generate_global_settings_form();
3726
-        // already escaped
3727
-        echo $form->form_open(
3728
-            $this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3729
-            'POST'
3730
-        );
3731
-        echo $form->get_html();
3732
-        echo $form->form_close();
3733
-    }
3734
-
3735
-
3736
-    /**
3737
-     * This generates and returns the form object for the global messages settings.
3738
-     *
3739
-     * @return EE_Form_Section_Proper
3740
-     * @throws EE_Error
3741
-     * @throws InvalidArgumentException
3742
-     * @throws ReflectionException
3743
-     * @throws InvalidDataTypeException
3744
-     * @throws InvalidInterfaceException
3745
-     */
3746
-    protected function _generate_global_settings_form()
3747
-    {
3748
-        /** @var EE_Network_Core_Config $network_config */
3749
-        $network_config = EE_Registry::instance()->NET_CFG->core;
3750
-
3751
-        return new EE_Form_Section_Proper(
3752
-            [
3753
-                'name'            => 'global_messages_settings',
3754
-                'html_id'         => 'global_messages_settings',
3755
-                'html_class'      => 'form-table',
3756
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3757
-                'subsections'     => apply_filters(
3758
-                    'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3759
-                    [
3760
-                        'do_messages_on_same_request' => new EE_Select_Input(
3761
-                            [
3762
-                                true  => esc_html__('On the same request', 'event_espresso'),
3763
-                                false => esc_html__('On a separate request', 'event_espresso'),
3764
-                            ],
3765
-                            [
3766
-                                'default'         => $network_config->do_messages_on_same_request,
3767
-                                'html_label_text' => esc_html__(
3768
-                                    'Generate and send all messages:',
3769
-                                    'event_espresso'
3770
-                                ),
3771
-                                'html_help_text'  => esc_html__(
3772
-                                    '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.',
3773
-                                    'event_espresso'
3774
-                                ),
3775
-                            ]
3776
-                        ),
3777
-                        'delete_threshold'            => new EE_Select_Input(
3778
-                            [
3779
-                                0  => esc_html__('Forever', 'event_espresso'),
3780
-                                3  => esc_html__('3 Months', 'event_espresso'),
3781
-                                6  => esc_html__('6 Months', 'event_espresso'),
3782
-                                9  => esc_html__('9 Months', 'event_espresso'),
3783
-                                12 => esc_html__('12 Months', 'event_espresso'),
3784
-                                24 => esc_html__('24 Months', 'event_espresso'),
3785
-                                36 => esc_html__('36 Months', 'event_espresso'),
3786
-                            ],
3787
-                            [
3788
-                                'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3789
-                                'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3790
-                                'html_help_text'  => esc_html__(
3791
-                                    'You can control how long a record of processed messages is kept via this option.',
3792
-                                    'event_espresso'
3793
-                                ),
3794
-                            ]
3795
-                        ),
3796
-                        'update_settings'             => new EE_Submit_Input(
3797
-                            [
3798
-                                'default'         => esc_html__('Update', 'event_espresso'),
3799
-                                'html_label_text' => '&nbsp',
3800
-                            ]
3801
-                        ),
3802
-                    ]
3803
-                ),
3804
-            ]
3805
-        );
3806
-    }
3807
-
3808
-
3809
-    /**
3810
-     * This handles updating the global settings set on the admin page.
3811
-     *
3812
-     * @throws EE_Error
3813
-     * @throws InvalidDataTypeException
3814
-     * @throws InvalidInterfaceException
3815
-     * @throws InvalidArgumentException
3816
-     * @throws ReflectionException
3817
-     */
3818
-    protected function _update_global_settings()
3819
-    {
3820
-        /** @var EE_Network_Core_Config $network_config */
3821
-        $network_config  = EE_Registry::instance()->NET_CFG->core;
3822
-        $messages_config = EE_Registry::instance()->CFG->messages;
3823
-        $form            = $this->_generate_global_settings_form();
3824
-        if ($form->was_submitted()) {
3825
-            $form->receive_form_submission();
3826
-            if ($form->is_valid()) {
3827
-                $valid_data = $form->valid_data();
3828
-                foreach ($valid_data as $property => $value) {
3829
-                    $setter = 'set_' . $property;
3830
-                    if (method_exists($network_config, $setter)) {
3831
-                        $network_config->{$setter}($value);
3832
-                    } elseif (
3833
-                        property_exists($network_config, $property)
3834
-                        && $network_config->{$property} !== $value
3835
-                    ) {
3836
-                        $network_config->{$property} = $value;
3837
-                    } elseif (
3838
-                        property_exists($messages_config, $property)
3839
-                        && $messages_config->{$property} !== $value
3840
-                    ) {
3841
-                        $messages_config->{$property} = $value;
3842
-                    }
3843
-                }
3844
-                // only update if the form submission was valid!
3845
-                EE_Registry::instance()->NET_CFG->update_config(true, false);
3846
-                EE_Registry::instance()->CFG->update_espresso_config();
3847
-                EE_Error::overwrite_success();
3848
-                EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3849
-            }
3850
-        }
3851
-        $this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3852
-    }
3853
-
3854
-
3855
-    /**
3856
-     * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3857
-     *
3858
-     * @param array $tab_array This is an array of message type tab details used to generate the tabs
3859
-     * @return string html formatted tabs
3860
-     * @throws DomainException
3861
-     */
3862
-    protected function _get_mt_tabs($tab_array)
3863
-    {
3864
-        $tab_array = (array) $tab_array;
3865
-        $template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3866
-        $tabs      = '';
3867
-
3868
-        foreach ($tab_array as $tab) {
3869
-            $tabs .= EEH_Template::display_template($template, $tab, true);
3870
-        }
3871
-
3872
-        return $tabs;
3873
-    }
3874
-
3875
-
3876
-    /**
3877
-     * This prepares the content of the messenger meta box admin settings
3878
-     *
3879
-     * @param EE_messenger $messenger The messenger we're setting up content for
3880
-     * @return string html formatted content
3881
-     * @throws DomainException
3882
-     */
3883
-    protected function _get_messenger_box_content(EE_messenger $messenger)
3884
-    {
3885
-
3886
-        $fields                                         = $messenger->get_admin_settings_fields();
3887
-        $settings_template_args['template_form_fields'] = '';
3888
-
3889
-        // is $messenger active?
3890
-        $settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3891
-
3892
-
3893
-        if (! empty($fields)) {
3894
-            $existing_settings = $messenger->get_existing_admin_settings();
3895
-
3896
-            foreach ($fields as $fldname => $fldprops) {
3897
-                $field_id                         = $messenger->name . '-' . $fldname;
3898
-                $template_form_field[ $field_id ] = [
3899
-                    'name'       => 'messenger_settings[' . $field_id . ']',
3900
-                    'label'      => $fldprops['label'],
3901
-                    'input'      => $fldprops['field_type'],
3902
-                    'type'       => $fldprops['value_type'],
3903
-                    'required'   => $fldprops['required'],
3904
-                    'validation' => $fldprops['validation'],
3905
-                    'value'      => isset($existing_settings[ $field_id ])
3906
-                        ? $existing_settings[ $field_id ]
3907
-                        : $fldprops['default'],
3908
-                    'css_class'  => '',
3909
-                    'format'     => $fldprops['format'],
3910
-                ];
3911
-            }
3912
-
3913
-
3914
-            $settings_template_args['template_form_fields'] = ! empty($template_form_field)
3915
-                ? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3916
-                : '';
3917
-        }
3918
-
3919
-        // we also need some hidden fields
3920
-        $settings_template_args['hidden_fields'] = [
3921
-            'messenger_settings[messenger]' . $messenger->name => [
3922
-                'type'  => 'hidden',
3923
-                'value' => $messenger->name,
3924
-            ],
3925
-            'type' . $messenger->name                          => [
3926
-                'type'  => 'hidden',
3927
-                'value' => 'messenger',
3928
-            ],
3929
-        ];
3930
-
3931
-        // make sure any active message types that are existing are included in the hidden fields
3932
-        if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3933
-            foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3934
-                $settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3935
-                    'type'  => 'hidden',
3936
-                    'value' => $mt,
3937
-                ];
3938
-            }
3939
-        }
3940
-        $settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3941
-            $settings_template_args['hidden_fields'],
3942
-            'array'
3943
-        );
3944
-        $active                                  =
3945
-            $this->_message_resource_manager->is_messenger_active($messenger->name);
3946
-
3947
-        $settings_template_args['messenger']           = $messenger->name;
3948
-        $settings_template_args['description']         = $messenger->description;
3949
-        $settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3950
-
3951
-
3952
-        $settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3953
-            $messenger->name
3954
-        )
3955
-            ? $settings_template_args['show_hide_edit_form']
3956
-            : ' hidden';
3957
-
3958
-        $settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3959
-            ? ' hidden'
3960
-            : $settings_template_args['show_hide_edit_form'];
3961
-
3962
-
3963
-        $settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3964
-        $settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3965
-        $settings_template_args['on_off_status'] = $active;
3966
-        $template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3967
-        return EEH_Template::display_template(
3968
-            $template,
3969
-            $settings_template_args,
3970
-            true
3971
-        );
3972
-    }
3973
-
3974
-
3975
-    /**
3976
-     * used by ajax on the messages settings page to activate|deactivate the messenger
3977
-     *
3978
-     * @throws DomainException
3979
-     * @throws EE_Error
3980
-     * @throws InvalidDataTypeException
3981
-     * @throws InvalidInterfaceException
3982
-     * @throws InvalidArgumentException
3983
-     * @throws ReflectionException
3984
-     */
3985
-    public function activate_messenger_toggle()
3986
-    {
3987
-        $success = true;
3988
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
3989
-        // let's check that we have required data
3990
-
3991
-        if (! $this->_active_messenger_name) {
3992
-            EE_Error::add_error(
3993
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3994
-                __FILE__,
3995
-                __FUNCTION__,
3996
-                __LINE__
3997
-            );
3998
-            $success = false;
3999
-        }
4000
-
4001
-        // do a nonce check here since we're not arriving via a normal route
4002
-        $nonce     = $this->request->getRequestParam('activate_nonce', '');
4003
-        $nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
4004
-
4005
-        $this->_verify_nonce($nonce, $nonce_ref);
4006
-
4007
-
4008
-        $status = $this->request->getRequestParam('status');
4009
-        if (! $status) {
4010
-            EE_Error::add_error(
4011
-                esc_html__(
4012
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4013
-                    'event_espresso'
4014
-                ),
4015
-                __FILE__,
4016
-                __FUNCTION__,
4017
-                __LINE__
4018
-            );
4019
-            $success = false;
4020
-        }
4021
-
4022
-        // do check to verify we have a valid status.
4023
-        if ($status !== 'off' && $status !== 'on') {
4024
-            EE_Error::add_error(
4025
-                sprintf(
4026
-                    esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
4027
-                    $status
4028
-                ),
4029
-                __FILE__,
4030
-                __FUNCTION__,
4031
-                __LINE__
4032
-            );
4033
-            $success = false;
4034
-        }
4035
-
4036
-        if ($success) {
4037
-            // made it here?  Stop dawdling then!!
4038
-            $success = $status === 'off'
4039
-                ? $this->_deactivate_messenger($this->_active_messenger_name)
4040
-                : $this->_activate_messenger($this->_active_messenger_name);
4041
-        }
4042
-
4043
-        $this->_template_args['success'] = $success;
4044
-
4045
-        // no special instructions so let's just do the json return (which should automatically do all the special stuff).
4046
-        $this->_return_json();
4047
-    }
4048
-
4049
-
4050
-    /**
4051
-     * used by ajax from the messages settings page to activate|deactivate a message type
4052
-     *
4053
-     * @throws DomainException
4054
-     * @throws EE_Error
4055
-     * @throws ReflectionException
4056
-     * @throws InvalidDataTypeException
4057
-     * @throws InvalidInterfaceException
4058
-     * @throws InvalidArgumentException
4059
-     */
4060
-    public function activate_mt_toggle()
4061
-    {
4062
-        $success = true;
4063
-        $this->_prep_default_response_for_messenger_or_message_type_toggle();
4064
-
4065
-        // let's make sure we have the necessary data
4066
-        if (! $this->_active_message_type_name) {
4067
-            EE_Error::add_error(
4068
-                esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
4069
-                __FILE__,
4070
-                __FUNCTION__,
4071
-                __LINE__
4072
-            );
4073
-            $success = false;
4074
-        }
4075
-
4076
-        if (! $this->_active_messenger_name) {
4077
-            EE_Error::add_error(
4078
-                esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
4079
-                __FILE__,
4080
-                __FUNCTION__,
4081
-                __LINE__
4082
-            );
4083
-            $success = false;
4084
-        }
4085
-
4086
-        $status = $this->request->getRequestParam('status');
4087
-        if (! $status) {
4088
-            EE_Error::add_error(
4089
-                esc_html__(
4090
-                    'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4091
-                    'event_espresso'
4092
-                ),
4093
-                __FILE__,
4094
-                __FUNCTION__,
4095
-                __LINE__
4096
-            );
4097
-            $success = false;
4098
-        }
4099
-
4100
-
4101
-        // do check to verify we have a valid status.
4102
-        if ($status !== 'activate' && $status !== 'deactivate') {
4103
-            EE_Error::add_error(
4104
-                sprintf(
4105
-                    esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
4106
-                    $status
4107
-                ),
4108
-                __FILE__,
4109
-                __FUNCTION__,
4110
-                __LINE__
4111
-            );
4112
-            $success = false;
4113
-        }
4114
-
4115
-
4116
-        // do a nonce check here since we're not arriving via a normal route
4117
-        $nonce = $this->request->getRequestParam('mt_nonce', '');
4118
-        $this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
4119
-
4120
-        if ($success) {
4121
-            // made it here? um, what are you waiting for then?
4122
-            $success = $status === 'deactivate'
4123
-                ? $this->_deactivate_message_type_for_messenger(
4124
-                    $this->_active_messenger_name,
4125
-                    $this->_active_message_type_name
4126
-                )
4127
-                : $this->_activate_message_type_for_messenger(
4128
-                    $this->_active_messenger_name,
4129
-                    $this->_active_message_type_name
4130
-                );
4131
-        }
4132
-
4133
-        $this->_template_args['success'] = $success;
4134
-        $this->_return_json();
4135
-    }
4136
-
4137
-
4138
-    /**
4139
-     * Takes care of processing activating a messenger and preparing the appropriate response.
4140
-     *
4141
-     * @param string $messenger_name The name of the messenger being activated
4142
-     * @return bool
4143
-     * @throws DomainException
4144
-     * @throws EE_Error
4145
-     * @throws InvalidArgumentException
4146
-     * @throws ReflectionException
4147
-     * @throws InvalidDataTypeException
4148
-     * @throws InvalidInterfaceException
4149
-     */
4150
-    protected function _activate_messenger($messenger_name)
4151
-    {
4152
-        $active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4153
-        $message_types_to_activate = $active_messenger instanceof EE_Messenger
4154
-            ? $active_messenger->get_default_message_types()
4155
-            : [];
4156
-
4157
-        // ensure is active
4158
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4159
-
4160
-        // set response_data for reload
4161
-        foreach ($message_types_to_activate as $message_type_name) {
4162
-            $message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4163
-            if (
4164
-                $this->_message_resource_manager->is_message_type_active_for_messenger(
4165
-                    $messenger_name,
4166
-                    $message_type_name
4167
-                )
4168
-                && $message_type instanceof EE_message_type
4169
-            ) {
4170
-                $this->_template_args['data']['active_mts'][] = $message_type_name;
4171
-                if ($message_type->get_admin_settings_fields()) {
4172
-                    $this->_template_args['data']['mt_reload'][] = $message_type_name;
4173
-                }
4174
-            }
4175
-        }
4176
-
4177
-        // add success message for activating messenger
4178
-        return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4179
-    }
4180
-
4181
-
4182
-    /**
4183
-     * Takes care of processing deactivating a messenger and preparing the appropriate response.
4184
-     *
4185
-     * @param string $messenger_name The name of the messenger being activated
4186
-     * @return bool
4187
-     * @throws DomainException
4188
-     * @throws EE_Error
4189
-     * @throws InvalidArgumentException
4190
-     * @throws ReflectionException
4191
-     * @throws InvalidDataTypeException
4192
-     * @throws InvalidInterfaceException
4193
-     */
4194
-    protected function _deactivate_messenger($messenger_name)
4195
-    {
4196
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4197
-        $this->_message_resource_manager->deactivate_messenger($messenger_name);
4198
-
4199
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4200
-    }
4201
-
4202
-
4203
-    /**
4204
-     * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4205
-     *
4206
-     * @param string $messenger_name    The name of the messenger the message type is being activated for.
4207
-     * @param string $message_type_name The name of the message type being activated for the messenger
4208
-     * @return bool
4209
-     * @throws DomainException
4210
-     * @throws EE_Error
4211
-     * @throws InvalidArgumentException
4212
-     * @throws ReflectionException
4213
-     * @throws InvalidDataTypeException
4214
-     * @throws InvalidInterfaceException
4215
-     */
4216
-    protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4217
-    {
4218
-        $active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
4219
-        $message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4220
-
4221
-        // ensure is active
4222
-        $this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4223
-
4224
-        // set response for load
4225
-        if (
4226
-            $this->_message_resource_manager->is_message_type_active_for_messenger(
4227
-                $messenger_name,
4228
-                $message_type_name
4229
-            )
4230
-        ) {
4231
-            $this->_template_args['data']['active_mts'][] = $message_type_name;
4232
-            if ($message_type_to_activate->get_admin_settings_fields()) {
4233
-                $this->_template_args['data']['mt_reload'][] = $message_type_name;
4234
-            }
4235
-        }
4236
-
4237
-        return $this->_setup_response_message_for_activating_messenger_with_message_types(
4238
-            $active_messenger,
4239
-            $message_type_to_activate
4240
-        );
4241
-    }
4242
-
4243
-
4244
-    /**
4245
-     * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4246
-     *
4247
-     * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4248
-     * @param string $message_type_name The name of the message type being deactivated for the messenger
4249
-     * @return bool
4250
-     * @throws DomainException
4251
-     * @throws EE_Error
4252
-     * @throws InvalidArgumentException
4253
-     * @throws ReflectionException
4254
-     * @throws InvalidDataTypeException
4255
-     * @throws InvalidInterfaceException
4256
-     */
4257
-    protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4258
-    {
4259
-        $active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4260
-        /** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4261
-        $message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4262
-        $this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4263
-
4264
-        return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4265
-            $active_messenger,
4266
-            $message_type_to_deactivate
4267
-        );
4268
-    }
4269
-
4270
-
4271
-    /**
4272
-     * This just initializes the defaults for activating messenger and message type responses.
4273
-     */
4274
-    protected function _prep_default_response_for_messenger_or_message_type_toggle()
4275
-    {
4276
-        $this->_template_args['data']['active_mts'] = [];
4277
-        $this->_template_args['data']['mt_reload']  = [];
4278
-    }
4279
-
4280
-
4281
-    /**
4282
-     * Setup appropriate response for activating a messenger and/or message types
4283
-     *
4284
-     * @param EE_messenger         $messenger
4285
-     * @param EE_message_type|null $message_type
4286
-     * @return bool
4287
-     * @throws DomainException
4288
-     * @throws EE_Error
4289
-     * @throws InvalidArgumentException
4290
-     * @throws ReflectionException
4291
-     * @throws InvalidDataTypeException
4292
-     * @throws InvalidInterfaceException
4293
-     */
4294
-    protected function _setup_response_message_for_activating_messenger_with_message_types(
4295
-        $messenger,
4296
-        EE_Message_Type $message_type = null
4297
-    ) {
4298
-        // if $messenger isn't a valid messenger object then get out.
4299
-        if (! $messenger instanceof EE_Messenger) {
4300
-            EE_Error::add_error(
4301
-                esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4302
-                __FILE__,
4303
-                __FUNCTION__,
4304
-                __LINE__
4305
-            );
4306
-            return false;
4307
-        }
4308
-        // activated
4309
-        if ($this->_template_args['data']['active_mts']) {
4310
-            EE_Error::overwrite_success();
4311
-            // activated a message type with the messenger
4312
-            if ($message_type instanceof EE_message_type) {
4313
-                EE_Error::add_success(
4314
-                    sprintf(
4315
-                        esc_html__(
4316
-                            '%s message type has been successfully activated with the %s messenger',
4317
-                            'event_espresso'
4318
-                        ),
4319
-                        ucwords($message_type->label['singular']),
4320
-                        ucwords($messenger->label['singular'])
4321
-                    )
4322
-                );
4323
-
4324
-                // if message type was invoice then let's make sure we activate the invoice payment method.
4325
-                if ($message_type->name === 'invoice') {
4326
-                    EE_Registry::instance()->load_lib('Payment_Method_Manager');
4327
-                    $pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4328
-                    if ($pm instanceof EE_Payment_Method) {
4329
-                        EE_Error::add_attention(
4330
-                            esc_html__(
4331
-                                '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.',
4332
-                                'event_espresso'
4333
-                            )
4334
-                        );
4335
-                    }
4336
-                }
4337
-                // just toggles the entire messenger
4338
-            } else {
4339
-                EE_Error::add_success(
4340
-                    sprintf(
4341
-                        esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4342
-                        ucwords($messenger->label['singular'])
4343
-                    )
4344
-                );
4345
-            }
4346
-
4347
-            return true;
4348
-
4349
-            // possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4350
-            // message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4351
-            // in which case we just give a success message for the messenger being successfully activated.
4352
-        } else {
4353
-            if (! $messenger->get_default_message_types()) {
4354
-                // messenger doesn't have any default message types so still a success.
4355
-                EE_Error::add_success(
4356
-                    sprintf(
4357
-                        esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4358
-                        ucwords($messenger->label['singular'])
4359
-                    )
4360
-                );
4361
-
4362
-                return true;
4363
-            } else {
4364
-                EE_Error::add_error(
4365
-                    $message_type instanceof EE_message_type
4366
-                    ? sprintf(
4367
-                        esc_html__(
4368
-                            '%s message type was not successfully activated with the %s messenger',
4369
-                            'event_espresso'
4370
-                        ),
4371
-                        ucwords($message_type->label['singular']),
4372
-                        ucwords($messenger->label['singular'])
4373
-                    )
4374
-                    : sprintf(
4375
-                        esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4376
-                        ucwords($messenger->label['singular'])
4377
-                    ),
4378
-                    __FILE__,
4379
-                    __FUNCTION__,
4380
-                    __LINE__
4381
-                );
4382
-
4383
-                return false;
4384
-            }
4385
-        }
4386
-    }
4387
-
4388
-
4389
-    /**
4390
-     * This sets up the appropriate response for deactivating a messenger and/or message type.
4391
-     *
4392
-     * @param EE_messenger         $messenger
4393
-     * @param EE_message_type|null $message_type
4394
-     * @return bool
4395
-     * @throws DomainException
4396
-     * @throws EE_Error
4397
-     * @throws InvalidArgumentException
4398
-     * @throws ReflectionException
4399
-     * @throws InvalidDataTypeException
4400
-     * @throws InvalidInterfaceException
4401
-     */
4402
-    protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4403
-        $messenger,
4404
-        EE_message_type $message_type = null
4405
-    ) {
4406
-        EE_Error::overwrite_success();
4407
-
4408
-        // if $messenger isn't a valid messenger object then get out.
4409
-        if (! $messenger instanceof EE_Messenger) {
4410
-            EE_Error::add_error(
4411
-                esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4412
-                __FILE__,
4413
-                __FUNCTION__,
4414
-                __LINE__
4415
-            );
4416
-
4417
-            return false;
4418
-        }
4419
-
4420
-        if ($message_type instanceof EE_message_type) {
4421
-            $message_type_name = $message_type->name;
4422
-            EE_Error::add_success(
4423
-                sprintf(
4424
-                    esc_html__(
4425
-                        '%s message type has been successfully deactivated for the %s messenger.',
4426
-                        'event_espresso'
4427
-                    ),
4428
-                    ucwords($message_type->label['singular']),
4429
-                    ucwords($messenger->label['singular'])
4430
-                )
4431
-            );
4432
-        } else {
4433
-            $message_type_name = '';
4434
-            EE_Error::add_success(
4435
-                sprintf(
4436
-                    esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4437
-                    ucwords($messenger->label['singular'])
4438
-                )
4439
-            );
4440
-        }
4441
-
4442
-        // if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4443
-        if (
4444
-            $messenger->name === 'html'
4445
-            && (
4446
-                is_null($message_type)
4447
-                || $message_type_name === 'invoice'
4448
-            )
4449
-        ) {
4450
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
4451
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4452
-            if ($count_updated > 0) {
4453
-                $msg = $message_type_name === 'invoice'
4454
-                    ? esc_html__(
4455
-                        '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.',
4456
-                        'event_espresso'
4457
-                    )
4458
-                    : esc_html__(
4459
-                        '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.',
4460
-                        'event_espresso'
4461
-                    );
4462
-                EE_Error::add_attention($msg);
4463
-            }
4464
-        }
4465
-
4466
-        return true;
4467
-    }
4468
-
4469
-
4470
-    /**
4471
-     * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4472
-     *
4473
-     * @throws DomainException
4474
-     * @throws EE_Error
4475
-     * @throws EE_Error
4476
-     */
4477
-    public function update_mt_form()
4478
-    {
4479
-        if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4480
-            EE_Error::add_error(
4481
-                esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4482
-                __FILE__,
4483
-                __FUNCTION__,
4484
-                __LINE__
4485
-            );
4486
-            $this->_return_json();
4487
-        }
4488
-
4489
-        $message_types = $this->get_installed_message_types();
4490
-        $message_type  = $message_types[ $this->_active_message_type_name ];
4491
-        $messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
4492
-        $content       = $this->_message_type_settings_content($message_type, $messenger, true);
4493
-
4494
-        $this->_template_args['success'] = true;
4495
-        $this->_template_args['content'] = $content;
4496
-        $this->_return_json();
4497
-    }
4498
-
4499
-
4500
-    /**
4501
-     * this handles saving the settings for a messenger or message type
4502
-     *
4503
-     * @throws EE_Error
4504
-     * @throws EE_Error
4505
-     */
4506
-    public function save_settings()
4507
-    {
4508
-        $type = $this->request->getRequestParam('type');
4509
-        if (! $type) {
4510
-            EE_Error::add_error(
4511
-                esc_html__(
4512
-                    'Cannot save settings because type is unknown (messenger settings or message type settings?)',
4513
-                    'event_espresso'
4514
-                ),
4515
-                __FILE__,
4516
-                __FUNCTION__,
4517
-                __LINE__
4518
-            );
4519
-            $this->_template_args['error'] = true;
4520
-            $this->_return_json();
4521
-        }
4522
-
4523
-
4524
-        if ($type === 'messenger') {
4525
-            // this should be an array.
4526
-            $settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
4527
-            $messenger = $settings['messenger'];
4528
-            // remove messenger and message_types from settings array
4529
-            unset($settings['messenger'], $settings['message_types']);
4530
-            $this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4531
-        } elseif ($type === 'message_type') {
4532
-            $settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
4533
-            $messenger    = $settings['messenger'];
4534
-            $message_type = $settings['message_type'];
4535
-            // remove messenger and message_types from settings array
4536
-            unset($settings['messenger'], $settings['message_types']);
4537
-            $this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4538
-        }
4539
-
4540
-        // okay we should have the data all setup.  Now we just update!
4541
-        $success = $this->_message_resource_manager->update_active_messengers_option();
4542
-
4543
-        if ($success) {
4544
-            EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4545
-        } else {
4546
-            EE_Error::add_error(
4547
-                esc_html__('Settings did not get updated', 'event_espresso'),
4548
-                __FILE__,
4549
-                __FUNCTION__,
4550
-                __LINE__
4551
-            );
4552
-        }
4553
-
4554
-        $this->_template_args['success'] = $success;
4555
-        $this->_return_json();
4556
-    }
4557
-
4558
-
4559
-
4560
-
4561
-    /**  EE MESSAGE PROCESSING ACTIONS **/
4562
-
4563
-
4564
-    /**
4565
-     * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4566
-     * However, this does not send immediately, it just queues for sending.
4567
-     *
4568
-     * @throws EE_Error
4569
-     * @throws InvalidDataTypeException
4570
-     * @throws InvalidInterfaceException
4571
-     * @throws InvalidArgumentException
4572
-     * @throws ReflectionException
4573
-     * @since 4.9.0
4574
-     */
4575
-    protected function _generate_now()
4576
-    {
4577
-        EED_Messages::generate_now($this->_get_msg_ids_from_request());
4578
-        $this->_redirect_after_action(false, '', '', [], true);
4579
-    }
4580
-
4581
-
4582
-    /**
4583
-     * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4584
-     * are EEM_Message::status_resend or EEM_Message::status_idle
4585
-     *
4586
-     * @throws EE_Error
4587
-     * @throws InvalidDataTypeException
4588
-     * @throws InvalidInterfaceException
4589
-     * @throws InvalidArgumentException
4590
-     * @throws ReflectionException
4591
-     * @since 4.9.0
4592
-     */
4593
-    protected function _generate_and_send_now()
4594
-    {
4595
-        EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4596
-        $this->_redirect_after_action(false, '', '', [], true);
4597
-    }
4598
-
4599
-
4600
-    /**
4601
-     * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4602
-     *
4603
-     * @throws EE_Error
4604
-     * @throws InvalidDataTypeException
4605
-     * @throws InvalidInterfaceException
4606
-     * @throws InvalidArgumentException
4607
-     * @throws ReflectionException
4608
-     * @since 4.9.0
4609
-     */
4610
-    protected function _queue_for_resending()
4611
-    {
4612
-        EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4613
-        $this->_redirect_after_action(false, '', '', [], true);
4614
-    }
4615
-
4616
-
4617
-    /**
4618
-     *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4619
-     *
4620
-     * @throws EE_Error
4621
-     * @throws InvalidDataTypeException
4622
-     * @throws InvalidInterfaceException
4623
-     * @throws InvalidArgumentException
4624
-     * @throws ReflectionException
4625
-     * @since 4.9.0
4626
-     */
4627
-    protected function _send_now()
4628
-    {
4629
-        EED_Messages::send_now($this->_get_msg_ids_from_request());
4630
-        $this->_redirect_after_action(false, '', '', [], true);
4631
-    }
4632
-
4633
-
4634
-    /**
4635
-     * Deletes EE_messages for IDs in the request.
4636
-     *
4637
-     * @throws EE_Error
4638
-     * @throws InvalidDataTypeException
4639
-     * @throws InvalidInterfaceException
4640
-     * @throws InvalidArgumentException
4641
-     * @since 4.9.0
4642
-     */
4643
-    protected function _delete_ee_messages()
4644
-    {
4645
-        $MSG_IDs       = $this->_get_msg_ids_from_request();
4646
-        $deleted_count = 0;
4647
-        foreach ($MSG_IDs as $MSG_ID) {
4648
-            if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4649
-                $deleted_count++;
4650
-            }
4651
-        }
4652
-        if ($deleted_count) {
4653
-            EE_Error::add_success(
4654
-                esc_html(
4655
-                    _n(
4656
-                        'Message successfully deleted',
4657
-                        'Messages successfully deleted',
4658
-                        $deleted_count,
4659
-                        'event_espresso'
4660
-                    )
4661
-                )
4662
-            );
4663
-        } else {
4664
-            EE_Error::add_error(
4665
-                _n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4666
-                __FILE__,
4667
-                __FUNCTION__,
4668
-                __LINE__
4669
-            );
4670
-        }
4671
-        $this->_redirect_after_action(false, '', '', [], true);
4672
-    }
4673
-
4674
-
4675
-    /**
4676
-     *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4677
-     *
4678
-     * @return array
4679
-     * @since 4.9.0
4680
-     */
4681
-    protected function _get_msg_ids_from_request()
4682
-    {
4683
-        $MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4684
-        if (empty($MSG_IDs)) {
4685
-            return [];
4686
-        }
4687
-        // if 'MSG_ID' was just a single ID (not an array)
4688
-        // then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4689
-        // otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4690
-        return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4691
-            ? $MSG_IDs
4692
-            : array_keys($MSG_IDs);
4693
-    }
2706
+		$this->_context_switcher = ob_get_clean();
2707
+	}
2708
+
2709
+
2710
+	/**
2711
+	 * @param bool $new
2712
+	 * @throws EE_Error
2713
+	 * @throws ReflectionException
2714
+	 */
2715
+	protected function _insert_or_update_message_template($new = false)
2716
+	{
2717
+		$form_data    = $this->getMessageTemplateFormData();
2718
+		$GRP_ID       = $form_data['GRP_ID'];
2719
+		$messenger    = $form_data['MTP_messenger'];
2720
+		$message_type = $form_data['MTP_message_type'];
2721
+		$context      = $form_data['MTP_context'];
2722
+
2723
+		// if this is "new" then we need to generate the default contexts
2724
+		// for the selected messenger/message_type for user to edit.
2725
+		list($success, $query_args) = $new
2726
+			? $this->generateNewTemplates($GRP_ID, $messenger, $message_type)
2727
+			: $this->updateExistingTemplates($GRP_ID, $messenger, $message_type, $context, $form_data);
2728
+
2729
+		$success     = $success ? 1 : 0;
2730
+		$action_desc = $new ? 'created' : 'updated';
2731
+		$item_desc   = $this->generateUpdateDescription($messenger, $message_type, $context);
2732
+		$override    = $this->performTestSendAfterUpdate($messenger, $message_type, $context);
2733
+
2734
+		$this->_redirect_after_action($success, $item_desc, $action_desc, $query_args, $override);
2735
+	}
2736
+
2737
+
2738
+	/**
2739
+	 * retrieve and sanitize form data
2740
+	 *
2741
+	 * @return array
2742
+	 * @since 4.10.29.p
2743
+	 */
2744
+	protected function getMessageTemplateFormData()
2745
+	{
2746
+		return [
2747
+			'GRP_ID'           => $this->request->getRequestParam('GRP_ID', 0, 'int'),
2748
+			'MTP_context'      => strtolower($this->request->getRequestParam('MTP_context', '')),
2749
+			'MTP_messenger'    => strtolower($this->request->getRequestParam('MTP_messenger', '')),
2750
+			'MTP_message_type' => strtolower($this->request->getRequestParam('MTP_message_type', '')),
2751
+			'MTP_user_id'      => $this->request->getRequestParam('MTP_user_id', 0, 'int'),
2752
+			'MTP_is_global'    => $this->request->getRequestParam('MTP_is_global', 0, 'int'),
2753
+			'MTP_is_override'  => $this->request->getRequestParam('MTP_is_override', 0, 'int'),
2754
+			'MTP_deleted'      => $this->request->getRequestParam('MTP_deleted', 0, 'int'),
2755
+			'MTP_is_active'    => $this->request->getRequestParam('MTP_is_active', 0, 'int'),
2756
+		];
2757
+	}
2758
+
2759
+
2760
+	/**
2761
+	 * @param int    $GRP_ID
2762
+	 * @param string $messenger
2763
+	 * @param string $message_type
2764
+	 * @return array no return on AJAX requests
2765
+	 * @throws EE_Error
2766
+	 * @throws ReflectionException
2767
+	 * @since 4.10.29.p
2768
+	 */
2769
+	private function generateNewTemplates($GRP_ID, $messenger, $message_type)
2770
+	{
2771
+		$new_templates = $this->_generate_new_templates($messenger, [$message_type], $GRP_ID);
2772
+		$success       = ! empty($new_templates);
2773
+
2774
+		// we return things differently if doing ajax
2775
+		if ($this->request->isAjax()) {
2776
+			$this->_template_args['success'] = $success;
2777
+			$this->_template_args['error']   = ! $success;
2778
+			$this->_template_args['content'] = '';
2779
+			$this->_template_args['data']    = [
2780
+				'grpID'        => $new_templates['GRP_ID'],
2781
+				'templateName' => $new_templates['template_name'],
2782
+			];
2783
+			if ($success) {
2784
+				EE_Error::overwrite_success();
2785
+				EE_Error::add_success(
2786
+					esc_html__(
2787
+						'The new template has been created and automatically selected for this event.  You can edit the new template by clicking the edit button.  Note before this template is assigned to this event, the event must be saved.',
2788
+						'event_espresso'
2789
+					)
2790
+				);
2791
+			}
2792
+			$this->_return_json();
2793
+		}
2794
+		return [
2795
+			$success,
2796
+			// 'query_args'
2797
+			[
2798
+				'id'      => $new_templates['GRP_ID'],
2799
+				'context' => $new_templates['MTP_context'],
2800
+				'action'  => 'edit_message_template',
2801
+			],
2802
+		];
2803
+	}
2804
+
2805
+
2806
+	/**
2807
+	 * @param int    $GRP_ID
2808
+	 * @param string $messenger
2809
+	 * @param string $message_type
2810
+	 * @param string $context
2811
+	 * @param array  $form_data
2812
+	 * @return array
2813
+	 * @throws EE_Error
2814
+	 * @since 4.10.29.p
2815
+	 */
2816
+	private function updateExistingTemplates(
2817
+		$GRP_ID,
2818
+		$messenger,
2819
+		$message_type,
2820
+		$context,
2821
+		array $form_data
2822
+	) {
2823
+		$success         = false;
2824
+		$template_fields = $this->getTemplateFields();
2825
+		if ($template_fields) {
2826
+			// if field data is valid, then success will be true
2827
+			$success = $this->validateTemplateFields(
2828
+				$messenger,
2829
+				$message_type,
2830
+				$context,
2831
+				$template_fields
2832
+			);
2833
+			if ($success) {
2834
+				$field_data = [];
2835
+				foreach ($template_fields as $template_field => $content) {
2836
+					// combine top-level form data with content for this field
2837
+					$field_data = $this->getTemplateFieldFormData($content, $form_data);
2838
+					$success    = $this->updateMessageTemplates($template_field, $field_data) ? $success : false;
2839
+				}
2840
+				// we can use the last set_column_values for the MTPG update
2841
+				// (because its the same for all of these specific MTPs)
2842
+				$success = $this->updateMessageTemplateGroup($field_data) ? $success : false;
2843
+			}
2844
+		}
2845
+
2846
+		return [
2847
+			$success,
2848
+			// 'query_args'
2849
+			[
2850
+				'id'      => $GRP_ID,
2851
+				'context' => $context,
2852
+				'action'  => 'edit_message_template',
2853
+			],
2854
+		];
2855
+	}
2856
+
2857
+
2858
+	/**
2859
+	 * @return array
2860
+	 * @since 4.10.29.p
2861
+	 */
2862
+	private function getTemplateFields()
2863
+	{
2864
+		$template_fields = $this->request->getRequestParam('MTP_template_fields', null, 'html', true);
2865
+		if (empty($template_fields)) {
2866
+			EE_Error::add_error(
2867
+				esc_html__(
2868
+					'There was a problem saving the template fields from the form because I didn\'t receive any actual template field data.',
2869
+					'event_espresso'
2870
+				),
2871
+				__FILE__,
2872
+				__FUNCTION__,
2873
+				__LINE__
2874
+			);
2875
+			return null;
2876
+		}
2877
+		// messages content is expected to be escaped
2878
+		return EEH_Array::addSlashesRecursively($template_fields);
2879
+	}
2880
+
2881
+
2882
+	/**
2883
+	 * @param string $messenger
2884
+	 * @param string $message_type
2885
+	 * @param string $context
2886
+	 * @param array  $template_fields
2887
+	 * @return bool
2888
+	 * @throws EE_Error
2889
+	 * @since   4.10.29.p
2890
+	 */
2891
+	private function validateTemplateFields(
2892
+		$messenger,
2893
+		$message_type,
2894
+		$context,
2895
+		array $template_fields
2896
+	) {
2897
+		// first validate all fields!
2898
+		// this filter allows client code to add its own validation to the template fields as well.
2899
+		// returning an empty array means everything passed validation.
2900
+		// errors in validation should be represented in an array with the following shape:
2901
+		// array(
2902
+		//   'fieldname' => array(
2903
+		//          'msg' => 'error message'
2904
+		//          'value' => 'value for field producing error'
2905
+		// )
2906
+		$custom_validation = (array) apply_filters(
2907
+			'FHEE__Messages_Admin_Page___insert_or_update_message_template__validates',
2908
+			[],
2909
+			$template_fields,
2910
+			$context,
2911
+			$messenger,
2912
+			$message_type
2913
+		);
2914
+
2915
+		$system_validation = $this->getMtgModel()->validate(
2916
+			$template_fields,
2917
+			$context,
2918
+			$messenger,
2919
+			$message_type
2920
+		);
2921
+
2922
+		$system_validation = ! is_array($system_validation) && $system_validation ? [] : $system_validation;
2923
+		$validates         = array_merge($custom_validation, $system_validation);
2924
+
2925
+		// if $validate returned error messages (i.e. is_array()) then we need to process them and setup an
2926
+		// appropriate response. HMM, dang this isn't correct, $validates will ALWAYS be an array.
2927
+		//  WE need to make sure there is no actual error messages in validates.
2928
+		if (empty($validates)) {
2929
+			return true;
2930
+		}
2931
+
2932
+		// add the transient so when the form loads we know which fields to highlight
2933
+		$this->_add_transient('edit_message_template', $validates);
2934
+		// setup notices
2935
+		foreach ($validates as $error) {
2936
+			if (isset($error['msg'])) {
2937
+				EE_Error::add_error($error['msg'], __FILE__, __FUNCTION__, __LINE__);
2938
+			}
2939
+		}
2940
+		return false;
2941
+	}
2942
+
2943
+
2944
+	/**
2945
+	 * @param array $field_data
2946
+	 * @param array $form_data
2947
+	 * @return array
2948
+	 * @since   4.10.29.p
2949
+	 */
2950
+	private function getTemplateFieldFormData(array $field_data, array $form_data)
2951
+	{
2952
+		return $form_data + [
2953
+				'MTP_ID'             => $field_data['MTP_ID'],
2954
+				'MTP_template_field' => $field_data['name'],
2955
+				// if they aren't allowed to use all JS, restrict them to standard allowed post tags
2956
+				'MTP_content'        => ! current_user_can('unfiltered_html')
2957
+					? $this->sanitizeMessageTemplateContent($field_data['content'])
2958
+					: $field_data['content'],
2959
+			];
2960
+	}
2961
+
2962
+
2963
+	/**
2964
+	 * @param string $template_field
2965
+	 * @param array  $form_data
2966
+	 * @return bool
2967
+	 * @throws EE_Error
2968
+	 * @since 4.10.29.p
2969
+	 */
2970
+	private function updateMessageTemplates($template_field, array $form_data)
2971
+	{
2972
+		$MTP_ID                  = $form_data['MTP_ID'];
2973
+		$message_template_fields = [
2974
+			'GRP_ID'             => $form_data['GRP_ID'],
2975
+			'MTP_template_field' => $form_data['MTP_template_field'],
2976
+			'MTP_context'        => $form_data['MTP_context'],
2977
+			'MTP_content'        => $form_data['MTP_content'],
2978
+		];
2979
+
2980
+		$hasMtpID = ! empty($MTP_ID);
2981
+		// if we have a MTP_ID for this field then update it, otherwise insert.
2982
+		// this has already been through the template field validator and sanitized, so it will be
2983
+		// safe to insert this field.  Why insert?  This typically happens when we introduce a new
2984
+		// message template field in a messenger/message type and existing users don't have the
2985
+		// default setup for it.
2986
+		// @link https://events.codebasehq.com/projects/event-espresso/tickets/9465
2987
+		$updated = $hasMtpID
2988
+			? $this->getMtpModel()->update($message_template_fields, [['MTP_ID' => $MTP_ID]])
2989
+			: $this->getMtpModel()->insert($message_template_fields);
2990
+
2991
+		$insert_failed = ! $hasMtpID && ! $updated;
2992
+		// updates will return 0 if the field was not changed (ie: no changes = nothing actually updated)
2993
+		// but we won't consider that a problem, but if it returns false, then something went BOOM!
2994
+		$update_failed = $hasMtpID && $updated === false;
2995
+
2996
+		if ($insert_failed || $update_failed) {
2997
+			EE_Error::add_error(
2998
+				sprintf(
2999
+					esc_html__('%s field was NOT updated for some reason', 'event_espresso'),
3000
+					$template_field
3001
+				),
3002
+				__FILE__,
3003
+				__FUNCTION__,
3004
+				__LINE__
3005
+			);
3006
+			return false;
3007
+		}
3008
+		return true;
3009
+	}
3010
+
3011
+
3012
+	/**
3013
+	 * @param array $form_data
3014
+	 * @return bool
3015
+	 * @throws EE_Error
3016
+	 * @since 4.10.29.p
3017
+	 */
3018
+	private function updateMessageTemplateGroup(array $form_data)
3019
+	{
3020
+		$GRP_ID  = $form_data['GRP_ID'];
3021
+		$updated = $this->getMtgModel()->update(
3022
+		// fields and values
3023
+			[
3024
+				'MTP_user_id'      => $form_data['MTP_user_id'],
3025
+				'MTP_messenger'    => $form_data['MTP_messenger'],
3026
+				'MTP_message_type' => $form_data['MTP_message_type'],
3027
+				'MTP_is_global'    => $form_data['MTP_is_global'],
3028
+				'MTP_is_override'  => $form_data['MTP_is_override'],
3029
+				'MTP_deleted'      => $form_data['MTP_deleted'],
3030
+				'MTP_is_active'    => $form_data['MTP_is_active'],
3031
+				'MTP_name'         => $this->request->getRequestParam('ee_msg_non_global_fields[MTP_name]', ''),
3032
+				'MTP_description'  => $this->request->getRequestParam(
3033
+					'ee_msg_non_global_fields[MTP_description]',
3034
+					''
3035
+				),
3036
+			],
3037
+			// where
3038
+			[['GRP_ID' => $GRP_ID]]
3039
+		);
3040
+
3041
+		if ($updated === false) {
3042
+			EE_Error::add_error(
3043
+				sprintf(
3044
+					esc_html__(
3045
+						'The Message Template Group (%d) was NOT updated for some reason',
3046
+						'event_espresso'
3047
+					),
3048
+					$form_data['GRP_ID']
3049
+				),
3050
+				__FILE__,
3051
+				__FUNCTION__,
3052
+				__LINE__
3053
+			);
3054
+			return false;
3055
+		}
3056
+		// k now we need to ensure the template_pack and template_variation fields are set.
3057
+		$template_pack      = $this->request->getRequestParam('MTP_template_pack', 'default');
3058
+		$template_variation = $this->request->getRequestParam('MTP_template_variation', 'default');
3059
+
3060
+		$message_template_group = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3061
+		if ($message_template_group instanceof EE_Message_Template_Group) {
3062
+			$message_template_group->set_template_pack_name($template_pack);
3063
+			$message_template_group->set_template_pack_variation($template_variation);
3064
+		}
3065
+		return true;
3066
+	}
3067
+
3068
+
3069
+	/**
3070
+	 * recursively runs wp_kses() on message template content in a model safe manner
3071
+	 *
3072
+	 * @param array|string $content
3073
+	 * @return array|string
3074
+	 * @since   4.10.29.p
3075
+	 */
3076
+	private function sanitizeMessageTemplateContent($content)
3077
+	{
3078
+		if (is_array($content)) {
3079
+			foreach ($content as $key => $value) {
3080
+				$content[ $key ] = $this->sanitizeMessageTemplateContent($value);
3081
+			}
3082
+			return $content;
3083
+		}
3084
+		// remove slashes so wp_kses() works properly
3085
+		// wp_kses_stripslashes() only removes slashes from double-quotes,
3086
+		// so attributes using single quotes always appear invalid.
3087
+		$content = stripslashes($content);
3088
+		$content = wp_kses($content, wp_kses_allowed_html('post'));
3089
+		// But currently the models expect slashed data, so after wp_kses()
3090
+		// runs we need to re-slash the data. Sheesh.
3091
+		// See https://events.codebasehq.com/projects/event-espresso/tickets/11211#update-47321587
3092
+		return addslashes($content);
3093
+	}
3094
+
3095
+
3096
+	/**
3097
+	 * @param string $messenger
3098
+	 * @param string $message_type
3099
+	 * @param string $context
3100
+	 * @return string
3101
+	 * @since 4.10.29.p
3102
+	 */
3103
+	private function generateUpdateDescription($messenger, $message_type, $context)
3104
+	{
3105
+		// need the message type and messenger objects to be able to use the labels for the notices
3106
+		$messenger_object = $this->_message_resource_manager->get_messenger($messenger);
3107
+		$messenger_label  = $messenger_object instanceof EE_messenger
3108
+			? ucwords($messenger_object->label['singular'])
3109
+			: '';
3110
+
3111
+		$message_type_object = $this->_message_resource_manager->get_message_type($message_type);
3112
+		$message_type_label  = $message_type_object instanceof EE_message_type
3113
+			? ucwords($message_type_object->label['singular'])
3114
+			: '';
3115
+
3116
+		$context   = ucwords(str_replace('_', ' ', $context));
3117
+		$item_desc = $messenger_label && $message_type_label
3118
+			? $messenger_label . ' ' . $message_type_label . ' ' . $context . ' '
3119
+			: '';
3120
+		$item_desc .= 'Message Template';
3121
+		return $item_desc;
3122
+	}
3123
+
3124
+
3125
+	/**
3126
+	 * @param string $messenger
3127
+	 * @param string $message_type
3128
+	 * @param string $context
3129
+	 * @return bool
3130
+	 * @throws EE_Error
3131
+	 * @throws ReflectionException
3132
+	 * @since 4.10.29.p
3133
+	 */
3134
+	private function performTestSendAfterUpdate($messenger, $message_type, $context)
3135
+	{
3136
+		// was a test send triggered?
3137
+		if ($this->request->requestParamIsSet('test_button')) {
3138
+			EE_Error::overwrite_success();
3139
+			$this->_do_test_send($context, $messenger, $message_type);
3140
+			return true;
3141
+		}
3142
+		return false;
3143
+	}
3144
+
3145
+
3146
+	/**
3147
+	 * processes a test send request to do an actual messenger delivery test for the given message template being tested
3148
+	 *
3149
+	 * @param string $context      what context being tested
3150
+	 * @param string $messenger    messenger being tested
3151
+	 * @param string $message_type message type being tested
3152
+	 * @throws EE_Error
3153
+	 * @throws InvalidArgumentException
3154
+	 * @throws InvalidDataTypeException
3155
+	 * @throws InvalidInterfaceException
3156
+	 * @throws ReflectionException
3157
+	 */
3158
+	protected function _do_test_send($context, $messenger, $message_type)
3159
+	{
3160
+		// set things up for preview
3161
+		$this->request->setRequestParam('messenger', $messenger);
3162
+		$this->request->setRequestParam('message_type', $message_type);
3163
+		$this->request->setRequestParam('context', $context);
3164
+		$GRP_ID = $this->request->getRequestParam('GRP_ID', 0, 'int');
3165
+		$this->request->setRequestParam('GRP_ID', $GRP_ID);
3166
+
3167
+		$active_messenger  = $this->_message_resource_manager->get_active_messenger($messenger);
3168
+		$test_settings_fld = $this->request->getRequestParam('test_settings_fld', [], 'string', true);
3169
+
3170
+		// let's save any existing fields that might be required by the messenger
3171
+		if (
3172
+			! empty($test_settings_fld)
3173
+			&& $active_messenger instanceof EE_messenger
3174
+			&& apply_filters(
3175
+				'FHEE__Messages_Admin_Page__do_test_send__set_existing_test_settings',
3176
+				true,
3177
+				$test_settings_fld,
3178
+				$active_messenger
3179
+			)
3180
+		) {
3181
+			$active_messenger->set_existing_test_settings($test_settings_fld);
3182
+		}
3183
+
3184
+		/**
3185
+		 * Use filter to add additional controls on whether message can send or not
3186
+		 */
3187
+		if (
3188
+			apply_filters(
3189
+				'FHEE__Messages_Admin_Page__do_test_send__can_send',
3190
+				true,
3191
+				$context,
3192
+				$this->request->requestParams(),
3193
+				$messenger,
3194
+				$message_type
3195
+			)
3196
+		) {
3197
+			if (EEM_Event::instance()->count() > 0) {
3198
+				$success = $this->_preview_message(true);
3199
+				if ($success) {
3200
+					EE_Error::add_success(esc_html__('Test message sent', 'event_espresso'));
3201
+				} else {
3202
+					EE_Error::add_error(
3203
+						esc_html__('The test message was not sent', 'event_espresso'),
3204
+						__FILE__,
3205
+						__FUNCTION__,
3206
+						__LINE__
3207
+					);
3208
+				}
3209
+			} else {
3210
+				$this->noEventsErrorMessage(true);
3211
+			}
3212
+		}
3213
+	}
3214
+
3215
+
3216
+	/**
3217
+	 * _generate_new_templates
3218
+	 * This will handle the messenger, message_type selection when "adding a new custom template" for an event and will
3219
+	 * automatically create the defaults for the event.  The user would then be redirected to edit the default context
3220
+	 * for the event.
3221
+	 *
3222
+	 *
3223
+	 * @param string $messenger      the messenger we are generating templates for
3224
+	 * @param array  $message_types  array of message types that the templates are generated for.
3225
+	 * @param int    $GRP_ID         If this is a custom template being generated then a GRP_ID needs to be included to
3226
+	 *                               indicate the message_template_group being used as the base.
3227
+	 *
3228
+	 * @param bool   $global
3229
+	 *
3230
+	 * @return array|bool array of data required for the redirect to the correct edit page or bool if
3231
+	 *                               encountering problems.
3232
+	 * @throws EE_Error
3233
+	 * @throws ReflectionException
3234
+	 */
3235
+	protected function _generate_new_templates($messenger, $message_types, $GRP_ID = 0, $global = false)
3236
+	{
3237
+		// if no $message_types are given then that's okay... this may be a messenger that just adds shortcodes, so we
3238
+		// just don't generate any templates.
3239
+		if (empty($message_types)) {
3240
+			return [];
3241
+		}
3242
+
3243
+		$templates = EEH_MSG_Template::generate_new_templates($messenger, $message_types, $GRP_ID, $global);
3244
+		return $templates[0];
3245
+	}
3246
+
3247
+
3248
+	/**
3249
+	 * [_trash_or_restore_message_template]
3250
+	 *
3251
+	 * @param boolean $trash  whether to move an item to trash/restore (TRUE) or restore it (FALSE)
3252
+	 * @param boolean $all    whether this is going to trash/restore all contexts within a template group (TRUE) OR just
3253
+	 *                        an individual context (FALSE).
3254
+	 * @return void
3255
+	 * @throws EE_Error
3256
+	 * @throws InvalidArgumentException
3257
+	 * @throws InvalidDataTypeException
3258
+	 * @throws InvalidInterfaceException
3259
+	 */
3260
+	protected function _trash_or_restore_message_template($trash = true, $all = false)
3261
+	{
3262
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3263
+
3264
+		$success = 1;
3265
+
3266
+		// incoming GRP_IDs
3267
+		if ($all) {
3268
+			// Checkboxes
3269
+			$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3270
+			if (! empty($checkboxes)) {
3271
+				// if array has more than one element then success message should be plural.
3272
+				// todo: what about nonce?
3273
+				$success = count($checkboxes) > 1 ? 2 : 1;
3274
+
3275
+				// cycle through checkboxes
3276
+				while (list($GRP_ID, $value) = each($checkboxes)) {
3277
+					$trashed_or_restored = $trash
3278
+						? $this->getMtgModel()->delete_by_ID($GRP_ID)
3279
+						: $this->getMtgModel()->restore_by_ID($GRP_ID);
3280
+					if (! $trashed_or_restored) {
3281
+						$success = 0;
3282
+					}
3283
+				}
3284
+			} else {
3285
+				// grab single GRP_ID and handle
3286
+				$GRP_ID = $this->request->getRequestParam('id', 0, 'int');
3287
+				if (! empty($GRP_ID)) {
3288
+					$trashed_or_restored = $trash
3289
+						? $this->getMtgModel()->delete_by_ID($GRP_ID)
3290
+						: $this->getMtgModel()->restore_by_ID($GRP_ID);
3291
+					if (! $trashed_or_restored) {
3292
+						$success = 0;
3293
+					}
3294
+				} else {
3295
+					$success = 0;
3296
+				}
3297
+			}
3298
+		}
3299
+
3300
+		$action_desc = $trash
3301
+			? esc_html__('moved to the trash', 'event_espresso')
3302
+			: esc_html__('restored', 'event_espresso');
3303
+
3304
+		$template_switch = $this->request->getRequestParam('template_switch', false, 'bool');
3305
+		$action_desc     = $template_switch ? esc_html__('switched', 'event_espresso') : $action_desc;
3306
+
3307
+		$item_desc = $all ? _n(
3308
+			'Message Template Group',
3309
+			'Message Template Groups',
3310
+			$success,
3311
+			'event_espresso'
3312
+		) : _n('Message Template Context', 'Message Template Contexts', $success, 'event_espresso');
3313
+
3314
+		$item_desc = $template_switch
3315
+			? _n('template', 'templates', $success, 'event_espresso')
3316
+			: $item_desc;
3317
+
3318
+		$this->_redirect_after_action($success, $item_desc, $action_desc, []);
3319
+	}
3320
+
3321
+
3322
+	/**
3323
+	 * [_delete_message_template]
3324
+	 * NOTE: this handles not only the deletion of the groups but also all the templates belonging to that group.
3325
+	 *
3326
+	 * @return void
3327
+	 * @throws EE_Error
3328
+	 * @throws InvalidArgumentException
3329
+	 * @throws InvalidDataTypeException
3330
+	 * @throws InvalidInterfaceException
3331
+	 * @throws ReflectionException
3332
+	 */
3333
+	protected function _delete_message_template()
3334
+	{
3335
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
3336
+
3337
+		// checkboxes
3338
+		$checkboxes = $this->request->getRequestParam('checkbox', [], 'int', true);
3339
+		if (! empty($checkboxes)) {
3340
+			// if array has more than one element then success message should be plural
3341
+			$success = count($checkboxes) > 1 ? 2 : 1;
3342
+
3343
+			// cycle through bulk action checkboxes
3344
+			while (list($GRP_ID, $value) = each($checkboxes)) {
3345
+				$success = $this->_delete_mtp_permanently($GRP_ID) ? $success : false;
3346
+			}
3347
+		} else {
3348
+			// grab single grp_id and delete
3349
+			$GRP_ID  = $this->request->getRequestParam('id', 0, 'int');
3350
+			$success = $this->_delete_mtp_permanently($GRP_ID);
3351
+		}
3352
+
3353
+		$this->_redirect_after_action($success, 'Message Templates', 'deleted', []);
3354
+	}
3355
+
3356
+
3357
+	/**
3358
+	 * helper for permanently deleting a mtP group and all related message_templates
3359
+	 *
3360
+	 * @param int  $GRP_ID        The group being deleted
3361
+	 * @param bool $include_group whether to delete the Message Template Group as well.
3362
+	 * @return bool boolean to indicate the success of the deletes or not.
3363
+	 * @throws EE_Error
3364
+	 * @throws InvalidArgumentException
3365
+	 * @throws InvalidDataTypeException
3366
+	 * @throws InvalidInterfaceException
3367
+	 * @throws ReflectionException
3368
+	 * @throws ReflectionException
3369
+	 */
3370
+	private function _delete_mtp_permanently($GRP_ID, $include_group = true)
3371
+	{
3372
+		$success = true;
3373
+		// first let's GET this group
3374
+		$MTG = $this->getMtgModel()->get_one_by_ID($GRP_ID);
3375
+		// then delete permanently all the related Message Templates
3376
+		$deleted = $MTG->delete_related_permanently('Message_Template');
3377
+
3378
+		if ($deleted === 0) {
3379
+			$success = false;
3380
+		}
3381
+
3382
+		// now delete permanently this particular group
3383
+
3384
+		if ($include_group && ! $MTG->delete_permanently()) {
3385
+			$success = false;
3386
+		}
3387
+
3388
+		return $success;
3389
+	}
3390
+
3391
+
3392
+	/**
3393
+	 *    _learn_more_about_message_templates_link
3394
+	 *
3395
+	 * @access protected
3396
+	 * @return string
3397
+	 */
3398
+	protected function _learn_more_about_message_templates_link()
3399
+	{
3400
+		return '<a class="hidden" style="margin:0 20px; cursor:pointer; font-size:12px;" >'
3401
+			   . esc_html__('learn more about how message templates works', 'event_espresso')
3402
+			   . '</a>';
3403
+	}
3404
+
3405
+
3406
+	/**
3407
+	 * Used for setting up messenger/message type activation.  This loads up the initial view.  The rest is handled by
3408
+	 * ajax and other routes.
3409
+	 *
3410
+	 * @return void
3411
+	 * @throws DomainException
3412
+	 * @throws EE_Error
3413
+	 */
3414
+	protected function _settings()
3415
+	{
3416
+		$this->_set_m_mt_settings();
3417
+
3418
+		// let's setup the messenger tabs
3419
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
3420
+			$this->_m_mt_settings['messenger_tabs'],
3421
+			'messenger_links',
3422
+			'|',
3423
+			$this->request->getRequestParam('selected_messenger', 'email')
3424
+		);
3425
+
3426
+		$this->_template_args['before_admin_page_content'] = '<div class="ui-widget ui-helper-clearfix">';
3427
+		$this->_template_args['after_admin_page_content']  = '</div><!-- end .ui-widget -->';
3428
+
3429
+		$this->display_admin_page_with_sidebar();
3430
+	}
3431
+
3432
+
3433
+	/**
3434
+	 * This sets the $_m_mt_settings property for when needed (used on the Messages settings page)
3435
+	 *
3436
+	 * @access protected
3437
+	 * @return void
3438
+	 * @throws DomainException
3439
+	 */
3440
+	protected function _set_m_mt_settings()
3441
+	{
3442
+		// first if this is already set then lets get out no need to regenerate data.
3443
+		if (! empty($this->_m_mt_settings)) {
3444
+			return;
3445
+		}
3446
+
3447
+		// get all installed messengers and message_types
3448
+		$messengers    = $this->_message_resource_manager->installed_messengers();
3449
+		$message_types = $this->_message_resource_manager->installed_message_types();
3450
+
3451
+
3452
+		// assemble the array for the _tab_text_links helper
3453
+
3454
+		foreach ($messengers as $messenger) {
3455
+			$this->_m_mt_settings['messenger_tabs'][ $messenger->name ] = [
3456
+				'label' => ucwords($messenger->label['singular']),
3457
+				'class' => $this->_message_resource_manager->is_messenger_active($messenger->name)
3458
+					? 'messenger-active'
3459
+					: '',
3460
+				'href'  => $messenger->name,
3461
+				'title' => esc_html__('Modify this Messenger', 'event_espresso'),
3462
+				'slug'  => $messenger->name,
3463
+				'obj'   => $messenger,
3464
+			];
3465
+
3466
+
3467
+			$message_types_for_messenger = $messenger->get_valid_message_types();
3468
+
3469
+			foreach ($message_types as $message_type) {
3470
+				// first we need to verify that this message type is valid with this messenger. Cause if it isn't then
3471
+				// it shouldn't show in either the inactive OR active metabox.
3472
+				if (! in_array($message_type->name, $message_types_for_messenger, true)) {
3473
+					continue;
3474
+				}
3475
+
3476
+				$a_or_i = $this->_message_resource_manager->is_message_type_active_for_messenger(
3477
+					$messenger->name,
3478
+					$message_type->name
3479
+				)
3480
+					? 'active'
3481
+					: 'inactive';
3482
+
3483
+				$this->_m_mt_settings['message_type_tabs'][ $messenger->name ][ $a_or_i ][ $message_type->name ] = [
3484
+					'label'    => ucwords($message_type->label['singular']),
3485
+					'class'    => 'message-type-' . $a_or_i,
3486
+					'slug_id'  => $message_type->name . '-messagetype-' . $messenger->name,
3487
+					'mt_nonce' => wp_create_nonce($message_type->name . '_nonce'),
3488
+					'href'     => 'espresso_' . $message_type->name . '_message_type_settings',
3489
+					'title'    => $a_or_i === 'active'
3490
+						? esc_html__('Drag this message type to the Inactive window to deactivate', 'event_espresso')
3491
+						: esc_html__('Drag this message type to the messenger to activate', 'event_espresso'),
3492
+					'content'  => $a_or_i === 'active'
3493
+						? $this->_message_type_settings_content($message_type, $messenger, true)
3494
+						: $this->_message_type_settings_content($message_type, $messenger),
3495
+					'slug'     => $message_type->name,
3496
+					'active'   => $a_or_i === 'active',
3497
+					'obj'      => $message_type,
3498
+				];
3499
+			}
3500
+		}
3501
+	}
3502
+
3503
+
3504
+	/**
3505
+	 * This just prepares the content for the message type settings
3506
+	 *
3507
+	 * @param EE_message_type $message_type The message type object
3508
+	 * @param EE_messenger    $messenger    The messenger object
3509
+	 * @param boolean         $active       Whether the message type is active or not
3510
+	 * @return string html output for the content
3511
+	 * @throws DomainException
3512
+	 */
3513
+	protected function _message_type_settings_content($message_type, $messenger, $active = false)
3514
+	{
3515
+		// get message type fields
3516
+		$fields                                         = $message_type->get_admin_settings_fields();
3517
+		$settings_template_args['template_form_fields'] = '';
3518
+
3519
+		if (! empty($fields) && $active) {
3520
+			$existing_settings = $message_type->get_existing_admin_settings($messenger->name);
3521
+			foreach ($fields as $fldname => $fldprops) {
3522
+				$field_id                         = $messenger->name . '-' . $message_type->name . '-' . $fldname;
3523
+				$template_form_field[ $field_id ] = [
3524
+					'name'       => 'message_type_settings[' . $fldname . ']',
3525
+					'label'      => $fldprops['label'],
3526
+					'input'      => $fldprops['field_type'],
3527
+					'type'       => $fldprops['value_type'],
3528
+					'required'   => $fldprops['required'],
3529
+					'validation' => $fldprops['validation'],
3530
+					'value'      => isset($existing_settings[ $fldname ])
3531
+						? $existing_settings[ $fldname ]
3532
+						: $fldprops['default'],
3533
+					'options'    => isset($fldprops['options'])
3534
+						? $fldprops['options']
3535
+						: [],
3536
+					'default'    => isset($existing_settings[ $fldname ])
3537
+						? $existing_settings[ $fldname ]
3538
+						: $fldprops['default'],
3539
+					'css_class'  => 'no-drag',
3540
+					'format'     => $fldprops['format'],
3541
+				];
3542
+			}
3543
+
3544
+
3545
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3546
+				? $this->_generate_admin_form_fields(
3547
+					$template_form_field,
3548
+					'string',
3549
+					'ee_mt_activate_form'
3550
+				)
3551
+				: '';
3552
+		}
3553
+
3554
+		$settings_template_args['description'] = $message_type->description;
3555
+		// we also need some hidden fields
3556
+		$hidden_fields = [
3557
+			'message_type_settings[messenger]' . $message_type->name    => [
3558
+				'type'  => 'hidden',
3559
+				'value' => $messenger->name,
3560
+			],
3561
+			'message_type_settings[message_type]' . $message_type->name => [
3562
+				'type'  => 'hidden',
3563
+				'value' => $message_type->name,
3564
+			],
3565
+			'type' . $message_type->name                                => [
3566
+				'type'  => 'hidden',
3567
+				'value' => 'message_type',
3568
+			],
3569
+		];
3570
+
3571
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3572
+			$hidden_fields,
3573
+			'array'
3574
+		);
3575
+		$settings_template_args['show_form']     = empty($settings_template_args['template_form_fields'])
3576
+			? ' hidden'
3577
+			: '';
3578
+
3579
+
3580
+		$template = EE_MSG_TEMPLATE_PATH . 'ee_msg_mt_settings_content.template.php';
3581
+		return EEH_Template::display_template($template, $settings_template_args, true);
3582
+	}
3583
+
3584
+
3585
+	/**
3586
+	 * Generate all the metaboxes for the message types and register them for the messages settings page.
3587
+	 *
3588
+	 * @access protected
3589
+	 * @return void
3590
+	 * @throws DomainException
3591
+	 */
3592
+	protected function _messages_settings_metaboxes()
3593
+	{
3594
+		$this->_set_m_mt_settings();
3595
+		$m_boxes         = $mt_boxes = [];
3596
+		$m_template_args = $mt_template_args = [];
3597
+
3598
+		$selected_messenger = $this->request->getRequestParam('selected_messenger', 'email');
3599
+
3600
+		if (isset($this->_m_mt_settings['messenger_tabs'])) {
3601
+			foreach ($this->_m_mt_settings['messenger_tabs'] as $messenger => $tab_array) {
3602
+				$is_messenger_active = $this->_message_resource_manager->is_messenger_active($messenger);
3603
+				$hide_on_message     = $is_messenger_active ? '' : 'hidden';
3604
+				$hide_off_message    = $is_messenger_active ? 'hidden' : '';
3605
+
3606
+				// messenger meta boxes
3607
+				$active         = $selected_messenger === $messenger;
3608
+				$active_mt_tabs = isset($this->_m_mt_settings['message_type_tabs'][ $messenger ]['active'])
3609
+					? $this->_m_mt_settings['message_type_tabs'][ $messenger ]['active']
3610
+					: '';
3611
+
3612
+				$m_boxes[ $messenger . '_a_box' ] = sprintf(
3613
+					esc_html__('%s Settings', 'event_espresso'),
3614
+					$tab_array['label']
3615
+				);
3616
+
3617
+				$m_template_args[ $messenger . '_a_box' ] = [
3618
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3619
+					'inactive_message_types' => isset(
3620
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3621
+					)
3622
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3623
+						: '',
3624
+					'content'                => $this->_get_messenger_box_content($tab_array['obj']),
3625
+					'hidden'                 => $active ? '' : ' hidden',
3626
+					'hide_on_message'        => $hide_on_message,
3627
+					'messenger'              => $messenger,
3628
+					'active'                 => $active,
3629
+				];
3630
+
3631
+				// message type meta boxes
3632
+				// (which is really just the inactive container for each messenger
3633
+				// showing inactive message types for that messenger)
3634
+				$mt_boxes[ $messenger . '_i_box' ]         = esc_html__('Inactive Message Types', 'event_espresso');
3635
+				$mt_template_args[ $messenger . '_i_box' ] = [
3636
+					'active_message_types'   => ! empty($active_mt_tabs) ? $this->_get_mt_tabs($active_mt_tabs) : '',
3637
+					'inactive_message_types' => isset(
3638
+						$this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive']
3639
+					)
3640
+						? $this->_get_mt_tabs($this->_m_mt_settings['message_type_tabs'][ $messenger ]['inactive'])
3641
+						: '',
3642
+					'hidden'                 => $active ? '' : ' hidden',
3643
+					'hide_on_message'        => $hide_on_message,
3644
+					'hide_off_message'       => $hide_off_message,
3645
+					'messenger'              => $messenger,
3646
+					'active'                 => $active,
3647
+				];
3648
+			}
3649
+		}
3650
+
3651
+
3652
+		// register messenger metaboxes
3653
+		$m_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_mt_meta_box.template.php';
3654
+		foreach ($m_boxes as $box => $label) {
3655
+			$callback_args = ['template_path' => $m_template_path, 'template_args' => $m_template_args[ $box ]];
3656
+			$msgr          = str_replace('_a_box', '', $box);
3657
+			add_meta_box(
3658
+				'espresso_' . $msgr . '_settings',
3659
+				$label,
3660
+				function ($post, $metabox) {
3661
+					EEH_Template::display_template(
3662
+						$metabox['args']['template_path'],
3663
+						$metabox['args']['template_args']
3664
+					);
3665
+				},
3666
+				$this->_current_screen->id,
3667
+				'normal',
3668
+				'high',
3669
+				$callback_args
3670
+			);
3671
+		}
3672
+
3673
+		// register message type metaboxes
3674
+		$mt_template_path = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_messenger_meta_box.template.php';
3675
+		foreach ($mt_boxes as $box => $label) {
3676
+			$callback_args = [
3677
+				'template_path' => $mt_template_path,
3678
+				'template_args' => $mt_template_args[ $box ],
3679
+			];
3680
+			$mt            = str_replace('_i_box', '', $box);
3681
+			add_meta_box(
3682
+				'espresso_' . $mt . '_inactive_mts',
3683
+				$label,
3684
+				function ($post, $metabox) {
3685
+					EEH_Template::display_template(
3686
+						$metabox['args']['template_path'],
3687
+						$metabox['args']['template_args']
3688
+					);
3689
+				},
3690
+				$this->_current_screen->id,
3691
+				'side',
3692
+				'high',
3693
+				$callback_args
3694
+			);
3695
+		}
3696
+
3697
+		// register metabox for global messages settings but only when on the main site.  On single site installs this
3698
+		// will always result in the metabox showing, on multisite installs the metabox will only show on the main site.
3699
+		if (is_main_site()) {
3700
+			add_meta_box(
3701
+				'espresso_global_message_settings',
3702
+				esc_html__('Global Message Settings', 'event_espresso'),
3703
+				[$this, 'global_messages_settings_metabox_content'],
3704
+				$this->_current_screen->id,
3705
+				'normal',
3706
+				'low',
3707
+				[]
3708
+			);
3709
+		}
3710
+	}
3711
+
3712
+
3713
+	/**
3714
+	 *  This generates the content for the global messages settings metabox.
3715
+	 *
3716
+	 * @return void
3717
+	 * @throws EE_Error
3718
+	 * @throws InvalidArgumentException
3719
+	 * @throws ReflectionException
3720
+	 * @throws InvalidDataTypeException
3721
+	 * @throws InvalidInterfaceException
3722
+	 */
3723
+	public function global_messages_settings_metabox_content()
3724
+	{
3725
+		$form = $this->_generate_global_settings_form();
3726
+		// already escaped
3727
+		echo $form->form_open(
3728
+			$this->add_query_args_and_nonce(['action' => 'update_global_settings'], EE_MSG_ADMIN_URL),
3729
+			'POST'
3730
+		);
3731
+		echo $form->get_html();
3732
+		echo $form->form_close();
3733
+	}
3734
+
3735
+
3736
+	/**
3737
+	 * This generates and returns the form object for the global messages settings.
3738
+	 *
3739
+	 * @return EE_Form_Section_Proper
3740
+	 * @throws EE_Error
3741
+	 * @throws InvalidArgumentException
3742
+	 * @throws ReflectionException
3743
+	 * @throws InvalidDataTypeException
3744
+	 * @throws InvalidInterfaceException
3745
+	 */
3746
+	protected function _generate_global_settings_form()
3747
+	{
3748
+		/** @var EE_Network_Core_Config $network_config */
3749
+		$network_config = EE_Registry::instance()->NET_CFG->core;
3750
+
3751
+		return new EE_Form_Section_Proper(
3752
+			[
3753
+				'name'            => 'global_messages_settings',
3754
+				'html_id'         => 'global_messages_settings',
3755
+				'html_class'      => 'form-table',
3756
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
3757
+				'subsections'     => apply_filters(
3758
+					'FHEE__Messages_Admin_Page__global_messages_settings_metabox_content__form_subsections',
3759
+					[
3760
+						'do_messages_on_same_request' => new EE_Select_Input(
3761
+							[
3762
+								true  => esc_html__('On the same request', 'event_espresso'),
3763
+								false => esc_html__('On a separate request', 'event_espresso'),
3764
+							],
3765
+							[
3766
+								'default'         => $network_config->do_messages_on_same_request,
3767
+								'html_label_text' => esc_html__(
3768
+									'Generate and send all messages:',
3769
+									'event_espresso'
3770
+								),
3771
+								'html_help_text'  => esc_html__(
3772
+									'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.',
3773
+									'event_espresso'
3774
+								),
3775
+							]
3776
+						),
3777
+						'delete_threshold'            => new EE_Select_Input(
3778
+							[
3779
+								0  => esc_html__('Forever', 'event_espresso'),
3780
+								3  => esc_html__('3 Months', 'event_espresso'),
3781
+								6  => esc_html__('6 Months', 'event_espresso'),
3782
+								9  => esc_html__('9 Months', 'event_espresso'),
3783
+								12 => esc_html__('12 Months', 'event_espresso'),
3784
+								24 => esc_html__('24 Months', 'event_espresso'),
3785
+								36 => esc_html__('36 Months', 'event_espresso'),
3786
+							],
3787
+							[
3788
+								'default'         => EE_Registry::instance()->CFG->messages->delete_threshold,
3789
+								'html_label_text' => esc_html__('Cleanup of old messages:', 'event_espresso'),
3790
+								'html_help_text'  => esc_html__(
3791
+									'You can control how long a record of processed messages is kept via this option.',
3792
+									'event_espresso'
3793
+								),
3794
+							]
3795
+						),
3796
+						'update_settings'             => new EE_Submit_Input(
3797
+							[
3798
+								'default'         => esc_html__('Update', 'event_espresso'),
3799
+								'html_label_text' => '&nbsp',
3800
+							]
3801
+						),
3802
+					]
3803
+				),
3804
+			]
3805
+		);
3806
+	}
3807
+
3808
+
3809
+	/**
3810
+	 * This handles updating the global settings set on the admin page.
3811
+	 *
3812
+	 * @throws EE_Error
3813
+	 * @throws InvalidDataTypeException
3814
+	 * @throws InvalidInterfaceException
3815
+	 * @throws InvalidArgumentException
3816
+	 * @throws ReflectionException
3817
+	 */
3818
+	protected function _update_global_settings()
3819
+	{
3820
+		/** @var EE_Network_Core_Config $network_config */
3821
+		$network_config  = EE_Registry::instance()->NET_CFG->core;
3822
+		$messages_config = EE_Registry::instance()->CFG->messages;
3823
+		$form            = $this->_generate_global_settings_form();
3824
+		if ($form->was_submitted()) {
3825
+			$form->receive_form_submission();
3826
+			if ($form->is_valid()) {
3827
+				$valid_data = $form->valid_data();
3828
+				foreach ($valid_data as $property => $value) {
3829
+					$setter = 'set_' . $property;
3830
+					if (method_exists($network_config, $setter)) {
3831
+						$network_config->{$setter}($value);
3832
+					} elseif (
3833
+						property_exists($network_config, $property)
3834
+						&& $network_config->{$property} !== $value
3835
+					) {
3836
+						$network_config->{$property} = $value;
3837
+					} elseif (
3838
+						property_exists($messages_config, $property)
3839
+						&& $messages_config->{$property} !== $value
3840
+					) {
3841
+						$messages_config->{$property} = $value;
3842
+					}
3843
+				}
3844
+				// only update if the form submission was valid!
3845
+				EE_Registry::instance()->NET_CFG->update_config(true, false);
3846
+				EE_Registry::instance()->CFG->update_espresso_config();
3847
+				EE_Error::overwrite_success();
3848
+				EE_Error::add_success(esc_html__('Global message settings were updated', 'event_espresso'));
3849
+			}
3850
+		}
3851
+		$this->_redirect_after_action(0, '', '', ['action' => 'settings'], true);
3852
+	}
3853
+
3854
+
3855
+	/**
3856
+	 * this prepares the messenger tabs that can be dragged in and out of messenger boxes to activate/deactivate
3857
+	 *
3858
+	 * @param array $tab_array This is an array of message type tab details used to generate the tabs
3859
+	 * @return string html formatted tabs
3860
+	 * @throws DomainException
3861
+	 */
3862
+	protected function _get_mt_tabs($tab_array)
3863
+	{
3864
+		$tab_array = (array) $tab_array;
3865
+		$template  = EE_MSG_TEMPLATE_PATH . 'ee_msg_details_mt_settings_tab_item.template.php';
3866
+		$tabs      = '';
3867
+
3868
+		foreach ($tab_array as $tab) {
3869
+			$tabs .= EEH_Template::display_template($template, $tab, true);
3870
+		}
3871
+
3872
+		return $tabs;
3873
+	}
3874
+
3875
+
3876
+	/**
3877
+	 * This prepares the content of the messenger meta box admin settings
3878
+	 *
3879
+	 * @param EE_messenger $messenger The messenger we're setting up content for
3880
+	 * @return string html formatted content
3881
+	 * @throws DomainException
3882
+	 */
3883
+	protected function _get_messenger_box_content(EE_messenger $messenger)
3884
+	{
3885
+
3886
+		$fields                                         = $messenger->get_admin_settings_fields();
3887
+		$settings_template_args['template_form_fields'] = '';
3888
+
3889
+		// is $messenger active?
3890
+		$settings_template_args['active'] = $this->_message_resource_manager->is_messenger_active($messenger->name);
3891
+
3892
+
3893
+		if (! empty($fields)) {
3894
+			$existing_settings = $messenger->get_existing_admin_settings();
3895
+
3896
+			foreach ($fields as $fldname => $fldprops) {
3897
+				$field_id                         = $messenger->name . '-' . $fldname;
3898
+				$template_form_field[ $field_id ] = [
3899
+					'name'       => 'messenger_settings[' . $field_id . ']',
3900
+					'label'      => $fldprops['label'],
3901
+					'input'      => $fldprops['field_type'],
3902
+					'type'       => $fldprops['value_type'],
3903
+					'required'   => $fldprops['required'],
3904
+					'validation' => $fldprops['validation'],
3905
+					'value'      => isset($existing_settings[ $field_id ])
3906
+						? $existing_settings[ $field_id ]
3907
+						: $fldprops['default'],
3908
+					'css_class'  => '',
3909
+					'format'     => $fldprops['format'],
3910
+				];
3911
+			}
3912
+
3913
+
3914
+			$settings_template_args['template_form_fields'] = ! empty($template_form_field)
3915
+				? $this->_generate_admin_form_fields($template_form_field, 'string', 'ee_m_activate_form')
3916
+				: '';
3917
+		}
3918
+
3919
+		// we also need some hidden fields
3920
+		$settings_template_args['hidden_fields'] = [
3921
+			'messenger_settings[messenger]' . $messenger->name => [
3922
+				'type'  => 'hidden',
3923
+				'value' => $messenger->name,
3924
+			],
3925
+			'type' . $messenger->name                          => [
3926
+				'type'  => 'hidden',
3927
+				'value' => 'messenger',
3928
+			],
3929
+		];
3930
+
3931
+		// make sure any active message types that are existing are included in the hidden fields
3932
+		if (isset($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'])) {
3933
+			foreach ($this->_m_mt_settings['message_type_tabs'][ $messenger->name ]['active'] as $mt => $values) {
3934
+				$settings_template_args['hidden_fields'][ 'messenger_settings[message_types][' . $mt . ']' ] = [
3935
+					'type'  => 'hidden',
3936
+					'value' => $mt,
3937
+				];
3938
+			}
3939
+		}
3940
+		$settings_template_args['hidden_fields'] = $this->_generate_admin_form_fields(
3941
+			$settings_template_args['hidden_fields'],
3942
+			'array'
3943
+		);
3944
+		$active                                  =
3945
+			$this->_message_resource_manager->is_messenger_active($messenger->name);
3946
+
3947
+		$settings_template_args['messenger']           = $messenger->name;
3948
+		$settings_template_args['description']         = $messenger->description;
3949
+		$settings_template_args['show_hide_edit_form'] = $active ? '' : ' hidden';
3950
+
3951
+
3952
+		$settings_template_args['show_hide_edit_form'] = $this->_message_resource_manager->is_messenger_active(
3953
+			$messenger->name
3954
+		)
3955
+			? $settings_template_args['show_hide_edit_form']
3956
+			: ' hidden';
3957
+
3958
+		$settings_template_args['show_hide_edit_form'] = empty($settings_template_args['template_form_fields'])
3959
+			? ' hidden'
3960
+			: $settings_template_args['show_hide_edit_form'];
3961
+
3962
+
3963
+		$settings_template_args['on_off_action'] = $active ? 'messenger-off' : 'messenger-on';
3964
+		$settings_template_args['nonce']         = wp_create_nonce('activate_' . $messenger->name . '_toggle_nonce');
3965
+		$settings_template_args['on_off_status'] = $active;
3966
+		$template                                = EE_MSG_TEMPLATE_PATH . 'ee_msg_m_settings_content.template.php';
3967
+		return EEH_Template::display_template(
3968
+			$template,
3969
+			$settings_template_args,
3970
+			true
3971
+		);
3972
+	}
3973
+
3974
+
3975
+	/**
3976
+	 * used by ajax on the messages settings page to activate|deactivate the messenger
3977
+	 *
3978
+	 * @throws DomainException
3979
+	 * @throws EE_Error
3980
+	 * @throws InvalidDataTypeException
3981
+	 * @throws InvalidInterfaceException
3982
+	 * @throws InvalidArgumentException
3983
+	 * @throws ReflectionException
3984
+	 */
3985
+	public function activate_messenger_toggle()
3986
+	{
3987
+		$success = true;
3988
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
3989
+		// let's check that we have required data
3990
+
3991
+		if (! $this->_active_messenger_name) {
3992
+			EE_Error::add_error(
3993
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
3994
+				__FILE__,
3995
+				__FUNCTION__,
3996
+				__LINE__
3997
+			);
3998
+			$success = false;
3999
+		}
4000
+
4001
+		// do a nonce check here since we're not arriving via a normal route
4002
+		$nonce     = $this->request->getRequestParam('activate_nonce', '');
4003
+		$nonce_ref = "activate_{$this->_active_messenger_name}_toggle_nonce";
4004
+
4005
+		$this->_verify_nonce($nonce, $nonce_ref);
4006
+
4007
+
4008
+		$status = $this->request->getRequestParam('status');
4009
+		if (! $status) {
4010
+			EE_Error::add_error(
4011
+				esc_html__(
4012
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4013
+					'event_espresso'
4014
+				),
4015
+				__FILE__,
4016
+				__FUNCTION__,
4017
+				__LINE__
4018
+			);
4019
+			$success = false;
4020
+		}
4021
+
4022
+		// do check to verify we have a valid status.
4023
+		if ($status !== 'off' && $status !== 'on') {
4024
+			EE_Error::add_error(
4025
+				sprintf(
4026
+					esc_html__('The given status (%s) is not valid. Must be "off" or "on"', 'event_espresso'),
4027
+					$status
4028
+				),
4029
+				__FILE__,
4030
+				__FUNCTION__,
4031
+				__LINE__
4032
+			);
4033
+			$success = false;
4034
+		}
4035
+
4036
+		if ($success) {
4037
+			// made it here?  Stop dawdling then!!
4038
+			$success = $status === 'off'
4039
+				? $this->_deactivate_messenger($this->_active_messenger_name)
4040
+				: $this->_activate_messenger($this->_active_messenger_name);
4041
+		}
4042
+
4043
+		$this->_template_args['success'] = $success;
4044
+
4045
+		// no special instructions so let's just do the json return (which should automatically do all the special stuff).
4046
+		$this->_return_json();
4047
+	}
4048
+
4049
+
4050
+	/**
4051
+	 * used by ajax from the messages settings page to activate|deactivate a message type
4052
+	 *
4053
+	 * @throws DomainException
4054
+	 * @throws EE_Error
4055
+	 * @throws ReflectionException
4056
+	 * @throws InvalidDataTypeException
4057
+	 * @throws InvalidInterfaceException
4058
+	 * @throws InvalidArgumentException
4059
+	 */
4060
+	public function activate_mt_toggle()
4061
+	{
4062
+		$success = true;
4063
+		$this->_prep_default_response_for_messenger_or_message_type_toggle();
4064
+
4065
+		// let's make sure we have the necessary data
4066
+		if (! $this->_active_message_type_name) {
4067
+			EE_Error::add_error(
4068
+				esc_html__('Message Type name needed to toggle activation. None given', 'event_espresso'),
4069
+				__FILE__,
4070
+				__FUNCTION__,
4071
+				__LINE__
4072
+			);
4073
+			$success = false;
4074
+		}
4075
+
4076
+		if (! $this->_active_messenger_name) {
4077
+			EE_Error::add_error(
4078
+				esc_html__('Messenger name needed to toggle activation. None given', 'event_espresso'),
4079
+				__FILE__,
4080
+				__FUNCTION__,
4081
+				__LINE__
4082
+			);
4083
+			$success = false;
4084
+		}
4085
+
4086
+		$status = $this->request->getRequestParam('status');
4087
+		if (! $status) {
4088
+			EE_Error::add_error(
4089
+				esc_html__(
4090
+					'Messenger status needed to know whether activation or deactivation is happening. No status is given',
4091
+					'event_espresso'
4092
+				),
4093
+				__FILE__,
4094
+				__FUNCTION__,
4095
+				__LINE__
4096
+			);
4097
+			$success = false;
4098
+		}
4099
+
4100
+
4101
+		// do check to verify we have a valid status.
4102
+		if ($status !== 'activate' && $status !== 'deactivate') {
4103
+			EE_Error::add_error(
4104
+				sprintf(
4105
+					esc_html__('The given status (%s) is not valid. Must be "active" or "inactive"', 'event_espresso'),
4106
+					$status
4107
+				),
4108
+				__FILE__,
4109
+				__FUNCTION__,
4110
+				__LINE__
4111
+			);
4112
+			$success = false;
4113
+		}
4114
+
4115
+
4116
+		// do a nonce check here since we're not arriving via a normal route
4117
+		$nonce = $this->request->getRequestParam('mt_nonce', '');
4118
+		$this->_verify_nonce($nonce, "{$this->_active_message_type_name}_nonce");
4119
+
4120
+		if ($success) {
4121
+			// made it here? um, what are you waiting for then?
4122
+			$success = $status === 'deactivate'
4123
+				? $this->_deactivate_message_type_for_messenger(
4124
+					$this->_active_messenger_name,
4125
+					$this->_active_message_type_name
4126
+				)
4127
+				: $this->_activate_message_type_for_messenger(
4128
+					$this->_active_messenger_name,
4129
+					$this->_active_message_type_name
4130
+				);
4131
+		}
4132
+
4133
+		$this->_template_args['success'] = $success;
4134
+		$this->_return_json();
4135
+	}
4136
+
4137
+
4138
+	/**
4139
+	 * Takes care of processing activating a messenger and preparing the appropriate response.
4140
+	 *
4141
+	 * @param string $messenger_name The name of the messenger being activated
4142
+	 * @return bool
4143
+	 * @throws DomainException
4144
+	 * @throws EE_Error
4145
+	 * @throws InvalidArgumentException
4146
+	 * @throws ReflectionException
4147
+	 * @throws InvalidDataTypeException
4148
+	 * @throws InvalidInterfaceException
4149
+	 */
4150
+	protected function _activate_messenger($messenger_name)
4151
+	{
4152
+		$active_messenger          = $this->_message_resource_manager->get_messenger($messenger_name);
4153
+		$message_types_to_activate = $active_messenger instanceof EE_Messenger
4154
+			? $active_messenger->get_default_message_types()
4155
+			: [];
4156
+
4157
+		// ensure is active
4158
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_types_to_activate);
4159
+
4160
+		// set response_data for reload
4161
+		foreach ($message_types_to_activate as $message_type_name) {
4162
+			$message_type = $this->_message_resource_manager->get_message_type($message_type_name);
4163
+			if (
4164
+				$this->_message_resource_manager->is_message_type_active_for_messenger(
4165
+					$messenger_name,
4166
+					$message_type_name
4167
+				)
4168
+				&& $message_type instanceof EE_message_type
4169
+			) {
4170
+				$this->_template_args['data']['active_mts'][] = $message_type_name;
4171
+				if ($message_type->get_admin_settings_fields()) {
4172
+					$this->_template_args['data']['mt_reload'][] = $message_type_name;
4173
+				}
4174
+			}
4175
+		}
4176
+
4177
+		// add success message for activating messenger
4178
+		return $this->_setup_response_message_for_activating_messenger_with_message_types($active_messenger);
4179
+	}
4180
+
4181
+
4182
+	/**
4183
+	 * Takes care of processing deactivating a messenger and preparing the appropriate response.
4184
+	 *
4185
+	 * @param string $messenger_name The name of the messenger being activated
4186
+	 * @return bool
4187
+	 * @throws DomainException
4188
+	 * @throws EE_Error
4189
+	 * @throws InvalidArgumentException
4190
+	 * @throws ReflectionException
4191
+	 * @throws InvalidDataTypeException
4192
+	 * @throws InvalidInterfaceException
4193
+	 */
4194
+	protected function _deactivate_messenger($messenger_name)
4195
+	{
4196
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4197
+		$this->_message_resource_manager->deactivate_messenger($messenger_name);
4198
+
4199
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types($active_messenger);
4200
+	}
4201
+
4202
+
4203
+	/**
4204
+	 * Takes care of processing activating a message type for a messenger and preparing the appropriate response.
4205
+	 *
4206
+	 * @param string $messenger_name    The name of the messenger the message type is being activated for.
4207
+	 * @param string $message_type_name The name of the message type being activated for the messenger
4208
+	 * @return bool
4209
+	 * @throws DomainException
4210
+	 * @throws EE_Error
4211
+	 * @throws InvalidArgumentException
4212
+	 * @throws ReflectionException
4213
+	 * @throws InvalidDataTypeException
4214
+	 * @throws InvalidInterfaceException
4215
+	 */
4216
+	protected function _activate_message_type_for_messenger($messenger_name, $message_type_name)
4217
+	{
4218
+		$active_messenger         = $this->_message_resource_manager->get_messenger($messenger_name);
4219
+		$message_type_to_activate = $this->_message_resource_manager->get_message_type($message_type_name);
4220
+
4221
+		// ensure is active
4222
+		$this->_message_resource_manager->activate_messenger($active_messenger, $message_type_name);
4223
+
4224
+		// set response for load
4225
+		if (
4226
+			$this->_message_resource_manager->is_message_type_active_for_messenger(
4227
+				$messenger_name,
4228
+				$message_type_name
4229
+			)
4230
+		) {
4231
+			$this->_template_args['data']['active_mts'][] = $message_type_name;
4232
+			if ($message_type_to_activate->get_admin_settings_fields()) {
4233
+				$this->_template_args['data']['mt_reload'][] = $message_type_name;
4234
+			}
4235
+		}
4236
+
4237
+		return $this->_setup_response_message_for_activating_messenger_with_message_types(
4238
+			$active_messenger,
4239
+			$message_type_to_activate
4240
+		);
4241
+	}
4242
+
4243
+
4244
+	/**
4245
+	 * Takes care of processing deactivating a message type for a messenger and preparing the appropriate response.
4246
+	 *
4247
+	 * @param string $messenger_name    The name of the messenger the message type is being deactivated for.
4248
+	 * @param string $message_type_name The name of the message type being deactivated for the messenger
4249
+	 * @return bool
4250
+	 * @throws DomainException
4251
+	 * @throws EE_Error
4252
+	 * @throws InvalidArgumentException
4253
+	 * @throws ReflectionException
4254
+	 * @throws InvalidDataTypeException
4255
+	 * @throws InvalidInterfaceException
4256
+	 */
4257
+	protected function _deactivate_message_type_for_messenger($messenger_name, $message_type_name)
4258
+	{
4259
+		$active_messenger = $this->_message_resource_manager->get_messenger($messenger_name);
4260
+		/** @var EE_message_type $message_type_to_activate This will be present because it can't be toggled if it isn't */
4261
+		$message_type_to_deactivate = $this->_message_resource_manager->get_message_type($message_type_name);
4262
+		$this->_message_resource_manager->deactivate_message_type_for_messenger($message_type_name, $messenger_name);
4263
+
4264
+		return $this->_setup_response_message_for_deactivating_messenger_with_message_types(
4265
+			$active_messenger,
4266
+			$message_type_to_deactivate
4267
+		);
4268
+	}
4269
+
4270
+
4271
+	/**
4272
+	 * This just initializes the defaults for activating messenger and message type responses.
4273
+	 */
4274
+	protected function _prep_default_response_for_messenger_or_message_type_toggle()
4275
+	{
4276
+		$this->_template_args['data']['active_mts'] = [];
4277
+		$this->_template_args['data']['mt_reload']  = [];
4278
+	}
4279
+
4280
+
4281
+	/**
4282
+	 * Setup appropriate response for activating a messenger and/or message types
4283
+	 *
4284
+	 * @param EE_messenger         $messenger
4285
+	 * @param EE_message_type|null $message_type
4286
+	 * @return bool
4287
+	 * @throws DomainException
4288
+	 * @throws EE_Error
4289
+	 * @throws InvalidArgumentException
4290
+	 * @throws ReflectionException
4291
+	 * @throws InvalidDataTypeException
4292
+	 * @throws InvalidInterfaceException
4293
+	 */
4294
+	protected function _setup_response_message_for_activating_messenger_with_message_types(
4295
+		$messenger,
4296
+		EE_Message_Type $message_type = null
4297
+	) {
4298
+		// if $messenger isn't a valid messenger object then get out.
4299
+		if (! $messenger instanceof EE_Messenger) {
4300
+			EE_Error::add_error(
4301
+				esc_html__('The messenger being activated is not a valid messenger', 'event_espresso'),
4302
+				__FILE__,
4303
+				__FUNCTION__,
4304
+				__LINE__
4305
+			);
4306
+			return false;
4307
+		}
4308
+		// activated
4309
+		if ($this->_template_args['data']['active_mts']) {
4310
+			EE_Error::overwrite_success();
4311
+			// activated a message type with the messenger
4312
+			if ($message_type instanceof EE_message_type) {
4313
+				EE_Error::add_success(
4314
+					sprintf(
4315
+						esc_html__(
4316
+							'%s message type has been successfully activated with the %s messenger',
4317
+							'event_espresso'
4318
+						),
4319
+						ucwords($message_type->label['singular']),
4320
+						ucwords($messenger->label['singular'])
4321
+					)
4322
+				);
4323
+
4324
+				// if message type was invoice then let's make sure we activate the invoice payment method.
4325
+				if ($message_type->name === 'invoice') {
4326
+					EE_Registry::instance()->load_lib('Payment_Method_Manager');
4327
+					$pm = EE_Payment_Method_Manager::instance()->activate_a_payment_method_of_type('Invoice');
4328
+					if ($pm instanceof EE_Payment_Method) {
4329
+						EE_Error::add_attention(
4330
+							esc_html__(
4331
+								'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.',
4332
+								'event_espresso'
4333
+							)
4334
+						);
4335
+					}
4336
+				}
4337
+				// just toggles the entire messenger
4338
+			} else {
4339
+				EE_Error::add_success(
4340
+					sprintf(
4341
+						esc_html__('%s messenger has been successfully activated', 'event_espresso'),
4342
+						ucwords($messenger->label['singular'])
4343
+					)
4344
+				);
4345
+			}
4346
+
4347
+			return true;
4348
+
4349
+			// possible error condition. This will happen when our active_mts data is empty because it is validated for actual active
4350
+			// message types after the activation process.  However its possible some messengers don't HAVE any default_message_types
4351
+			// in which case we just give a success message for the messenger being successfully activated.
4352
+		} else {
4353
+			if (! $messenger->get_default_message_types()) {
4354
+				// messenger doesn't have any default message types so still a success.
4355
+				EE_Error::add_success(
4356
+					sprintf(
4357
+						esc_html__('%s messenger was successfully activated.', 'event_espresso'),
4358
+						ucwords($messenger->label['singular'])
4359
+					)
4360
+				);
4361
+
4362
+				return true;
4363
+			} else {
4364
+				EE_Error::add_error(
4365
+					$message_type instanceof EE_message_type
4366
+					? sprintf(
4367
+						esc_html__(
4368
+							'%s message type was not successfully activated with the %s messenger',
4369
+							'event_espresso'
4370
+						),
4371
+						ucwords($message_type->label['singular']),
4372
+						ucwords($messenger->label['singular'])
4373
+					)
4374
+					: sprintf(
4375
+						esc_html__('%s messenger was not successfully activated', 'event_espresso'),
4376
+						ucwords($messenger->label['singular'])
4377
+					),
4378
+					__FILE__,
4379
+					__FUNCTION__,
4380
+					__LINE__
4381
+				);
4382
+
4383
+				return false;
4384
+			}
4385
+		}
4386
+	}
4387
+
4388
+
4389
+	/**
4390
+	 * This sets up the appropriate response for deactivating a messenger and/or message type.
4391
+	 *
4392
+	 * @param EE_messenger         $messenger
4393
+	 * @param EE_message_type|null $message_type
4394
+	 * @return bool
4395
+	 * @throws DomainException
4396
+	 * @throws EE_Error
4397
+	 * @throws InvalidArgumentException
4398
+	 * @throws ReflectionException
4399
+	 * @throws InvalidDataTypeException
4400
+	 * @throws InvalidInterfaceException
4401
+	 */
4402
+	protected function _setup_response_message_for_deactivating_messenger_with_message_types(
4403
+		$messenger,
4404
+		EE_message_type $message_type = null
4405
+	) {
4406
+		EE_Error::overwrite_success();
4407
+
4408
+		// if $messenger isn't a valid messenger object then get out.
4409
+		if (! $messenger instanceof EE_Messenger) {
4410
+			EE_Error::add_error(
4411
+				esc_html__('The messenger being deactivated is not a valid messenger', 'event_espresso'),
4412
+				__FILE__,
4413
+				__FUNCTION__,
4414
+				__LINE__
4415
+			);
4416
+
4417
+			return false;
4418
+		}
4419
+
4420
+		if ($message_type instanceof EE_message_type) {
4421
+			$message_type_name = $message_type->name;
4422
+			EE_Error::add_success(
4423
+				sprintf(
4424
+					esc_html__(
4425
+						'%s message type has been successfully deactivated for the %s messenger.',
4426
+						'event_espresso'
4427
+					),
4428
+					ucwords($message_type->label['singular']),
4429
+					ucwords($messenger->label['singular'])
4430
+				)
4431
+			);
4432
+		} else {
4433
+			$message_type_name = '';
4434
+			EE_Error::add_success(
4435
+				sprintf(
4436
+					esc_html__('%s messenger has been successfully deactivated.', 'event_espresso'),
4437
+					ucwords($messenger->label['singular'])
4438
+				)
4439
+			);
4440
+		}
4441
+
4442
+		// if messenger was html or message type was invoice then let's make sure we deactivate invoice payment method.
4443
+		if (
4444
+			$messenger->name === 'html'
4445
+			&& (
4446
+				is_null($message_type)
4447
+				|| $message_type_name === 'invoice'
4448
+			)
4449
+		) {
4450
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
4451
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method('invoice');
4452
+			if ($count_updated > 0) {
4453
+				$msg = $message_type_name === 'invoice'
4454
+					? esc_html__(
4455
+						'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.',
4456
+						'event_espresso'
4457
+					)
4458
+					: esc_html__(
4459
+						'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.',
4460
+						'event_espresso'
4461
+					);
4462
+				EE_Error::add_attention($msg);
4463
+			}
4464
+		}
4465
+
4466
+		return true;
4467
+	}
4468
+
4469
+
4470
+	/**
4471
+	 * handles updating a message type form on messenger activation IF the message type has settings fields. (via ajax)
4472
+	 *
4473
+	 * @throws DomainException
4474
+	 * @throws EE_Error
4475
+	 * @throws EE_Error
4476
+	 */
4477
+	public function update_mt_form()
4478
+	{
4479
+		if (! $this->_active_messenger_name || ! $this->_active_message_type_name) {
4480
+			EE_Error::add_error(
4481
+				esc_html__('Require message type or messenger to send an updated form', 'event_espresso'),
4482
+				__FILE__,
4483
+				__FUNCTION__,
4484
+				__LINE__
4485
+			);
4486
+			$this->_return_json();
4487
+		}
4488
+
4489
+		$message_types = $this->get_installed_message_types();
4490
+		$message_type  = $message_types[ $this->_active_message_type_name ];
4491
+		$messenger     = $this->_message_resource_manager->get_active_messenger($this->_active_messenger_name);
4492
+		$content       = $this->_message_type_settings_content($message_type, $messenger, true);
4493
+
4494
+		$this->_template_args['success'] = true;
4495
+		$this->_template_args['content'] = $content;
4496
+		$this->_return_json();
4497
+	}
4498
+
4499
+
4500
+	/**
4501
+	 * this handles saving the settings for a messenger or message type
4502
+	 *
4503
+	 * @throws EE_Error
4504
+	 * @throws EE_Error
4505
+	 */
4506
+	public function save_settings()
4507
+	{
4508
+		$type = $this->request->getRequestParam('type');
4509
+		if (! $type) {
4510
+			EE_Error::add_error(
4511
+				esc_html__(
4512
+					'Cannot save settings because type is unknown (messenger settings or message type settings?)',
4513
+					'event_espresso'
4514
+				),
4515
+				__FILE__,
4516
+				__FUNCTION__,
4517
+				__LINE__
4518
+			);
4519
+			$this->_template_args['error'] = true;
4520
+			$this->_return_json();
4521
+		}
4522
+
4523
+
4524
+		if ($type === 'messenger') {
4525
+			// this should be an array.
4526
+			$settings  = $this->request->getRequestParam('messenger_settings', [], 'string', true);
4527
+			$messenger = $settings['messenger'];
4528
+			// remove messenger and message_types from settings array
4529
+			unset($settings['messenger'], $settings['message_types']);
4530
+			$this->_message_resource_manager->add_settings_for_messenger($messenger, $settings);
4531
+		} elseif ($type === 'message_type') {
4532
+			$settings     = $this->request->getRequestParam('message_type_settings', [], 'string', true);
4533
+			$messenger    = $settings['messenger'];
4534
+			$message_type = $settings['message_type'];
4535
+			// remove messenger and message_types from settings array
4536
+			unset($settings['messenger'], $settings['message_types']);
4537
+			$this->_message_resource_manager->add_settings_for_message_type($messenger, $message_type, $settings);
4538
+		}
4539
+
4540
+		// okay we should have the data all setup.  Now we just update!
4541
+		$success = $this->_message_resource_manager->update_active_messengers_option();
4542
+
4543
+		if ($success) {
4544
+			EE_Error::add_success(esc_html__('Settings updated', 'event_espresso'));
4545
+		} else {
4546
+			EE_Error::add_error(
4547
+				esc_html__('Settings did not get updated', 'event_espresso'),
4548
+				__FILE__,
4549
+				__FUNCTION__,
4550
+				__LINE__
4551
+			);
4552
+		}
4553
+
4554
+		$this->_template_args['success'] = $success;
4555
+		$this->_return_json();
4556
+	}
4557
+
4558
+
4559
+
4560
+
4561
+	/**  EE MESSAGE PROCESSING ACTIONS **/
4562
+
4563
+
4564
+	/**
4565
+	 * This immediately generates any EE_Message ID's that are selected that are EEM_Message::status_incomplete
4566
+	 * However, this does not send immediately, it just queues for sending.
4567
+	 *
4568
+	 * @throws EE_Error
4569
+	 * @throws InvalidDataTypeException
4570
+	 * @throws InvalidInterfaceException
4571
+	 * @throws InvalidArgumentException
4572
+	 * @throws ReflectionException
4573
+	 * @since 4.9.0
4574
+	 */
4575
+	protected function _generate_now()
4576
+	{
4577
+		EED_Messages::generate_now($this->_get_msg_ids_from_request());
4578
+		$this->_redirect_after_action(false, '', '', [], true);
4579
+	}
4580
+
4581
+
4582
+	/**
4583
+	 * This immediately generates AND sends any EE_Message's selected that are EEM_Message::status_incomplete or that
4584
+	 * are EEM_Message::status_resend or EEM_Message::status_idle
4585
+	 *
4586
+	 * @throws EE_Error
4587
+	 * @throws InvalidDataTypeException
4588
+	 * @throws InvalidInterfaceException
4589
+	 * @throws InvalidArgumentException
4590
+	 * @throws ReflectionException
4591
+	 * @since 4.9.0
4592
+	 */
4593
+	protected function _generate_and_send_now()
4594
+	{
4595
+		EED_Messages::generate_and_send_now($this->_get_msg_ids_from_request());
4596
+		$this->_redirect_after_action(false, '', '', [], true);
4597
+	}
4598
+
4599
+
4600
+	/**
4601
+	 * This queues any EEM_Message::status_sent EE_Message ids in the request for resending.
4602
+	 *
4603
+	 * @throws EE_Error
4604
+	 * @throws InvalidDataTypeException
4605
+	 * @throws InvalidInterfaceException
4606
+	 * @throws InvalidArgumentException
4607
+	 * @throws ReflectionException
4608
+	 * @since 4.9.0
4609
+	 */
4610
+	protected function _queue_for_resending()
4611
+	{
4612
+		EED_Messages::queue_for_resending($this->_get_msg_ids_from_request());
4613
+		$this->_redirect_after_action(false, '', '', [], true);
4614
+	}
4615
+
4616
+
4617
+	/**
4618
+	 *  This sends immediately any EEM_Message::status_idle or EEM_Message::status_resend messages in the queue
4619
+	 *
4620
+	 * @throws EE_Error
4621
+	 * @throws InvalidDataTypeException
4622
+	 * @throws InvalidInterfaceException
4623
+	 * @throws InvalidArgumentException
4624
+	 * @throws ReflectionException
4625
+	 * @since 4.9.0
4626
+	 */
4627
+	protected function _send_now()
4628
+	{
4629
+		EED_Messages::send_now($this->_get_msg_ids_from_request());
4630
+		$this->_redirect_after_action(false, '', '', [], true);
4631
+	}
4632
+
4633
+
4634
+	/**
4635
+	 * Deletes EE_messages for IDs in the request.
4636
+	 *
4637
+	 * @throws EE_Error
4638
+	 * @throws InvalidDataTypeException
4639
+	 * @throws InvalidInterfaceException
4640
+	 * @throws InvalidArgumentException
4641
+	 * @since 4.9.0
4642
+	 */
4643
+	protected function _delete_ee_messages()
4644
+	{
4645
+		$MSG_IDs       = $this->_get_msg_ids_from_request();
4646
+		$deleted_count = 0;
4647
+		foreach ($MSG_IDs as $MSG_ID) {
4648
+			if ($this->getMsgModel()->delete_by_ID($MSG_ID)) {
4649
+				$deleted_count++;
4650
+			}
4651
+		}
4652
+		if ($deleted_count) {
4653
+			EE_Error::add_success(
4654
+				esc_html(
4655
+					_n(
4656
+						'Message successfully deleted',
4657
+						'Messages successfully deleted',
4658
+						$deleted_count,
4659
+						'event_espresso'
4660
+					)
4661
+				)
4662
+			);
4663
+		} else {
4664
+			EE_Error::add_error(
4665
+				_n('The message was not deleted.', 'The messages were not deleted', count($MSG_IDs), 'event_espresso'),
4666
+				__FILE__,
4667
+				__FUNCTION__,
4668
+				__LINE__
4669
+			);
4670
+		}
4671
+		$this->_redirect_after_action(false, '', '', [], true);
4672
+	}
4673
+
4674
+
4675
+	/**
4676
+	 *  This looks for 'MSG_ID' key in the request and returns an array of MSG_ID's if present.
4677
+	 *
4678
+	 * @return array
4679
+	 * @since 4.9.0
4680
+	 */
4681
+	protected function _get_msg_ids_from_request()
4682
+	{
4683
+		$MSG_IDs = $this->request->getRequestParam('MSG_ID', [], 'string', true);
4684
+		if (empty($MSG_IDs)) {
4685
+			return [];
4686
+		}
4687
+		// if 'MSG_ID' was just a single ID (not an array)
4688
+		// then $MSG_IDs will be something like [123] so $MSG_IDs[0] should be 123
4689
+		// otherwise, $MSG_IDs was already an array where message IDs were used as the keys
4690
+		return count($MSG_IDs) === 1 && isset($MSG_IDs[0])
4691
+			? $MSG_IDs
4692
+			: array_keys($MSG_IDs);
4693
+	}
4694 4694
 }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1196 added lines, -1196 removed lines patch added patch discarded remove patch
@@ -25,1200 +25,1200 @@
 block discarded – undo
25 25
 final class EE_System implements ResettableInterface
26 26
 {
27 27
 
28
-    /**
29
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
-     */
32
-    const req_type_normal = 0;
33
-
34
-    /**
35
-     * Indicates this is a brand new installation of EE so we should install
36
-     * tables and default data etc
37
-     */
38
-    const req_type_new_activation = 1;
39
-
40
-    /**
41
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
-     * and we just exited maintenance mode). We MUST check the database is setup properly
43
-     * and that default data is setup too
44
-     */
45
-    const req_type_reactivation = 2;
46
-
47
-    /**
48
-     * indicates that EE has been upgraded since its previous request.
49
-     * We may have data migration scripts to call and will want to trigger maintenance mode
50
-     */
51
-    const req_type_upgrade = 3;
52
-
53
-    /**
54
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
-     */
56
-    const req_type_downgrade = 4;
57
-
58
-    /**
59
-     * @deprecated since version 4.6.0.dev.006
60
-     * Now whenever a new_activation is detected the request type is still just
61
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
-     * (Specifically, when the migration manager indicates migrations are finished
65
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
-     */
67
-    const req_type_activation_but_not_installed = 5;
68
-
69
-    /**
70
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
-     */
72
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
-
74
-    /**
75
-     * @var AddonManager $addon_manager
76
-     */
77
-    private $addon_manager;
78
-
79
-    /**
80
-     * @var EE_System $_instance
81
-     */
82
-    private static $_instance;
83
-
84
-    /**
85
-     * @var EE_Registry $registry
86
-     */
87
-    private $registry;
88
-
89
-    /**
90
-     * @var LoaderInterface $loader
91
-     */
92
-    private $loader;
93
-
94
-    /**
95
-     * @var EE_Capabilities $capabilities
96
-     */
97
-    private $capabilities;
98
-
99
-    /**
100
-     * @var EE_Maintenance_Mode $maintenance_mode
101
-     */
102
-    private $maintenance_mode;
103
-
104
-    /**
105
-     * @var RequestInterface $request
106
-     */
107
-    private $request;
108
-
109
-    /**
110
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
-     *
113
-     * @var int $_req_type
114
-     */
115
-    private $_req_type;
116
-
117
-    /**
118
-     * Whether or not there was a non-micro version change in EE core version during this request
119
-     *
120
-     * @var boolean $_major_version_change
121
-     */
122
-    private $_major_version_change = false;
123
-
124
-    /**
125
-     * @var Router $router
126
-     */
127
-    private $router;
128
-
129
-    /**
130
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
131
-     */
132
-    private $register_custom_post_types;
133
-
134
-    /**
135
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
136
-     */
137
-    private $register_custom_taxonomies;
138
-
139
-    /**
140
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
141
-     */
142
-    private $register_custom_taxonomy_terms;
143
-
144
-    /**
145
-     * @singleton method used to instantiate class object
146
-     * @param LoaderInterface|null     $loader
147
-     * @param EE_Maintenance_Mode|null $maintenance_mode
148
-     * @param EE_Registry|null         $registry
149
-     * @param RequestInterface|null    $request
150
-     * @param Router|null              $router
151
-     * @return EE_System
152
-     */
153
-    public static function instance(
154
-        LoaderInterface $loader = null,
155
-        EE_Maintenance_Mode $maintenance_mode = null,
156
-        EE_Registry $registry = null,
157
-        RequestInterface $request = null,
158
-        Router $router = null
159
-    ): EE_System {
160
-        // check if class object is instantiated
161
-        if (! self::$_instance instanceof EE_System) {
162
-            self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
163
-        }
164
-        return self::$_instance;
165
-    }
166
-
167
-
168
-    /**
169
-     * resets the instance and returns it
170
-     *
171
-     * @return EE_System
172
-     */
173
-    public static function reset(): EE_System
174
-    {
175
-        self::$_instance->_req_type = null;
176
-        // make sure none of the old hooks are left hanging around
177
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
178
-        // we need to reset the migration manager in order for it to detect DMSs properly
179
-        EE_Data_Migration_Manager::reset();
180
-        self::instance()->detect_activations_or_upgrades();
181
-        self::instance()->perform_activations_upgrades_and_migrations();
182
-        return self::instance();
183
-    }
184
-
185
-
186
-    /**
187
-     * sets hooks for running rest of system
188
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
189
-     * starting EE Addons from any other point may lead to problems
190
-     *
191
-     * @param LoaderInterface     $loader
192
-     * @param EE_Maintenance_Mode $maintenance_mode
193
-     * @param EE_Registry         $registry
194
-     * @param RequestInterface    $request
195
-     * @param Router              $router
196
-     */
197
-    private function __construct(
198
-        LoaderInterface $loader,
199
-        EE_Maintenance_Mode $maintenance_mode,
200
-        EE_Registry $registry,
201
-        RequestInterface $request,
202
-        Router $router
203
-    ) {
204
-        $this->registry         = $registry;
205
-        $this->loader           = $loader;
206
-        $this->request          = $request;
207
-        $this->router           = $router;
208
-        $this->maintenance_mode = $maintenance_mode;
209
-        do_action('AHEE__EE_System__construct__begin', $this);
210
-        add_action(
211
-            'AHEE__EE_Bootstrap__load_espresso_addons',
212
-            [$this, 'loadCapabilities'],
213
-            5
214
-        );
215
-        add_action(
216
-            'AHEE__EE_Bootstrap__load_espresso_addons',
217
-            [$this, 'loadCommandBus'],
218
-            7
219
-        );
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_espresso_addons',
222
-            [$this, 'loadPluginApi'],
223
-            9
224
-        );
225
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_espresso_addons',
228
-            [$this, 'load_espresso_addons']
229
-        );
230
-        // when an ee addon is activated, we want to call the core hook(s) again
231
-        // because the newly-activated addon didn't get a chance to run at all
232
-        add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
233
-        // detect whether install or upgrade
234
-        add_action(
235
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
236
-            [$this, 'detect_activations_or_upgrades'],
237
-            3
238
-        );
239
-        // load EE_Config, EE_Textdomain, etc
240
-        add_action(
241
-            'AHEE__EE_Bootstrap__load_core_configuration',
242
-            [$this, 'load_core_configuration'],
243
-            5
244
-        );
245
-        // load specifications for matching routes to current request
246
-        add_action(
247
-            'AHEE__EE_Bootstrap__load_core_configuration',
248
-            [$this, 'loadRouteMatchSpecifications']
249
-        );
250
-        // load specifications for custom post types
251
-        add_action(
252
-            'AHEE__EE_Bootstrap__load_core_configuration',
253
-            array($this, 'loadCustomPostTypes')
254
-        );
255
-        // load specifications for custom post types
256
-        add_action(
257
-            'AHEE__EE_Bootstrap__load_core_configuration',
258
-            array($this, 'loadCustomPostTypes')
259
-        );
260
-        // load EE_Config, EE_Textdomain, etc
261
-        add_action(
262
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
263
-            [$this, 'register_shortcodes_modules_and_widgets'],
264
-            7
265
-        );
266
-        // you wanna get going? I wanna get going... let's get going!
267
-        add_action(
268
-            'AHEE__EE_Bootstrap__brew_espresso',
269
-            [$this, 'brew_espresso'],
270
-            9
271
-        );
272
-        // other housekeeping
273
-        // exclude EE critical pages from wp_list_pages
274
-        add_filter(
275
-            'wp_list_pages_excludes',
276
-            [$this, 'remove_pages_from_wp_list_pages'],
277
-            10
278
-        );
279
-        // ALL EE Addons should use the following hook point to attach their initial setup too
280
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
281
-        do_action('AHEE__EE_System__construct__complete', $this);
282
-    }
283
-
284
-
285
-    /**
286
-     * load and setup EE_Capabilities
287
-     *
288
-     * @return void
289
-     */
290
-    public function loadCapabilities()
291
-    {
292
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
293
-        add_action(
294
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
295
-            function () {
296
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
297
-            }
298
-        );
299
-    }
300
-
301
-
302
-    /**
303
-     * create and cache the CommandBus, and also add middleware
304
-     * The CapChecker middleware requires the use of EE_Capabilities
305
-     * which is why we need to load the CommandBus after Caps are set up
306
-     *
307
-     * @return void
308
-     */
309
-    public function loadCommandBus()
310
-    {
311
-        $this->loader->getShared(
312
-            'CommandBusInterface',
313
-            [
314
-                null,
315
-                apply_filters(
316
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
317
-                    [
318
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
319
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
320
-                    ]
321
-                ),
322
-            ]
323
-        );
324
-    }
325
-
326
-
327
-    /**
328
-     * @return void
329
-     * @throws Exception
330
-     */
331
-    public function loadPluginApi()
332
-    {
333
-        $this->addon_manager = $this->loader->getShared(AddonManager::class);
334
-        $this->addon_manager->initialize();
335
-        $this->loader->getShared('EE_Request_Handler');
336
-    }
337
-
338
-
339
-    /**
340
-     * load_espresso_addons
341
-     * allow addons to load first so that they can set hooks for running DMS's, etc
342
-     * this is hooked into both:
343
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
344
-     *        which runs during the WP 'plugins_loaded' action at priority 5
345
-     *    and the WP 'activate_plugin' hook point
346
-     *
347
-     * @return void
348
-     * @throws Exception
349
-     */
350
-    public function load_espresso_addons()
351
-    {
352
-        // looking for hooks? they've been moved into the AddonManager to maintain compatibility
353
-        $this->addon_manager->loadAddons();
354
-    }
355
-
356
-
357
-    /**
358
-     * detect_activations_or_upgrades
359
-     * Checks for activation or upgrade of core first;
360
-     * then also checks if any registered addons have been activated or upgraded
361
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
362
-     * which runs during the WP 'plugins_loaded' action at priority 3
363
-     *
364
-     * @access public
365
-     * @return void
366
-     */
367
-    public function detect_activations_or_upgrades()
368
-    {
369
-        // first off: let's make sure to handle core
370
-        $this->detect_if_activation_or_upgrade();
371
-        foreach ($this->registry->addons as $addon) {
372
-            if ($addon instanceof EE_Addon) {
373
-                // detect teh request type for that addon
374
-                $addon->detect_req_type();
375
-            }
376
-        }
377
-    }
378
-
379
-
380
-    /**
381
-     * detect_if_activation_or_upgrade
382
-     * Takes care of detecting whether this is a brand new install or code upgrade,
383
-     * and either setting up the DB or setting up maintenance mode etc.
384
-     *
385
-     * @access public
386
-     * @return void
387
-     */
388
-    public function detect_if_activation_or_upgrade()
389
-    {
390
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
391
-        // check if db has been updated, or if its a brand-new installation
392
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
393
-        $request_type       = $this->detect_req_type($espresso_db_update);
394
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
395
-        switch ($request_type) {
396
-            case EE_System::req_type_new_activation:
397
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
398
-                $this->_handle_core_version_change($espresso_db_update);
399
-                break;
400
-            case EE_System::req_type_reactivation:
401
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
402
-                $this->_handle_core_version_change($espresso_db_update);
403
-                break;
404
-            case EE_System::req_type_upgrade:
405
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
406
-                // migrations may be required now that we've upgraded
407
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
408
-                $this->_handle_core_version_change($espresso_db_update);
409
-                break;
410
-            case EE_System::req_type_downgrade:
411
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
412
-                // its possible migrations are no longer required
413
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
414
-                $this->_handle_core_version_change($espresso_db_update);
415
-                break;
416
-            case EE_System::req_type_normal:
417
-            default:
418
-                break;
419
-        }
420
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
421
-    }
422
-
423
-
424
-    /**
425
-     * Updates the list of installed versions and sets hooks for
426
-     * initializing the database later during the request
427
-     *
428
-     * @param array $espresso_db_update
429
-     */
430
-    private function _handle_core_version_change(array $espresso_db_update)
431
-    {
432
-        $this->update_list_of_installed_versions($espresso_db_update);
433
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
434
-        add_action(
435
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
436
-            [$this, 'initialize_db_if_no_migrations_required']
437
-        );
438
-    }
439
-
440
-
441
-    /**
442
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
443
-     * information about what versions of EE have been installed and activated,
444
-     * NOT necessarily the state of the database
445
-     *
446
-     * @param mixed $espresso_db_update           the value of the WordPress option.
447
-     *                                            If not supplied, fetches it from the options table
448
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
449
-     */
450
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
451
-    {
452
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
453
-        if (! $espresso_db_update) {
454
-            $espresso_db_update = get_option('espresso_db_update');
455
-        }
456
-        // check that option is an array
457
-        if (! is_array($espresso_db_update)) {
458
-            // if option is FALSE, then it never existed
459
-            if ($espresso_db_update === false) {
460
-                // make $espresso_db_update an array and save option with autoload OFF
461
-                $espresso_db_update = [];
462
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
463
-            } else {
464
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
465
-                $espresso_db_update = [$espresso_db_update => []];
466
-                update_option('espresso_db_update', $espresso_db_update);
467
-            }
468
-        } else {
469
-            $corrected_db_update = [];
470
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
471
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
472
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
473
-                    // the key is an int, and the value IS NOT an array
474
-                    // so it must be numerically-indexed, where values are versions installed...
475
-                    // fix it!
476
-                    $version_string                         = $should_be_array;
477
-                    $corrected_db_update[ $version_string ] = ['unknown-date'];
478
-                } else {
479
-                    // ok it checks out
480
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
481
-                }
482
-            }
483
-            $espresso_db_update = $corrected_db_update;
484
-            update_option('espresso_db_update', $espresso_db_update);
485
-        }
486
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
487
-        return ! empty($espresso_db_update) ? $espresso_db_update : [];
488
-    }
489
-
490
-
491
-    /**
492
-     * Does the traditional work of setting up the plugin's database and adding default data.
493
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
494
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
495
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
496
-     * so that it will be done when migrations are finished
497
-     *
498
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
499
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
500
-     *                                       This is a resource-intensive job
501
-     *                                       so we prefer to only do it when necessary
502
-     * @return void
503
-     * @throws EE_Error
504
-     * @throws ReflectionException
505
-     */
506
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
507
-    {
508
-        $request_type = $this->detect_req_type();
509
-        // only initialize system if we're not in maintenance mode.
510
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
511
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
512
-            $rewrite_rules = $this->loader->getShared(
513
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
514
-            );
515
-            $rewrite_rules->flush();
516
-            if ($verify_schema) {
517
-                EEH_Activation::initialize_db_and_folders();
518
-            }
519
-            EEH_Activation::initialize_db_content();
520
-            EEH_Activation::system_initialization();
521
-            if ($initialize_addons_too) {
522
-                $this->initialize_addons();
523
-            }
524
-        } else {
525
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
526
-        }
527
-        if (
528
-            $request_type === EE_System::req_type_new_activation
529
-            || $request_type === EE_System::req_type_reactivation
530
-            || (
531
-                $request_type === EE_System::req_type_upgrade
532
-                && $this->is_major_version_change()
533
-            )
534
-        ) {
535
-            add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
536
-        }
537
-    }
538
-
539
-
540
-    /**
541
-     * Initializes the db for all registered addons
542
-     *
543
-     * @throws EE_Error
544
-     * @throws ReflectionException
545
-     */
546
-    public function initialize_addons()
547
-    {
548
-        // foreach registered addon, make sure its db is up-to-date too
549
-        foreach ($this->registry->addons as $addon) {
550
-            if ($addon instanceof EE_Addon) {
551
-                $addon->initialize_db_if_no_migrations_required();
552
-            }
553
-        }
554
-    }
555
-
556
-
557
-    /**
558
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
559
-     *
560
-     * @param array  $version_history
561
-     * @param string $current_version_to_add version to be added to the version history
562
-     * @return    boolean success as to whether or not this option was changed
563
-     */
564
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
565
-    {
566
-        if (! $version_history) {
567
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
568
-        }
569
-        if ($current_version_to_add === null) {
570
-            $current_version_to_add = espresso_version();
571
-        }
572
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
573
-        // re-save
574
-        return update_option('espresso_db_update', $version_history);
575
-    }
576
-
577
-
578
-    /**
579
-     * Detects if the current version indicated in the has existed in the list of
580
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
581
-     *
582
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
583
-     *                                  If not supplied, fetches it from the options table.
584
-     *                                  Also, caches its result so later parts of the code can also know whether
585
-     *                                  there's been an update or not. This way we can add the current version to
586
-     *                                  espresso_db_update, but still know if this is a new install or not
587
-     * @return int one of the constants on EE_System::req_type_
588
-     */
589
-    public function detect_req_type($espresso_db_update = null): int
590
-    {
591
-        if ($this->_req_type === null) {
592
-            $espresso_db_update          = ! empty($espresso_db_update)
593
-                ? $espresso_db_update
594
-                : $this->fix_espresso_db_upgrade_option();
595
-            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
596
-                $espresso_db_update,
597
-                'ee_espresso_activation',
598
-                espresso_version()
599
-            );
600
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
601
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
602
-        }
603
-        return $this->_req_type;
604
-    }
605
-
606
-
607
-    /**
608
-     * Returns whether or not there was a non-micro version change (ie, change in either
609
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
610
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
611
-     *
612
-     * @param $activation_history
613
-     * @return bool
614
-     */
615
-    private function _detect_major_version_change($activation_history): bool
616
-    {
617
-        $previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
618
-        $previous_version_parts = explode('.', $previous_version);
619
-        $current_version_parts  = explode('.', espresso_version());
620
-        return isset(
621
-            $previous_version_parts[0],
622
-            $previous_version_parts[1],
623
-            $current_version_parts[0],
624
-            $current_version_parts[1]
625
-        ) && (
626
-            $previous_version_parts[0] !== $current_version_parts[0]
627
-            || $previous_version_parts[1] !== $current_version_parts[1]
628
-        );
629
-    }
630
-
631
-
632
-    /**
633
-     * Returns true if either the major or minor version of EE changed during this request.
634
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
635
-     *
636
-     * @return bool
637
-     */
638
-    public function is_major_version_change(): bool
639
-    {
640
-        return $this->_major_version_change;
641
-    }
642
-
643
-
644
-    /**
645
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
646
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
647
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
648
-     * just activated to (for core that will always be espresso_version())
649
-     *
650
-     * @param array|null $activation_history             the option's value which stores the activation history for
651
-     *                                                 this
652
-     *                                                 ee plugin. for core that's 'espresso_db_update'
653
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
654
-     *                                                 indicate that this plugin was just activated
655
-     * @param string $current_version                  the version that was just upgraded to (for core that will be
656
-     *                                                 espresso_version())
657
-     * @return int one of the constants on EE_System::req_type_
658
-     */
659
-    public static function detect_req_type_given_activation_history(
660
-        array $activation_history,
661
-        string $activation_indicator_option_name,
662
-        string $current_version
663
-    ): int {
664
-        $version_change = self::compareVersionWithPrevious($activation_history, $current_version);
665
-        $is_activation  = get_option($activation_indicator_option_name, false);
666
-        $req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
667
-        if ($is_activation) {
668
-            // cleanup in aisle 6
669
-            delete_option($activation_indicator_option_name);
670
-        }
671
-        return $req_type;
672
-    }
673
-
674
-
675
-    /**
676
-     * @param array  $activation_history
677
-     * @param int    $version_change
678
-     * @param bool   $is_activation
679
-     * @return int
680
-     * @since $VID:$
681
-     */
682
-    private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
683
-    {
684
-        // if no previous activation history exists, then this is a brand new install
685
-        if (empty($activation_history)) {
686
-            return EE_System::req_type_new_activation;
687
-        }
688
-        // current version is higher than previous version, so it's an upgrade
689
-        if ($version_change === 1) {
690
-            return EE_System::req_type_upgrade;
691
-        }
692
-        // current version is lower than previous version, so it's a downgrade
693
-        if ($version_change === -1) {
694
-            return EE_System::req_type_downgrade;
695
-        }
696
-        // version hasn't changed since last version so check if the activation indicator is set
697
-        // to determine if it's a reactivation, or just a normal request
698
-        return $is_activation
699
-            ? EE_System::req_type_reactivation
700
-            : EE_System::req_type_normal;
701
-    }
702
-
703
-
704
-    /**
705
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
706
-     * the $activation_history_for_addon
707
-     *
708
-     * @param array  $activation_history    array where keys are versions,
709
-     *                                      values are arrays of times activated (sometimes 'unknown-date')
710
-     * @param string $current_version
711
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
712
-     *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
713
-     *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
714
-     *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
715
-     */
716
-    private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
717
-    {
718
-        // find the most recently-activated version
719
-        $most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
720
-        return version_compare($current_version, $most_recently_active_version);
721
-    }
722
-
723
-
724
-    /**
725
-     * Gets the most recently active version listed in the activation history,
726
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
727
-     *
728
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
729
-     *                                   sometimes containing 'unknown-date'
730
-     * @return string
731
-     */
732
-    private static function getMostRecentlyActiveVersion(array $activation_history): string
733
-    {
734
-        $most_recent_activation_date  = '1970-01-01 00:00:00';
735
-        $most_recently_active_version = '0.0.0.dev.000';
736
-        if (is_array($activation_history)) {
737
-            foreach ($activation_history as $version => $activation_dates) {
738
-                // check there is a record of when this version was activated.
739
-                // Otherwise, mark it as unknown
740
-                if (! $activation_dates) {
741
-                    $activation_dates = ['unknown-date'];
742
-                }
743
-                $activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
744
-                foreach ($activation_dates as $activation_date) {
745
-                    if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
746
-                        $most_recently_active_version = $version;
747
-                        $most_recent_activation_date  = $activation_date;
748
-                    }
749
-                }
750
-            }
751
-        }
752
-        return $most_recently_active_version;
753
-    }
754
-
755
-
756
-    /**
757
-     * This redirects to the about EE page after activation
758
-     *
759
-     * @return void
760
-     */
761
-    public function redirect_to_about_ee()
762
-    {
763
-        $notices = EE_Error::get_notices(false);
764
-        // if current user is an admin and it's not an ajax or rest request
765
-        if (
766
-            ! isset($notices['errors'])
767
-            && $this->request->isAdmin()
768
-            && apply_filters(
769
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
770
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
771
-            )
772
-        ) {
773
-            $query_params = ['page' => 'espresso_about'];
774
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
775
-                $query_params['new_activation'] = true;
776
-            }
777
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
778
-                $query_params['reactivation'] = true;
779
-            }
780
-            $url = add_query_arg($query_params, admin_url('admin.php'));
781
-            EEH_URL::safeRedirectAndExit($url);
782
-        }
783
-    }
784
-
785
-
786
-    /**
787
-     * load_core_configuration
788
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
789
-     * which runs during the WP 'plugins_loaded' action at priority 5
790
-     *
791
-     * @return void
792
-     * @throws ReflectionException
793
-     * @throws Exception
794
-     */
795
-    public function load_core_configuration()
796
-    {
797
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
798
-        $this->loader->getShared('EE_Load_Textdomain');
799
-        // load textdomain
800
-        EE_Load_Textdomain::load_textdomain();
801
-        // load caf stuff a chance to play during the activation process too.
802
-        $this->_maybe_brew_regular();
803
-        // load and setup EE_Config and EE_Network_Config
804
-        $config = $this->loader->getShared('EE_Config');
805
-        $this->loader->getShared('EE_Network_Config');
806
-        // setup autoloaders
807
-        // enable logging?
808
-        if ($config->admin->use_remote_logging) {
809
-            $this->loader->getShared('EE_Log');
810
-        }
811
-        // check for activation errors
812
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
813
-        if ($activation_errors) {
814
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
815
-            update_option('ee_plugin_activation_errors', false);
816
-        }
817
-        // get model names
818
-        $this->_parse_model_names();
819
-        // configure custom post type definitions
820
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
821
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
822
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
823
-    }
824
-
825
-
826
-    /**
827
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
828
-     *
829
-     * @return void
830
-     * @throws ReflectionException
831
-     */
832
-    private function _parse_model_names()
833
-    {
834
-        // get all the files in the EE_MODELS folder that end in .model.php
835
-        $models                 = glob(EE_MODELS . '*.model.php');
836
-        $model_names            = [];
837
-        $non_abstract_db_models = [];
838
-        foreach ($models as $model) {
839
-            // get model classname
840
-            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
841
-            $short_name      = str_replace('EEM_', '', $classname);
842
-            $reflectionClass = new ReflectionClass($classname);
843
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
844
-                $non_abstract_db_models[ $short_name ] = $classname;
845
-            }
846
-            $model_names[ $short_name ] = $classname;
847
-        }
848
-        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
849
-        $this->registry->non_abstract_db_models = apply_filters(
850
-            'FHEE__EE_System__parse_implemented_model_names',
851
-            $non_abstract_db_models
852
-        );
853
-    }
854
-
855
-
856
-    /**
857
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
858
-     * that need to be setup before our EE_System launches.
859
-     *
860
-     * @return void
861
-     * @throws DomainException
862
-     * @throws InvalidArgumentException
863
-     * @throws InvalidDataTypeException
864
-     * @throws InvalidInterfaceException
865
-     * @throws InvalidClassException
866
-     * @throws InvalidFilePathException
867
-     */
868
-    private function _maybe_brew_regular()
869
-    {
870
-        /** @var Domain $domain */
871
-        $domain = DomainFactory::getEventEspressoCoreDomain();
872
-        if ($domain->isCaffeinated()) {
873
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
874
-        }
875
-    }
876
-
877
-
878
-    /**
879
-     * @throws Exception
880
-     * @since 4.9.71.p
881
-     */
882
-    public function loadRouteMatchSpecifications()
883
-    {
884
-        try {
885
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
886
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
887
-            $this->router->loadPrimaryRoutes();
888
-        } catch (Exception $exception) {
889
-            new ExceptionStackTraceDisplay($exception);
890
-        }
891
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
892
-    }
893
-
894
-
895
-    /**
896
-     * loading CPT related classes earlier so that their definitions are available
897
-     * but not performing any actual registration with WP core until load_CPTs_and_session() is called
898
-     *
899
-     * @since   4.10.21.p
900
-     */
901
-    public function loadCustomPostTypes()
902
-    {
903
-        $this->register_custom_taxonomies = $this->loader->getShared(
904
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
905
-        );
906
-        $this->register_custom_post_types = $this->loader->getShared(
907
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
908
-        );
909
-        $this->register_custom_taxonomy_terms = $this->loader->getShared(
910
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
911
-        );
912
-        // integrate WP_Query with the EE models
913
-        $this->loader->getShared('EE_CPT_Strategy');
914
-        // load legacy EE_Request_Handler in case add-ons still need it
915
-        $this->loader->getShared('EE_Request_Handler');
916
-    }
917
-
918
-
919
-    /**
920
-     * register_shortcodes_modules_and_widgets
921
-     * generate lists of shortcodes and modules, then verify paths and classes
922
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
923
-     * which runs during the WP 'plugins_loaded' action at priority 7
924
-     *
925
-     * @access public
926
-     * @return void
927
-     * @throws Exception
928
-     */
929
-    public function register_shortcodes_modules_and_widgets()
930
-    {
931
-        $this->router->registerShortcodesModulesAndWidgets();
932
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
933
-        // check for addons using old hook point
934
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
935
-            $this->_incompatible_addon_error();
936
-        }
937
-    }
938
-
939
-
940
-    /**
941
-     * _incompatible_addon_error
942
-     *
943
-     * @access public
944
-     * @return void
945
-     */
946
-    private function _incompatible_addon_error()
947
-    {
948
-        // get array of classes hooking into here
949
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
950
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
951
-        );
952
-        if (! empty($class_names)) {
953
-            $msg = esc_html__(
954
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
955
-                'event_espresso'
956
-            );
957
-            $msg .= '<ul>';
958
-            foreach ($class_names as $class_name) {
959
-                $msg .= '<li><b>Event Espresso - '
960
-                        . str_replace(
961
-                            ['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
962
-                            '',
963
-                            $class_name
964
-                        ) . '</b></li>';
965
-            }
966
-            $msg .= '</ul>';
967
-            $msg .= esc_html__(
968
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
969
-                'event_espresso'
970
-            );
971
-            // save list of incompatible addons to wp-options for later use
972
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
973
-            if (is_admin()) {
974
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
975
-            }
976
-        }
977
-    }
978
-
979
-
980
-    /**
981
-     * brew_espresso
982
-     * begins the process of setting hooks for initializing EE in the correct order
983
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
984
-     * which runs during the WP 'plugins_loaded' action at priority 9
985
-     *
986
-     * @return void
987
-     * @throws Exception
988
-     */
989
-    public function brew_espresso()
990
-    {
991
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
992
-        // load some final core systems
993
-        add_action('init', [$this, 'set_hooks_for_core'], 1);
994
-        add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
995
-        add_action('init', [$this, 'load_CPTs_and_session'], 5);
996
-        add_action('init', [$this, 'load_controllers'], 7);
997
-        add_action('init', [$this, 'core_loaded_and_ready'], 9);
998
-        add_action('init', [$this, 'initialize'], 10);
999
-        add_action('init', [$this, 'initialize_last'], 100);
1000
-        $this->router->brewEspresso();
1001
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1002
-    }
1003
-
1004
-
1005
-    /**
1006
-     *    set_hooks_for_core
1007
-     *
1008
-     * @access public
1009
-     * @return    void
1010
-     * @throws EE_Error
1011
-     */
1012
-    public function set_hooks_for_core()
1013
-    {
1014
-        $this->_deactivate_incompatible_addons();
1015
-        do_action('AHEE__EE_System__set_hooks_for_core');
1016
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1017
-        // caps need to be initialized on every request so that capability maps are set.
1018
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1019
-        $this->registry->CAP->init_caps();
1020
-    }
1021
-
1022
-
1023
-    /**
1024
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1025
-     * deactivates any addons considered incompatible with the current version of EE
1026
-     */
1027
-    private function _deactivate_incompatible_addons()
1028
-    {
1029
-        $incompatible_addons = get_option('ee_incompatible_addons', []);
1030
-        if (! empty($incompatible_addons)) {
1031
-            $active_plugins = get_option('active_plugins', []);
1032
-            foreach ($active_plugins as $active_plugin) {
1033
-                foreach ($incompatible_addons as $incompatible_addon) {
1034
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1035
-                        $this->request->unSetRequestParams(['activate'], true);
1036
-                        espresso_deactivate_plugin($active_plugin);
1037
-                    }
1038
-                }
1039
-            }
1040
-        }
1041
-    }
1042
-
1043
-
1044
-    /**
1045
-     *    perform_activations_upgrades_and_migrations
1046
-     *
1047
-     * @access public
1048
-     * @return    void
1049
-     */
1050
-    public function perform_activations_upgrades_and_migrations()
1051
-    {
1052
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1053
-    }
1054
-
1055
-
1056
-    /**
1057
-     * @return void
1058
-     * @throws DomainException
1059
-     */
1060
-    public function load_CPTs_and_session()
1061
-    {
1062
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1063
-        $this->register_custom_taxonomies->registerCustomTaxonomies();
1064
-        $this->register_custom_post_types->registerCustomPostTypes();
1065
-        $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1066
-        // load legacy Custom Post Types and Taxonomies
1067
-        $this->loader->getShared('EE_Register_CPTs');
1068
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1069
-    }
1070
-
1071
-
1072
-    /**
1073
-     * load_controllers
1074
-     * this is the best place to load any additional controllers that needs access to EE core.
1075
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1076
-     * time
1077
-     *
1078
-     * @access public
1079
-     * @return void
1080
-     * @throws Exception
1081
-     */
1082
-    public function load_controllers()
1083
-    {
1084
-        do_action('AHEE__EE_System__load_controllers__start');
1085
-        $this->router->loadControllers();
1086
-        do_action('AHEE__EE_System__load_controllers__complete');
1087
-    }
1088
-
1089
-
1090
-    /**
1091
-     * core_loaded_and_ready
1092
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1093
-     *
1094
-     * @access public
1095
-     * @return void
1096
-     * @throws Exception
1097
-     */
1098
-    public function core_loaded_and_ready()
1099
-    {
1100
-        $this->router->coreLoadedAndReady();
1101
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1102
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1103
-        // builders require these even on the front-end
1104
-        require_once EE_PUBLIC . 'template_tags.php';
1105
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1106
-    }
1107
-
1108
-
1109
-    /**
1110
-     * initialize
1111
-     * this is the best place to begin initializing client code
1112
-     *
1113
-     * @access public
1114
-     * @return void
1115
-     */
1116
-    public function initialize()
1117
-    {
1118
-        do_action('AHEE__EE_System__initialize');
1119
-    }
1120
-
1121
-
1122
-    /**
1123
-     * initialize_last
1124
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1125
-     * initialize has done so
1126
-     *
1127
-     * @access public
1128
-     * @return void
1129
-     * @throws Exception
1130
-     */
1131
-    public function initialize_last()
1132
-    {
1133
-        $this->router->initializeLast();
1134
-        do_action('AHEE__EE_System__initialize_last');
1135
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1136
-        $rewrite_rules = $this->loader->getShared(
1137
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1138
-        );
1139
-        $rewrite_rules->flushRewriteRules();
1140
-        add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * @return void
1146
-     */
1147
-    public function addEspressoToolbar()
1148
-    {
1149
-        $this->loader->getShared(
1150
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1151
-            [$this->registry->CAP]
1152
-        );
1153
-    }
1154
-
1155
-
1156
-    /**
1157
-     * do_not_cache
1158
-     * sets no cache headers and defines no cache constants for WP plugins
1159
-     *
1160
-     * @access public
1161
-     * @return void
1162
-     */
1163
-    public static function do_not_cache()
1164
-    {
1165
-        // set no cache constants
1166
-        if (! defined('DONOTCACHEPAGE')) {
1167
-            define('DONOTCACHEPAGE', true);
1168
-        }
1169
-        if (! defined('DONOTCACHCEOBJECT')) {
1170
-            define('DONOTCACHCEOBJECT', true);
1171
-        }
1172
-        if (! defined('DONOTCACHEDB')) {
1173
-            define('DONOTCACHEDB', true);
1174
-        }
1175
-        // add no cache headers
1176
-        add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1177
-        // plus a little extra for nginx and Google Chrome
1178
-        add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1179
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1180
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1181
-    }
1182
-
1183
-
1184
-    /**
1185
-     *    extra_nocache_headers
1186
-     *
1187
-     * @access    public
1188
-     * @param $headers
1189
-     * @return    array
1190
-     */
1191
-    public static function extra_nocache_headers($headers): array
1192
-    {
1193
-        // for NGINX
1194
-        $headers['X-Accel-Expires'] = 0;
1195
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1196
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1197
-        return $headers;
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     *    nocache_headers
1203
-     *
1204
-     * @access    public
1205
-     * @return    void
1206
-     */
1207
-    public static function nocache_headers()
1208
-    {
1209
-        nocache_headers();
1210
-    }
1211
-
1212
-
1213
-    /**
1214
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1215
-     * never returned with the function.
1216
-     *
1217
-     * @param array $exclude_array any existing pages being excluded are in this array.
1218
-     * @return array
1219
-     */
1220
-    public function remove_pages_from_wp_list_pages(array $exclude_array): array
1221
-    {
1222
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1223
-    }
28
+	/**
29
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
30
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
31
+	 */
32
+	const req_type_normal = 0;
33
+
34
+	/**
35
+	 * Indicates this is a brand new installation of EE so we should install
36
+	 * tables and default data etc
37
+	 */
38
+	const req_type_new_activation = 1;
39
+
40
+	/**
41
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
42
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
43
+	 * and that default data is setup too
44
+	 */
45
+	const req_type_reactivation = 2;
46
+
47
+	/**
48
+	 * indicates that EE has been upgraded since its previous request.
49
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
50
+	 */
51
+	const req_type_upgrade = 3;
52
+
53
+	/**
54
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
55
+	 */
56
+	const req_type_downgrade = 4;
57
+
58
+	/**
59
+	 * @deprecated since version 4.6.0.dev.006
60
+	 * Now whenever a new_activation is detected the request type is still just
61
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
62
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
63
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
64
+	 * (Specifically, when the migration manager indicates migrations are finished
65
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
66
+	 */
67
+	const req_type_activation_but_not_installed = 5;
68
+
69
+	/**
70
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
71
+	 */
72
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
73
+
74
+	/**
75
+	 * @var AddonManager $addon_manager
76
+	 */
77
+	private $addon_manager;
78
+
79
+	/**
80
+	 * @var EE_System $_instance
81
+	 */
82
+	private static $_instance;
83
+
84
+	/**
85
+	 * @var EE_Registry $registry
86
+	 */
87
+	private $registry;
88
+
89
+	/**
90
+	 * @var LoaderInterface $loader
91
+	 */
92
+	private $loader;
93
+
94
+	/**
95
+	 * @var EE_Capabilities $capabilities
96
+	 */
97
+	private $capabilities;
98
+
99
+	/**
100
+	 * @var EE_Maintenance_Mode $maintenance_mode
101
+	 */
102
+	private $maintenance_mode;
103
+
104
+	/**
105
+	 * @var RequestInterface $request
106
+	 */
107
+	private $request;
108
+
109
+	/**
110
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
111
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
112
+	 *
113
+	 * @var int $_req_type
114
+	 */
115
+	private $_req_type;
116
+
117
+	/**
118
+	 * Whether or not there was a non-micro version change in EE core version during this request
119
+	 *
120
+	 * @var boolean $_major_version_change
121
+	 */
122
+	private $_major_version_change = false;
123
+
124
+	/**
125
+	 * @var Router $router
126
+	 */
127
+	private $router;
128
+
129
+	/**
130
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
131
+	 */
132
+	private $register_custom_post_types;
133
+
134
+	/**
135
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
136
+	 */
137
+	private $register_custom_taxonomies;
138
+
139
+	/**
140
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
141
+	 */
142
+	private $register_custom_taxonomy_terms;
143
+
144
+	/**
145
+	 * @singleton method used to instantiate class object
146
+	 * @param LoaderInterface|null     $loader
147
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
148
+	 * @param EE_Registry|null         $registry
149
+	 * @param RequestInterface|null    $request
150
+	 * @param Router|null              $router
151
+	 * @return EE_System
152
+	 */
153
+	public static function instance(
154
+		LoaderInterface $loader = null,
155
+		EE_Maintenance_Mode $maintenance_mode = null,
156
+		EE_Registry $registry = null,
157
+		RequestInterface $request = null,
158
+		Router $router = null
159
+	): EE_System {
160
+		// check if class object is instantiated
161
+		if (! self::$_instance instanceof EE_System) {
162
+			self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
163
+		}
164
+		return self::$_instance;
165
+	}
166
+
167
+
168
+	/**
169
+	 * resets the instance and returns it
170
+	 *
171
+	 * @return EE_System
172
+	 */
173
+	public static function reset(): EE_System
174
+	{
175
+		self::$_instance->_req_type = null;
176
+		// make sure none of the old hooks are left hanging around
177
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
178
+		// we need to reset the migration manager in order for it to detect DMSs properly
179
+		EE_Data_Migration_Manager::reset();
180
+		self::instance()->detect_activations_or_upgrades();
181
+		self::instance()->perform_activations_upgrades_and_migrations();
182
+		return self::instance();
183
+	}
184
+
185
+
186
+	/**
187
+	 * sets hooks for running rest of system
188
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
189
+	 * starting EE Addons from any other point may lead to problems
190
+	 *
191
+	 * @param LoaderInterface     $loader
192
+	 * @param EE_Maintenance_Mode $maintenance_mode
193
+	 * @param EE_Registry         $registry
194
+	 * @param RequestInterface    $request
195
+	 * @param Router              $router
196
+	 */
197
+	private function __construct(
198
+		LoaderInterface $loader,
199
+		EE_Maintenance_Mode $maintenance_mode,
200
+		EE_Registry $registry,
201
+		RequestInterface $request,
202
+		Router $router
203
+	) {
204
+		$this->registry         = $registry;
205
+		$this->loader           = $loader;
206
+		$this->request          = $request;
207
+		$this->router           = $router;
208
+		$this->maintenance_mode = $maintenance_mode;
209
+		do_action('AHEE__EE_System__construct__begin', $this);
210
+		add_action(
211
+			'AHEE__EE_Bootstrap__load_espresso_addons',
212
+			[$this, 'loadCapabilities'],
213
+			5
214
+		);
215
+		add_action(
216
+			'AHEE__EE_Bootstrap__load_espresso_addons',
217
+			[$this, 'loadCommandBus'],
218
+			7
219
+		);
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_espresso_addons',
222
+			[$this, 'loadPluginApi'],
223
+			9
224
+		);
225
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_espresso_addons',
228
+			[$this, 'load_espresso_addons']
229
+		);
230
+		// when an ee addon is activated, we want to call the core hook(s) again
231
+		// because the newly-activated addon didn't get a chance to run at all
232
+		add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
233
+		// detect whether install or upgrade
234
+		add_action(
235
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
236
+			[$this, 'detect_activations_or_upgrades'],
237
+			3
238
+		);
239
+		// load EE_Config, EE_Textdomain, etc
240
+		add_action(
241
+			'AHEE__EE_Bootstrap__load_core_configuration',
242
+			[$this, 'load_core_configuration'],
243
+			5
244
+		);
245
+		// load specifications for matching routes to current request
246
+		add_action(
247
+			'AHEE__EE_Bootstrap__load_core_configuration',
248
+			[$this, 'loadRouteMatchSpecifications']
249
+		);
250
+		// load specifications for custom post types
251
+		add_action(
252
+			'AHEE__EE_Bootstrap__load_core_configuration',
253
+			array($this, 'loadCustomPostTypes')
254
+		);
255
+		// load specifications for custom post types
256
+		add_action(
257
+			'AHEE__EE_Bootstrap__load_core_configuration',
258
+			array($this, 'loadCustomPostTypes')
259
+		);
260
+		// load EE_Config, EE_Textdomain, etc
261
+		add_action(
262
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
263
+			[$this, 'register_shortcodes_modules_and_widgets'],
264
+			7
265
+		);
266
+		// you wanna get going? I wanna get going... let's get going!
267
+		add_action(
268
+			'AHEE__EE_Bootstrap__brew_espresso',
269
+			[$this, 'brew_espresso'],
270
+			9
271
+		);
272
+		// other housekeeping
273
+		// exclude EE critical pages from wp_list_pages
274
+		add_filter(
275
+			'wp_list_pages_excludes',
276
+			[$this, 'remove_pages_from_wp_list_pages'],
277
+			10
278
+		);
279
+		// ALL EE Addons should use the following hook point to attach their initial setup too
280
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
281
+		do_action('AHEE__EE_System__construct__complete', $this);
282
+	}
283
+
284
+
285
+	/**
286
+	 * load and setup EE_Capabilities
287
+	 *
288
+	 * @return void
289
+	 */
290
+	public function loadCapabilities()
291
+	{
292
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
293
+		add_action(
294
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
295
+			function () {
296
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
297
+			}
298
+		);
299
+	}
300
+
301
+
302
+	/**
303
+	 * create and cache the CommandBus, and also add middleware
304
+	 * The CapChecker middleware requires the use of EE_Capabilities
305
+	 * which is why we need to load the CommandBus after Caps are set up
306
+	 *
307
+	 * @return void
308
+	 */
309
+	public function loadCommandBus()
310
+	{
311
+		$this->loader->getShared(
312
+			'CommandBusInterface',
313
+			[
314
+				null,
315
+				apply_filters(
316
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
317
+					[
318
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
319
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
320
+					]
321
+				),
322
+			]
323
+		);
324
+	}
325
+
326
+
327
+	/**
328
+	 * @return void
329
+	 * @throws Exception
330
+	 */
331
+	public function loadPluginApi()
332
+	{
333
+		$this->addon_manager = $this->loader->getShared(AddonManager::class);
334
+		$this->addon_manager->initialize();
335
+		$this->loader->getShared('EE_Request_Handler');
336
+	}
337
+
338
+
339
+	/**
340
+	 * load_espresso_addons
341
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
342
+	 * this is hooked into both:
343
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
344
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
345
+	 *    and the WP 'activate_plugin' hook point
346
+	 *
347
+	 * @return void
348
+	 * @throws Exception
349
+	 */
350
+	public function load_espresso_addons()
351
+	{
352
+		// looking for hooks? they've been moved into the AddonManager to maintain compatibility
353
+		$this->addon_manager->loadAddons();
354
+	}
355
+
356
+
357
+	/**
358
+	 * detect_activations_or_upgrades
359
+	 * Checks for activation or upgrade of core first;
360
+	 * then also checks if any registered addons have been activated or upgraded
361
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
362
+	 * which runs during the WP 'plugins_loaded' action at priority 3
363
+	 *
364
+	 * @access public
365
+	 * @return void
366
+	 */
367
+	public function detect_activations_or_upgrades()
368
+	{
369
+		// first off: let's make sure to handle core
370
+		$this->detect_if_activation_or_upgrade();
371
+		foreach ($this->registry->addons as $addon) {
372
+			if ($addon instanceof EE_Addon) {
373
+				// detect teh request type for that addon
374
+				$addon->detect_req_type();
375
+			}
376
+		}
377
+	}
378
+
379
+
380
+	/**
381
+	 * detect_if_activation_or_upgrade
382
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
383
+	 * and either setting up the DB or setting up maintenance mode etc.
384
+	 *
385
+	 * @access public
386
+	 * @return void
387
+	 */
388
+	public function detect_if_activation_or_upgrade()
389
+	{
390
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
391
+		// check if db has been updated, or if its a brand-new installation
392
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
393
+		$request_type       = $this->detect_req_type($espresso_db_update);
394
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
395
+		switch ($request_type) {
396
+			case EE_System::req_type_new_activation:
397
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
398
+				$this->_handle_core_version_change($espresso_db_update);
399
+				break;
400
+			case EE_System::req_type_reactivation:
401
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
402
+				$this->_handle_core_version_change($espresso_db_update);
403
+				break;
404
+			case EE_System::req_type_upgrade:
405
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
406
+				// migrations may be required now that we've upgraded
407
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
408
+				$this->_handle_core_version_change($espresso_db_update);
409
+				break;
410
+			case EE_System::req_type_downgrade:
411
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
412
+				// its possible migrations are no longer required
413
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
414
+				$this->_handle_core_version_change($espresso_db_update);
415
+				break;
416
+			case EE_System::req_type_normal:
417
+			default:
418
+				break;
419
+		}
420
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
421
+	}
422
+
423
+
424
+	/**
425
+	 * Updates the list of installed versions and sets hooks for
426
+	 * initializing the database later during the request
427
+	 *
428
+	 * @param array $espresso_db_update
429
+	 */
430
+	private function _handle_core_version_change(array $espresso_db_update)
431
+	{
432
+		$this->update_list_of_installed_versions($espresso_db_update);
433
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
434
+		add_action(
435
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
436
+			[$this, 'initialize_db_if_no_migrations_required']
437
+		);
438
+	}
439
+
440
+
441
+	/**
442
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
443
+	 * information about what versions of EE have been installed and activated,
444
+	 * NOT necessarily the state of the database
445
+	 *
446
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
447
+	 *                                            If not supplied, fetches it from the options table
448
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
449
+	 */
450
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
451
+	{
452
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
453
+		if (! $espresso_db_update) {
454
+			$espresso_db_update = get_option('espresso_db_update');
455
+		}
456
+		// check that option is an array
457
+		if (! is_array($espresso_db_update)) {
458
+			// if option is FALSE, then it never existed
459
+			if ($espresso_db_update === false) {
460
+				// make $espresso_db_update an array and save option with autoload OFF
461
+				$espresso_db_update = [];
462
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
463
+			} else {
464
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
465
+				$espresso_db_update = [$espresso_db_update => []];
466
+				update_option('espresso_db_update', $espresso_db_update);
467
+			}
468
+		} else {
469
+			$corrected_db_update = [];
470
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
471
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
472
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
473
+					// the key is an int, and the value IS NOT an array
474
+					// so it must be numerically-indexed, where values are versions installed...
475
+					// fix it!
476
+					$version_string                         = $should_be_array;
477
+					$corrected_db_update[ $version_string ] = ['unknown-date'];
478
+				} else {
479
+					// ok it checks out
480
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
481
+				}
482
+			}
483
+			$espresso_db_update = $corrected_db_update;
484
+			update_option('espresso_db_update', $espresso_db_update);
485
+		}
486
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
487
+		return ! empty($espresso_db_update) ? $espresso_db_update : [];
488
+	}
489
+
490
+
491
+	/**
492
+	 * Does the traditional work of setting up the plugin's database and adding default data.
493
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
494
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
495
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
496
+	 * so that it will be done when migrations are finished
497
+	 *
498
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
499
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
500
+	 *                                       This is a resource-intensive job
501
+	 *                                       so we prefer to only do it when necessary
502
+	 * @return void
503
+	 * @throws EE_Error
504
+	 * @throws ReflectionException
505
+	 */
506
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
507
+	{
508
+		$request_type = $this->detect_req_type();
509
+		// only initialize system if we're not in maintenance mode.
510
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
511
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
512
+			$rewrite_rules = $this->loader->getShared(
513
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
514
+			);
515
+			$rewrite_rules->flush();
516
+			if ($verify_schema) {
517
+				EEH_Activation::initialize_db_and_folders();
518
+			}
519
+			EEH_Activation::initialize_db_content();
520
+			EEH_Activation::system_initialization();
521
+			if ($initialize_addons_too) {
522
+				$this->initialize_addons();
523
+			}
524
+		} else {
525
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
526
+		}
527
+		if (
528
+			$request_type === EE_System::req_type_new_activation
529
+			|| $request_type === EE_System::req_type_reactivation
530
+			|| (
531
+				$request_type === EE_System::req_type_upgrade
532
+				&& $this->is_major_version_change()
533
+			)
534
+		) {
535
+			add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
536
+		}
537
+	}
538
+
539
+
540
+	/**
541
+	 * Initializes the db for all registered addons
542
+	 *
543
+	 * @throws EE_Error
544
+	 * @throws ReflectionException
545
+	 */
546
+	public function initialize_addons()
547
+	{
548
+		// foreach registered addon, make sure its db is up-to-date too
549
+		foreach ($this->registry->addons as $addon) {
550
+			if ($addon instanceof EE_Addon) {
551
+				$addon->initialize_db_if_no_migrations_required();
552
+			}
553
+		}
554
+	}
555
+
556
+
557
+	/**
558
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
559
+	 *
560
+	 * @param array  $version_history
561
+	 * @param string $current_version_to_add version to be added to the version history
562
+	 * @return    boolean success as to whether or not this option was changed
563
+	 */
564
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
565
+	{
566
+		if (! $version_history) {
567
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
568
+		}
569
+		if ($current_version_to_add === null) {
570
+			$current_version_to_add = espresso_version();
571
+		}
572
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
573
+		// re-save
574
+		return update_option('espresso_db_update', $version_history);
575
+	}
576
+
577
+
578
+	/**
579
+	 * Detects if the current version indicated in the has existed in the list of
580
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
581
+	 *
582
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
583
+	 *                                  If not supplied, fetches it from the options table.
584
+	 *                                  Also, caches its result so later parts of the code can also know whether
585
+	 *                                  there's been an update or not. This way we can add the current version to
586
+	 *                                  espresso_db_update, but still know if this is a new install or not
587
+	 * @return int one of the constants on EE_System::req_type_
588
+	 */
589
+	public function detect_req_type($espresso_db_update = null): int
590
+	{
591
+		if ($this->_req_type === null) {
592
+			$espresso_db_update          = ! empty($espresso_db_update)
593
+				? $espresso_db_update
594
+				: $this->fix_espresso_db_upgrade_option();
595
+			$this->_req_type             = EE_System::detect_req_type_given_activation_history(
596
+				$espresso_db_update,
597
+				'ee_espresso_activation',
598
+				espresso_version()
599
+			);
600
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
601
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
602
+		}
603
+		return $this->_req_type;
604
+	}
605
+
606
+
607
+	/**
608
+	 * Returns whether or not there was a non-micro version change (ie, change in either
609
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
610
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
611
+	 *
612
+	 * @param $activation_history
613
+	 * @return bool
614
+	 */
615
+	private function _detect_major_version_change($activation_history): bool
616
+	{
617
+		$previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
618
+		$previous_version_parts = explode('.', $previous_version);
619
+		$current_version_parts  = explode('.', espresso_version());
620
+		return isset(
621
+			$previous_version_parts[0],
622
+			$previous_version_parts[1],
623
+			$current_version_parts[0],
624
+			$current_version_parts[1]
625
+		) && (
626
+			$previous_version_parts[0] !== $current_version_parts[0]
627
+			|| $previous_version_parts[1] !== $current_version_parts[1]
628
+		);
629
+	}
630
+
631
+
632
+	/**
633
+	 * Returns true if either the major or minor version of EE changed during this request.
634
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
635
+	 *
636
+	 * @return bool
637
+	 */
638
+	public function is_major_version_change(): bool
639
+	{
640
+		return $this->_major_version_change;
641
+	}
642
+
643
+
644
+	/**
645
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
646
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
647
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
648
+	 * just activated to (for core that will always be espresso_version())
649
+	 *
650
+	 * @param array|null $activation_history             the option's value which stores the activation history for
651
+	 *                                                 this
652
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
653
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
654
+	 *                                                 indicate that this plugin was just activated
655
+	 * @param string $current_version                  the version that was just upgraded to (for core that will be
656
+	 *                                                 espresso_version())
657
+	 * @return int one of the constants on EE_System::req_type_
658
+	 */
659
+	public static function detect_req_type_given_activation_history(
660
+		array $activation_history,
661
+		string $activation_indicator_option_name,
662
+		string $current_version
663
+	): int {
664
+		$version_change = self::compareVersionWithPrevious($activation_history, $current_version);
665
+		$is_activation  = get_option($activation_indicator_option_name, false);
666
+		$req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
667
+		if ($is_activation) {
668
+			// cleanup in aisle 6
669
+			delete_option($activation_indicator_option_name);
670
+		}
671
+		return $req_type;
672
+	}
673
+
674
+
675
+	/**
676
+	 * @param array  $activation_history
677
+	 * @param int    $version_change
678
+	 * @param bool   $is_activation
679
+	 * @return int
680
+	 * @since $VID:$
681
+	 */
682
+	private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
683
+	{
684
+		// if no previous activation history exists, then this is a brand new install
685
+		if (empty($activation_history)) {
686
+			return EE_System::req_type_new_activation;
687
+		}
688
+		// current version is higher than previous version, so it's an upgrade
689
+		if ($version_change === 1) {
690
+			return EE_System::req_type_upgrade;
691
+		}
692
+		// current version is lower than previous version, so it's a downgrade
693
+		if ($version_change === -1) {
694
+			return EE_System::req_type_downgrade;
695
+		}
696
+		// version hasn't changed since last version so check if the activation indicator is set
697
+		// to determine if it's a reactivation, or just a normal request
698
+		return $is_activation
699
+			? EE_System::req_type_reactivation
700
+			: EE_System::req_type_normal;
701
+	}
702
+
703
+
704
+	/**
705
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
706
+	 * the $activation_history_for_addon
707
+	 *
708
+	 * @param array  $activation_history    array where keys are versions,
709
+	 *                                      values are arrays of times activated (sometimes 'unknown-date')
710
+	 * @param string $current_version
711
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
712
+	 *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
713
+	 *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
714
+	 *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
715
+	 */
716
+	private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
717
+	{
718
+		// find the most recently-activated version
719
+		$most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
720
+		return version_compare($current_version, $most_recently_active_version);
721
+	}
722
+
723
+
724
+	/**
725
+	 * Gets the most recently active version listed in the activation history,
726
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
727
+	 *
728
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
729
+	 *                                   sometimes containing 'unknown-date'
730
+	 * @return string
731
+	 */
732
+	private static function getMostRecentlyActiveVersion(array $activation_history): string
733
+	{
734
+		$most_recent_activation_date  = '1970-01-01 00:00:00';
735
+		$most_recently_active_version = '0.0.0.dev.000';
736
+		if (is_array($activation_history)) {
737
+			foreach ($activation_history as $version => $activation_dates) {
738
+				// check there is a record of when this version was activated.
739
+				// Otherwise, mark it as unknown
740
+				if (! $activation_dates) {
741
+					$activation_dates = ['unknown-date'];
742
+				}
743
+				$activation_dates = is_string($activation_dates) ? [$activation_dates] : $activation_dates;
744
+				foreach ($activation_dates as $activation_date) {
745
+					if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
746
+						$most_recently_active_version = $version;
747
+						$most_recent_activation_date  = $activation_date;
748
+					}
749
+				}
750
+			}
751
+		}
752
+		return $most_recently_active_version;
753
+	}
754
+
755
+
756
+	/**
757
+	 * This redirects to the about EE page after activation
758
+	 *
759
+	 * @return void
760
+	 */
761
+	public function redirect_to_about_ee()
762
+	{
763
+		$notices = EE_Error::get_notices(false);
764
+		// if current user is an admin and it's not an ajax or rest request
765
+		if (
766
+			! isset($notices['errors'])
767
+			&& $this->request->isAdmin()
768
+			&& apply_filters(
769
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
770
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
771
+			)
772
+		) {
773
+			$query_params = ['page' => 'espresso_about'];
774
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
775
+				$query_params['new_activation'] = true;
776
+			}
777
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
778
+				$query_params['reactivation'] = true;
779
+			}
780
+			$url = add_query_arg($query_params, admin_url('admin.php'));
781
+			EEH_URL::safeRedirectAndExit($url);
782
+		}
783
+	}
784
+
785
+
786
+	/**
787
+	 * load_core_configuration
788
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
789
+	 * which runs during the WP 'plugins_loaded' action at priority 5
790
+	 *
791
+	 * @return void
792
+	 * @throws ReflectionException
793
+	 * @throws Exception
794
+	 */
795
+	public function load_core_configuration()
796
+	{
797
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
798
+		$this->loader->getShared('EE_Load_Textdomain');
799
+		// load textdomain
800
+		EE_Load_Textdomain::load_textdomain();
801
+		// load caf stuff a chance to play during the activation process too.
802
+		$this->_maybe_brew_regular();
803
+		// load and setup EE_Config and EE_Network_Config
804
+		$config = $this->loader->getShared('EE_Config');
805
+		$this->loader->getShared('EE_Network_Config');
806
+		// setup autoloaders
807
+		// enable logging?
808
+		if ($config->admin->use_remote_logging) {
809
+			$this->loader->getShared('EE_Log');
810
+		}
811
+		// check for activation errors
812
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
813
+		if ($activation_errors) {
814
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
815
+			update_option('ee_plugin_activation_errors', false);
816
+		}
817
+		// get model names
818
+		$this->_parse_model_names();
819
+		// configure custom post type definitions
820
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
821
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
822
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
823
+	}
824
+
825
+
826
+	/**
827
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
828
+	 *
829
+	 * @return void
830
+	 * @throws ReflectionException
831
+	 */
832
+	private function _parse_model_names()
833
+	{
834
+		// get all the files in the EE_MODELS folder that end in .model.php
835
+		$models                 = glob(EE_MODELS . '*.model.php');
836
+		$model_names            = [];
837
+		$non_abstract_db_models = [];
838
+		foreach ($models as $model) {
839
+			// get model classname
840
+			$classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
841
+			$short_name      = str_replace('EEM_', '', $classname);
842
+			$reflectionClass = new ReflectionClass($classname);
843
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
844
+				$non_abstract_db_models[ $short_name ] = $classname;
845
+			}
846
+			$model_names[ $short_name ] = $classname;
847
+		}
848
+		$this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
849
+		$this->registry->non_abstract_db_models = apply_filters(
850
+			'FHEE__EE_System__parse_implemented_model_names',
851
+			$non_abstract_db_models
852
+		);
853
+	}
854
+
855
+
856
+	/**
857
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
858
+	 * that need to be setup before our EE_System launches.
859
+	 *
860
+	 * @return void
861
+	 * @throws DomainException
862
+	 * @throws InvalidArgumentException
863
+	 * @throws InvalidDataTypeException
864
+	 * @throws InvalidInterfaceException
865
+	 * @throws InvalidClassException
866
+	 * @throws InvalidFilePathException
867
+	 */
868
+	private function _maybe_brew_regular()
869
+	{
870
+		/** @var Domain $domain */
871
+		$domain = DomainFactory::getEventEspressoCoreDomain();
872
+		if ($domain->isCaffeinated()) {
873
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
874
+		}
875
+	}
876
+
877
+
878
+	/**
879
+	 * @throws Exception
880
+	 * @since 4.9.71.p
881
+	 */
882
+	public function loadRouteMatchSpecifications()
883
+	{
884
+		try {
885
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
886
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
887
+			$this->router->loadPrimaryRoutes();
888
+		} catch (Exception $exception) {
889
+			new ExceptionStackTraceDisplay($exception);
890
+		}
891
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
892
+	}
893
+
894
+
895
+	/**
896
+	 * loading CPT related classes earlier so that their definitions are available
897
+	 * but not performing any actual registration with WP core until load_CPTs_and_session() is called
898
+	 *
899
+	 * @since   4.10.21.p
900
+	 */
901
+	public function loadCustomPostTypes()
902
+	{
903
+		$this->register_custom_taxonomies = $this->loader->getShared(
904
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
905
+		);
906
+		$this->register_custom_post_types = $this->loader->getShared(
907
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
908
+		);
909
+		$this->register_custom_taxonomy_terms = $this->loader->getShared(
910
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
911
+		);
912
+		// integrate WP_Query with the EE models
913
+		$this->loader->getShared('EE_CPT_Strategy');
914
+		// load legacy EE_Request_Handler in case add-ons still need it
915
+		$this->loader->getShared('EE_Request_Handler');
916
+	}
917
+
918
+
919
+	/**
920
+	 * register_shortcodes_modules_and_widgets
921
+	 * generate lists of shortcodes and modules, then verify paths and classes
922
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
923
+	 * which runs during the WP 'plugins_loaded' action at priority 7
924
+	 *
925
+	 * @access public
926
+	 * @return void
927
+	 * @throws Exception
928
+	 */
929
+	public function register_shortcodes_modules_and_widgets()
930
+	{
931
+		$this->router->registerShortcodesModulesAndWidgets();
932
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
933
+		// check for addons using old hook point
934
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
935
+			$this->_incompatible_addon_error();
936
+		}
937
+	}
938
+
939
+
940
+	/**
941
+	 * _incompatible_addon_error
942
+	 *
943
+	 * @access public
944
+	 * @return void
945
+	 */
946
+	private function _incompatible_addon_error()
947
+	{
948
+		// get array of classes hooking into here
949
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
950
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
951
+		);
952
+		if (! empty($class_names)) {
953
+			$msg = esc_html__(
954
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
955
+				'event_espresso'
956
+			);
957
+			$msg .= '<ul>';
958
+			foreach ($class_names as $class_name) {
959
+				$msg .= '<li><b>Event Espresso - '
960
+						. str_replace(
961
+							['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
962
+							'',
963
+							$class_name
964
+						) . '</b></li>';
965
+			}
966
+			$msg .= '</ul>';
967
+			$msg .= esc_html__(
968
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
969
+				'event_espresso'
970
+			);
971
+			// save list of incompatible addons to wp-options for later use
972
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
973
+			if (is_admin()) {
974
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
975
+			}
976
+		}
977
+	}
978
+
979
+
980
+	/**
981
+	 * brew_espresso
982
+	 * begins the process of setting hooks for initializing EE in the correct order
983
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
984
+	 * which runs during the WP 'plugins_loaded' action at priority 9
985
+	 *
986
+	 * @return void
987
+	 * @throws Exception
988
+	 */
989
+	public function brew_espresso()
990
+	{
991
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
992
+		// load some final core systems
993
+		add_action('init', [$this, 'set_hooks_for_core'], 1);
994
+		add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
995
+		add_action('init', [$this, 'load_CPTs_and_session'], 5);
996
+		add_action('init', [$this, 'load_controllers'], 7);
997
+		add_action('init', [$this, 'core_loaded_and_ready'], 9);
998
+		add_action('init', [$this, 'initialize'], 10);
999
+		add_action('init', [$this, 'initialize_last'], 100);
1000
+		$this->router->brewEspresso();
1001
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1002
+	}
1003
+
1004
+
1005
+	/**
1006
+	 *    set_hooks_for_core
1007
+	 *
1008
+	 * @access public
1009
+	 * @return    void
1010
+	 * @throws EE_Error
1011
+	 */
1012
+	public function set_hooks_for_core()
1013
+	{
1014
+		$this->_deactivate_incompatible_addons();
1015
+		do_action('AHEE__EE_System__set_hooks_for_core');
1016
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1017
+		// caps need to be initialized on every request so that capability maps are set.
1018
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1019
+		$this->registry->CAP->init_caps();
1020
+	}
1021
+
1022
+
1023
+	/**
1024
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1025
+	 * deactivates any addons considered incompatible with the current version of EE
1026
+	 */
1027
+	private function _deactivate_incompatible_addons()
1028
+	{
1029
+		$incompatible_addons = get_option('ee_incompatible_addons', []);
1030
+		if (! empty($incompatible_addons)) {
1031
+			$active_plugins = get_option('active_plugins', []);
1032
+			foreach ($active_plugins as $active_plugin) {
1033
+				foreach ($incompatible_addons as $incompatible_addon) {
1034
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1035
+						$this->request->unSetRequestParams(['activate'], true);
1036
+						espresso_deactivate_plugin($active_plugin);
1037
+					}
1038
+				}
1039
+			}
1040
+		}
1041
+	}
1042
+
1043
+
1044
+	/**
1045
+	 *    perform_activations_upgrades_and_migrations
1046
+	 *
1047
+	 * @access public
1048
+	 * @return    void
1049
+	 */
1050
+	public function perform_activations_upgrades_and_migrations()
1051
+	{
1052
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1053
+	}
1054
+
1055
+
1056
+	/**
1057
+	 * @return void
1058
+	 * @throws DomainException
1059
+	 */
1060
+	public function load_CPTs_and_session()
1061
+	{
1062
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1063
+		$this->register_custom_taxonomies->registerCustomTaxonomies();
1064
+		$this->register_custom_post_types->registerCustomPostTypes();
1065
+		$this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1066
+		// load legacy Custom Post Types and Taxonomies
1067
+		$this->loader->getShared('EE_Register_CPTs');
1068
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1069
+	}
1070
+
1071
+
1072
+	/**
1073
+	 * load_controllers
1074
+	 * this is the best place to load any additional controllers that needs access to EE core.
1075
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1076
+	 * time
1077
+	 *
1078
+	 * @access public
1079
+	 * @return void
1080
+	 * @throws Exception
1081
+	 */
1082
+	public function load_controllers()
1083
+	{
1084
+		do_action('AHEE__EE_System__load_controllers__start');
1085
+		$this->router->loadControllers();
1086
+		do_action('AHEE__EE_System__load_controllers__complete');
1087
+	}
1088
+
1089
+
1090
+	/**
1091
+	 * core_loaded_and_ready
1092
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1093
+	 *
1094
+	 * @access public
1095
+	 * @return void
1096
+	 * @throws Exception
1097
+	 */
1098
+	public function core_loaded_and_ready()
1099
+	{
1100
+		$this->router->coreLoadedAndReady();
1101
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1102
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1103
+		// builders require these even on the front-end
1104
+		require_once EE_PUBLIC . 'template_tags.php';
1105
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1106
+	}
1107
+
1108
+
1109
+	/**
1110
+	 * initialize
1111
+	 * this is the best place to begin initializing client code
1112
+	 *
1113
+	 * @access public
1114
+	 * @return void
1115
+	 */
1116
+	public function initialize()
1117
+	{
1118
+		do_action('AHEE__EE_System__initialize');
1119
+	}
1120
+
1121
+
1122
+	/**
1123
+	 * initialize_last
1124
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1125
+	 * initialize has done so
1126
+	 *
1127
+	 * @access public
1128
+	 * @return void
1129
+	 * @throws Exception
1130
+	 */
1131
+	public function initialize_last()
1132
+	{
1133
+		$this->router->initializeLast();
1134
+		do_action('AHEE__EE_System__initialize_last');
1135
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1136
+		$rewrite_rules = $this->loader->getShared(
1137
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1138
+		);
1139
+		$rewrite_rules->flushRewriteRules();
1140
+		add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * @return void
1146
+	 */
1147
+	public function addEspressoToolbar()
1148
+	{
1149
+		$this->loader->getShared(
1150
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1151
+			[$this->registry->CAP]
1152
+		);
1153
+	}
1154
+
1155
+
1156
+	/**
1157
+	 * do_not_cache
1158
+	 * sets no cache headers and defines no cache constants for WP plugins
1159
+	 *
1160
+	 * @access public
1161
+	 * @return void
1162
+	 */
1163
+	public static function do_not_cache()
1164
+	{
1165
+		// set no cache constants
1166
+		if (! defined('DONOTCACHEPAGE')) {
1167
+			define('DONOTCACHEPAGE', true);
1168
+		}
1169
+		if (! defined('DONOTCACHCEOBJECT')) {
1170
+			define('DONOTCACHCEOBJECT', true);
1171
+		}
1172
+		if (! defined('DONOTCACHEDB')) {
1173
+			define('DONOTCACHEDB', true);
1174
+		}
1175
+		// add no cache headers
1176
+		add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1177
+		// plus a little extra for nginx and Google Chrome
1178
+		add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1179
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1180
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1181
+	}
1182
+
1183
+
1184
+	/**
1185
+	 *    extra_nocache_headers
1186
+	 *
1187
+	 * @access    public
1188
+	 * @param $headers
1189
+	 * @return    array
1190
+	 */
1191
+	public static function extra_nocache_headers($headers): array
1192
+	{
1193
+		// for NGINX
1194
+		$headers['X-Accel-Expires'] = 0;
1195
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1196
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1197
+		return $headers;
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 *    nocache_headers
1203
+	 *
1204
+	 * @access    public
1205
+	 * @return    void
1206
+	 */
1207
+	public static function nocache_headers()
1208
+	{
1209
+		nocache_headers();
1210
+	}
1211
+
1212
+
1213
+	/**
1214
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1215
+	 * never returned with the function.
1216
+	 *
1217
+	 * @param array $exclude_array any existing pages being excluded are in this array.
1218
+	 * @return array
1219
+	 */
1220
+	public function remove_pages_from_wp_list_pages(array $exclude_array): array
1221
+	{
1222
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1223
+	}
1224 1224
 }
Please login to merge, or discard this patch.
core/domain/entities/custom_post_types/CustomPostTypeDefinitions.php 2 patches
Indentation   +274 added lines, -274 removed lines patch added patch discarded remove patch
@@ -17,299 +17,299 @@
 block discarded – undo
17 17
 class CustomPostTypeDefinitions
18 18
 {
19 19
 
20
-    /**
21
-     * @var string $namespace The graphql namespace/prefix.
22
-     */
23
-    protected $namespace = 'Espresso';
20
+	/**
21
+	 * @var string $namespace The graphql namespace/prefix.
22
+	 */
23
+	protected $namespace = 'Espresso';
24 24
 
25
-    /**
26
-     * @var EE_Core_Config
27
-     */
28
-    public $core_config;
25
+	/**
26
+	 * @var EE_Core_Config
27
+	 */
28
+	public $core_config;
29 29
 
30
-    /**
31
-     * @var array $custom_post_types
32
-     */
33
-    private $custom_post_types;
30
+	/**
31
+	 * @var array $custom_post_types
32
+	 */
33
+	private $custom_post_types;
34 34
 
35
-    /**
36
-     * @var LoaderInterface $loader
37
-     */
38
-    private $loader;
35
+	/**
36
+	 * @var LoaderInterface $loader
37
+	 */
38
+	private $loader;
39 39
 
40 40
 
41
-    /**
42
-     * EspressoCustomPostTypeDefinitions constructor.
43
-     *
44
-     * @param EE_Core_Config  $core_config
45
-     * @param LoaderInterface $loader
46
-     */
47
-    public function __construct(EE_Core_Config $core_config, LoaderInterface $loader)
48
-    {
49
-        $this->core_config = $core_config;
50
-        $this->loader = $loader;
51
-        $this->setDefinitions();
52
-    }
41
+	/**
42
+	 * EspressoCustomPostTypeDefinitions constructor.
43
+	 *
44
+	 * @param EE_Core_Config  $core_config
45
+	 * @param LoaderInterface $loader
46
+	 */
47
+	public function __construct(EE_Core_Config $core_config, LoaderInterface $loader)
48
+	{
49
+		$this->core_config = $core_config;
50
+		$this->loader = $loader;
51
+		$this->setDefinitions();
52
+	}
53 53
 
54 54
 
55
-    /**
56
-     * defines Espresso Custom Post Types
57
-     * NOTE the ['args']['page_templates'] array index is something specific to our CPTs
58
-     * and not part of the WP custom post type api.
59
-     *
60
-     * @return void
61
-     */
62
-    private function setDefinitions()
63
-    {
64
-        $this->custom_post_types = [
65
-            'espresso_events'    => [
66
-                'singular_name' => esc_html__('Event', 'event_espresso'),
67
-                'plural_name'   => esc_html__('Events', 'event_espresso'),
68
-                'singular_slug' => esc_html__('event', 'event_espresso'),
69
-                'plural_slug'   => $this->core_config->event_cpt_slug,
70
-                'class_name'    => 'EE_Event',
71
-                'model_name'    => 'EEM_Event',
72
-                'args'          => [
73
-                    'public'              => true,
74
-                    'show_in_nav_menus'   => true,
75
-                    'show_in_graphql'     => true,
76
-                    'graphql_single_name' => $this->namespace . 'Event',
77
-                    'graphql_plural_name' => $this->namespace . 'Events',
78
-                    'capability_type'     => 'event',
79
-                    'capabilities'        => [
80
-                        'edit_post'              => 'ee_edit_event',
81
-                        'read_post'              => 'ee_read_event',
82
-                        'delete_post'            => 'ee_delete_event',
83
-                        'edit_posts'             => 'ee_edit_events',
84
-                        'edit_others_posts'      => 'ee_edit_others_events',
85
-                        'publish_posts'          => 'ee_publish_events',
86
-                        'read_private_posts'     => 'ee_read_private_events',
87
-                        'delete_posts'           => 'ee_delete_events',
88
-                        'delete_private_posts'   => 'ee_delete_private_events',
89
-                        'delete_published_posts' => 'ee_delete_published_events',
90
-                        'delete_others_posts'    => 'ee_delete_others_events',
91
-                        'edit_private_posts'     => 'ee_edit_private_events',
92
-                        'edit_published_posts'   => 'ee_edit_published_events',
93
-                    ],
94
-                    'taxonomies'          => [
95
-                        'espresso_event_categories',
96
-                        'espresso_event_type',
97
-                        'post_tag',
98
-                    ],
99
-                    'page_templates'      => true,
100
-                ],
101
-            ],
102
-            'espresso_venues'    => [
103
-                'singular_name' => esc_html__('Venue', 'event_espresso'),
104
-                'plural_name'   => esc_html__('Venues', 'event_espresso'),
105
-                'singular_slug' => esc_html__('venue', 'event_espresso'),
106
-                'plural_slug'   => esc_html__('venues', 'event_espresso'),
107
-                'class_name'    => 'EE_Venue',
108
-                'model_name'    => 'EEM_Venue',
109
-                'args'          => [
110
-                    'public'              => true,
111
-                    'show_in_nav_menus'   => false, // by default this doesn't show for decaf,
112
-                    'show_in_graphql'     => true,
113
-                    'graphql_single_name' => $this->namespace . 'Venue',
114
-                    'graphql_plural_name' => $this->namespace . 'Venues',
115
-                    'capability_type'     => 'venue',
116
-                    'capabilities'        => [
117
-                        'edit_post'              => 'ee_edit_venue',
118
-                        'read_post'              => 'ee_read_venue',
119
-                        'delete_post'            => 'ee_delete_venue',
120
-                        'edit_posts'             => 'ee_edit_venues',
121
-                        'edit_others_posts'      => 'ee_edit_others_venues',
122
-                        'publish_posts'          => 'ee_publish_venues',
123
-                        'read_private_posts'     => 'ee_read_private_venues',
124
-                        'delete_posts'           => 'ee_delete_venues',
125
-                        'delete_private_posts'   => 'ee_delete_private_venues',
126
-                        'delete_published_posts' => 'ee_delete_published_venues',
127
-                        'delete_others_posts'    => 'ee_edit_others_venues',
128
-                        'edit_private_posts'     => 'ee_edit_private_venues',
129
-                        'edit_published_posts'   => 'ee_edit_published_venues',
130
-                    ],
131
-                    'taxonomies'          => [
132
-                        'espresso_venue_categories',
133
-                        'post_tag',
134
-                    ],
135
-                    'page_templates'      => true,
136
-                ],
137
-            ],
138
-            'espresso_attendees' => [
139
-                'singular_name' => esc_html__('Contact', 'event_espresso'),
140
-                'plural_name'   => esc_html__('Contacts', 'event_espresso'),
141
-                'singular_slug' => esc_html__('contact', 'event_espresso'),
142
-                'plural_slug'   => esc_html__('contacts', 'event_espresso'),
143
-                'class_name'    => 'EE_Attendee',
144
-                'model_name'    => 'EEM_Attendee',
145
-                'args'          => [
146
-                    'public'             => false,
147
-                    'publicly_queryable' => false,
148
-                    'hierarchical'       => false,
149
-                    'has_archive'        => false,
150
-                    'supports'           => [
151
-                        'editor',
152
-                        'thumbnail',
153
-                        'excerpt',
154
-                        'custom-fields',
155
-                        'comments',
156
-                    ],
157
-                    'taxonomies'         => ['post_tag'],
158
-                    'capability_type'    => 'contact',
159
-                    'capabilities'       => [
160
-                        'edit_post'              => 'ee_edit_contact',
161
-                        'read_post'              => 'ee_read_contact',
162
-                        'delete_post'            => 'ee_delete_contact',
163
-                        'edit_posts'             => 'ee_edit_contacts',
164
-                        'edit_others_posts'      => 'ee_edit_contacts',
165
-                        'publish_posts'          => 'ee_edit_contacts',
166
-                        'read_private_posts'     => 'ee_edit_contacts',
167
-                        'delete_posts'           => 'ee_delete_contacts',
168
-                        'delete_private_posts'   => 'ee_delete_contacts',
169
-                        'delete_published_posts' => 'ee_delete_contacts',
170
-                        'delete_others_posts'    => 'ee_delete_contacts',
171
-                        'edit_private_posts'     => 'ee_edit_contacts',
172
-                        'edit_published_posts'   => 'ee_edit_contacts',
173
-                    ],
174
-                ],
175
-            ],
176
-        ];
177
-    }
55
+	/**
56
+	 * defines Espresso Custom Post Types
57
+	 * NOTE the ['args']['page_templates'] array index is something specific to our CPTs
58
+	 * and not part of the WP custom post type api.
59
+	 *
60
+	 * @return void
61
+	 */
62
+	private function setDefinitions()
63
+	{
64
+		$this->custom_post_types = [
65
+			'espresso_events'    => [
66
+				'singular_name' => esc_html__('Event', 'event_espresso'),
67
+				'plural_name'   => esc_html__('Events', 'event_espresso'),
68
+				'singular_slug' => esc_html__('event', 'event_espresso'),
69
+				'plural_slug'   => $this->core_config->event_cpt_slug,
70
+				'class_name'    => 'EE_Event',
71
+				'model_name'    => 'EEM_Event',
72
+				'args'          => [
73
+					'public'              => true,
74
+					'show_in_nav_menus'   => true,
75
+					'show_in_graphql'     => true,
76
+					'graphql_single_name' => $this->namespace . 'Event',
77
+					'graphql_plural_name' => $this->namespace . 'Events',
78
+					'capability_type'     => 'event',
79
+					'capabilities'        => [
80
+						'edit_post'              => 'ee_edit_event',
81
+						'read_post'              => 'ee_read_event',
82
+						'delete_post'            => 'ee_delete_event',
83
+						'edit_posts'             => 'ee_edit_events',
84
+						'edit_others_posts'      => 'ee_edit_others_events',
85
+						'publish_posts'          => 'ee_publish_events',
86
+						'read_private_posts'     => 'ee_read_private_events',
87
+						'delete_posts'           => 'ee_delete_events',
88
+						'delete_private_posts'   => 'ee_delete_private_events',
89
+						'delete_published_posts' => 'ee_delete_published_events',
90
+						'delete_others_posts'    => 'ee_delete_others_events',
91
+						'edit_private_posts'     => 'ee_edit_private_events',
92
+						'edit_published_posts'   => 'ee_edit_published_events',
93
+					],
94
+					'taxonomies'          => [
95
+						'espresso_event_categories',
96
+						'espresso_event_type',
97
+						'post_tag',
98
+					],
99
+					'page_templates'      => true,
100
+				],
101
+			],
102
+			'espresso_venues'    => [
103
+				'singular_name' => esc_html__('Venue', 'event_espresso'),
104
+				'plural_name'   => esc_html__('Venues', 'event_espresso'),
105
+				'singular_slug' => esc_html__('venue', 'event_espresso'),
106
+				'plural_slug'   => esc_html__('venues', 'event_espresso'),
107
+				'class_name'    => 'EE_Venue',
108
+				'model_name'    => 'EEM_Venue',
109
+				'args'          => [
110
+					'public'              => true,
111
+					'show_in_nav_menus'   => false, // by default this doesn't show for decaf,
112
+					'show_in_graphql'     => true,
113
+					'graphql_single_name' => $this->namespace . 'Venue',
114
+					'graphql_plural_name' => $this->namespace . 'Venues',
115
+					'capability_type'     => 'venue',
116
+					'capabilities'        => [
117
+						'edit_post'              => 'ee_edit_venue',
118
+						'read_post'              => 'ee_read_venue',
119
+						'delete_post'            => 'ee_delete_venue',
120
+						'edit_posts'             => 'ee_edit_venues',
121
+						'edit_others_posts'      => 'ee_edit_others_venues',
122
+						'publish_posts'          => 'ee_publish_venues',
123
+						'read_private_posts'     => 'ee_read_private_venues',
124
+						'delete_posts'           => 'ee_delete_venues',
125
+						'delete_private_posts'   => 'ee_delete_private_venues',
126
+						'delete_published_posts' => 'ee_delete_published_venues',
127
+						'delete_others_posts'    => 'ee_edit_others_venues',
128
+						'edit_private_posts'     => 'ee_edit_private_venues',
129
+						'edit_published_posts'   => 'ee_edit_published_venues',
130
+					],
131
+					'taxonomies'          => [
132
+						'espresso_venue_categories',
133
+						'post_tag',
134
+					],
135
+					'page_templates'      => true,
136
+				],
137
+			],
138
+			'espresso_attendees' => [
139
+				'singular_name' => esc_html__('Contact', 'event_espresso'),
140
+				'plural_name'   => esc_html__('Contacts', 'event_espresso'),
141
+				'singular_slug' => esc_html__('contact', 'event_espresso'),
142
+				'plural_slug'   => esc_html__('contacts', 'event_espresso'),
143
+				'class_name'    => 'EE_Attendee',
144
+				'model_name'    => 'EEM_Attendee',
145
+				'args'          => [
146
+					'public'             => false,
147
+					'publicly_queryable' => false,
148
+					'hierarchical'       => false,
149
+					'has_archive'        => false,
150
+					'supports'           => [
151
+						'editor',
152
+						'thumbnail',
153
+						'excerpt',
154
+						'custom-fields',
155
+						'comments',
156
+					],
157
+					'taxonomies'         => ['post_tag'],
158
+					'capability_type'    => 'contact',
159
+					'capabilities'       => [
160
+						'edit_post'              => 'ee_edit_contact',
161
+						'read_post'              => 'ee_read_contact',
162
+						'delete_post'            => 'ee_delete_contact',
163
+						'edit_posts'             => 'ee_edit_contacts',
164
+						'edit_others_posts'      => 'ee_edit_contacts',
165
+						'publish_posts'          => 'ee_edit_contacts',
166
+						'read_private_posts'     => 'ee_edit_contacts',
167
+						'delete_posts'           => 'ee_delete_contacts',
168
+						'delete_private_posts'   => 'ee_delete_contacts',
169
+						'delete_published_posts' => 'ee_delete_contacts',
170
+						'delete_others_posts'    => 'ee_delete_contacts',
171
+						'edit_private_posts'     => 'ee_edit_contacts',
172
+						'edit_published_posts'   => 'ee_edit_contacts',
173
+					],
174
+				],
175
+			],
176
+		];
177
+	}
178 178
 
179 179
 
180
-    /**
181
-     * @return array
182
-     */
183
-    public function getDefinitions()
184
-    {
185
-        return (array) apply_filters(
186
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
187
-            // legacy filter applied for now,
188
-            // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
189
-            apply_filters(
190
-                'FHEE__EE_Register_CPTs__get_CPTs__cpts',
191
-                $this->custom_post_types
192
-            )
193
-        );
194
-    }
180
+	/**
181
+	 * @return array
182
+	 */
183
+	public function getDefinitions()
184
+	{
185
+		return (array) apply_filters(
186
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
187
+			// legacy filter applied for now,
188
+			// later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
189
+			apply_filters(
190
+				'FHEE__EE_Register_CPTs__get_CPTs__cpts',
191
+				$this->custom_post_types
192
+			)
193
+		);
194
+	}
195 195
 
196 196
 
197
-    /**
198
-     * @return array
199
-     */
200
-    public function getCustomPostTypeSlugs()
201
-    {
202
-        return array_keys($this->getDefinitions());
203
-    }
197
+	/**
198
+	 * @return array
199
+	 */
200
+	public function getCustomPostTypeSlugs()
201
+	{
202
+		return array_keys($this->getDefinitions());
203
+	}
204 204
 
205 205
 
206
-    /**
207
-     * This basically goes through the CPT array and returns only CPT's
208
-     * that have the ['args']['public'] option set as false
209
-     *
210
-     * @return array
211
-     */
212
-    public function getPrivateCustomPostTypes()
213
-    {
214
-        $private_CPTs = [];
215
-        foreach ($this->getDefinitions() as $CPT => $details) {
216
-            if (empty($details['args']['public'])) {
217
-                $private_CPTs[ $CPT ] = $details;
218
-            }
219
-        }
220
-        return $private_CPTs;
221
-    }
206
+	/**
207
+	 * This basically goes through the CPT array and returns only CPT's
208
+	 * that have the ['args']['public'] option set as false
209
+	 *
210
+	 * @return array
211
+	 */
212
+	public function getPrivateCustomPostTypes()
213
+	{
214
+		$private_CPTs = [];
215
+		foreach ($this->getDefinitions() as $CPT => $details) {
216
+			if (empty($details['args']['public'])) {
217
+				$private_CPTs[ $CPT ] = $details;
218
+			}
219
+		}
220
+		return $private_CPTs;
221
+	}
222 222
 
223 223
 
224
-    /**
225
-     * This returns the corresponding model name for cpts registered by EE.
226
-     *
227
-     * @param string $post_type_slug    If a slug is included, then attempt to retrieve
228
-     *                                  the model name for the given cpt slug.
229
-     *                                  Otherwise if empty, then we'll return
230
-     *                                  all cpt model names for cpts registered in EE.
231
-     * @return array                    Empty array if no matching model names for the given slug
232
-     *                                  or an array of model names indexed by post type slug.
233
-     */
234
-    public function getCustomPostTypeModelNames($post_type_slug = '')
235
-    {
236
-        $cpts = $this->getDefinitions();
237
-        // first if slug passed in...
238
-        if (! empty($post_type_slug)) {
239
-            // check that slug and cpt match
240
-            if (! isset($cpts[ $post_type_slug ])) {
241
-                return [];
242
-            }
243
-            if (
244
-                empty($cpts[ $post_type_slug ]['class_name'])
245
-                && empty($cpts[ $post_type_slug ]['model_name'])
246
-            ) {
247
-                return [];
248
-            }
249
-            // k let's get the model name for this cpt.
250
-            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
251
-        }
252
-        // if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
253
-        $cpt_models = [];
254
-        foreach ($cpts as $slug => $args) {
255
-            $model = $this->getCustomPostTypeModelName($slug, $args);
256
-            if (! empty($model)) {
257
-                $cpt_models[ $slug ] = $model;
258
-            }
259
-        }
260
-        return $cpt_models;
261
-    }
224
+	/**
225
+	 * This returns the corresponding model name for cpts registered by EE.
226
+	 *
227
+	 * @param string $post_type_slug    If a slug is included, then attempt to retrieve
228
+	 *                                  the model name for the given cpt slug.
229
+	 *                                  Otherwise if empty, then we'll return
230
+	 *                                  all cpt model names for cpts registered in EE.
231
+	 * @return array                    Empty array if no matching model names for the given slug
232
+	 *                                  or an array of model names indexed by post type slug.
233
+	 */
234
+	public function getCustomPostTypeModelNames($post_type_slug = '')
235
+	{
236
+		$cpts = $this->getDefinitions();
237
+		// first if slug passed in...
238
+		if (! empty($post_type_slug)) {
239
+			// check that slug and cpt match
240
+			if (! isset($cpts[ $post_type_slug ])) {
241
+				return [];
242
+			}
243
+			if (
244
+				empty($cpts[ $post_type_slug ]['class_name'])
245
+				&& empty($cpts[ $post_type_slug ]['model_name'])
246
+			) {
247
+				return [];
248
+			}
249
+			// k let's get the model name for this cpt.
250
+			return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
251
+		}
252
+		// if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
253
+		$cpt_models = [];
254
+		foreach ($cpts as $slug => $args) {
255
+			$model = $this->getCustomPostTypeModelName($slug, $args);
256
+			if (! empty($model)) {
257
+				$cpt_models[ $slug ] = $model;
258
+			}
259
+		}
260
+		return $cpt_models;
261
+	}
262 262
 
263 263
 
264
-    /**
265
-     * @param       $post_type_slug
266
-     * @param array $cpt
267
-     * @return array
268
-     */
269
-    private function getCustomPostTypeModelName($post_type_slug, array $cpt)
270
-    {
271
-        if (! empty($cpt['model_name'])) {
272
-            return [$post_type_slug => $cpt['model_name']];
273
-        }
274
-        if (! empty($cpt['class_name'])) {
275
-            return [
276
-                $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
277
-            ];
278
-        }
279
-        return [];
280
-    }
264
+	/**
265
+	 * @param       $post_type_slug
266
+	 * @param array $cpt
267
+	 * @return array
268
+	 */
269
+	private function getCustomPostTypeModelName($post_type_slug, array $cpt)
270
+	{
271
+		if (! empty($cpt['model_name'])) {
272
+			return [$post_type_slug => $cpt['model_name']];
273
+		}
274
+		if (! empty($cpt['class_name'])) {
275
+			return [
276
+				$post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
277
+			];
278
+		}
279
+		return [];
280
+	}
281 281
 
282 282
 
283
-    /**
284
-     * @param string $class_name
285
-     * @return string
286
-     */
287
-    private function deriveCptModelNameFromClassName($class_name)
288
-    {
289
-        return str_replace('EE', 'EEM', $class_name);
290
-    }
283
+	/**
284
+	 * @param string $class_name
285
+	 * @return string
286
+	 */
287
+	private function deriveCptModelNameFromClassName($class_name)
288
+	{
289
+		return str_replace('EE', 'EEM', $class_name);
290
+	}
291 291
 
292 292
 
293
-    /**
294
-     * This instantiates cpt models related to the cpts registered via EE.
295
-     *
296
-     * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for
297
-     *                               the cpt matching the given slug.  Otherwise all cpt models will be
298
-     *                               instantiated (if possible).
299
-     * @return EEM_CPT_Base[]        successful instantiation will return an array of successfully instantiated
300
-     *                               EEM models indexed by post slug.
301
-     * @since 4.6.16.rc.000
302
-     */
303
-    public function getCustomPostTypeModels($post_type_slug = '')
304
-    {
305
-        $cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug);
306
-        $instantiated = [];
307
-        foreach ($cpt_model_names as $slug => $model_name) {
308
-            $model = $this->loader->getShared($model_name);
309
-            if ($model instanceof EEM_CPT_Base) {
310
-                $instantiated[ $slug ] = $model;
311
-            }
312
-        }
313
-        return $instantiated;
314
-    }
293
+	/**
294
+	 * This instantiates cpt models related to the cpts registered via EE.
295
+	 *
296
+	 * @param string $post_type_slug If valid slug is provided, then will instantiate the model only for
297
+	 *                               the cpt matching the given slug.  Otherwise all cpt models will be
298
+	 *                               instantiated (if possible).
299
+	 * @return EEM_CPT_Base[]        successful instantiation will return an array of successfully instantiated
300
+	 *                               EEM models indexed by post slug.
301
+	 * @since 4.6.16.rc.000
302
+	 */
303
+	public function getCustomPostTypeModels($post_type_slug = '')
304
+	{
305
+		$cpt_model_names = $this->getCustomPostTypeModelNames($post_type_slug);
306
+		$instantiated = [];
307
+		foreach ($cpt_model_names as $slug => $model_name) {
308
+			$model = $this->loader->getShared($model_name);
309
+			if ($model instanceof EEM_CPT_Base) {
310
+				$instantiated[ $slug ] = $model;
311
+			}
312
+		}
313
+		return $instantiated;
314
+	}
315 315
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -73,8 +73,8 @@  discard block
 block discarded – undo
73 73
                     'public'              => true,
74 74
                     'show_in_nav_menus'   => true,
75 75
                     'show_in_graphql'     => true,
76
-                    'graphql_single_name' => $this->namespace . 'Event',
77
-                    'graphql_plural_name' => $this->namespace . 'Events',
76
+                    'graphql_single_name' => $this->namespace.'Event',
77
+                    'graphql_plural_name' => $this->namespace.'Events',
78 78
                     'capability_type'     => 'event',
79 79
                     'capabilities'        => [
80 80
                         'edit_post'              => 'ee_edit_event',
@@ -110,8 +110,8 @@  discard block
 block discarded – undo
110 110
                     'public'              => true,
111 111
                     'show_in_nav_menus'   => false, // by default this doesn't show for decaf,
112 112
                     'show_in_graphql'     => true,
113
-                    'graphql_single_name' => $this->namespace . 'Venue',
114
-                    'graphql_plural_name' => $this->namespace . 'Venues',
113
+                    'graphql_single_name' => $this->namespace.'Venue',
114
+                    'graphql_plural_name' => $this->namespace.'Venues',
115 115
                     'capability_type'     => 'venue',
116 116
                     'capabilities'        => [
117 117
                         'edit_post'              => 'ee_edit_venue',
@@ -214,7 +214,7 @@  discard block
 block discarded – undo
214 214
         $private_CPTs = [];
215 215
         foreach ($this->getDefinitions() as $CPT => $details) {
216 216
             if (empty($details['args']['public'])) {
217
-                $private_CPTs[ $CPT ] = $details;
217
+                $private_CPTs[$CPT] = $details;
218 218
             }
219 219
         }
220 220
         return $private_CPTs;
@@ -235,26 +235,26 @@  discard block
 block discarded – undo
235 235
     {
236 236
         $cpts = $this->getDefinitions();
237 237
         // first if slug passed in...
238
-        if (! empty($post_type_slug)) {
238
+        if ( ! empty($post_type_slug)) {
239 239
             // check that slug and cpt match
240
-            if (! isset($cpts[ $post_type_slug ])) {
240
+            if ( ! isset($cpts[$post_type_slug])) {
241 241
                 return [];
242 242
             }
243 243
             if (
244
-                empty($cpts[ $post_type_slug ]['class_name'])
245
-                && empty($cpts[ $post_type_slug ]['model_name'])
244
+                empty($cpts[$post_type_slug]['class_name'])
245
+                && empty($cpts[$post_type_slug]['model_name'])
246 246
             ) {
247 247
                 return [];
248 248
             }
249 249
             // k let's get the model name for this cpt.
250
-            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[ $post_type_slug ]);
250
+            return $this->getCustomPostTypeModelName($post_type_slug, $cpts[$post_type_slug]);
251 251
         }
252 252
         // if we made it here then we're returning an array of cpt model names indexed by post_type_slug.
253 253
         $cpt_models = [];
254 254
         foreach ($cpts as $slug => $args) {
255 255
             $model = $this->getCustomPostTypeModelName($slug, $args);
256
-            if (! empty($model)) {
257
-                $cpt_models[ $slug ] = $model;
256
+            if ( ! empty($model)) {
257
+                $cpt_models[$slug] = $model;
258 258
             }
259 259
         }
260 260
         return $cpt_models;
@@ -268,10 +268,10 @@  discard block
 block discarded – undo
268 268
      */
269 269
     private function getCustomPostTypeModelName($post_type_slug, array $cpt)
270 270
     {
271
-        if (! empty($cpt['model_name'])) {
271
+        if ( ! empty($cpt['model_name'])) {
272 272
             return [$post_type_slug => $cpt['model_name']];
273 273
         }
274
-        if (! empty($cpt['class_name'])) {
274
+        if ( ! empty($cpt['class_name'])) {
275 275
             return [
276 276
                 $post_type_slug => $this->deriveCptModelNameFromClassName($cpt['class_name']),
277 277
             ];
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
         foreach ($cpt_model_names as $slug => $model_name) {
308 308
             $model = $this->loader->getShared($model_name);
309 309
             if ($model instanceof EEM_CPT_Base) {
310
-                $instantiated[ $slug ] = $model;
310
+                $instantiated[$slug] = $model;
311 311
             }
312 312
         }
313 313
         return $instantiated;
Please login to merge, or discard this patch.
core/domain/entities/routing/handlers/shared/SessionRequests.php 1 patch
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -16,52 +16,52 @@
 block discarded – undo
16 16
 class SessionRequests extends Route
17 17
 {
18 18
 
19
-    /**
20
-     * returns true if the current request matches this route
21
-     *
22
-     * @return bool
23
-     * @since   $VID:$
24
-     */
25
-    public function matchesCurrentRequest(): bool
26
-    {
27
-        return $this->request->isAdmin()
28
-               || $this->request->isEeAjax()
29
-               || $this->request->isFrontend()
30
-               || $this->request->isIframe();
31
-    }
19
+	/**
20
+	 * returns true if the current request matches this route
21
+	 *
22
+	 * @return bool
23
+	 * @since   $VID:$
24
+	 */
25
+	public function matchesCurrentRequest(): bool
26
+	{
27
+		return $this->request->isAdmin()
28
+			   || $this->request->isEeAjax()
29
+			   || $this->request->isFrontend()
30
+			   || $this->request->isIframe();
31
+	}
32 32
 
33 33
 
34
-    /**
35
-     * @since $VID:$
36
-     */
37
-    protected function registerDependencies()
38
-    {
39
-        $this->dependency_map->registerDependencies(
40
-            'EE_Session',
41
-            [
42
-                'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
43
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
44
-                'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
45
-                'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
46
-                'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
47
-            ]
48
-        );
49
-        $this->dependency_map->registerDependencies(
50
-            'EventEspresso\core\services\session\SessionStartHandler',
51
-            ['EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache]
52
-        );
53
-    }
34
+	/**
35
+	 * @since $VID:$
36
+	 */
37
+	protected function registerDependencies()
38
+	{
39
+		$this->dependency_map->registerDependencies(
40
+			'EE_Session',
41
+			[
42
+				'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
43
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
44
+				'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
45
+				'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
46
+				'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
47
+			]
48
+		);
49
+		$this->dependency_map->registerDependencies(
50
+			'EventEspresso\core\services\session\SessionStartHandler',
51
+			['EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache]
52
+		);
53
+	}
54 54
 
55 55
 
56
-    /**
57
-     * implements logic required to run during request
58
-     *
59
-     * @return bool
60
-     * @since   $VID:$
61
-     */
62
-    protected function requestHandler(): bool
63
-    {
64
-        $this->loader->getShared('EE_Session');
65
-        return true;
66
-    }
56
+	/**
57
+	 * implements logic required to run during request
58
+	 *
59
+	 * @return bool
60
+	 * @since   $VID:$
61
+	 */
62
+	protected function requestHandler(): bool
63
+	{
64
+		$this->loader->getShared('EE_Session');
65
+		return true;
66
+	}
67 67
 }
Please login to merge, or discard this patch.
core/libraries/messages/EE_Message_To_Generate.php 1 patch
Indentation   +304 added lines, -304 removed lines patch added patch discarded remove patch
@@ -12,308 +12,308 @@
 block discarded – undo
12 12
 class EE_Message_To_Generate
13 13
 {
14 14
 
15
-    /**
16
-     * @var string
17
-     */
18
-    protected $_messenger_name;
19
-
20
-    /**
21
-     * @var string
22
-     */
23
-    protected $_message_type_name;
24
-
25
-    /**
26
-     * @var EE_messenger
27
-     */
28
-    protected $_messenger;
29
-
30
-    /**
31
-     * @var EE_message_type
32
-     */
33
-    protected $_message_type;
34
-
35
-    /**
36
-     * Identifier for the context the message is to be generated for.
37
-     *
38
-     * @var string
39
-     */
40
-    protected $_context = '';
41
-
42
-    /**
43
-     * Data that will be used to generate message.
44
-     *
45
-     * @var array
46
-     */
47
-    protected $_data = [];
48
-
49
-    /**
50
-     * Whether this message is for a preview or not.
51
-     *
52
-     * @var bool
53
-     */
54
-    protected $_preview = false;
55
-
56
-    /**
57
-     * @var EE_Message
58
-     */
59
-    protected $_message;
60
-
61
-    /**
62
-     * This is set by the constructor to indicate whether the incoming messenger
63
-     * and message type are valid.  This can then be checked by callers to determine whether
64
-     * to generate this message or not.
65
-     *
66
-     * @var bool
67
-     */
68
-    protected $_valid = false;
69
-
70
-    /**
71
-     * If there are any errors (non exception errors) they get added to this array for callers to decide
72
-     * how to handle.
73
-     *
74
-     * @var array
75
-     */
76
-    protected $_error_msg = [];
77
-
78
-    /**
79
-     * Can be accessed via the send_now() method, this is set in the validation
80
-     * routine via the EE_messenger::send_now() method.
81
-     *
82
-     * @var bool
83
-     */
84
-    protected $_send_now = false;
85
-
86
-    /**
87
-     * Holds the classname for the data handler used by the current message type.
88
-     * This is set on the first call to the public `get_data_handler_class_name()` method.
89
-     *
90
-     * @var string
91
-     */
92
-    protected $_data_handler_class_name = '';
93
-
94
-    /**
95
-     * one of the message status constants on EEM_Message
96
-     *
97
-     * @var string
98
-     * @since 4.10.29.p
99
-     */
100
-    protected $_status = '';
101
-
102
-    /**
103
-     * use $_status var above
104
-     *
105
-     * @var string
106
-     * @deprecated 4.10.29.p
107
-     */
108
-    protected $_message_status = '';
109
-
110
-
111
-    /**
112
-     * Constructor
113
-     *
114
-     * @param string $messenger_name    Slug representing messenger
115
-     * @param string $message_type_name Slug representing message type.
116
-     * @param mixed  $data              Data used for generating message.
117
-     * @param string $context           Optional context to restrict message generated for.
118
-     * @param bool   $preview           Whether this is being used to generate a preview or not.
119
-     * @param string $status
120
-     */
121
-    public function __construct(
122
-        $messenger_name,
123
-        $message_type_name,
124
-        $data = [],
125
-        $context = '',
126
-        $preview = false,
127
-        $status = EEM_Message::status_incomplete
128
-    ) {
129
-        $this->_messenger_name    = $messenger_name;
130
-        $this->_message_type_name = $message_type_name;
131
-        $this->_data              = is_array($data) ? $data : [$data];
132
-        $this->_context           = $context;
133
-        $this->_preview           = $preview;
134
-        $this->_status            = $status;
135
-        // attempt to generate message immediately
136
-        $this->_message = $this->_generate_message();
137
-    }
138
-
139
-
140
-    /**
141
-     * @return string
142
-     */
143
-    public function context()
144
-    {
145
-        return $this->_context;
146
-    }
147
-
148
-
149
-    /**
150
-     * @return array
151
-     */
152
-    public function data()
153
-    {
154
-        return $this->_data;
155
-    }
156
-
157
-
158
-    /**
159
-     * @return EE_messenger
160
-     */
161
-    public function messenger()
162
-    {
163
-        return $this->_messenger;
164
-    }
165
-
166
-
167
-    /**
168
-     * @return EE_message_type
169
-     */
170
-    public function message_type()
171
-    {
172
-        return $this->_message_type;
173
-    }
174
-
175
-
176
-    /**
177
-     * @return boolean
178
-     */
179
-    public function preview()
180
-    {
181
-        return $this->_preview;
182
-    }
183
-
184
-
185
-    /**
186
-     * @param boolean $preview
187
-     */
188
-    public function set_preview($preview)
189
-    {
190
-        $this->_preview = filter_var($preview, FILTER_VALIDATE_BOOLEAN);
191
-    }
192
-
193
-
194
-    /**
195
-     * @return bool
196
-     */
197
-    public function send_now()
198
-    {
199
-        return $this->_send_now;
200
-    }
201
-
202
-
203
-    /**
204
-     * Simply returns the state of the $_valid property.
205
-     *
206
-     * @return bool
207
-     */
208
-    public function valid()
209
-    {
210
-        return $this->_valid;
211
-    }
212
-
213
-
214
-    /**
215
-     * generates an EE_Message using the supplied arguments and some defaults
216
-     *
217
-     * @param array $properties
218
-     * @return EE_Message
219
-     */
220
-    protected function _generate_message($properties = [])
221
-    {
222
-        $message = EE_Message_Factory::create(
223
-            array_merge(
224
-                [
225
-                    'MSG_messenger'    => $this->_messenger_name,
226
-                    'MSG_message_type' => $this->_message_type_name,
227
-                    'MSG_context'      => $this->_context,
228
-                    'STS_ID'           => $this->_status,
229
-                ],
230
-                $properties
231
-            )
232
-        );
233
-        // validate the message, and if it's good, set some properties
234
-        try {
235
-            $message->is_valid_for_sending_or_generation(true);
236
-            $this->_valid        = true;
237
-            $this->_messenger    = $message->messenger_object();
238
-            $this->_message_type = $message->message_type_object();
239
-            $this->_send_now     = $message->send_now();
240
-        } catch (Exception $e) {
241
-            $this->_valid       = false;
242
-            $this->_error_msg[] = $e->getMessage();
243
-        }
244
-        return $message;
245
-    }
246
-
247
-
248
-    /**
249
-     *  Returns an instantiated EE_Message object from the internal data.
250
-     *
251
-     * @return EE_Message
252
-     */
253
-    public function get_EE_Message()
254
-    {
255
-        // already set ?
256
-        if ($this->_message instanceof EE_Message) {
257
-            return $this->_message;
258
-        }
259
-        // no? then let's create one
260
-        $this->_message = $this->_generate_message();
261
-        return $this->_message;
262
-    }
263
-
264
-
265
-    /**
266
-     * This returns the data_handler class name for the internal message type set.
267
-     * Note: this also verifies that the data handler class exists.  If it doesn't then $_valid is set to false
268
-     * and the data_handler_class name is set to an empty string.
269
-     *
270
-     * @param bool $preview Used to indicate that the preview data handler is to be returned.
271
-     * @return  string
272
-     */
273
-    public function get_data_handler_class_name($preview = false)
274
-    {
275
-        if ($this->_data_handler_class_name === '' && $this->valid()) {
276
-            $ref = $preview ? 'Preview' : $this->_message_type->get_data_handler($this->_data);
277
-            // make sure internal data is updated.
278
-            $this->_data = $this->_message_type->get_data();
279
-
280
-            // verify
281
-            $this->_data_handler_class_name =
282
-                EE_Message_To_Generate::verify_and_retrieve_class_name_for_data_handler_reference($ref);
283
-            if ($this->_data_handler_class_name === '') {
284
-                $this->_valid = false;
285
-            }
286
-        }
287
-        return $this->_data_handler_class_name;
288
-    }
289
-
290
-
291
-    /**
292
-     * Validates the given string as a reference for an existing, accessible data handler and returns the class name
293
-     * For the handler the reference matches.
294
-     *
295
-     * @param string $data_handler_reference
296
-     * @return string
297
-     */
298
-    public static function verify_and_retrieve_class_name_for_data_handler_reference($data_handler_reference)
299
-    {
300
-        $class_name = 'EE_Messages_' . $data_handler_reference . '_incoming_data';
301
-        if (! class_exists($class_name)) {
302
-            EE_Error::add_error(
303
-                sprintf(
304
-                    esc_html__(
305
-                        'The included data handler reference (%s) does not match any valid, accessible, "EE_Messages_incoming_data" classes.  Looking for %s.',
306
-                        'event_espresso'
307
-                    ),
308
-                    $data_handler_reference,
309
-                    $class_name
310
-                ),
311
-                __FILE__,
312
-                __FUNCTION__,
313
-                __LINE__
314
-            );
315
-            $class_name = ''; // clear out class_name so caller knows this isn't valid.
316
-        }
317
-        return $class_name;
318
-    }
15
+	/**
16
+	 * @var string
17
+	 */
18
+	protected $_messenger_name;
19
+
20
+	/**
21
+	 * @var string
22
+	 */
23
+	protected $_message_type_name;
24
+
25
+	/**
26
+	 * @var EE_messenger
27
+	 */
28
+	protected $_messenger;
29
+
30
+	/**
31
+	 * @var EE_message_type
32
+	 */
33
+	protected $_message_type;
34
+
35
+	/**
36
+	 * Identifier for the context the message is to be generated for.
37
+	 *
38
+	 * @var string
39
+	 */
40
+	protected $_context = '';
41
+
42
+	/**
43
+	 * Data that will be used to generate message.
44
+	 *
45
+	 * @var array
46
+	 */
47
+	protected $_data = [];
48
+
49
+	/**
50
+	 * Whether this message is for a preview or not.
51
+	 *
52
+	 * @var bool
53
+	 */
54
+	protected $_preview = false;
55
+
56
+	/**
57
+	 * @var EE_Message
58
+	 */
59
+	protected $_message;
60
+
61
+	/**
62
+	 * This is set by the constructor to indicate whether the incoming messenger
63
+	 * and message type are valid.  This can then be checked by callers to determine whether
64
+	 * to generate this message or not.
65
+	 *
66
+	 * @var bool
67
+	 */
68
+	protected $_valid = false;
69
+
70
+	/**
71
+	 * If there are any errors (non exception errors) they get added to this array for callers to decide
72
+	 * how to handle.
73
+	 *
74
+	 * @var array
75
+	 */
76
+	protected $_error_msg = [];
77
+
78
+	/**
79
+	 * Can be accessed via the send_now() method, this is set in the validation
80
+	 * routine via the EE_messenger::send_now() method.
81
+	 *
82
+	 * @var bool
83
+	 */
84
+	protected $_send_now = false;
85
+
86
+	/**
87
+	 * Holds the classname for the data handler used by the current message type.
88
+	 * This is set on the first call to the public `get_data_handler_class_name()` method.
89
+	 *
90
+	 * @var string
91
+	 */
92
+	protected $_data_handler_class_name = '';
93
+
94
+	/**
95
+	 * one of the message status constants on EEM_Message
96
+	 *
97
+	 * @var string
98
+	 * @since 4.10.29.p
99
+	 */
100
+	protected $_status = '';
101
+
102
+	/**
103
+	 * use $_status var above
104
+	 *
105
+	 * @var string
106
+	 * @deprecated 4.10.29.p
107
+	 */
108
+	protected $_message_status = '';
109
+
110
+
111
+	/**
112
+	 * Constructor
113
+	 *
114
+	 * @param string $messenger_name    Slug representing messenger
115
+	 * @param string $message_type_name Slug representing message type.
116
+	 * @param mixed  $data              Data used for generating message.
117
+	 * @param string $context           Optional context to restrict message generated for.
118
+	 * @param bool   $preview           Whether this is being used to generate a preview or not.
119
+	 * @param string $status
120
+	 */
121
+	public function __construct(
122
+		$messenger_name,
123
+		$message_type_name,
124
+		$data = [],
125
+		$context = '',
126
+		$preview = false,
127
+		$status = EEM_Message::status_incomplete
128
+	) {
129
+		$this->_messenger_name    = $messenger_name;
130
+		$this->_message_type_name = $message_type_name;
131
+		$this->_data              = is_array($data) ? $data : [$data];
132
+		$this->_context           = $context;
133
+		$this->_preview           = $preview;
134
+		$this->_status            = $status;
135
+		// attempt to generate message immediately
136
+		$this->_message = $this->_generate_message();
137
+	}
138
+
139
+
140
+	/**
141
+	 * @return string
142
+	 */
143
+	public function context()
144
+	{
145
+		return $this->_context;
146
+	}
147
+
148
+
149
+	/**
150
+	 * @return array
151
+	 */
152
+	public function data()
153
+	{
154
+		return $this->_data;
155
+	}
156
+
157
+
158
+	/**
159
+	 * @return EE_messenger
160
+	 */
161
+	public function messenger()
162
+	{
163
+		return $this->_messenger;
164
+	}
165
+
166
+
167
+	/**
168
+	 * @return EE_message_type
169
+	 */
170
+	public function message_type()
171
+	{
172
+		return $this->_message_type;
173
+	}
174
+
175
+
176
+	/**
177
+	 * @return boolean
178
+	 */
179
+	public function preview()
180
+	{
181
+		return $this->_preview;
182
+	}
183
+
184
+
185
+	/**
186
+	 * @param boolean $preview
187
+	 */
188
+	public function set_preview($preview)
189
+	{
190
+		$this->_preview = filter_var($preview, FILTER_VALIDATE_BOOLEAN);
191
+	}
192
+
193
+
194
+	/**
195
+	 * @return bool
196
+	 */
197
+	public function send_now()
198
+	{
199
+		return $this->_send_now;
200
+	}
201
+
202
+
203
+	/**
204
+	 * Simply returns the state of the $_valid property.
205
+	 *
206
+	 * @return bool
207
+	 */
208
+	public function valid()
209
+	{
210
+		return $this->_valid;
211
+	}
212
+
213
+
214
+	/**
215
+	 * generates an EE_Message using the supplied arguments and some defaults
216
+	 *
217
+	 * @param array $properties
218
+	 * @return EE_Message
219
+	 */
220
+	protected function _generate_message($properties = [])
221
+	{
222
+		$message = EE_Message_Factory::create(
223
+			array_merge(
224
+				[
225
+					'MSG_messenger'    => $this->_messenger_name,
226
+					'MSG_message_type' => $this->_message_type_name,
227
+					'MSG_context'      => $this->_context,
228
+					'STS_ID'           => $this->_status,
229
+				],
230
+				$properties
231
+			)
232
+		);
233
+		// validate the message, and if it's good, set some properties
234
+		try {
235
+			$message->is_valid_for_sending_or_generation(true);
236
+			$this->_valid        = true;
237
+			$this->_messenger    = $message->messenger_object();
238
+			$this->_message_type = $message->message_type_object();
239
+			$this->_send_now     = $message->send_now();
240
+		} catch (Exception $e) {
241
+			$this->_valid       = false;
242
+			$this->_error_msg[] = $e->getMessage();
243
+		}
244
+		return $message;
245
+	}
246
+
247
+
248
+	/**
249
+	 *  Returns an instantiated EE_Message object from the internal data.
250
+	 *
251
+	 * @return EE_Message
252
+	 */
253
+	public function get_EE_Message()
254
+	{
255
+		// already set ?
256
+		if ($this->_message instanceof EE_Message) {
257
+			return $this->_message;
258
+		}
259
+		// no? then let's create one
260
+		$this->_message = $this->_generate_message();
261
+		return $this->_message;
262
+	}
263
+
264
+
265
+	/**
266
+	 * This returns the data_handler class name for the internal message type set.
267
+	 * Note: this also verifies that the data handler class exists.  If it doesn't then $_valid is set to false
268
+	 * and the data_handler_class name is set to an empty string.
269
+	 *
270
+	 * @param bool $preview Used to indicate that the preview data handler is to be returned.
271
+	 * @return  string
272
+	 */
273
+	public function get_data_handler_class_name($preview = false)
274
+	{
275
+		if ($this->_data_handler_class_name === '' && $this->valid()) {
276
+			$ref = $preview ? 'Preview' : $this->_message_type->get_data_handler($this->_data);
277
+			// make sure internal data is updated.
278
+			$this->_data = $this->_message_type->get_data();
279
+
280
+			// verify
281
+			$this->_data_handler_class_name =
282
+				EE_Message_To_Generate::verify_and_retrieve_class_name_for_data_handler_reference($ref);
283
+			if ($this->_data_handler_class_name === '') {
284
+				$this->_valid = false;
285
+			}
286
+		}
287
+		return $this->_data_handler_class_name;
288
+	}
289
+
290
+
291
+	/**
292
+	 * Validates the given string as a reference for an existing, accessible data handler and returns the class name
293
+	 * For the handler the reference matches.
294
+	 *
295
+	 * @param string $data_handler_reference
296
+	 * @return string
297
+	 */
298
+	public static function verify_and_retrieve_class_name_for_data_handler_reference($data_handler_reference)
299
+	{
300
+		$class_name = 'EE_Messages_' . $data_handler_reference . '_incoming_data';
301
+		if (! class_exists($class_name)) {
302
+			EE_Error::add_error(
303
+				sprintf(
304
+					esc_html__(
305
+						'The included data handler reference (%s) does not match any valid, accessible, "EE_Messages_incoming_data" classes.  Looking for %s.',
306
+						'event_espresso'
307
+					),
308
+					$data_handler_reference,
309
+					$class_name
310
+				),
311
+				__FILE__,
312
+				__FUNCTION__,
313
+				__LINE__
314
+			);
315
+			$class_name = ''; // clear out class_name so caller knows this isn't valid.
316
+		}
317
+		return $class_name;
318
+	}
319 319
 }
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +700 added lines, -700 removed lines patch added patch discarded remove patch
@@ -2,137 +2,137 @@  discard block
 block discarded – undo
2 2
 /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3 3
 $generated_i18n_strings = array(
4 4
 	// Reference: packages/ui-components/src/Pagination/constants.ts:6
5
-	__( '2', 'event_espresso' ),
5
+	__('2', 'event_espresso'),
6 6
 
7 7
 	// Reference: packages/ui-components/src/Pagination/constants.ts:7
8
-	__( '6', 'event_espresso' ),
8
+	__('6', 'event_espresso'),
9 9
 
10 10
 	// Reference: packages/ui-components/src/Pagination/constants.ts:8
11
-	__( '12', 'event_espresso' ),
11
+	__('12', 'event_espresso'),
12 12
 
13 13
 	// Reference: packages/ui-components/src/Pagination/constants.ts:9
14
-	__( '24', 'event_espresso' ),
14
+	__('24', 'event_espresso'),
15 15
 
16 16
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
17
-	__( '48', 'event_espresso' ),
17
+	__('48', 'event_espresso'),
18 18
 
19 19
 	// Reference: domains/core/admin/blocks/src/components/AvatarImage.tsx:27
20
-	__( 'contact avatar', 'event_espresso' ),
20
+	__('contact avatar', 'event_espresso'),
21 21
 
22 22
 	// Reference: domains/core/admin/blocks/src/components/OrderByControl.tsx:12
23
-	__( 'Order by', 'event_espresso' ),
23
+	__('Order by', 'event_espresso'),
24 24
 
25 25
 	// Reference: domains/core/admin/blocks/src/components/RegStatusControl.tsx:17
26 26
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectStatus.tsx:13
27
-	__( 'Select Registration Status', 'event_espresso' ),
27
+	__('Select Registration Status', 'event_espresso'),
28 28
 
29 29
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:14
30
-	__( 'Ascending', 'event_espresso' ),
30
+	__('Ascending', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:18
33
-	__( 'Descending', 'event_espresso' ),
33
+	__('Descending', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:24
36
-	__( 'Sort order:', 'event_espresso' ),
36
+	__('Sort order:', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:41
39
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
39
+	__('There was some error fetching attendees list', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:47
42
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
42
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:53
45
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
45
+	__('There are no attendees for selected options.', 'event_espresso'),
46 46
 
47 47
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:12
48
-	__( 'Display on Archives', 'event_espresso' ),
48
+	__('Display on Archives', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
51
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
51
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:18
54
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
54
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:29
57
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
57
+	__('Number of Attendees to Display:', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:34
60 60
 	/* translators: %d attendees count */
61
-	_n_noop( 'Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso' ),
61
+	_n_noop('Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso'),
62 62
 
63 63
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:27
64
-	__( 'Display Gravatar', 'event_espresso' ),
64
+	__('Display Gravatar', 'event_espresso'),
65 65
 
66 66
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
67
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
67
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
68 68
 
69 69
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:33
70
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
70
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
71 71
 
72 72
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:38
73
-	__( 'Size of Gravatar', 'event_espresso' ),
73
+	__('Size of Gravatar', 'event_espresso'),
74 74
 
75 75
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectDatetime.tsx:22
76
-	__( 'Select Datetime', 'event_espresso' ),
76
+	__('Select Datetime', 'event_espresso'),
77 77
 
78 78
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectEvent.tsx:22
79 79
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectEvent.tsx:22
80
-	__( 'Select Event', 'event_espresso' ),
80
+	__('Select Event', 'event_espresso'),
81 81
 
82 82
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:11
83
-	__( 'Attendee id', 'event_espresso' ),
83
+	__('Attendee id', 'event_espresso'),
84 84
 
85 85
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:15
86
-	__( 'Last name only', 'event_espresso' ),
86
+	__('Last name only', 'event_espresso'),
87 87
 
88 88
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:19
89
-	__( 'First name only', 'event_espresso' ),
89
+	__('First name only', 'event_espresso'),
90 90
 
91 91
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:23
92
-	__( 'First, then Last name', 'event_espresso' ),
92
+	__('First, then Last name', 'event_espresso'),
93 93
 
94 94
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:27
95
-	__( 'Last, then First name', 'event_espresso' ),
95
+	__('Last, then First name', 'event_espresso'),
96 96
 
97 97
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:41
98
-	__( 'Order Attendees by:', 'event_espresso' ),
98
+	__('Order Attendees by:', 'event_espresso'),
99 99
 
100 100
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectTicket.tsx:22
101
-	__( 'Select Ticket', 'event_espresso' ),
101
+	__('Select Ticket', 'event_espresso'),
102 102
 
103 103
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:21
104
-	__( 'Filter By Settings', 'event_espresso' ),
104
+	__('Filter By Settings', 'event_espresso'),
105 105
 
106 106
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:36
107
-	__( 'Gravatar Setttings', 'event_espresso' ),
107
+	__('Gravatar Setttings', 'event_espresso'),
108 108
 
109 109
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:39
110
-	__( 'Archive Settings', 'event_espresso' ),
110
+	__('Archive Settings', 'event_espresso'),
111 111
 
112 112
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:10
113
-	__( 'Event Attendees', 'event_espresso' ),
113
+	__('Event Attendees', 'event_espresso'),
114 114
 
115 115
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:11
116
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
116
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
117 117
 
118 118
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
119 119
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
120 120
 	// Reference: packages/edtr-services/src/constants.ts:25
121
-	__( 'event', 'event_espresso' ),
121
+	__('event', 'event_espresso'),
122 122
 
123 123
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
124
-	__( 'attendees', 'event_espresso' ),
124
+	__('attendees', 'event_espresso'),
125 125
 
126 126
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
127
-	__( 'list', 'event_espresso' ),
127
+	__('list', 'event_espresso'),
128 128
 
129 129
 	// Reference: domains/core/admin/blocks/src/event/DisplayField.tsx:41
130
-	__( 'An unknown error occurred while fetching event details.', 'event_espresso' ),
130
+	__('An unknown error occurred while fetching event details.', 'event_espresso'),
131 131
 
132 132
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:10
133 133
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:24
134 134
 	// Reference: packages/utils/src/list/index.ts:14
135
-	__( 'Select…', 'event_espresso' ),
135
+	__('Select…', 'event_espresso'),
136 136
 
137 137
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:15
138 138
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:75
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:97
142 142
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:49
143 143
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:40
144
-	__( 'Name', 'event_espresso' ),
144
+	__('Name', 'event_espresso'),
145 145
 
146 146
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:19
147 147
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:80
@@ -149,401 +149,401 @@  discard block
 block discarded – undo
149 149
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:102
150 150
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:55
151 151
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
152
-	__( 'Description', 'event_espresso' ),
152
+	__('Description', 'event_espresso'),
153 153
 
154 154
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:23
155
-	__( 'Short description', 'event_espresso' ),
155
+	__('Short description', 'event_espresso'),
156 156
 
157 157
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:35
158
-	__( 'Select Field', 'event_espresso' ),
158
+	__('Select Field', 'event_espresso'),
159 159
 
160 160
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:27
161
-	__( 'Text Color', 'event_espresso' ),
161
+	__('Text Color', 'event_espresso'),
162 162
 
163 163
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:32
164
-	__( 'Background Color', 'event_espresso' ),
164
+	__('Background Color', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:41
167 167
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:22
168 168
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:21
169
-	__( 'Settings', 'event_espresso' ),
169
+	__('Settings', 'event_espresso'),
170 170
 
171 171
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:45
172
-	__( 'Typography', 'event_espresso' ),
172
+	__('Typography', 'event_espresso'),
173 173
 
174 174
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:48
175
-	__( 'Color', 'event_espresso' ),
175
+	__('Color', 'event_espresso'),
176 176
 
177 177
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
178
-	__( 'field', 'event_espresso' ),
178
+	__('field', 'event_espresso'),
179 179
 
180 180
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:8
181
-	__( 'Event Field', 'event_espresso' ),
181
+	__('Event Field', 'event_espresso'),
182 182
 
183 183
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:9
184
-	__( 'Displays the selected field of an event', 'event_espresso' ),
184
+	__('Displays the selected field of an event', 'event_espresso'),
185 185
 
186 186
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:17
187
-	__( 'Error', 'event_espresso' ),
187
+	__('Error', 'event_espresso'),
188 188
 
189 189
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:9
190
-	__( 'Loading…', 'event_espresso' ),
190
+	__('Loading…', 'event_espresso'),
191 191
 
192 192
 	// Reference: domains/core/admin/eventEditor/src/ui/EventDescription.tsx:33
193
-	__( 'Event Description', 'event_espresso' ),
193
+	__('Event Description', 'event_espresso'),
194 194
 
195 195
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/ActiveStatus.tsx:29
196
-	__( 'Active status', 'event_espresso' ),
196
+	__('Active status', 'event_espresso'),
197 197
 
198 198
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/AltRegPage.tsx:12
199
-	__( 'Alternative Registration Page', 'event_espresso' ),
199
+	__('Alternative Registration Page', 'event_espresso'),
200 200
 
201 201
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/DefaultRegistrationStatus.tsx:26
202
-	__( 'Default Registration Status', 'event_espresso' ),
202
+	__('Default Registration Status', 'event_espresso'),
203 203
 
204 204
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
205
-	__( 'Donations Enabled', 'event_espresso' ),
205
+	__('Donations Enabled', 'event_espresso'),
206 206
 
207 207
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
208
-	__( 'Donations Disabled', 'event_espresso' ),
208
+	__('Donations Disabled', 'event_espresso'),
209 209
 
210 210
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventManager.tsx:16
211
-	__( 'Event Manager', 'event_espresso' ),
211
+	__('Event Manager', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventPhoneNumber.tsx:15
214
-	__( 'Event Phone Number', 'event_espresso' ),
214
+	__('Event Phone Number', 'event_espresso'),
215 215
 
216 216
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/MaxRegistrations.tsx:13
217
-	__( 'Max Registrations per Transaction', 'event_espresso' ),
217
+	__('Max Registrations per Transaction', 'event_espresso'),
218 218
 
219 219
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
220
-	__( 'Ticket Selector Enabled', 'event_espresso' ),
220
+	__('Ticket Selector Enabled', 'event_espresso'),
221 221
 
222 222
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
223
-	__( 'Ticket Selector Disabled', 'event_espresso' ),
223
+	__('Ticket Selector Disabled', 'event_espresso'),
224 224
 
225 225
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:41
226
-	__( 'Event Details', 'event_espresso' ),
226
+	__('Event Details', 'event_espresso'),
227 227
 
228 228
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:47
229
-	__( 'Registration Options', 'event_espresso' ),
229
+	__('Registration Options', 'event_espresso'),
230 230
 
231 231
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
232
-	__( 'primary information about the date', 'event_espresso' ),
232
+	__('primary information about the date', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
235
-	__( 'Date Details', 'event_espresso' ),
235
+	__('Date Details', 'event_espresso'),
236 236
 
237 237
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
238 238
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
239 239
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
240
-	__( 'relations between tickets and dates', 'event_espresso' ),
240
+	__('relations between tickets and dates', 'event_espresso'),
241 241
 
242 242
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
243
-	__( 'Assign Tickets', 'event_espresso' ),
243
+	__('Assign Tickets', 'event_espresso'),
244 244
 
245 245
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/FooterButtons.tsx:22
246
-	__( 'Save and assign tickets', 'event_espresso' ),
246
+	__('Save and assign tickets', 'event_espresso'),
247 247
 
248 248
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:27
249 249
 	/* translators: %s datetime id */
250
-	__( 'Edit datetime %s', 'event_espresso' ),
250
+	__('Edit datetime %s', 'event_espresso'),
251 251
 
252 252
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:30
253
-	__( 'New Datetime', 'event_espresso' ),
253
+	__('New Datetime', 'event_espresso'),
254 254
 
255 255
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:110
256 256
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:108
257 257
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:132
258 258
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:108
259
-	__( 'Details', 'event_espresso' ),
259
+	__('Details', 'event_espresso'),
260 260
 
261 261
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:114
262 262
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:112
263 263
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:81
264
-	__( 'Capacity', 'event_espresso' ),
264
+	__('Capacity', 'event_espresso'),
265 265
 
266 266
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:119
267
-	__( 'The maximum number of registrants that can attend the event at this particular date.', 'event_espresso' ),
267
+	__('The maximum number of registrants that can attend the event at this particular date.', 'event_espresso'),
268 268
 
269 269
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:123
270
-	__( 'Set to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
270
+	__('Set to 0 to close registration or leave blank for no limit.', 'event_espresso'),
271 271
 
272 272
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:129
273 273
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:209
274
-	__( 'Trash', 'event_espresso' ),
274
+	__('Trash', 'event_espresso'),
275 275
 
276 276
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:71
277 277
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:45
278 278
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:93
279 279
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:45
280
-	__( 'Basics', 'event_espresso' ),
280
+	__('Basics', 'event_espresso'),
281 281
 
282 282
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:88
283 283
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:63
284 284
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:63
285
-	__( 'Dates', 'event_espresso' ),
285
+	__('Dates', 'event_espresso'),
286 286
 
287 287
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
288 288
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:51
289 289
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:114
290
-	__( 'Start Date', 'event_espresso' ),
290
+	__('Start Date', 'event_espresso'),
291 291
 
292 292
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:99
293 293
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:65
294 294
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:121
295
-	__( 'End Date', 'event_espresso' ),
295
+	__('End Date', 'event_espresso'),
296 296
 
297 297
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateRegistrationsLink.tsx:13
298
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
298
+	__('view ALL registrations for this date.', 'event_espresso'),
299 299
 
300 300
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateSoldLink.tsx:13
301
-	__( 'view approved registrations for this date.', 'event_espresso' ),
301
+	__('view approved registrations for this date.', 'event_espresso'),
302 302
 
303 303
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:35
304 304
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:33
305
-	__( 'Event Dates', 'event_espresso' ),
305
+	__('Event Dates', 'event_espresso'),
306 306
 
307 307
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:38
308
-	__( 'loading event dates…', 'event_espresso' ),
308
+	__('loading event dates…', 'event_espresso'),
309 309
 
310 310
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:21
311
-	__( 'Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso' ),
311
+	__('Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso'),
312 312
 
313 313
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:31
314
-	__( 'Ticket Assignments', 'event_espresso' ),
314
+	__('Ticket Assignments', 'event_espresso'),
315 315
 
316 316
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:25
317
-	__( 'Number of related tickets', 'event_espresso' ),
317
+	__('Number of related tickets', 'event_espresso'),
318 318
 
319 319
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:26
320
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
320
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
321 321
 
322 322
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:34
323
-	__( 'assign tickets', 'event_espresso' ),
323
+	__('assign tickets', 'event_espresso'),
324 324
 
325 325
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
326
-	__( 'Permanently delete Datetime?', 'event_espresso' ),
326
+	__('Permanently delete Datetime?', 'event_espresso'),
327 327
 
328 328
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:25
329
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
329
+	__('Move Datetime to Trash?', 'event_espresso'),
330 330
 
331 331
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:27
332
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
332
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
333 333
 
334 334
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:30
335
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
335
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
336 336
 
337 337
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
338 338
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
339
-	__( 'delete permanently', 'event_espresso' ),
339
+	__('delete permanently', 'event_espresso'),
340 340
 
341 341
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:39
342
-	__( 'trash datetime', 'event_espresso' ),
342
+	__('trash datetime', 'event_espresso'),
343 343
 
344 344
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:45
345
-	__( 'event date main menu', 'event_espresso' ),
345
+	__('event date main menu', 'event_espresso'),
346 346
 
347 347
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:59
348
-	__( 'edit datetime', 'event_espresso' ),
348
+	__('edit datetime', 'event_espresso'),
349 349
 
350 350
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:60
351
-	__( 'copy datetime', 'event_espresso' ),
351
+	__('copy datetime', 'event_espresso'),
352 352
 
353 353
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:36
354 354
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:39
355 355
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:43
356
-	__( 'bulk actions', 'event_espresso' ),
356
+	__('bulk actions', 'event_espresso'),
357 357
 
358 358
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:40
359
-	__( 'edit datetime details', 'event_espresso' ),
359
+	__('edit datetime details', 'event_espresso'),
360 360
 
361 361
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
362
-	__( 'delete datetimes', 'event_espresso' ),
362
+	__('delete datetimes', 'event_espresso'),
363 363
 
364 364
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
365
-	__( 'trash datetimes', 'event_espresso' ),
365
+	__('trash datetimes', 'event_espresso'),
366 366
 
367 367
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
368
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
368
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
369 369
 
370 370
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
371
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
371
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
372 372
 
373 373
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
374
-	__( 'Delete datetimes permanently', 'event_espresso' ),
374
+	__('Delete datetimes permanently', 'event_espresso'),
375 375
 
376 376
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
377
-	__( 'Trash datetimes', 'event_espresso' ),
377
+	__('Trash datetimes', 'event_espresso'),
378 378
 
379 379
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:21
380
-	__( 'Bulk edit date details', 'event_espresso' ),
380
+	__('Bulk edit date details', 'event_espresso'),
381 381
 
382 382
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
383
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
383
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
384 384
 
385 385
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
386 386
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
387
-	__( 'Name must be at least three characters', 'event_espresso' ),
387
+	__('Name must be at least three characters', 'event_espresso'),
388 388
 
389 389
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:67
390 390
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:67
391
-	__( 'Shift dates', 'event_espresso' ),
391
+	__('Shift dates', 'event_espresso'),
392 392
 
393 393
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:92
394 394
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:92
395
-	__( 'earlier', 'event_espresso' ),
395
+	__('earlier', 'event_espresso'),
396 396
 
397 397
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:96
398 398
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:96
399
-	__( 'later', 'event_espresso' ),
399
+	__('later', 'event_espresso'),
400 400
 
401 401
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:31
402 402
 	/* translators: click to edit capacity<linebreak>(registration limit)… */
403
-	__( 'click to edit capacity%s(registration limit)…', 'event_espresso' ),
403
+	__('click to edit capacity%s(registration limit)…', 'event_espresso'),
404 404
 
405 405
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:31
406 406
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:27
407 407
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:34
408
-	__( 'starts', 'event_espresso' ),
408
+	__('starts', 'event_espresso'),
409 409
 
410 410
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
411 411
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:34
412 412
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:47
413
-	__( 'ends', 'event_espresso' ),
413
+	__('ends', 'event_espresso'),
414 414
 
415 415
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
416
-	__( 'started', 'event_espresso' ),
416
+	__('started', 'event_espresso'),
417 417
 
418 418
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
419
-	__( 'ended', 'event_espresso' ),
419
+	__('ended', 'event_espresso'),
420 420
 
421 421
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:46
422
-	__( 'Edit Event Date', 'event_espresso' ),
422
+	__('Edit Event Date', 'event_espresso'),
423 423
 
424 424
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:50
425
-	__( 'edit start and end dates', 'event_espresso' ),
425
+	__('edit start and end dates', 'event_espresso'),
426 426
 
427 427
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:16
428 428
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:16
429
-	__( 'sold', 'event_espresso' ),
429
+	__('sold', 'event_espresso'),
430 430
 
431 431
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:21
432
-	__( 'capacity', 'event_espresso' ),
432
+	__('capacity', 'event_espresso'),
433 433
 
434 434
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:27
435 435
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:26
436
-	__( 'reg list', 'event_espresso' ),
436
+	__('reg list', 'event_espresso'),
437 437
 
438 438
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:43
439 439
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:35
440
-	__( 'add description…', 'event_espresso' ),
440
+	__('add description…', 'event_espresso'),
441 441
 
442 442
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:44
443 443
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:36
444
-	__( 'Edit description', 'event_espresso' ),
444
+	__('Edit description', 'event_espresso'),
445 445
 
446 446
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:45
447 447
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:37
448
-	__( 'click to edit description…', 'event_espresso' ),
448
+	__('click to edit description…', 'event_espresso'),
449 449
 
450 450
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:10
451
-	__( 'Move Date to Trash', 'event_espresso' ),
451
+	__('Move Date to Trash', 'event_espresso'),
452 452
 
453 453
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:13
454 454
 	// Reference: packages/constants/src/datetime.ts:6
455
-	__( 'Active', 'event_espresso' ),
455
+	__('Active', 'event_espresso'),
456 456
 
457 457
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:14
458 458
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:13
459
-	__( 'Trashed', 'event_espresso' ),
459
+	__('Trashed', 'event_espresso'),
460 460
 
461 461
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:15
462 462
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:14
463 463
 	// Reference: packages/constants/src/datetime.ts:8
464
-	__( 'Expired', 'event_espresso' ),
464
+	__('Expired', 'event_espresso'),
465 465
 
466 466
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:16
467 467
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:16
468
-	__( 'Sold Out', 'event_espresso' ),
468
+	__('Sold Out', 'event_espresso'),
469 469
 
470 470
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:17
471 471
 	// Reference: packages/constants/src/datetime.ts:12
472
-	__( 'Upcoming', 'event_espresso' ),
472
+	__('Upcoming', 'event_espresso'),
473 473
 
474 474
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:7
475
-	__( 'Edit Event Date Details', 'event_espresso' ),
475
+	__('Edit Event Date Details', 'event_espresso'),
476 476
 
477 477
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:8
478
-	__( 'View Registrations for this Date', 'event_espresso' ),
478
+	__('View Registrations for this Date', 'event_espresso'),
479 479
 
480 480
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:9
481
-	__( 'Manage Ticket Assignments', 'event_espresso' ),
481
+	__('Manage Ticket Assignments', 'event_espresso'),
482 482
 
483 483
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:41
484 484
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:41
485
-	__( 'click to edit title…', 'event_espresso' ),
485
+	__('click to edit title…', 'event_espresso'),
486 486
 
487 487
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:42
488 488
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:42
489
-	__( 'add title…', 'event_espresso' ),
489
+	__('add title…', 'event_espresso'),
490 490
 
491 491
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:17
492 492
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:17
493
-	__( 'ON', 'event_espresso' ),
493
+	__('ON', 'event_espresso'),
494 494
 
495 495
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
496
-	__( 'end dates only', 'event_espresso' ),
496
+	__('end dates only', 'event_espresso'),
497 497
 
498 498
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:11
499
-	__( 'start and end dates', 'event_espresso' ),
499
+	__('start and end dates', 'event_espresso'),
500 500
 
501 501
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
502
-	__( 'dates above 90% capacity', 'event_espresso' ),
502
+	__('dates above 90% capacity', 'event_espresso'),
503 503
 
504 504
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
505
-	__( 'dates above 75% capacity', 'event_espresso' ),
505
+	__('dates above 75% capacity', 'event_espresso'),
506 506
 
507 507
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
508
-	__( 'dates above 50% capacity', 'event_espresso' ),
508
+	__('dates above 50% capacity', 'event_espresso'),
509 509
 
510 510
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:19
511
-	__( 'dates below 50% capacity', 'event_espresso' ),
511
+	__('dates below 50% capacity', 'event_espresso'),
512 512
 
513 513
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
514
-	__( 'all dates', 'event_espresso' ),
514
+	__('all dates', 'event_espresso'),
515 515
 
516 516
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
517
-	__( 'all active and upcoming', 'event_espresso' ),
517
+	__('all active and upcoming', 'event_espresso'),
518 518
 
519 519
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
520
-	__( 'active dates only', 'event_espresso' ),
520
+	__('active dates only', 'event_espresso'),
521 521
 
522 522
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
523
-	__( 'upcoming dates only', 'event_espresso' ),
523
+	__('upcoming dates only', 'event_espresso'),
524 524
 
525 525
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
526
-	__( 'next active or upcoming only', 'event_espresso' ),
526
+	__('next active or upcoming only', 'event_espresso'),
527 527
 
528 528
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
529
-	__( 'sold out dates only', 'event_espresso' ),
529
+	__('sold out dates only', 'event_espresso'),
530 530
 
531 531
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
532
-	__( 'recently expired dates', 'event_espresso' ),
532
+	__('recently expired dates', 'event_espresso'),
533 533
 
534 534
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
535
-	__( 'all expired dates', 'event_espresso' ),
535
+	__('all expired dates', 'event_espresso'),
536 536
 
537 537
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:31
538
-	__( 'trashed dates only', 'event_espresso' ),
538
+	__('trashed dates only', 'event_espresso'),
539 539
 
540 540
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
541 541
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:9
542 542
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:61
543
-	__( 'start date', 'event_espresso' ),
543
+	__('start date', 'event_espresso'),
544 544
 
545 545
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
546
-	__( 'name', 'event_espresso' ),
546
+	__('name', 'event_espresso'),
547 547
 
548 548
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
549 549
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:31
@@ -551,182 +551,182 @@  discard block
 block discarded – undo
551 551
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:27
552 552
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:31
553 553
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
554
-	__( 'ID', 'event_espresso' ),
554
+	__('ID', 'event_espresso'),
555 555
 
556 556
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:38
557 557
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:47
558
-	__( 'custom order', 'event_espresso' ),
558
+	__('custom order', 'event_espresso'),
559 559
 
560 560
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
561 561
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:51
562
-	__( 'display', 'event_espresso' ),
562
+	__('display', 'event_espresso'),
563 563
 
564 564
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
565
-	__( 'recurrence', 'event_espresso' ),
565
+	__('recurrence', 'event_espresso'),
566 566
 
567 567
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
568 568
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
569
-	__( 'sales', 'event_espresso' ),
569
+	__('sales', 'event_espresso'),
570 570
 
571 571
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
572 572
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
573
-	__( 'sort by', 'event_espresso' ),
573
+	__('sort by', 'event_espresso'),
574 574
 
575 575
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
576 576
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
577 577
 	// Reference: packages/ee-components/src/EntityList/EntityListFilterBar.tsx:46
578
-	__( 'search', 'event_espresso' ),
578
+	__('search', 'event_espresso'),
579 579
 
580 580
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:47
581 581
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
582
-	__( 'status', 'event_espresso' ),
582
+	__('status', 'event_espresso'),
583 583
 
584 584
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
585
-	__( 'start dates only', 'event_espresso' ),
585
+	__('start dates only', 'event_espresso'),
586 586
 
587 587
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
588 588
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/NewDateModal.tsx:12
589 589
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsModalButton.tsx:18
590
-	__( 'Add New Date', 'event_espresso' ),
590
+	__('Add New Date', 'event_espresso'),
591 591
 
592 592
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
593
-	__( 'Add Single Date', 'event_espresso' ),
593
+	__('Add Single Date', 'event_espresso'),
594 594
 
595 595
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:44
596
-	__( 'Add a single date that only occurs once', 'event_espresso' ),
596
+	__('Add a single date that only occurs once', 'event_espresso'),
597 597
 
598 598
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:46
599
-	__( 'Single Date', 'event_espresso' ),
599
+	__('Single Date', 'event_espresso'),
600 600
 
601 601
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:106
602
-	__( 'Reg list', 'event_espresso' ),
602
+	__('Reg list', 'event_espresso'),
603 603
 
604 604
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:107
605 605
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:111
606
-	__( 'Regs', 'event_espresso' ),
606
+	__('Regs', 'event_espresso'),
607 607
 
608 608
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:122
609 609
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:126
610 610
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:59
611
-	__( 'Actions', 'event_espresso' ),
611
+	__('Actions', 'event_espresso'),
612 612
 
613 613
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:52
614
-	__( 'Start', 'event_espresso' ),
614
+	__('Start', 'event_espresso'),
615 615
 
616 616
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:66
617
-	__( 'End', 'event_espresso' ),
617
+	__('End', 'event_espresso'),
618 618
 
619 619
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:82
620
-	__( 'Cap', 'event_espresso' ),
620
+	__('Cap', 'event_espresso'),
621 621
 
622 622
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:94
623 623
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:98
624
-	__( 'Sold', 'event_espresso' ),
624
+	__('Sold', 'event_espresso'),
625 625
 
626 626
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:33
627 627
 	// Reference: packages/form-builder/src/constants.ts:67
628
-	__( 'Text Input', 'event_espresso' ),
628
+	__('Text Input', 'event_espresso'),
629 629
 
630 630
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:34
631 631
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:32
632
-	__( 'Attendee First Name', 'event_espresso' ),
632
+	__('Attendee First Name', 'event_espresso'),
633 633
 
634 634
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:39
635 635
 	/* translators: field name */
636
-	__( 'Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso' ),
636
+	__('Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso'),
637 637
 
638 638
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:40
639 639
 	// Reference: packages/form-builder/src/constants.ts:82
640
-	__( 'Email Address', 'event_espresso' ),
640
+	__('Email Address', 'event_espresso'),
641 641
 
642 642
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:41
643 643
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:40
644
-	__( 'Attendee Email Address', 'event_espresso' ),
644
+	__('Attendee Email Address', 'event_espresso'),
645 645
 
646 646
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:49
647
-	__( 'Please add the required fields', 'event_espresso' ),
647
+	__('Please add the required fields', 'event_espresso'),
648 648
 
649 649
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/RegistrationForm.tsx:12
650
-	__( 'Registration Form', 'event_espresso' ),
650
+	__('Registration Form', 'event_espresso'),
651 651
 
652 652
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:13
653
-	__( 'primary registrant', 'event_espresso' ),
653
+	__('primary registrant', 'event_espresso'),
654 654
 
655 655
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:17
656
-	__( 'purchaser', 'event_espresso' ),
656
+	__('purchaser', 'event_espresso'),
657 657
 
658 658
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:21
659
-	__( 'registrants', 'event_espresso' ),
659
+	__('registrants', 'event_espresso'),
660 660
 
661 661
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:36
662
-	__( 'Attendee Last Name', 'event_espresso' ),
662
+	__('Attendee Last Name', 'event_espresso'),
663 663
 
664 664
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:44
665
-	__( 'Attendee Address', 'event_espresso' ),
665
+	__('Attendee Address', 'event_espresso'),
666 666
 
667 667
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:9
668
-	__( 'all', 'event_espresso' ),
668
+	__('all', 'event_espresso'),
669 669
 
670 670
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
671
-	__( 'Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
672
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
671
+	__('Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
672
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
673 673
 
674 674
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
675
-	__( 'Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
676
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
675
+	__('Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
676
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
677 677
 
678 678
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
679
-	__( 'Please Update Assignments', 'event_espresso' ),
679
+	__('Please Update Assignments', 'event_espresso'),
680 680
 
681 681
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:26
682
-	__( 'There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso' ),
682
+	__('There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso'),
683 683
 
684 684
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:29
685 685
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:74
686 686
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:21
687
-	__( 'Alert!', 'event_espresso' ),
687
+	__('Alert!', 'event_espresso'),
688 688
 
689 689
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:42
690 690
 	/* translators: 1 entity id, 2 entity name */
691
-	__( 'Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso' ),
691
+	__('Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso'),
692 692
 
693 693
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:49
694 694
 	/* translators: 1 entity id, 2 entity name */
695
-	__( 'Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso' ),
695
+	__('Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso'),
696 696
 
697 697
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal.tsx:28
698 698
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:13
699
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
699
+	__('Ticket Assignment Manager', 'event_espresso'),
700 700
 
701 701
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:10
702
-	__( 'existing relation', 'event_espresso' ),
702
+	__('existing relation', 'event_espresso'),
703 703
 
704 704
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:15
705
-	__( 'remove existing relation', 'event_espresso' ),
705
+	__('remove existing relation', 'event_espresso'),
706 706
 
707 707
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:20
708
-	__( 'add new relation', 'event_espresso' ),
708
+	__('add new relation', 'event_espresso'),
709 709
 
710 710
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:25
711
-	__( 'invalid relation', 'event_espresso' ),
711
+	__('invalid relation', 'event_espresso'),
712 712
 
713 713
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:29
714
-	__( 'no relation', 'event_espresso' ),
714
+	__('no relation', 'event_espresso'),
715 715
 
716 716
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/BodyCell.tsx:23
717
-	__( 'assign ticket', 'event_espresso' ),
717
+	__('assign ticket', 'event_espresso'),
718 718
 
719 719
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:15
720
-	__( 'Assignments', 'event_espresso' ),
720
+	__('Assignments', 'event_espresso'),
721 721
 
722 722
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:16
723
-	__( 'Event Dates are listed below', 'event_espresso' ),
723
+	__('Event Dates are listed below', 'event_espresso'),
724 724
 
725 725
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:17
726
-	__( 'Tickets are listed along the top', 'event_espresso' ),
726
+	__('Tickets are listed along the top', 'event_espresso'),
727 727
 
728 728
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:18
729
-	__( 'Click the cell buttons to toggle assigments', 'event_espresso' ),
729
+	__('Click the cell buttons to toggle assigments', 'event_espresso'),
730 730
 
731 731
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/useSubmitButtonProps.ts:29
732 732
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
@@ -735,1533 +735,1533 @@  discard block
 block discarded – undo
735 735
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:29
736 736
 	// Reference: packages/ui-components/src/Modal/useSubmitButtonProps.tsx:13
737 737
 	// Reference: packages/ui-components/src/Stepper/buttons/Submit.tsx:7
738
-	__( 'Submit', 'event_espresso' ),
738
+	__('Submit', 'event_espresso'),
739 739
 
740 740
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:20
741
-	__( 'All Dates', 'event_espresso' ),
741
+	__('All Dates', 'event_espresso'),
742 742
 
743 743
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:27
744
-	__( 'dates by month', 'event_espresso' ),
744
+	__('dates by month', 'event_espresso'),
745 745
 
746 746
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:16
747
-	__( 'show expired tickets', 'event_espresso' ),
747
+	__('show expired tickets', 'event_espresso'),
748 748
 
749 749
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:13
750
-	__( 'show trashed dates', 'event_espresso' ),
750
+	__('show trashed dates', 'event_espresso'),
751 751
 
752 752
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:16
753
-	__( 'show trashed tickets', 'event_espresso' ),
753
+	__('show trashed tickets', 'event_espresso'),
754 754
 
755 755
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/Container.tsx:38
756 756
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actions/Actions.tsx:21
757
-	__( 'Default tickets', 'event_espresso' ),
757
+	__('Default tickets', 'event_espresso'),
758 758
 
759 759
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/ModalBody.tsx:63
760 760
 	// Reference: packages/edtr-services/src/constants.ts:26
761
-	__( 'ticket', 'event_espresso' ),
761
+	__('ticket', 'event_espresso'),
762 762
 
763 763
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:26
764 764
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:33
765
-	__( 'Set ticket prices', 'event_espresso' ),
765
+	__('Set ticket prices', 'event_espresso'),
766 766
 
767 767
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:31
768
-	__( 'Skip prices - Save', 'event_espresso' ),
768
+	__('Skip prices - Save', 'event_espresso'),
769 769
 
770 770
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:37
771 771
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:57
772
-	__( 'Ticket details', 'event_espresso' ),
772
+	__('Ticket details', 'event_espresso'),
773 773
 
774 774
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:38
775
-	__( 'Save', 'event_espresso' ),
775
+	__('Save', 'event_espresso'),
776 776
 
777 777
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:22
778 778
 	/* translators: %s ticket id */
779
-	__( 'Edit ticket %s', 'event_espresso' ),
779
+	__('Edit ticket %s', 'event_espresso'),
780 780
 
781 781
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:25
782 782
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:30
783
-	__( 'New Ticket Details', 'event_espresso' ),
783
+	__('New Ticket Details', 'event_espresso'),
784 784
 
785 785
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
786 786
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
787
-	__( 'primary information about the ticket', 'event_espresso' ),
787
+	__('primary information about the ticket', 'event_espresso'),
788 788
 
789 789
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
790 790
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
791
-	__( 'Ticket Details', 'event_espresso' ),
791
+	__('Ticket Details', 'event_espresso'),
792 792
 
793 793
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:12
794 794
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:12
795
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
795
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
796 796
 
797 797
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:14
798 798
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:14
799
-	__( 'Price Calculator', 'event_espresso' ),
799
+	__('Price Calculator', 'event_espresso'),
800 800
 
801 801
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
802 802
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
803
-	__( 'Assign Dates', 'event_espresso' ),
803
+	__('Assign Dates', 'event_espresso'),
804 804
 
805 805
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:39
806
-	__( 'Skip prices - assign dates', 'event_espresso' ),
806
+	__('Skip prices - assign dates', 'event_espresso'),
807 807
 
808 808
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:50
809
-	__( 'Save and assign dates', 'event_espresso' ),
809
+	__('Save and assign dates', 'event_espresso'),
810 810
 
811 811
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:26
812 812
 	/* translators: 1 ticket name, 2 ticket id */
813
-	__( 'Edit ticket "%1$s" - %2$s', 'event_espresso' ),
813
+	__('Edit ticket "%1$s" - %2$s', 'event_espresso'),
814 814
 
815 815
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:110
816
-	__( 'Ticket Sales', 'event_espresso' ),
816
+	__('Ticket Sales', 'event_espresso'),
817 817
 
818 818
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:136
819 819
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:112
820
-	__( 'Quantity For Sale', 'event_espresso' ),
820
+	__('Quantity For Sale', 'event_espresso'),
821 821
 
822 822
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:142
823
-	__( 'The maximum number of this ticket available for sale.', 'event_espresso' ),
823
+	__('The maximum number of this ticket available for sale.', 'event_espresso'),
824 824
 
825 825
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:144
826
-	__( 'Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
826
+	__('Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
827 827
 
828 828
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:150
829 829
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:121
830
-	__( 'Number of Uses', 'event_espresso' ),
830
+	__('Number of Uses', 'event_espresso'),
831 831
 
832 832
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:156
833
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso' ),
833
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso'),
834 834
 
835 835
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:160
836
-	__( 'Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso' ),
836
+	__('Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso'),
837 837
 
838 838
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:168
839 839
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:129
840
-	__( 'Minimum Quantity', 'event_espresso' ),
840
+	__('Minimum Quantity', 'event_espresso'),
841 841
 
842 842
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:173
843
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
843
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
844 844
 
845 845
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:177
846
-	__( 'Leave blank for no minimum.', 'event_espresso' ),
846
+	__('Leave blank for no minimum.', 'event_espresso'),
847 847
 
848 848
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:183
849 849
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:137
850
-	__( 'Maximum Quantity', 'event_espresso' ),
850
+	__('Maximum Quantity', 'event_espresso'),
851 851
 
852 852
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:189
853
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
853
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
854 854
 
855 855
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:193
856
-	__( 'Leave blank for no maximum.', 'event_espresso' ),
856
+	__('Leave blank for no maximum.', 'event_espresso'),
857 857
 
858 858
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:199
859 859
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:146
860
-	__( 'Required Ticket', 'event_espresso' ),
860
+	__('Required Ticket', 'event_espresso'),
861 861
 
862 862
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:201
863
-	__( 'If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso' ),
863
+	__('If enabled, the ticket must be selected and will appear first in frontend ticket lists.', 'event_espresso'),
864 864
 
865 865
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:215
866
-	__( 'Visibility', 'event_espresso' ),
866
+	__('Visibility', 'event_espresso'),
867 867
 
868 868
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:217
869
-	__( 'Where the ticket can be viewed throughout the UI.', 'event_espresso' ),
869
+	__('Where the ticket can be viewed throughout the UI.', 'event_espresso'),
870 870
 
871 871
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:13
872
-	__( 'total registrations.', 'event_espresso' ),
872
+	__('total registrations.', 'event_espresso'),
873 873
 
874 874
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:14
875
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
875
+	__('view ALL registrations for this ticket.', 'event_espresso'),
876 876
 
877 877
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketSoldLink.tsx:13
878
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
878
+	__('view approved registrations for this ticket.', 'event_espresso'),
879 879
 
880 880
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:36
881
-	__( 'Available Tickets', 'event_espresso' ),
881
+	__('Available Tickets', 'event_espresso'),
882 882
 
883 883
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:39
884
-	__( 'loading tickets…', 'event_espresso' ),
884
+	__('loading tickets…', 'event_espresso'),
885 885
 
886 886
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:26
887
-	__( 'Number of related dates', 'event_espresso' ),
887
+	__('Number of related dates', 'event_espresso'),
888 888
 
889 889
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
890
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
890
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
891 891
 
892 892
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:37
893
-	__( 'assign dates', 'event_espresso' ),
893
+	__('assign dates', 'event_espresso'),
894 894
 
895 895
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
896
-	__( 'Permanently delete Ticket?', 'event_espresso' ),
896
+	__('Permanently delete Ticket?', 'event_espresso'),
897 897
 
898 898
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:18
899
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
899
+	__('Move Ticket to Trash?', 'event_espresso'),
900 900
 
901 901
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:21
902
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
902
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
903 903
 
904 904
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:22
905
-	__( 'Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso' ),
905
+	__('Are you sure you want to move this ticket to the trash? You can "untrash" this ticket later if you need to.', 'event_espresso'),
906 906
 
907 907
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:44
908 908
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Trash.tsx:6
909
-	__( 'trash ticket', 'event_espresso' ),
909
+	__('trash ticket', 'event_espresso'),
910 910
 
911 911
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:25
912
-	__( 'ticket main menu', 'event_espresso' ),
912
+	__('ticket main menu', 'event_espresso'),
913 913
 
914 914
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:38
915 915
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Edit.tsx:15
916
-	__( 'edit ticket', 'event_espresso' ),
916
+	__('edit ticket', 'event_espresso'),
917 917
 
918 918
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:39
919
-	__( 'copy ticket', 'event_espresso' ),
919
+	__('copy ticket', 'event_espresso'),
920 920
 
921 921
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:43
922
-	__( 'edit ticket details', 'event_espresso' ),
922
+	__('edit ticket details', 'event_espresso'),
923 923
 
924 924
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
925
-	__( 'delete tickets', 'event_espresso' ),
925
+	__('delete tickets', 'event_espresso'),
926 926
 
927 927
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:47
928
-	__( 'trash tickets', 'event_espresso' ),
928
+	__('trash tickets', 'event_espresso'),
929 929
 
930 930
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:51
931
-	__( 'edit ticket prices', 'event_espresso' ),
931
+	__('edit ticket prices', 'event_espresso'),
932 932
 
933 933
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
934
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
934
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
935 935
 
936 936
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
937
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
937
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
938 938
 
939 939
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
940
-	__( 'Delete tickets permanently', 'event_espresso' ),
940
+	__('Delete tickets permanently', 'event_espresso'),
941 941
 
942 942
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
943
-	__( 'Trash tickets', 'event_espresso' ),
943
+	__('Trash tickets', 'event_espresso'),
944 944
 
945 945
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:21
946
-	__( 'Bulk edit ticket details', 'event_espresso' ),
946
+	__('Bulk edit ticket details', 'event_espresso'),
947 947
 
948 948
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
949
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
949
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
950 950
 
951 951
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:19
952
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
952
+	__('Bulk edit ticket prices', 'event_espresso'),
953 953
 
954 954
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:20
955
-	__( 'Edit all prices together', 'event_espresso' ),
955
+	__('Edit all prices together', 'event_espresso'),
956 956
 
957 957
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:21
958
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
958
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
959 959
 
960 960
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:25
961
-	__( 'Edit prices individually', 'event_espresso' ),
961
+	__('Edit prices individually', 'event_espresso'),
962 962
 
963 963
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:26
964
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
964
+	__('Edit prices for each ticket individually', 'event_espresso'),
965 965
 
966 966
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:14
967 967
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:34
968 968
 	// Reference: packages/form/src/ResetButton.tsx:18
969 969
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
970
-	__( 'Reset', 'event_espresso' ),
970
+	__('Reset', 'event_espresso'),
971 971
 
972 972
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
973 973
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:76
974 974
 	// Reference: packages/ui-components/src/Modal/useCancelButtonProps.tsx:10
975
-	__( 'Cancel', 'event_espresso' ),
975
+	__('Cancel', 'event_espresso'),
976 976
 
977 977
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:26
978 978
 	/* translators: %s ticket name */
979
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
979
+	__('Edit prices for Ticket: %s', 'event_espresso'),
980 980
 
981 981
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:30
982
-	__( 'sales start', 'event_espresso' ),
982
+	__('sales start', 'event_espresso'),
983 983
 
984 984
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:33
985
-	__( 'sales began', 'event_espresso' ),
985
+	__('sales began', 'event_espresso'),
986 986
 
987 987
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:35
988
-	__( 'sales ended', 'event_espresso' ),
988
+	__('sales ended', 'event_espresso'),
989 989
 
990 990
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:36
991
-	__( 'sales end', 'event_espresso' ),
991
+	__('sales end', 'event_espresso'),
992 992
 
993 993
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:50
994
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
994
+	__('Edit Ticket Sale Dates', 'event_espresso'),
995 995
 
996 996
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:54
997
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
997
+	__('edit ticket sales start and end dates', 'event_espresso'),
998 998
 
999 999
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:21
1000
-	__( 'quantity', 'event_espresso' ),
1000
+	__('quantity', 'event_espresso'),
1001 1001
 
1002 1002
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:28
1003 1003
 	// Reference: packages/edtr-services/src/apollo/mutations/tickets/useUpdateTicketQtyByCapacity.ts:78
1004
-	__( 'Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso' ),
1004
+	__('Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso'),
1005 1005
 
1006 1006
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:51
1007
-	__( 'edit quantity of tickets available…', 'event_espresso' ),
1007
+	__('edit quantity of tickets available…', 'event_espresso'),
1008 1008
 
1009 1009
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:10
1010
-	__( 'Move Ticket to Trash', 'event_espresso' ),
1010
+	__('Move Ticket to Trash', 'event_espresso'),
1011 1011
 
1012 1012
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:15
1013 1013
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:52
1014
-	__( 'On Sale', 'event_espresso' ),
1014
+	__('On Sale', 'event_espresso'),
1015 1015
 
1016 1016
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:17
1017
-	__( 'Pending', 'event_espresso' ),
1017
+	__('Pending', 'event_espresso'),
1018 1018
 
1019 1019
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:7
1020
-	__( 'Edit Ticket Details', 'event_espresso' ),
1020
+	__('Edit Ticket Details', 'event_espresso'),
1021 1021
 
1022 1022
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:8
1023
-	__( 'Manage Date Assignments', 'event_espresso' ),
1023
+	__('Manage Date Assignments', 'event_espresso'),
1024 1024
 
1025 1025
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:9
1026 1026
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
1027
-	__( 'Ticket Price Calculator', 'event_espresso' ),
1027
+	__('Ticket Price Calculator', 'event_espresso'),
1028 1028
 
1029 1029
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:39
1030
-	__( 'edit ticket total…', 'event_espresso' ),
1030
+	__('edit ticket total…', 'event_espresso'),
1031 1031
 
1032 1032
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:53
1033
-	__( 'set price…', 'event_espresso' ),
1033
+	__('set price…', 'event_espresso'),
1034 1034
 
1035 1035
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:23
1036
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
1036
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
1037 1037
 
1038 1038
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
1039
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
1039
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
1040 1040
 
1041 1041
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
1042
-	__( 'ticket sales start and end dates', 'event_espresso' ),
1042
+	__('ticket sales start and end dates', 'event_espresso'),
1043 1043
 
1044 1044
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
1045
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
1045
+	__('tickets with 90% or more sold', 'event_espresso'),
1046 1046
 
1047 1047
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
1048
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
1048
+	__('tickets with 75% or more sold', 'event_espresso'),
1049 1049
 
1050 1050
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
1051
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
1051
+	__('tickets with 50% or more sold', 'event_espresso'),
1052 1052
 
1053 1053
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:19
1054
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
1054
+	__('tickets with less than 50% sold', 'event_espresso'),
1055 1055
 
1056 1056
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
1057
-	__( 'all tickets for all dates', 'event_espresso' ),
1057
+	__('all tickets for all dates', 'event_espresso'),
1058 1058
 
1059 1059
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
1060
-	__( 'all on sale and sale pending', 'event_espresso' ),
1060
+	__('all on sale and sale pending', 'event_espresso'),
1061 1061
 
1062 1062
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
1063
-	__( 'on sale tickets only', 'event_espresso' ),
1063
+	__('on sale tickets only', 'event_espresso'),
1064 1064
 
1065 1065
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
1066
-	__( 'sale pending tickets only', 'event_espresso' ),
1066
+	__('sale pending tickets only', 'event_espresso'),
1067 1067
 
1068 1068
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
1069
-	__( 'next on sale or sale pending only', 'event_espresso' ),
1069
+	__('next on sale or sale pending only', 'event_espresso'),
1070 1070
 
1071 1071
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
1072
-	__( 'sold out tickets only', 'event_espresso' ),
1072
+	__('sold out tickets only', 'event_espresso'),
1073 1073
 
1074 1074
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
1075
-	__( 'expired tickets only', 'event_espresso' ),
1075
+	__('expired tickets only', 'event_espresso'),
1076 1076
 
1077 1077
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:35
1078
-	__( 'trashed tickets only', 'event_espresso' ),
1078
+	__('trashed tickets only', 'event_espresso'),
1079 1079
 
1080 1080
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:40
1081
-	__( 'all tickets for above dates', 'event_espresso' ),
1081
+	__('all tickets for above dates', 'event_espresso'),
1082 1082
 
1083 1083
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
1084
-	__( 'ticket sale date', 'event_espresso' ),
1084
+	__('ticket sale date', 'event_espresso'),
1085 1085
 
1086 1086
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
1087
-	__( 'ticket name', 'event_espresso' ),
1087
+	__('ticket name', 'event_espresso'),
1088 1088
 
1089 1089
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
1090
-	__( 'ticket ID', 'event_espresso' ),
1090
+	__('ticket ID', 'event_espresso'),
1091 1091
 
1092 1092
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
1093
-	__( 'link', 'event_espresso' ),
1093
+	__('link', 'event_espresso'),
1094 1094
 
1095 1095
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
1096
-	__( 'ticket sales start date only', 'event_espresso' ),
1096
+	__('ticket sales start date only', 'event_espresso'),
1097 1097
 
1098 1098
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
1099
-	__( 'ticket sales end date only', 'event_espresso' ),
1099
+	__('ticket sales end date only', 'event_espresso'),
1100 1100
 
1101 1101
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:18
1102
-	__( 'Add New Ticket', 'event_espresso' ),
1102
+	__('Add New Ticket', 'event_espresso'),
1103 1103
 
1104 1104
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:32
1105
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
1105
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
1106 1106
 
1107 1107
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:34
1108
-	__( 'Single Ticket', 'event_espresso' ),
1108
+	__('Single Ticket', 'event_espresso'),
1109 1109
 
1110 1110
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:39
1111
-	__( 'Tickets', 'event_espresso' ),
1111
+	__('Tickets', 'event_espresso'),
1112 1112
 
1113 1113
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:110
1114
-	__( 'Registrations', 'event_espresso' ),
1114
+	__('Registrations', 'event_espresso'),
1115 1115
 
1116 1116
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:51
1117
-	__( 'Goes on Sale', 'event_espresso' ),
1117
+	__('Goes on Sale', 'event_espresso'),
1118 1118
 
1119 1119
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:65
1120
-	__( 'Sale Ends', 'event_espresso' ),
1120
+	__('Sale Ends', 'event_espresso'),
1121 1121
 
1122 1122
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:66
1123
-	__( 'Ends', 'event_espresso' ),
1123
+	__('Ends', 'event_espresso'),
1124 1124
 
1125 1125
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:78
1126
-	__( 'Price', 'event_espresso' ),
1126
+	__('Price', 'event_espresso'),
1127 1127
 
1128 1128
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:88
1129
-	__( 'Quantity', 'event_espresso' ),
1129
+	__('Quantity', 'event_espresso'),
1130 1130
 
1131 1131
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:105
1132
-	__( 'Select a Venue for the Event', 'event_espresso' ),
1132
+	__('Select a Venue for the Event', 'event_espresso'),
1133 1133
 
1134 1134
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:21
1135
-	__( 'Venue Details', 'event_espresso' ),
1135
+	__('Venue Details', 'event_espresso'),
1136 1136
 
1137 1137
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:38
1138
-	__( 'unlimited space', 'event_espresso' ),
1138
+	__('unlimited space', 'event_espresso'),
1139 1139
 
1140 1140
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:41
1141 1141
 	/* translators: %d venue capacity */
1142
-	__( 'Space for up to %d people', 'event_espresso' ),
1142
+	__('Space for up to %d people', 'event_espresso'),
1143 1143
 
1144 1144
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:60
1145
-	__( 'no image', 'event_espresso' ),
1145
+	__('no image', 'event_espresso'),
1146 1146
 
1147 1147
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:96
1148
-	__( 'Edit this Venue', 'event_espresso' ),
1148
+	__('Edit this Venue', 'event_espresso'),
1149 1149
 
1150 1150
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:29
1151
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
1151
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
1152 1152
 
1153 1153
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:40
1154
-	__( 'Skip', 'event_espresso' ),
1154
+	__('Skip', 'event_espresso'),
1155 1155
 
1156 1156
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:42
1157
-	__( 'Sure I\'ll help', 'event_espresso' ),
1157
+	__('Sure I\'ll help', 'event_espresso'),
1158 1158
 
1159 1159
 	// Reference: packages/adapters/src/Pagination/Pagination.tsx:23
1160
-	__( 'pagination', 'event_espresso' ),
1160
+	__('pagination', 'event_espresso'),
1161 1161
 
1162 1162
 	// Reference: packages/adapters/src/TagSelector/TagSelector.tsx:112
1163
-	__( 'toggle menu', 'event_espresso' ),
1163
+	__('toggle menu', 'event_espresso'),
1164 1164
 
1165 1165
 	// Reference: packages/constants/src/datetime.ts:10
1166
-	__( 'Postponed', 'event_espresso' ),
1166
+	__('Postponed', 'event_espresso'),
1167 1167
 
1168 1168
 	// Reference: packages/constants/src/datetime.ts:11
1169
-	__( 'SoldOut', 'event_espresso' ),
1169
+	__('SoldOut', 'event_espresso'),
1170 1170
 
1171 1171
 	// Reference: packages/constants/src/datetime.ts:7
1172 1172
 	// Reference: packages/predicates/src/registration/statusOptions.ts:11
1173
-	__( 'Cancelled', 'event_espresso' ),
1173
+	__('Cancelled', 'event_espresso'),
1174 1174
 
1175 1175
 	// Reference: packages/constants/src/datetime.ts:9
1176
-	__( 'Inactive', 'event_espresso' ),
1176
+	__('Inactive', 'event_espresso'),
1177 1177
 
1178 1178
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:25
1179
-	__( 'error creating %s', 'event_espresso' ),
1179
+	__('error creating %s', 'event_espresso'),
1180 1180
 
1181 1181
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:26
1182
-	__( 'error deleting %s', 'event_espresso' ),
1182
+	__('error deleting %s', 'event_espresso'),
1183 1183
 
1184 1184
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:27
1185
-	__( 'error updating %s', 'event_espresso' ),
1185
+	__('error updating %s', 'event_espresso'),
1186 1186
 
1187 1187
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:28
1188
-	__( 'creating %s', 'event_espresso' ),
1188
+	__('creating %s', 'event_espresso'),
1189 1189
 
1190 1190
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:29
1191
-	__( 'deleting %s', 'event_espresso' ),
1191
+	__('deleting %s', 'event_espresso'),
1192 1192
 
1193 1193
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:30
1194
-	__( 'updating %s', 'event_espresso' ),
1194
+	__('updating %s', 'event_espresso'),
1195 1195
 
1196 1196
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:31
1197
-	__( 'successfully created %s', 'event_espresso' ),
1197
+	__('successfully created %s', 'event_espresso'),
1198 1198
 
1199 1199
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:32
1200
-	__( 'successfully deleted %s', 'event_espresso' ),
1200
+	__('successfully deleted %s', 'event_espresso'),
1201 1201
 
1202 1202
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:33
1203
-	__( 'successfully updated %s', 'event_espresso' ),
1203
+	__('successfully updated %s', 'event_espresso'),
1204 1204
 
1205 1205
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:13
1206
-	__( 'day in range', 'event_espresso' ),
1206
+	__('day in range', 'event_espresso'),
1207 1207
 
1208 1208
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:17
1209 1209
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:79
1210
-	__( 'end date', 'event_espresso' ),
1210
+	__('end date', 'event_espresso'),
1211 1211
 
1212 1212
 	// Reference: packages/dates/src/components/DateTimePicker.tsx:13
1213 1213
 	// Reference: packages/dates/src/components/TimePicker.tsx:14
1214 1214
 	// Reference: packages/form-builder/src/state/utils.ts:433
1215
-	__( 'time', 'event_espresso' ),
1215
+	__('time', 'event_espresso'),
1216 1216
 
1217 1217
 	// Reference: packages/dates/src/constants.ts:5
1218
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1218
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1219 1219
 
1220 1220
 	// Reference: packages/dates/src/constants.ts:7
1221
-	__( 'Start Date & Time must be set before the End Date & Time', 'event_espresso' ),
1221
+	__('Start Date & Time must be set before the End Date & Time', 'event_espresso'),
1222 1222
 
1223 1223
 	// Reference: packages/dates/src/utils/misc.ts:16
1224
-	__( 'month(s)', 'event_espresso' ),
1224
+	__('month(s)', 'event_espresso'),
1225 1225
 
1226 1226
 	// Reference: packages/dates/src/utils/misc.ts:17
1227
-	__( 'week(s)', 'event_espresso' ),
1227
+	__('week(s)', 'event_espresso'),
1228 1228
 
1229 1229
 	// Reference: packages/dates/src/utils/misc.ts:18
1230
-	__( 'day(s)', 'event_espresso' ),
1230
+	__('day(s)', 'event_espresso'),
1231 1231
 
1232 1232
 	// Reference: packages/dates/src/utils/misc.ts:19
1233
-	__( 'hour(s)', 'event_espresso' ),
1233
+	__('hour(s)', 'event_espresso'),
1234 1234
 
1235 1235
 	// Reference: packages/dates/src/utils/misc.ts:20
1236
-	__( 'minute(s)', 'event_espresso' ),
1236
+	__('minute(s)', 'event_espresso'),
1237 1237
 
1238 1238
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:107
1239
-	__( 'price types initialized', 'event_espresso' ),
1239
+	__('price types initialized', 'event_espresso'),
1240 1240
 
1241 1241
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:117
1242
-	__( 'datetimes initialized', 'event_espresso' ),
1242
+	__('datetimes initialized', 'event_espresso'),
1243 1243
 
1244 1244
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:127
1245
-	__( 'tickets initialized', 'event_espresso' ),
1245
+	__('tickets initialized', 'event_espresso'),
1246 1246
 
1247 1247
 	// Reference: packages/edtr-services/src/apollo/initialization/useCacheRehydration.ts:137
1248
-	__( 'prices initialized', 'event_espresso' ),
1248
+	__('prices initialized', 'event_espresso'),
1249 1249
 
1250 1250
 	// Reference: packages/edtr-services/src/apollo/mutations/useReorderEntities.ts:72
1251
-	__( 'reordering has been applied', 'event_espresso' ),
1251
+	__('reordering has been applied', 'event_espresso'),
1252 1252
 
1253 1253
 	// Reference: packages/edtr-services/src/constants.ts:24
1254
-	__( 'datetime', 'event_espresso' ),
1254
+	__('datetime', 'event_espresso'),
1255 1255
 
1256 1256
 	// Reference: packages/edtr-services/src/constants.ts:27
1257
-	__( 'price', 'event_espresso' ),
1257
+	__('price', 'event_espresso'),
1258 1258
 
1259 1259
 	// Reference: packages/edtr-services/src/constants.ts:28
1260 1260
 	// Reference: packages/tpc/src/inputs/PriceTypeInput.tsx:19
1261
-	__( 'price type', 'event_espresso' ),
1261
+	__('price type', 'event_espresso'),
1262 1262
 
1263 1263
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:38
1264 1264
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:39
1265
-	__( 'End date has been adjusted', 'event_espresso' ),
1265
+	__('End date has been adjusted', 'event_espresso'),
1266 1266
 
1267 1267
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:59
1268
-	__( 'Required', 'event_espresso' ),
1268
+	__('Required', 'event_espresso'),
1269 1269
 
1270 1270
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:64
1271
-	__( 'Start Date is required', 'event_espresso' ),
1271
+	__('Start Date is required', 'event_espresso'),
1272 1272
 
1273 1273
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:68
1274
-	__( 'End Date is required', 'event_espresso' ),
1274
+	__('End Date is required', 'event_espresso'),
1275 1275
 
1276 1276
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:32
1277
-	__( 'no results found', 'event_espresso' ),
1277
+	__('no results found', 'event_espresso'),
1278 1278
 
1279 1279
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:33
1280
-	__( 'try changing filter settings', 'event_espresso' ),
1280
+	__('try changing filter settings', 'event_espresso'),
1281 1281
 
1282 1282
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:38
1283 1283
 	/* translators: %d entity id */
1284
-	__( 'select entity with id %d', 'event_espresso' ),
1284
+	__('select entity with id %d', 'event_espresso'),
1285 1285
 
1286 1286
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:41
1287
-	__( 'select all entities', 'event_espresso' ),
1287
+	__('select all entities', 'event_espresso'),
1288 1288
 
1289 1289
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1290
-	__( 'Note: ', 'event_espresso' ),
1290
+	__('Note: ', 'event_espresso'),
1291 1291
 
1292 1292
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1293
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
1293
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
1294 1294
 
1295 1295
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:27
1296
-	__( 'Bulk edit details', 'event_espresso' ),
1296
+	__('Bulk edit details', 'event_espresso'),
1297 1297
 
1298 1298
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:17
1299
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
1299
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
1300 1300
 
1301 1301
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:18
1302
-	__( 'Bulk update details', 'event_espresso' ),
1302
+	__('Bulk update details', 'event_espresso'),
1303 1303
 
1304 1304
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:27
1305
-	__( 'reorder dates', 'event_espresso' ),
1305
+	__('reorder dates', 'event_espresso'),
1306 1306
 
1307 1307
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:27
1308
-	__( 'reorder tickets', 'event_espresso' ),
1308
+	__('reorder tickets', 'event_espresso'),
1309 1309
 
1310 1310
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:32
1311
-	__( 'delete form element', 'event_espresso' ),
1311
+	__('delete form element', 'event_espresso'),
1312 1312
 
1313 1313
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:49
1314
-	__( 'form element settings', 'event_espresso' ),
1314
+	__('form element settings', 'event_espresso'),
1315 1315
 
1316 1316
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:59
1317
-	__( 'copy form element', 'event_espresso' ),
1317
+	__('copy form element', 'event_espresso'),
1318 1318
 
1319 1319
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:69
1320
-	__( 'click, hold, and drag to reorder form element', 'event_espresso' ),
1320
+	__('click, hold, and drag to reorder form element', 'event_espresso'),
1321 1321
 
1322 1322
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:20
1323
-	__( 'remove option', 'event_espresso' ),
1323
+	__('remove option', 'event_espresso'),
1324 1324
 
1325 1325
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:42
1326
-	__( 'value', 'event_espresso' ),
1326
+	__('value', 'event_espresso'),
1327 1327
 
1328 1328
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:52
1329
-	__( 'label', 'event_espresso' ),
1329
+	__('label', 'event_espresso'),
1330 1330
 
1331 1331
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:63
1332
-	__( 'click, hold, and drag to reorder field option', 'event_espresso' ),
1332
+	__('click, hold, and drag to reorder field option', 'event_espresso'),
1333 1333
 
1334 1334
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:61
1335
-	__( 'Options are the choices you give people to select from.', 'event_espresso' ),
1335
+	__('Options are the choices you give people to select from.', 'event_espresso'),
1336 1336
 
1337 1337
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:63
1338
-	__( 'The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso' ),
1338
+	__('The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso'),
1339 1339
 
1340 1340
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:96
1341
-	__( 'add new option', 'event_espresso' ),
1341
+	__('add new option', 'event_espresso'),
1342 1342
 
1343 1343
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:26
1344 1344
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:25
1345
-	__( 'Styles', 'event_espresso' ),
1345
+	__('Styles', 'event_espresso'),
1346 1346
 
1347 1347
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:30
1348
-	__( 'Validation', 'event_espresso' ),
1348
+	__('Validation', 'event_espresso'),
1349 1349
 
1350 1350
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:18
1351
-	__( 'Change input type', 'event_espresso' ),
1351
+	__('Change input type', 'event_espresso'),
1352 1352
 
1353 1353
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:19
1354
-	__( 'Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso' ),
1354
+	__('Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso'),
1355 1355
 
1356 1356
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:40
1357
-	__( 'type', 'event_espresso' ),
1357
+	__('type', 'event_espresso'),
1358 1358
 
1359 1359
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:26
1360 1360
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:17
1361
-	__( 'public label', 'event_espresso' ),
1361
+	__('public label', 'event_espresso'),
1362 1362
 
1363 1363
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:33
1364 1364
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:22
1365
-	__( 'admin label', 'event_espresso' ),
1365
+	__('admin label', 'event_espresso'),
1366 1366
 
1367 1367
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:40
1368
-	__( 'content', 'event_espresso' ),
1368
+	__('content', 'event_espresso'),
1369 1369
 
1370 1370
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:48
1371
-	__( 'options', 'event_espresso' ),
1371
+	__('options', 'event_espresso'),
1372 1372
 
1373 1373
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:51
1374
-	__( 'placeholder', 'event_espresso' ),
1374
+	__('placeholder', 'event_espresso'),
1375 1375
 
1376 1376
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:57
1377
-	__( 'admin only', 'event_espresso' ),
1377
+	__('admin only', 'event_espresso'),
1378 1378
 
1379 1379
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:62
1380
-	__( 'help text', 'event_espresso' ),
1380
+	__('help text', 'event_espresso'),
1381 1381
 
1382 1382
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:71
1383
-	__( 'maps to', 'event_espresso' ),
1383
+	__('maps to', 'event_espresso'),
1384 1384
 
1385 1385
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:15
1386 1386
 	// Reference: packages/form-builder/src/FormSection/Tabs/Styles.tsx:13
1387
-	__( 'css class', 'event_espresso' ),
1387
+	__('css class', 'event_espresso'),
1388 1388
 
1389 1389
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:20
1390
-	__( 'help text css class', 'event_espresso' ),
1390
+	__('help text css class', 'event_espresso'),
1391 1391
 
1392 1392
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:27
1393
-	__( 'size', 'event_espresso' ),
1393
+	__('size', 'event_espresso'),
1394 1394
 
1395 1395
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:35
1396
-	__( 'step', 'event_espresso' ),
1396
+	__('step', 'event_espresso'),
1397 1397
 
1398 1398
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:41
1399
-	__( 'maxlength', 'event_espresso' ),
1399
+	__('maxlength', 'event_espresso'),
1400 1400
 
1401 1401
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:123
1402
-	__( 'min', 'event_espresso' ),
1402
+	__('min', 'event_espresso'),
1403 1403
 
1404 1404
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:128
1405
-	__( 'max', 'event_espresso' ),
1405
+	__('max', 'event_espresso'),
1406 1406
 
1407 1407
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:28
1408
-	__( 'Germany', 'event_espresso' ),
1408
+	__('Germany', 'event_espresso'),
1409 1409
 
1410 1410
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:32
1411
-	__( 'France', 'event_espresso' ),
1411
+	__('France', 'event_espresso'),
1412 1412
 
1413 1413
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:36
1414
-	__( 'United Kingdom', 'event_espresso' ),
1414
+	__('United Kingdom', 'event_espresso'),
1415 1415
 
1416 1416
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:40
1417
-	__( 'United States', 'event_espresso' ),
1417
+	__('United States', 'event_espresso'),
1418 1418
 
1419 1419
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:44
1420
-	__( 'Custom', 'event_espresso' ),
1420
+	__('Custom', 'event_espresso'),
1421 1421
 
1422 1422
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:54
1423
-	__( 'required', 'event_espresso' ),
1423
+	__('required', 'event_espresso'),
1424 1424
 
1425 1425
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:59
1426
-	__( 'required text', 'event_espresso' ),
1426
+	__('required text', 'event_espresso'),
1427 1427
 
1428 1428
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:66
1429
-	__( 'autocomplete', 'event_espresso' ),
1429
+	__('autocomplete', 'event_espresso'),
1430 1430
 
1431 1431
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:74
1432
-	__( 'custom format', 'event_espresso' ),
1432
+	__('custom format', 'event_espresso'),
1433 1433
 
1434 1434
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:75
1435
-	__( 'format', 'event_espresso' ),
1435
+	__('format', 'event_espresso'),
1436 1436
 
1437 1437
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:83
1438
-	__( 'pattern', 'event_espresso' ),
1438
+	__('pattern', 'event_espresso'),
1439 1439
 
1440 1440
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:110
1441
-	__( 'add new form element', 'event_espresso' ),
1441
+	__('add new form element', 'event_espresso'),
1442 1442
 
1443 1443
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:117
1444 1444
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:52
1445
-	__( 'Add', 'event_espresso' ),
1445
+	__('Add', 'event_espresso'),
1446 1446
 
1447 1447
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:76
1448
-	__( 'Add Form Element', 'event_espresso' ),
1448
+	__('Add Form Element', 'event_espresso'),
1449 1449
 
1450 1450
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:85
1451
-	__( 'form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso' ),
1451
+	__('form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso'),
1452 1452
 
1453 1453
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:92
1454
-	__( 'load existing form section', 'event_espresso' ),
1454
+	__('load existing form section', 'event_espresso'),
1455 1455
 
1456 1456
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:32
1457
-	__( 'delete form section', 'event_espresso' ),
1457
+	__('delete form section', 'event_espresso'),
1458 1458
 
1459 1459
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:47
1460
-	__( 'form section settings', 'event_espresso' ),
1460
+	__('form section settings', 'event_espresso'),
1461 1461
 
1462 1462
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:57
1463
-	__( 'copy form section', 'event_espresso' ),
1463
+	__('copy form section', 'event_espresso'),
1464 1464
 
1465 1465
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:74
1466
-	__( 'click, hold, and drag to reorder form section', 'event_espresso' ),
1466
+	__('click, hold, and drag to reorder form section', 'event_espresso'),
1467 1467
 
1468 1468
 	// Reference: packages/form-builder/src/FormSection/FormSections.tsx:26
1469
-	__( 'Add Form Section', 'event_espresso' ),
1469
+	__('Add Form Section', 'event_espresso'),
1470 1470
 
1471 1471
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:47
1472
-	__( 'save form section for use in other forms', 'event_espresso' ),
1472
+	__('save form section for use in other forms', 'event_espresso'),
1473 1473
 
1474 1474
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:51
1475
-	__( 'save as', 'event_espresso' ),
1475
+	__('save as', 'event_espresso'),
1476 1476
 
1477 1477
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:55
1478
-	__( 'default', 'event_espresso' ),
1478
+	__('default', 'event_espresso'),
1479 1479
 
1480 1480
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:58
1481
-	__( ' a copy of this form section will be automatically added to ALL new events', 'event_espresso' ),
1481
+	__(' a copy of this form section will be automatically added to ALL new events', 'event_espresso'),
1482 1482
 
1483 1483
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:61
1484
-	__( 'shared', 'event_espresso' ),
1484
+	__('shared', 'event_espresso'),
1485 1485
 
1486 1486
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:64
1487
-	__( 'a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso' ),
1487
+	__('a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso'),
1488 1488
 
1489 1489
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:27
1490
-	__( 'show label', 'event_espresso' ),
1490
+	__('show label', 'event_espresso'),
1491 1491
 
1492 1492
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:33
1493
-	__( 'applies to', 'event_espresso' ),
1493
+	__('applies to', 'event_espresso'),
1494 1494
 
1495 1495
 	// Reference: packages/form-builder/src/constants.ts:102
1496 1496
 	// Reference: packages/form-builder/src/state/utils.ts:436
1497
-	__( 'URL', 'event_espresso' ),
1497
+	__('URL', 'event_espresso'),
1498 1498
 
1499 1499
 	// Reference: packages/form-builder/src/constants.ts:104
1500
-	__( 'adds a text input for entering a URL address', 'event_espresso' ),
1500
+	__('adds a text input for entering a URL address', 'event_espresso'),
1501 1501
 
1502 1502
 	// Reference: packages/form-builder/src/constants.ts:107
1503
-	__( 'Date', 'event_espresso' ),
1503
+	__('Date', 'event_espresso'),
1504 1504
 
1505 1505
 	// Reference: packages/form-builder/src/constants.ts:109
1506
-	__( 'adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso' ),
1506
+	__('adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso'),
1507 1507
 
1508 1508
 	// Reference: packages/form-builder/src/constants.ts:112
1509 1509
 	// Reference: packages/form-builder/src/state/utils.ts:369
1510
-	__( 'Local Date', 'event_espresso' ),
1510
+	__('Local Date', 'event_espresso'),
1511 1511
 
1512 1512
 	// Reference: packages/form-builder/src/constants.ts:117
1513
-	__( 'Month', 'event_espresso' ),
1513
+	__('Month', 'event_espresso'),
1514 1514
 
1515 1515
 	// Reference: packages/form-builder/src/constants.ts:119
1516
-	__( 'adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso' ),
1516
+	__('adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso'),
1517 1517
 
1518 1518
 	// Reference: packages/form-builder/src/constants.ts:122
1519
-	__( 'Time', 'event_espresso' ),
1519
+	__('Time', 'event_espresso'),
1520 1520
 
1521 1521
 	// Reference: packages/form-builder/src/constants.ts:124
1522
-	__( 'adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso' ),
1522
+	__('adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso'),
1523 1523
 
1524 1524
 	// Reference: packages/form-builder/src/constants.ts:127
1525
-	__( 'Week', 'event_espresso' ),
1525
+	__('Week', 'event_espresso'),
1526 1526
 
1527 1527
 	// Reference: packages/form-builder/src/constants.ts:129
1528
-	__( 'adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso' ),
1528
+	__('adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso'),
1529 1529
 
1530 1530
 	// Reference: packages/form-builder/src/constants.ts:132
1531
-	__( 'Day Selector', 'event_espresso' ),
1531
+	__('Day Selector', 'event_espresso'),
1532 1532
 
1533 1533
 	// Reference: packages/form-builder/src/constants.ts:134
1534
-	__( 'adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso' ),
1534
+	__('adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso'),
1535 1535
 
1536 1536
 	// Reference: packages/form-builder/src/constants.ts:137
1537
-	__( 'Month Selector', 'event_espresso' ),
1537
+	__('Month Selector', 'event_espresso'),
1538 1538
 
1539 1539
 	// Reference: packages/form-builder/src/constants.ts:139
1540
-	__( 'adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso' ),
1540
+	__('adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso'),
1541 1541
 
1542 1542
 	// Reference: packages/form-builder/src/constants.ts:142
1543
-	__( 'Year Selector', 'event_espresso' ),
1543
+	__('Year Selector', 'event_espresso'),
1544 1544
 
1545 1545
 	// Reference: packages/form-builder/src/constants.ts:144
1546
-	__( 'adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso' ),
1546
+	__('adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso'),
1547 1547
 
1548 1548
 	// Reference: packages/form-builder/src/constants.ts:147
1549
-	__( 'Radio Buttons', 'event_espresso' ),
1549
+	__('Radio Buttons', 'event_espresso'),
1550 1550
 
1551 1551
 	// Reference: packages/form-builder/src/constants.ts:149
1552
-	__( 'adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso' ),
1552
+	__('adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso'),
1553 1553
 
1554 1554
 	// Reference: packages/form-builder/src/constants.ts:152
1555 1555
 	// Reference: packages/form-builder/src/state/utils.ts:375
1556
-	__( 'Decimal Number', 'event_espresso' ),
1556
+	__('Decimal Number', 'event_espresso'),
1557 1557
 
1558 1558
 	// Reference: packages/form-builder/src/constants.ts:154
1559
-	__( 'adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso' ),
1559
+	__('adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso'),
1560 1560
 
1561 1561
 	// Reference: packages/form-builder/src/constants.ts:157
1562 1562
 	// Reference: packages/form-builder/src/state/utils.ts:378
1563
-	__( 'Whole Number', 'event_espresso' ),
1563
+	__('Whole Number', 'event_espresso'),
1564 1564
 
1565 1565
 	// Reference: packages/form-builder/src/constants.ts:159
1566
-	__( 'adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso' ),
1566
+	__('adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso'),
1567 1567
 
1568 1568
 	// Reference: packages/form-builder/src/constants.ts:162
1569
-	__( 'Number Range', 'event_espresso' ),
1569
+	__('Number Range', 'event_espresso'),
1570 1570
 
1571 1571
 	// Reference: packages/form-builder/src/constants.ts:167
1572
-	__( 'Phone Number', 'event_espresso' ),
1572
+	__('Phone Number', 'event_espresso'),
1573 1573
 
1574 1574
 	// Reference: packages/form-builder/src/constants.ts:172
1575
-	__( 'Dropdown', 'event_espresso' ),
1575
+	__('Dropdown', 'event_espresso'),
1576 1576
 
1577 1577
 	// Reference: packages/form-builder/src/constants.ts:174
1578
-	__( 'adds a dropdown selector that accepts a single value', 'event_espresso' ),
1578
+	__('adds a dropdown selector that accepts a single value', 'event_espresso'),
1579 1579
 
1580 1580
 	// Reference: packages/form-builder/src/constants.ts:177
1581
-	__( 'Multi Select', 'event_espresso' ),
1581
+	__('Multi Select', 'event_espresso'),
1582 1582
 
1583 1583
 	// Reference: packages/form-builder/src/constants.ts:179
1584
-	__( 'adds a dropdown selector that accepts multiple values', 'event_espresso' ),
1584
+	__('adds a dropdown selector that accepts multiple values', 'event_espresso'),
1585 1585
 
1586 1586
 	// Reference: packages/form-builder/src/constants.ts:182
1587
-	__( 'Toggle/Switch', 'event_espresso' ),
1587
+	__('Toggle/Switch', 'event_espresso'),
1588 1588
 
1589 1589
 	// Reference: packages/form-builder/src/constants.ts:184
1590
-	__( 'adds a toggle or a switch to accept true or false value', 'event_espresso' ),
1590
+	__('adds a toggle or a switch to accept true or false value', 'event_espresso'),
1591 1591
 
1592 1592
 	// Reference: packages/form-builder/src/constants.ts:187
1593
-	__( 'Multi Checkbox', 'event_espresso' ),
1593
+	__('Multi Checkbox', 'event_espresso'),
1594 1594
 
1595 1595
 	// Reference: packages/form-builder/src/constants.ts:189
1596
-	__( 'adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso' ),
1596
+	__('adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso'),
1597 1597
 
1598 1598
 	// Reference: packages/form-builder/src/constants.ts:192
1599
-	__( 'Country Selector', 'event_espresso' ),
1599
+	__('Country Selector', 'event_espresso'),
1600 1600
 
1601 1601
 	// Reference: packages/form-builder/src/constants.ts:194
1602
-	__( 'adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso' ),
1602
+	__('adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso'),
1603 1603
 
1604 1604
 	// Reference: packages/form-builder/src/constants.ts:197
1605
-	__( 'State Selector', 'event_espresso' ),
1605
+	__('State Selector', 'event_espresso'),
1606 1606
 
1607 1607
 	// Reference: packages/form-builder/src/constants.ts:202
1608
-	__( 'Button', 'event_espresso' ),
1608
+	__('Button', 'event_espresso'),
1609 1609
 
1610 1610
 	// Reference: packages/form-builder/src/constants.ts:204
1611
-	__( 'adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso' ),
1611
+	__('adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso'),
1612 1612
 
1613 1613
 	// Reference: packages/form-builder/src/constants.ts:207
1614
-	__( 'Reset Button', 'event_espresso' ),
1614
+	__('Reset Button', 'event_espresso'),
1615 1615
 
1616 1616
 	// Reference: packages/form-builder/src/constants.ts:209
1617
-	__( 'adds a button that will reset the form back to its original state.', 'event_espresso' ),
1617
+	__('adds a button that will reset the form back to its original state.', 'event_espresso'),
1618 1618
 
1619 1619
 	// Reference: packages/form-builder/src/constants.ts:55
1620
-	__( 'Form Section', 'event_espresso' ),
1620
+	__('Form Section', 'event_espresso'),
1621 1621
 
1622 1622
 	// Reference: packages/form-builder/src/constants.ts:57
1623
-	__( 'Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso' ),
1623
+	__('Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso'),
1624 1624
 
1625 1625
 	// Reference: packages/form-builder/src/constants.ts:62
1626
-	__( 'HTML Block', 'event_espresso' ),
1626
+	__('HTML Block', 'event_espresso'),
1627 1627
 
1628 1628
 	// Reference: packages/form-builder/src/constants.ts:64
1629
-	__( 'allows you to add HTML like headings or text paragraphs to your form', 'event_espresso' ),
1629
+	__('allows you to add HTML like headings or text paragraphs to your form', 'event_espresso'),
1630 1630
 
1631 1631
 	// Reference: packages/form-builder/src/constants.ts:69
1632
-	__( 'adds a text input that only accepts plain text', 'event_espresso' ),
1632
+	__('adds a text input that only accepts plain text', 'event_espresso'),
1633 1633
 
1634 1634
 	// Reference: packages/form-builder/src/constants.ts:72
1635
-	__( 'Plain Text Area', 'event_espresso' ),
1635
+	__('Plain Text Area', 'event_espresso'),
1636 1636
 
1637 1637
 	// Reference: packages/form-builder/src/constants.ts:74
1638
-	__( 'adds a textarea block that only accepts plain text', 'event_espresso' ),
1638
+	__('adds a textarea block that only accepts plain text', 'event_espresso'),
1639 1639
 
1640 1640
 	// Reference: packages/form-builder/src/constants.ts:77
1641
-	__( 'HTML Text Area', 'event_espresso' ),
1641
+	__('HTML Text Area', 'event_espresso'),
1642 1642
 
1643 1643
 	// Reference: packages/form-builder/src/constants.ts:79
1644
-	__( 'adds a textarea block that accepts text including simple HTML markup', 'event_espresso' ),
1644
+	__('adds a textarea block that accepts text including simple HTML markup', 'event_espresso'),
1645 1645
 
1646 1646
 	// Reference: packages/form-builder/src/constants.ts:84
1647
-	__( 'adds a text input that only accepts a valid email address', 'event_espresso' ),
1647
+	__('adds a text input that only accepts a valid email address', 'event_espresso'),
1648 1648
 
1649 1649
 	// Reference: packages/form-builder/src/constants.ts:87
1650
-	__( 'Email Confirmation', 'event_espresso' ),
1650
+	__('Email Confirmation', 'event_espresso'),
1651 1651
 
1652 1652
 	// Reference: packages/form-builder/src/constants.ts:92
1653
-	__( 'Password', 'event_espresso' ),
1653
+	__('Password', 'event_espresso'),
1654 1654
 
1655 1655
 	// Reference: packages/form-builder/src/constants.ts:94
1656
-	__( 'adds a text input that accepts text but masks what the user enters', 'event_espresso' ),
1656
+	__('adds a text input that accepts text but masks what the user enters', 'event_espresso'),
1657 1657
 
1658 1658
 	// Reference: packages/form-builder/src/constants.ts:97
1659
-	__( 'Password Confirmation', 'event_espresso' ),
1659
+	__('Password Confirmation', 'event_espresso'),
1660 1660
 
1661 1661
 	// Reference: packages/form-builder/src/data/useElementMutator.ts:54
1662
-	__( 'element', 'event_espresso' ),
1662
+	__('element', 'event_espresso'),
1663 1663
 
1664 1664
 	// Reference: packages/form-builder/src/data/useSectionMutator.ts:54
1665
-	__( 'section', 'event_espresso' ),
1665
+	__('section', 'event_espresso'),
1666 1666
 
1667 1667
 	// Reference: packages/form-builder/src/state/utils.ts:360
1668
-	__( 'click', 'event_espresso' ),
1668
+	__('click', 'event_espresso'),
1669 1669
 
1670 1670
 	// Reference: packages/form-builder/src/state/utils.ts:363
1671
-	__( 'checkboxes', 'event_espresso' ),
1671
+	__('checkboxes', 'event_espresso'),
1672 1672
 
1673 1673
 	// Reference: packages/form-builder/src/state/utils.ts:366
1674
-	__( 'date', 'event_espresso' ),
1674
+	__('date', 'event_espresso'),
1675 1675
 
1676 1676
 	// Reference: packages/form-builder/src/state/utils.ts:372
1677
-	__( 'day', 'event_espresso' ),
1677
+	__('day', 'event_espresso'),
1678 1678
 
1679 1679
 	// Reference: packages/form-builder/src/state/utils.ts:381
1680
-	__( 'email address', 'event_espresso' ),
1680
+	__('email address', 'event_espresso'),
1681 1681
 
1682 1682
 	// Reference: packages/form-builder/src/state/utils.ts:384
1683
-	__( 'confirm email address', 'event_espresso' ),
1683
+	__('confirm email address', 'event_espresso'),
1684 1684
 
1685 1685
 	// Reference: packages/form-builder/src/state/utils.ts:388
1686
-	__( 'month', 'event_espresso' ),
1686
+	__('month', 'event_espresso'),
1687 1687
 
1688 1688
 	// Reference: packages/form-builder/src/state/utils.ts:391
1689
-	__( 'password', 'event_espresso' ),
1689
+	__('password', 'event_espresso'),
1690 1690
 
1691 1691
 	// Reference: packages/form-builder/src/state/utils.ts:394
1692
-	__( 'confirm password', 'event_espresso' ),
1692
+	__('confirm password', 'event_espresso'),
1693 1693
 
1694 1694
 	// Reference: packages/form-builder/src/state/utils.ts:397
1695
-	__( 'radio buttons', 'event_espresso' ),
1695
+	__('radio buttons', 'event_espresso'),
1696 1696
 
1697 1697
 	// Reference: packages/form-builder/src/state/utils.ts:400
1698
-	__( 'number range', 'event_espresso' ),
1698
+	__('number range', 'event_espresso'),
1699 1699
 
1700 1700
 	// Reference: packages/form-builder/src/state/utils.ts:403
1701
-	__( 'selection dropdown', 'event_espresso' ),
1701
+	__('selection dropdown', 'event_espresso'),
1702 1702
 
1703 1703
 	// Reference: packages/form-builder/src/state/utils.ts:406
1704
-	__( 'country', 'event_espresso' ),
1704
+	__('country', 'event_espresso'),
1705 1705
 
1706 1706
 	// Reference: packages/form-builder/src/state/utils.ts:409
1707
-	__( 'multi-select dropdown', 'event_espresso' ),
1707
+	__('multi-select dropdown', 'event_espresso'),
1708 1708
 
1709 1709
 	// Reference: packages/form-builder/src/state/utils.ts:412
1710
-	__( 'state/province', 'event_espresso' ),
1710
+	__('state/province', 'event_espresso'),
1711 1711
 
1712 1712
 	// Reference: packages/form-builder/src/state/utils.ts:415
1713
-	__( 'on/off switch', 'event_espresso' ),
1713
+	__('on/off switch', 'event_espresso'),
1714 1714
 
1715 1715
 	// Reference: packages/form-builder/src/state/utils.ts:418
1716
-	__( 'reset', 'event_espresso' ),
1716
+	__('reset', 'event_espresso'),
1717 1717
 
1718 1718
 	// Reference: packages/form-builder/src/state/utils.ts:421
1719
-	__( 'phone number', 'event_espresso' ),
1719
+	__('phone number', 'event_espresso'),
1720 1720
 
1721 1721
 	// Reference: packages/form-builder/src/state/utils.ts:424
1722
-	__( 'text', 'event_espresso' ),
1722
+	__('text', 'event_espresso'),
1723 1723
 
1724 1724
 	// Reference: packages/form-builder/src/state/utils.ts:427
1725
-	__( 'simple textarea', 'event_espresso' ),
1725
+	__('simple textarea', 'event_espresso'),
1726 1726
 
1727 1727
 	// Reference: packages/form-builder/src/state/utils.ts:430
1728
-	__( 'html textarea', 'event_espresso' ),
1728
+	__('html textarea', 'event_espresso'),
1729 1729
 
1730 1730
 	// Reference: packages/form-builder/src/state/utils.ts:439
1731
-	__( 'week', 'event_espresso' ),
1731
+	__('week', 'event_espresso'),
1732 1732
 
1733 1733
 	// Reference: packages/form-builder/src/state/utils.ts:442
1734
-	__( 'year', 'event_espresso' ),
1734
+	__('year', 'event_espresso'),
1735 1735
 
1736 1736
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:12
1737
-	__( 'Select Image', 'event_espresso' ),
1737
+	__('Select Image', 'event_espresso'),
1738 1738
 
1739 1739
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:44
1740 1740
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:11
1741 1741
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:12
1742 1742
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityTemplate.tsx:32
1743
-	__( 'Select', 'event_espresso' ),
1743
+	__('Select', 'event_espresso'),
1744 1744
 
1745 1745
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:36
1746 1746
 	/* translators: %d the entry number */
1747
-	__( 'Entry %d', 'event_espresso' ),
1747
+	__('Entry %d', 'event_espresso'),
1748 1748
 
1749 1749
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1750 1750
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1751
-	__( 'sold out', 'event_espresso' ),
1751
+	__('sold out', 'event_espresso'),
1752 1752
 
1753 1753
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1754 1754
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1755
-	__( 'expired', 'event_espresso' ),
1755
+	__('expired', 'event_espresso'),
1756 1756
 
1757 1757
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1758
-	__( 'upcoming', 'event_espresso' ),
1758
+	__('upcoming', 'event_espresso'),
1759 1759
 
1760 1760
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1761
-	__( 'active', 'event_espresso' ),
1761
+	__('active', 'event_espresso'),
1762 1762
 
1763 1763
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1764 1764
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1765
-	__( 'trashed', 'event_espresso' ),
1765
+	__('trashed', 'event_espresso'),
1766 1766
 
1767 1767
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1768
-	__( 'cancelled', 'event_espresso' ),
1768
+	__('cancelled', 'event_espresso'),
1769 1769
 
1770 1770
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1771
-	__( 'postponed', 'event_espresso' ),
1771
+	__('postponed', 'event_espresso'),
1772 1772
 
1773 1773
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1774
-	__( 'inactive', 'event_espresso' ),
1774
+	__('inactive', 'event_espresso'),
1775 1775
 
1776 1776
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1777
-	__( 'pending', 'event_espresso' ),
1777
+	__('pending', 'event_espresso'),
1778 1778
 
1779 1779
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1780
-	__( 'on sale', 'event_espresso' ),
1780
+	__('on sale', 'event_espresso'),
1781 1781
 
1782 1782
 	// Reference: packages/predicates/src/registration/statusOptions.ts:16
1783
-	__( 'Declined', 'event_espresso' ),
1783
+	__('Declined', 'event_espresso'),
1784 1784
 
1785 1785
 	// Reference: packages/predicates/src/registration/statusOptions.ts:21
1786
-	__( 'Incomplete', 'event_espresso' ),
1786
+	__('Incomplete', 'event_espresso'),
1787 1787
 
1788 1788
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1789
-	__( 'Not Approved', 'event_espresso' ),
1789
+	__('Not Approved', 'event_espresso'),
1790 1790
 
1791 1791
 	// Reference: packages/predicates/src/registration/statusOptions.ts:31
1792
-	__( 'Pending Payment', 'event_espresso' ),
1792
+	__('Pending Payment', 'event_espresso'),
1793 1793
 
1794 1794
 	// Reference: packages/predicates/src/registration/statusOptions.ts:36
1795
-	__( 'Wait List', 'event_espresso' ),
1795
+	__('Wait List', 'event_espresso'),
1796 1796
 
1797 1797
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1798
-	__( 'Approved', 'event_espresso' ),
1798
+	__('Approved', 'event_espresso'),
1799 1799
 
1800 1800
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:9
1801 1801
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:10
1802
-	__( 'Select media', 'event_espresso' ),
1802
+	__('Select media', 'event_espresso'),
1803 1803
 
1804 1804
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/RichTextEditor.tsx:84
1805
-	__( 'Write something…', 'event_espresso' ),
1805
+	__('Write something…', 'event_espresso'),
1806 1806
 
1807 1807
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/Toolbar.tsx:20
1808
-	__( 'RTE Toolbar', 'event_espresso' ),
1808
+	__('RTE Toolbar', 'event_espresso'),
1809 1809
 
1810 1810
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:11
1811
-	__( 'Normal', 'event_espresso' ),
1811
+	__('Normal', 'event_espresso'),
1812 1812
 
1813 1813
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:12
1814
-	__( 'H1', 'event_espresso' ),
1814
+	__('H1', 'event_espresso'),
1815 1815
 
1816 1816
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:13
1817
-	__( 'H2', 'event_espresso' ),
1817
+	__('H2', 'event_espresso'),
1818 1818
 
1819 1819
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:14
1820
-	__( 'H3', 'event_espresso' ),
1820
+	__('H3', 'event_espresso'),
1821 1821
 
1822 1822
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:15
1823
-	__( 'H4', 'event_espresso' ),
1823
+	__('H4', 'event_espresso'),
1824 1824
 
1825 1825
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:16
1826
-	__( 'H5', 'event_espresso' ),
1826
+	__('H5', 'event_espresso'),
1827 1827
 
1828 1828
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:17
1829
-	__( 'H6', 'event_espresso' ),
1829
+	__('H6', 'event_espresso'),
1830 1830
 
1831 1831
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:18
1832
-	__( 'Block quote', 'event_espresso' ),
1832
+	__('Block quote', 'event_espresso'),
1833 1833
 
1834 1834
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:19
1835
-	__( 'Code', 'event_espresso' ),
1835
+	__('Code', 'event_espresso'),
1836 1836
 
1837 1837
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:36
1838
-	__( 'Set color', 'event_espresso' ),
1838
+	__('Set color', 'event_espresso'),
1839 1839
 
1840 1840
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:45
1841
-	__( 'Text color', 'event_espresso' ),
1841
+	__('Text color', 'event_espresso'),
1842 1842
 
1843 1843
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:47
1844
-	__( 'Background color', 'event_espresso' ),
1844
+	__('Background color', 'event_espresso'),
1845 1845
 
1846 1846
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:39
1847
-	__( 'Add image', 'event_espresso' ),
1847
+	__('Add image', 'event_espresso'),
1848 1848
 
1849 1849
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:51
1850
-	__( 'Image URL', 'event_espresso' ),
1850
+	__('Image URL', 'event_espresso'),
1851 1851
 
1852 1852
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:55
1853
-	__( 'Alt text', 'event_espresso' ),
1853
+	__('Alt text', 'event_espresso'),
1854 1854
 
1855 1855
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:56
1856
-	__( 'Width', 'event_espresso' ),
1856
+	__('Width', 'event_espresso'),
1857 1857
 
1858 1858
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:60
1859
-	__( 'Height', 'event_espresso' ),
1859
+	__('Height', 'event_espresso'),
1860 1860
 
1861 1861
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:54
1862
-	__( 'Edit link', 'event_espresso' ),
1862
+	__('Edit link', 'event_espresso'),
1863 1863
 
1864 1864
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:64
1865
-	__( 'URL title', 'event_espresso' ),
1865
+	__('URL title', 'event_espresso'),
1866 1866
 
1867 1867
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:11
1868
-	__( 'Unordered list', 'event_espresso' ),
1868
+	__('Unordered list', 'event_espresso'),
1869 1869
 
1870 1870
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:12
1871
-	__( 'Ordered list', 'event_espresso' ),
1871
+	__('Ordered list', 'event_espresso'),
1872 1872
 
1873 1873
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:13
1874 1874
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:13
1875
-	__( 'Indent', 'event_espresso' ),
1875
+	__('Indent', 'event_espresso'),
1876 1876
 
1877 1877
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:14
1878 1878
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:14
1879
-	__( 'Outdent', 'event_espresso' ),
1879
+	__('Outdent', 'event_espresso'),
1880 1880
 
1881 1881
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:11
1882
-	__( 'Unordered textalign', 'event_espresso' ),
1882
+	__('Unordered textalign', 'event_espresso'),
1883 1883
 
1884 1884
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:12
1885
-	__( 'Ordered textalign', 'event_espresso' ),
1885
+	__('Ordered textalign', 'event_espresso'),
1886 1886
 
1887 1887
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/render/Image/Toolbar.tsx:32
1888
-	__( 'Image toolbar', 'event_espresso' ),
1888
+	__('Image toolbar', 'event_espresso'),
1889 1889
 
1890 1890
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:62
1891 1891
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:35
1892
-	__( 'Visual editor', 'event_espresso' ),
1892
+	__('Visual editor', 'event_espresso'),
1893 1893
 
1894 1894
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:66
1895 1895
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:39
1896
-	__( 'HTML editor', 'event_espresso' ),
1896
+	__('HTML editor', 'event_espresso'),
1897 1897
 
1898 1898
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:68
1899
-	__( 'Add Media', 'event_espresso' ),
1899
+	__('Add Media', 'event_espresso'),
1900 1900
 
1901 1901
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:14
1902
-	__( 'add new price modifier after this row', 'event_espresso' ),
1902
+	__('add new price modifier after this row', 'event_espresso'),
1903 1903
 
1904 1904
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:14
1905
-	__( 'Delete all prices', 'event_espresso' ),
1905
+	__('Delete all prices', 'event_espresso'),
1906 1906
 
1907 1907
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:27
1908
-	__( 'Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso' ),
1908
+	__('Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso'),
1909 1909
 
1910 1910
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:31
1911
-	__( 'Delete all prices?', 'event_espresso' ),
1911
+	__('Delete all prices?', 'event_espresso'),
1912 1912
 
1913 1913
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1914
-	__( 'delete price modifier', 'event_espresso' ),
1914
+	__('delete price modifier', 'event_espresso'),
1915 1915
 
1916 1916
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:14
1917
-	__( 'Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso' ),
1917
+	__('Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso'),
1918 1918
 
1919 1919
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:17
1920
-	__( 'Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso' ),
1920
+	__('Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso'),
1921 1921
 
1922 1922
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1923
-	__( 'Disable reverse calculate', 'event_espresso' ),
1923
+	__('Disable reverse calculate', 'event_espresso'),
1924 1924
 
1925 1925
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1926
-	__( 'Enable reverse calculate', 'event_espresso' ),
1926
+	__('Enable reverse calculate', 'event_espresso'),
1927 1927
 
1928 1928
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:28
1929
-	__( 'ticket price calculator', 'event_espresso' ),
1929
+	__('ticket price calculator', 'event_espresso'),
1930 1930
 
1931 1931
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:9
1932
-	__( 'Add default taxes', 'event_espresso' ),
1932
+	__('Add default taxes', 'event_espresso'),
1933 1933
 
1934 1934
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:10
1935
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1935
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1936 1936
 
1937 1937
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:14
1938
-	__( 'Remove all taxes?', 'event_espresso' ),
1938
+	__('Remove all taxes?', 'event_espresso'),
1939 1939
 
1940 1940
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:7
1941
-	__( 'Remove taxes', 'event_espresso' ),
1941
+	__('Remove taxes', 'event_espresso'),
1942 1942
 
1943 1943
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:29
1944
-	__( 'Modify default prices.', 'event_espresso' ),
1944
+	__('Modify default prices.', 'event_espresso'),
1945 1945
 
1946 1946
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:29
1947
-	__( 'New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso' ),
1947
+	__('New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso'),
1948 1948
 
1949 1949
 	// Reference: packages/tpc/src/components/LockedTicketsBanner.tsx:12
1950
-	__( 'Editing of prices is disabled', 'event_espresso' ),
1950
+	__('Editing of prices is disabled', 'event_espresso'),
1951 1951
 
1952 1952
 	// Reference: packages/tpc/src/components/NoPricesBanner/AddDefaultPricesButton.tsx:9
1953
-	__( 'Add default prices', 'event_espresso' ),
1953
+	__('Add default prices', 'event_espresso'),
1954 1954
 
1955 1955
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:13
1956
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1956
+	__('This Ticket is Currently Free', 'event_espresso'),
1957 1957
 
1958 1958
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:21
1959 1959
 	/* translators: %s default prices */
1960
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1960
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1961 1961
 
1962 1962
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:22
1963
-	__( 'default prices', 'event_espresso' ),
1963
+	__('default prices', 'event_espresso'),
1964 1964
 
1965 1965
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:29
1966
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1966
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1967 1967
 
1968 1968
 	// Reference: packages/tpc/src/components/NoPricesBanner/index.tsx:32
1969
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1969
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1970 1970
 
1971 1971
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:32
1972 1972
 	/* translators: %s ticket name */
1973
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
1973
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
1974 1974
 
1975 1975
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:48
1976
-	__( 'Total', 'event_espresso' ),
1976
+	__('Total', 'event_espresso'),
1977 1977
 
1978 1978
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:57
1979
-	__( 'ticket total', 'event_espresso' ),
1979
+	__('ticket total', 'event_espresso'),
1980 1980
 
1981 1981
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
1982
-	__( 'Order', 'event_espresso' ),
1982
+	__('Order', 'event_espresso'),
1983 1983
 
1984 1984
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
1985
-	__( 'Price Type', 'event_espresso' ),
1985
+	__('Price Type', 'event_espresso'),
1986 1986
 
1987 1987
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
1988
-	__( 'Label', 'event_espresso' ),
1988
+	__('Label', 'event_espresso'),
1989 1989
 
1990 1990
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
1991
-	__( 'Amount', 'event_espresso' ),
1991
+	__('Amount', 'event_espresso'),
1992 1992
 
1993 1993
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:22
1994
-	__( 'Copy ticket', 'event_espresso' ),
1994
+	__('Copy ticket', 'event_espresso'),
1995 1995
 
1996 1996
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:26
1997
-	__( 'Copy and archive this ticket', 'event_espresso' ),
1997
+	__('Copy and archive this ticket', 'event_espresso'),
1998 1998
 
1999 1999
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:29
2000
-	__( 'OK', 'event_espresso' ),
2000
+	__('OK', 'event_espresso'),
2001 2001
 
2002 2002
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:32
2003
-	__( 'amount', 'event_espresso' ),
2003
+	__('amount', 'event_espresso'),
2004 2004
 
2005 2005
 	// Reference: packages/tpc/src/inputs/PriceAmountInput.tsx:44
2006
-	__( 'amount…', 'event_espresso' ),
2006
+	__('amount…', 'event_espresso'),
2007 2007
 
2008 2008
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:14
2009
-	__( 'description…', 'event_espresso' ),
2009
+	__('description…', 'event_espresso'),
2010 2010
 
2011 2011
 	// Reference: packages/tpc/src/inputs/PriceDescriptionInput.tsx:9
2012
-	__( 'price description', 'event_espresso' ),
2012
+	__('price description', 'event_espresso'),
2013 2013
 
2014 2014
 	// Reference: packages/tpc/src/inputs/PriceIdInput.tsx:5
2015
-	__( 'price id', 'event_espresso' ),
2015
+	__('price id', 'event_espresso'),
2016 2016
 
2017 2017
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:13
2018
-	__( 'label…', 'event_espresso' ),
2018
+	__('label…', 'event_espresso'),
2019 2019
 
2020 2020
 	// Reference: packages/tpc/src/inputs/PriceNameInput.tsx:8
2021
-	__( 'price name', 'event_espresso' ),
2021
+	__('price name', 'event_espresso'),
2022 2022
 
2023 2023
 	// Reference: packages/tpc/src/inputs/PriceOrderInput.tsx:14
2024
-	__( 'price order', 'event_espresso' ),
2024
+	__('price order', 'event_espresso'),
2025 2025
 
2026 2026
 	// Reference: packages/tpc/src/utils/constants.ts:8
2027
-	__( 'Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso' ),
2027
+	__('Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso'),
2028 2028
 
2029 2029
 	// Reference: packages/ui-components/src/ActiveFilters/ActiveFilters.tsx:8
2030
-	__( 'active filters:', 'event_espresso' ),
2030
+	__('active filters:', 'event_espresso'),
2031 2031
 
2032 2032
 	// Reference: packages/ui-components/src/ActiveFilters/FilterTag/index.tsx:15
2033 2033
 	/* translators: %s filter name */
2034
-	__( 'remove filter - %s', 'event_espresso' ),
2034
+	__('remove filter - %s', 'event_espresso'),
2035 2035
 
2036 2036
 	// Reference: packages/ui-components/src/Address/Address.tsx:72
2037
-	__( 'Address:', 'event_espresso' ),
2037
+	__('Address:', 'event_espresso'),
2038 2038
 
2039 2039
 	// Reference: packages/ui-components/src/Address/Address.tsx:80
2040
-	__( 'City:', 'event_espresso' ),
2040
+	__('City:', 'event_espresso'),
2041 2041
 
2042 2042
 	// Reference: packages/ui-components/src/Address/Address.tsx:86
2043
-	__( 'State:', 'event_espresso' ),
2043
+	__('State:', 'event_espresso'),
2044 2044
 
2045 2045
 	// Reference: packages/ui-components/src/Address/Address.tsx:92
2046
-	__( 'Country:', 'event_espresso' ),
2046
+	__('Country:', 'event_espresso'),
2047 2047
 
2048 2048
 	// Reference: packages/ui-components/src/Address/Address.tsx:98
2049
-	__( 'Zip:', 'event_espresso' ),
2049
+	__('Zip:', 'event_espresso'),
2050 2050
 
2051 2051
 	// Reference: packages/ui-components/src/CalendarDateRange/CalendarDateRange.tsx:37
2052
-	__( 'to', 'event_espresso' ),
2052
+	__('to', 'event_espresso'),
2053 2053
 
2054 2054
 	// Reference: packages/ui-components/src/CalendarPageDate/CalendarPageDate.tsx:54
2055
-	__( 'TO', 'event_espresso' ),
2055
+	__('TO', 'event_espresso'),
2056 2056
 
2057 2057
 	// Reference: packages/ui-components/src/ColorPicker/ColorPicker.tsx:60
2058
-	__( 'Custom color', 'event_espresso' ),
2058
+	__('Custom color', 'event_espresso'),
2059 2059
 
2060 2060
 	// Reference: packages/ui-components/src/ColorPicker/Swatch.tsx:23
2061 2061
 	/* translators: color name */
2062
-	__( 'Color: %s', 'event_espresso' ),
2062
+	__('Color: %s', 'event_espresso'),
2063 2063
 
2064 2064
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:13
2065
-	__( 'Cyan bluish gray', 'event_espresso' ),
2065
+	__('Cyan bluish gray', 'event_espresso'),
2066 2066
 
2067 2067
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:17
2068
-	__( 'White', 'event_espresso' ),
2068
+	__('White', 'event_espresso'),
2069 2069
 
2070 2070
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:21
2071
-	__( 'Pale pink', 'event_espresso' ),
2071
+	__('Pale pink', 'event_espresso'),
2072 2072
 
2073 2073
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:25
2074
-	__( 'Vivid red', 'event_espresso' ),
2074
+	__('Vivid red', 'event_espresso'),
2075 2075
 
2076 2076
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:29
2077
-	__( 'Luminous vivid orange', 'event_espresso' ),
2077
+	__('Luminous vivid orange', 'event_espresso'),
2078 2078
 
2079 2079
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:33
2080
-	__( 'Luminous vivid amber', 'event_espresso' ),
2080
+	__('Luminous vivid amber', 'event_espresso'),
2081 2081
 
2082 2082
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:37
2083
-	__( 'Light green cyan', 'event_espresso' ),
2083
+	__('Light green cyan', 'event_espresso'),
2084 2084
 
2085 2085
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:41
2086
-	__( 'Vivid green cyan', 'event_espresso' ),
2086
+	__('Vivid green cyan', 'event_espresso'),
2087 2087
 
2088 2088
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:45
2089
-	__( 'Pale cyan blue', 'event_espresso' ),
2089
+	__('Pale cyan blue', 'event_espresso'),
2090 2090
 
2091 2091
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:49
2092
-	__( 'Vivid cyan blue', 'event_espresso' ),
2092
+	__('Vivid cyan blue', 'event_espresso'),
2093 2093
 
2094 2094
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:53
2095
-	__( 'Vivid purple', 'event_espresso' ),
2095
+	__('Vivid purple', 'event_espresso'),
2096 2096
 
2097 2097
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:9
2098
-	__( 'Black', 'event_espresso' ),
2098
+	__('Black', 'event_espresso'),
2099 2099
 
2100 2100
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:7
2101 2101
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:22
2102
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
2102
+	__('Are you sure you want to close this?', 'event_espresso'),
2103 2103
 
2104 2104
 	// Reference: packages/ui-components/src/Confirm/ConfirmDelete.tsx:7
2105
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
2105
+	__('Are you sure you want to delete this?', 'event_espresso'),
2106 2106
 
2107 2107
 	// Reference: packages/ui-components/src/Confirm/useConfirmWithButton.tsx:10
2108
-	__( 'Please confirm this action.', 'event_espresso' ),
2108
+	__('Please confirm this action.', 'event_espresso'),
2109 2109
 
2110 2110
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:32
2111
-	__( 'No', 'event_espresso' ),
2111
+	__('No', 'event_espresso'),
2112 2112
 
2113 2113
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:33
2114
-	__( 'Yes', 'event_espresso' ),
2114
+	__('Yes', 'event_espresso'),
2115 2115
 
2116 2116
 	// Reference: packages/ui-components/src/CurrencyDisplay/CurrencyDisplay.tsx:34
2117
-	__( 'free', 'event_espresso' ),
2117
+	__('free', 'event_espresso'),
2118 2118
 
2119 2119
 	// Reference: packages/ui-components/src/DateTimeRangePicker/DateTimeRangePicker.tsx:117
2120 2120
 	// Reference: packages/ui-components/src/Popover/PopoverForm/PopoverForm.tsx:44
2121
-	__( 'save', 'event_espresso' ),
2121
+	__('save', 'event_espresso'),
2122 2122
 
2123 2123
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2124
-	__( 'Hide Debug Info', 'event_espresso' ),
2124
+	__('Hide Debug Info', 'event_espresso'),
2125 2125
 
2126 2126
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2127
-	__( 'Show Debug Info', 'event_espresso' ),
2127
+	__('Show Debug Info', 'event_espresso'),
2128 2128
 
2129 2129
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:49
2130
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
2130
+	__('Edit Start and End Dates and Times', 'event_espresso'),
2131 2131
 
2132 2132
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Copy.tsx:8
2133
-	__( 'copy', 'event_espresso' ),
2133
+	__('copy', 'event_espresso'),
2134 2134
 
2135 2135
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Edit.tsx:8
2136
-	__( 'edit', 'event_espresso' ),
2136
+	__('edit', 'event_espresso'),
2137 2137
 
2138 2138
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Trash.tsx:8
2139
-	__( 'trash', 'event_espresso' ),
2139
+	__('trash', 'event_espresso'),
2140 2140
 
2141 2141
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Untrash.tsx:8
2142
-	__( 'untrash', 'event_espresso' ),
2142
+	__('untrash', 'event_espresso'),
2143 2143
 
2144 2144
 	// Reference: packages/ui-components/src/EntityList/RegistrationsLink/index.tsx:12
2145
-	__( 'click to open the registrations admin page in a new tab or window', 'event_espresso' ),
2145
+	__('click to open the registrations admin page in a new tab or window', 'event_espresso'),
2146 2146
 
2147 2147
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:22
2148
-	__( 'card view', 'event_espresso' ),
2148
+	__('card view', 'event_espresso'),
2149 2149
 
2150 2150
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:21
2151
-	__( 'table view', 'event_espresso' ),
2151
+	__('table view', 'event_espresso'),
2152 2152
 
2153 2153
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2154
-	__( 'hide bulk actions', 'event_espresso' ),
2154
+	__('hide bulk actions', 'event_espresso'),
2155 2155
 
2156 2156
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2157
-	__( 'show bulk actions', 'event_espresso' ),
2157
+	__('show bulk actions', 'event_espresso'),
2158 2158
 
2159 2159
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
2160
-	__( 'hide filters', 'event_espresso' ),
2160
+	__('hide filters', 'event_espresso'),
2161 2161
 
2162 2162
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:9
2163
-	__( 'show filters', 'event_espresso' ),
2163
+	__('show filters', 'event_espresso'),
2164 2164
 
2165 2165
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
2166
-	__( 'hide legend', 'event_espresso' ),
2166
+	__('hide legend', 'event_espresso'),
2167 2167
 
2168 2168
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:26
2169
-	__( 'show legend', 'event_espresso' ),
2169
+	__('show legend', 'event_espresso'),
2170 2170
 
2171 2171
 	// Reference: packages/ui-components/src/LoadingNotice/LoadingNotice.tsx:11
2172
-	__( 'loading…', 'event_espresso' ),
2172
+	__('loading…', 'event_espresso'),
2173 2173
 
2174 2174
 	// Reference: packages/ui-components/src/Modal/Modal.tsx:58
2175
-	__( 'close modal', 'event_espresso' ),
2175
+	__('close modal', 'event_espresso'),
2176 2176
 
2177 2177
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:10
2178
-	__( 'jump to previous', 'event_espresso' ),
2178
+	__('jump to previous', 'event_espresso'),
2179 2179
 
2180 2180
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:11
2181
-	__( 'jump to next', 'event_espresso' ),
2181
+	__('jump to next', 'event_espresso'),
2182 2182
 
2183 2183
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:12
2184
-	__( 'page', 'event_espresso' ),
2184
+	__('page', 'event_espresso'),
2185 2185
 
2186 2186
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:8
2187
-	__( 'previous', 'event_espresso' ),
2187
+	__('previous', 'event_espresso'),
2188 2188
 
2189 2189
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:9
2190
-	__( 'next', 'event_espresso' ),
2190
+	__('next', 'event_espresso'),
2191 2191
 
2192 2192
 	// Reference: packages/ui-components/src/Pagination/PerPage.tsx:37
2193
-	__( 'items per page', 'event_espresso' ),
2193
+	__('items per page', 'event_espresso'),
2194 2194
 
2195 2195
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
2196 2196
 	/* translators: %s is per page value */
2197
-	__( '%s / page', 'event_espresso' ),
2197
+	__('%s / page', 'event_espresso'),
2198 2198
 
2199 2199
 	// Reference: packages/ui-components/src/Pagination/constants.ts:13
2200
-	__( 'Next Page', 'event_espresso' ),
2200
+	__('Next Page', 'event_espresso'),
2201 2201
 
2202 2202
 	// Reference: packages/ui-components/src/Pagination/constants.ts:14
2203
-	__( 'Previous Page', 'event_espresso' ),
2203
+	__('Previous Page', 'event_espresso'),
2204 2204
 
2205 2205
 	// Reference: packages/ui-components/src/PercentSign/index.tsx:10
2206
-	__( '%', 'event_espresso' ),
2206
+	__('%', 'event_espresso'),
2207 2207
 
2208 2208
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:31
2209 2209
 	/* translators: entity type to select */
2210
-	__( 'Select an existing %s to use as a template.', 'event_espresso' ),
2210
+	__('Select an existing %s to use as a template.', 'event_espresso'),
2211 2211
 
2212 2212
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:38
2213
-	__( 'or', 'event_espresso' ),
2213
+	__('or', 'event_espresso'),
2214 2214
 
2215 2215
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:43
2216 2216
 	/* translators: entity type to add */
2217
-	__( 'Add a new %s and insert details manually', 'event_espresso' ),
2217
+	__('Add a new %s and insert details manually', 'event_espresso'),
2218 2218
 
2219 2219
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:48
2220
-	__( 'Add New', 'event_espresso' ),
2220
+	__('Add New', 'event_espresso'),
2221 2221
 
2222 2222
 	// Reference: packages/ui-components/src/Stepper/buttons/Next.tsx:8
2223
-	__( 'Next', 'event_espresso' ),
2223
+	__('Next', 'event_espresso'),
2224 2224
 
2225 2225
 	// Reference: packages/ui-components/src/Stepper/buttons/Previous.tsx:8
2226
-	__( 'Previous', 'event_espresso' ),
2226
+	__('Previous', 'event_espresso'),
2227 2227
 
2228 2228
 	// Reference: packages/ui-components/src/Steps/Steps.tsx:31
2229
-	__( 'Steps', 'event_espresso' ),
2229
+	__('Steps', 'event_espresso'),
2230 2230
 
2231 2231
 	// Reference: packages/ui-components/src/TabbableText/index.tsx:21
2232
-	__( 'click to edit…', 'event_espresso' ),
2232
+	__('click to edit…', 'event_espresso'),
2233 2233
 
2234 2234
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:14
2235
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
2235
+	__('The Website\'s Time Zone', 'event_espresso'),
2236 2236
 
2237 2237
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:19
2238
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
2238
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
2239 2239
 
2240 2240
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:9
2241
-	__( 'Your Local Time Zone', 'event_espresso' ),
2241
+	__('Your Local Time Zone', 'event_espresso'),
2242 2242
 
2243 2243
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:27
2244
-	__( 'click for timezone information', 'event_espresso' ),
2244
+	__('click for timezone information', 'event_espresso'),
2245 2245
 
2246 2246
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:32
2247
-	__( 'This Date Converted To:', 'event_espresso' ),
2247
+	__('This Date Converted To:', 'event_espresso'),
2248 2248
 
2249 2249
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:120
2250
-	__( 'Add New Venue', 'event_espresso' ),
2250
+	__('Add New Venue', 'event_espresso'),
2251 2251
 
2252 2252
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:36
2253
-	__( '~ no venue ~', 'event_espresso' ),
2253
+	__('~ no venue ~', 'event_espresso'),
2254 2254
 
2255 2255
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:43
2256
-	__( 'assign venue…', 'event_espresso' ),
2256
+	__('assign venue…', 'event_espresso'),
2257 2257
 
2258 2258
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:44
2259
-	__( 'click to select a venue…', 'event_espresso' ),
2259
+	__('click to select a venue…', 'event_espresso'),
2260 2260
 
2261 2261
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:51
2262
-	__( 'select all', 'event_espresso' ),
2262
+	__('select all', 'event_espresso'),
2263 2263
 
2264 2264
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:54
2265
-	__( 'apply', 'event_espresso' )
2265
+	__('apply', 'event_espresso')
2266 2266
 );
2267 2267
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.
core/helpers/EEH_Array.helper.php 1 patch
Indentation   +217 added lines, -217 removed lines patch added patch discarded remove patch
@@ -13,221 +13,221 @@
 block discarded – undo
13 13
 {
14 14
 
15 15
 
16
-    /**
17
-     * This method basically works the same as the PHP core function array_diff except it allows you to compare arrays
18
-     * of EE_Base_Class objects NOTE: This will ONLY work on an array of EE_Base_Class objects
19
-     *
20
-     * @uses array_udiff core php function for setting up our own array comparison
21
-     * @uses self::_compare_objects as the custom method for array_udiff
22
-     * @param  array $array1 an array of objects
23
-     * @param  array $array2 an array of objects
24
-     * @return array         an array of objects found in array 1 that aren't found in array 2.
25
-     */
26
-    public static function object_array_diff($array1, $array2)
27
-    {
28
-        return array_udiff($array1, $array2, array('self', '_compare_objects'));
29
-    }
30
-
31
-    /**
32
-     * Given that $arr is an array, determines if it's associative or numerically AND sequentially indexed
33
-     *
34
-     * @param array $array
35
-     * @return boolean
36
-     */
37
-    public static function is_associative_array(array $array): bool
38
-    {
39
-        return ! empty($array) && array_keys($array) !== range(0, count($array) - 1);
40
-    }
41
-
42
-    /**
43
-     * Gets an item from the array and leave the array intact. Use in place of end()
44
-     * when you don't want to change the array
45
-     *
46
-     * @param array $arr
47
-     * @return mixed what ever is in the array
48
-     */
49
-    public static function get_one_item_from_array($arr)
50
-    {
51
-        $item = end($arr);
52
-        reset($arr);
53
-        return $item;
54
-    }
55
-
56
-    /**
57
-     * Detects if this is a multi-dimensional array
58
-     * meaning that at least one top-level value is an array. Eg [ [], ...]
59
-     *
60
-     * @param mixed $arr
61
-     * @return boolean
62
-     */
63
-    public static function is_multi_dimensional_array($arr)
64
-    {
65
-        if (is_array($arr)) {
66
-            foreach ($arr as $item) {
67
-                if (is_array($item)) {
68
-                    return true; // yep, there's at least 2 levels to this array
69
-                }
70
-            }
71
-        }
72
-        return false; // there's only 1 level, or it's not an array at all!
73
-    }
74
-
75
-    /**
76
-     * Shorthand for isset( $arr[ $index ] ) ? $arr[ $index ] : $default
77
-     *
78
-     * @param array $arr
79
-     * @param mixed $index
80
-     * @param mixed $default
81
-     * @return mixed
82
-     */
83
-    public static function is_set($arr, $index, $default)
84
-    {
85
-        return isset($arr[ $index ]) ? $arr[ $index ] : $default;
86
-    }
87
-
88
-    /**
89
-     * Exactly like `maybe_unserialize`, but also accounts for a WP bug: http://core.trac.wordpress.org/ticket/26118
90
-     *
91
-     * @param mixed $value usually a string, but could be an array or object
92
-     * @return mixed the UN-serialized data
93
-     */
94
-    public static function maybe_unserialize($value)
95
-    {
96
-        $data = maybe_unserialize($value);
97
-        // it's possible that this still has serialized data if it's the session.
98
-        //  WP has a bug, http://core.trac.wordpress.org/ticket/26118 that doesn't unserialize this automatically.
99
-        $token = 'C';
100
-        $data = is_string($data) ? trim($data) : $data;
101
-        if (is_string($data) && strlen($data) > 1 && $data[0] == $token && preg_match("/^{$token}:[0-9]+:/s", $data)) {
102
-            return unserialize($data);
103
-        } else {
104
-            return $data;
105
-        }
106
-    }
107
-
108
-
109
-    /**
110
-     * insert_into_array
111
-     *
112
-     * @param array        $target_array the array to insert new data into
113
-     * @param array        $array_to_insert the new data to be inserted
114
-     * @param int | string $offset a known key within $target_array where new data will be inserted
115
-     * @param bool         $add_before whether to add new data before or after the offset key
116
-     * @param bool         $preserve_keys whether or not to reset numerically indexed arrays
117
-     * @return array
118
-     */
119
-    public static function insert_into_array(
120
-        $target_array = array(),
121
-        $array_to_insert = array(),
122
-        $offset = null,
123
-        $add_before = true,
124
-        $preserve_keys = true
125
-    ) {
126
-        // ensure incoming arrays are actually arrays
127
-        $target_array = (array) $target_array;
128
-        $array_to_insert = (array) $array_to_insert;
129
-        // if no offset key was supplied
130
-        if (empty($offset)) {
131
-            // use start or end of $target_array based on whether we are adding before or not
132
-            $offset = $add_before ? 0 : count($target_array);
133
-        }
134
-        // if offset key is a string, then find the corresponding numeric location for that element
135
-        $offset = is_int($offset) ? $offset : array_search($offset, array_keys($target_array));
136
-        // add one to the offset if adding after
137
-        $offset = $add_before ? $offset : $offset + 1;
138
-        // but ensure offset does not exceed the length of the array
139
-        $offset = $offset > count($target_array) ? count($target_array) : $offset;
140
-        // reindex array ???
141
-        if ($preserve_keys) {
142
-            // take a slice of the target array from the beginning till the offset,
143
-            // then add the new data
144
-            // then add another slice that starts at the offset and goes till the end
145
-            return array_slice($target_array, 0, $offset, true) + $array_to_insert + array_slice(
146
-                $target_array,
147
-                $offset,
148
-                null,
149
-                true
150
-            );
151
-        } else {
152
-            // since we don't want to preserve keys, we can use array_splice
153
-            array_splice($target_array, $offset, 0, $array_to_insert);
154
-            return $target_array;
155
-        }
156
-    }
157
-
158
-
159
-    /**
160
-     * array_merge() is slow and should never be used while looping over data
161
-     * if you don't need to preserve keys from all arrays, then using a foreach loop is much faster
162
-     * so really this acts more like array_replace( $array1, $array2 )
163
-     * or a union with the arrays flipped ( $array2 + $array1 )
164
-     * this saves a few lines of code and improves readability
165
-     *
166
-     * @param array $array1
167
-     * @param array $array2
168
-     * @return array
169
-     */
170
-    public static function merge_arrays_and_overwrite_keys(array $array1, array $array2)
171
-    {
172
-        foreach ($array2 as $key => $value) {
173
-            $array1[ $key ] = $value;
174
-        }
175
-        return $array1;
176
-    }
177
-
178
-
179
-    /**
180
-     * given a flat array like $array = array('A', 'B', 'C')
181
-     * will convert into a multidimensional array like $array[A][B][C]
182
-     * if $final_value is provided and is anything other than null,
183
-     * then that will be set as the value for the innermost array key
184
-     * like so: $array[A][B][C] = $final_value
185
-     *
186
-     * @param array $flat_array
187
-     * @param mixed $final_value
188
-     * @return array
189
-     */
190
-    public static function convert_array_values_to_keys(array $flat_array, $final_value = null)
191
-    {
192
-        $multidimensional = array();
193
-        $reference = &$multidimensional;
194
-        foreach ($flat_array as $key) {
195
-            $reference[ $key ] = array();
196
-            $reference = &$reference[ $key ];
197
-        }
198
-        if ($final_value !== null) {
199
-            $reference = $final_value;
200
-        }
201
-        return $multidimensional;
202
-    }
203
-
204
-
205
-    /**
206
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
207
-     * @param array $array
208
-     * @return bool
209
-     */
210
-    public static function is_array_numerically_and_sequentially_indexed(array $array)
211
-    {
212
-        return empty($array) || array_keys($array) === range(0, count($array) - 1);
213
-    }
214
-
215
-
216
-    /**
217
-     * recursively walks through an array and adds slashes to all no array elements
218
-     *
219
-     * @param mixed $element
220
-     * @return array|string
221
-     * @since   4.10.29.p
222
-     */
223
-    public static function addSlashesRecursively($element)
224
-    {
225
-        if (is_array($element)) {
226
-            foreach ($element as $key => $value) {
227
-                $element[ $key ] = EEH_Array::addSlashesRecursively($value);
228
-            }
229
-            return $element;
230
-        }
231
-        return is_string($element) ? addslashes($element) : $element;
232
-    }
16
+	/**
17
+	 * This method basically works the same as the PHP core function array_diff except it allows you to compare arrays
18
+	 * of EE_Base_Class objects NOTE: This will ONLY work on an array of EE_Base_Class objects
19
+	 *
20
+	 * @uses array_udiff core php function for setting up our own array comparison
21
+	 * @uses self::_compare_objects as the custom method for array_udiff
22
+	 * @param  array $array1 an array of objects
23
+	 * @param  array $array2 an array of objects
24
+	 * @return array         an array of objects found in array 1 that aren't found in array 2.
25
+	 */
26
+	public static function object_array_diff($array1, $array2)
27
+	{
28
+		return array_udiff($array1, $array2, array('self', '_compare_objects'));
29
+	}
30
+
31
+	/**
32
+	 * Given that $arr is an array, determines if it's associative or numerically AND sequentially indexed
33
+	 *
34
+	 * @param array $array
35
+	 * @return boolean
36
+	 */
37
+	public static function is_associative_array(array $array): bool
38
+	{
39
+		return ! empty($array) && array_keys($array) !== range(0, count($array) - 1);
40
+	}
41
+
42
+	/**
43
+	 * Gets an item from the array and leave the array intact. Use in place of end()
44
+	 * when you don't want to change the array
45
+	 *
46
+	 * @param array $arr
47
+	 * @return mixed what ever is in the array
48
+	 */
49
+	public static function get_one_item_from_array($arr)
50
+	{
51
+		$item = end($arr);
52
+		reset($arr);
53
+		return $item;
54
+	}
55
+
56
+	/**
57
+	 * Detects if this is a multi-dimensional array
58
+	 * meaning that at least one top-level value is an array. Eg [ [], ...]
59
+	 *
60
+	 * @param mixed $arr
61
+	 * @return boolean
62
+	 */
63
+	public static function is_multi_dimensional_array($arr)
64
+	{
65
+		if (is_array($arr)) {
66
+			foreach ($arr as $item) {
67
+				if (is_array($item)) {
68
+					return true; // yep, there's at least 2 levels to this array
69
+				}
70
+			}
71
+		}
72
+		return false; // there's only 1 level, or it's not an array at all!
73
+	}
74
+
75
+	/**
76
+	 * Shorthand for isset( $arr[ $index ] ) ? $arr[ $index ] : $default
77
+	 *
78
+	 * @param array $arr
79
+	 * @param mixed $index
80
+	 * @param mixed $default
81
+	 * @return mixed
82
+	 */
83
+	public static function is_set($arr, $index, $default)
84
+	{
85
+		return isset($arr[ $index ]) ? $arr[ $index ] : $default;
86
+	}
87
+
88
+	/**
89
+	 * Exactly like `maybe_unserialize`, but also accounts for a WP bug: http://core.trac.wordpress.org/ticket/26118
90
+	 *
91
+	 * @param mixed $value usually a string, but could be an array or object
92
+	 * @return mixed the UN-serialized data
93
+	 */
94
+	public static function maybe_unserialize($value)
95
+	{
96
+		$data = maybe_unserialize($value);
97
+		// it's possible that this still has serialized data if it's the session.
98
+		//  WP has a bug, http://core.trac.wordpress.org/ticket/26118 that doesn't unserialize this automatically.
99
+		$token = 'C';
100
+		$data = is_string($data) ? trim($data) : $data;
101
+		if (is_string($data) && strlen($data) > 1 && $data[0] == $token && preg_match("/^{$token}:[0-9]+:/s", $data)) {
102
+			return unserialize($data);
103
+		} else {
104
+			return $data;
105
+		}
106
+	}
107
+
108
+
109
+	/**
110
+	 * insert_into_array
111
+	 *
112
+	 * @param array        $target_array the array to insert new data into
113
+	 * @param array        $array_to_insert the new data to be inserted
114
+	 * @param int | string $offset a known key within $target_array where new data will be inserted
115
+	 * @param bool         $add_before whether to add new data before or after the offset key
116
+	 * @param bool         $preserve_keys whether or not to reset numerically indexed arrays
117
+	 * @return array
118
+	 */
119
+	public static function insert_into_array(
120
+		$target_array = array(),
121
+		$array_to_insert = array(),
122
+		$offset = null,
123
+		$add_before = true,
124
+		$preserve_keys = true
125
+	) {
126
+		// ensure incoming arrays are actually arrays
127
+		$target_array = (array) $target_array;
128
+		$array_to_insert = (array) $array_to_insert;
129
+		// if no offset key was supplied
130
+		if (empty($offset)) {
131
+			// use start or end of $target_array based on whether we are adding before or not
132
+			$offset = $add_before ? 0 : count($target_array);
133
+		}
134
+		// if offset key is a string, then find the corresponding numeric location for that element
135
+		$offset = is_int($offset) ? $offset : array_search($offset, array_keys($target_array));
136
+		// add one to the offset if adding after
137
+		$offset = $add_before ? $offset : $offset + 1;
138
+		// but ensure offset does not exceed the length of the array
139
+		$offset = $offset > count($target_array) ? count($target_array) : $offset;
140
+		// reindex array ???
141
+		if ($preserve_keys) {
142
+			// take a slice of the target array from the beginning till the offset,
143
+			// then add the new data
144
+			// then add another slice that starts at the offset and goes till the end
145
+			return array_slice($target_array, 0, $offset, true) + $array_to_insert + array_slice(
146
+				$target_array,
147
+				$offset,
148
+				null,
149
+				true
150
+			);
151
+		} else {
152
+			// since we don't want to preserve keys, we can use array_splice
153
+			array_splice($target_array, $offset, 0, $array_to_insert);
154
+			return $target_array;
155
+		}
156
+	}
157
+
158
+
159
+	/**
160
+	 * array_merge() is slow and should never be used while looping over data
161
+	 * if you don't need to preserve keys from all arrays, then using a foreach loop is much faster
162
+	 * so really this acts more like array_replace( $array1, $array2 )
163
+	 * or a union with the arrays flipped ( $array2 + $array1 )
164
+	 * this saves a few lines of code and improves readability
165
+	 *
166
+	 * @param array $array1
167
+	 * @param array $array2
168
+	 * @return array
169
+	 */
170
+	public static function merge_arrays_and_overwrite_keys(array $array1, array $array2)
171
+	{
172
+		foreach ($array2 as $key => $value) {
173
+			$array1[ $key ] = $value;
174
+		}
175
+		return $array1;
176
+	}
177
+
178
+
179
+	/**
180
+	 * given a flat array like $array = array('A', 'B', 'C')
181
+	 * will convert into a multidimensional array like $array[A][B][C]
182
+	 * if $final_value is provided and is anything other than null,
183
+	 * then that will be set as the value for the innermost array key
184
+	 * like so: $array[A][B][C] = $final_value
185
+	 *
186
+	 * @param array $flat_array
187
+	 * @param mixed $final_value
188
+	 * @return array
189
+	 */
190
+	public static function convert_array_values_to_keys(array $flat_array, $final_value = null)
191
+	{
192
+		$multidimensional = array();
193
+		$reference = &$multidimensional;
194
+		foreach ($flat_array as $key) {
195
+			$reference[ $key ] = array();
196
+			$reference = &$reference[ $key ];
197
+		}
198
+		if ($final_value !== null) {
199
+			$reference = $final_value;
200
+		}
201
+		return $multidimensional;
202
+	}
203
+
204
+
205
+	/**
206
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
207
+	 * @param array $array
208
+	 * @return bool
209
+	 */
210
+	public static function is_array_numerically_and_sequentially_indexed(array $array)
211
+	{
212
+		return empty($array) || array_keys($array) === range(0, count($array) - 1);
213
+	}
214
+
215
+
216
+	/**
217
+	 * recursively walks through an array and adds slashes to all no array elements
218
+	 *
219
+	 * @param mixed $element
220
+	 * @return array|string
221
+	 * @since   4.10.29.p
222
+	 */
223
+	public static function addSlashesRecursively($element)
224
+	{
225
+		if (is_array($element)) {
226
+			foreach ($element as $key => $value) {
227
+				$element[ $key ] = EEH_Array::addSlashesRecursively($value);
228
+			}
229
+			return $element;
230
+		}
231
+		return is_string($element) ? addslashes($element) : $element;
232
+	}
233 233
 }
Please login to merge, or discard this patch.